@@ -548,10 +548,10 @@ class Puzzle {
548548 // For this function to work correctly, cells need to have their surrond to be exact and their neighbor to contain all correct edges (there may be more edges than the correct ones)
549549 // This function fills in the rest of the fields, and modify incorrect fields if needed
550550
551- fix_points(point, fix_adjacent = true, off_centered = false ) {
551+ fix_points(point) {
552552 // First pass - reset fields
553553 for (var i in point) {
554- if (this.types[0].indexOf(point[i].type) !== -1 && fix_adjacent ) {
554+ if (this.types[0].indexOf(point[i].type) !== -1) {
555555 point[i].adjacent = [];
556556 }
557557 if (this.types[1].indexOf(point[i].type) !== -1) {
@@ -579,40 +579,24 @@ class Puzzle {
579579 for (let j = 0; j < vertices.length; j++) {
580580 point[vertices[j]].neighbor.push(parseInt(i));
581581 for (let k = j + 1; k < vertices.length; k++) {
582+ let not_connected = false;
582583 let vertex1 = point[vertices[j]];
583584 let vertex2 = point[vertices[k]];
584- if (Math.abs(vertex1.x - vertex2.x) < 0.001) {
585- for (let l = 0; l < edge_bank.length; l++) {
586- if (Math.abs(point[edge_bank[l]].x - vertex1.x) < 0.001) {
587- if ((!off_centered && (Math.abs(vertex1.y + vertex2.y - 2*point[edge_bank[l]].y) < 0.001)) || (off_centered && (vertex1.y < point[edge_bank[l]].y === point[edge_bank[l]].y < vertex2.y))) {
588- deltas.push({diff: 0,
589- v1: Math.min(vertices[j], vertices[k]),
590- v2: Math.max(vertices[j], vertices[k]),
591- edge: edge_bank[l]});
592- }
585+ for (let l = 0; l < vertices.length; l++) {
586+ if (l !== j && l !== k) {
587+ if ((this.distance_to_line(vertex1, vertex2, point[vertices[l]]) < 0.001) && this.between_points(vertex1, vertex2, point[vertices[l]])) {
588+ not_connected = true;
593589 }
594590 }
595- } else if (Math.abs(vertex1.y - vertex2.y) < 0.001) {
596- for (let l = 0; l < edge_bank.length; l++) {
597- if (Math.abs(point[edge_bank[l]].y - vertex1.y) < 0.001) {
598- if ((!off_centered && (Math.abs(vertex1.x + vertex2.x - 2*point[edge_bank[l]].x) < 0.001)) || (off_centered && (vertex1.x < point[edge_bank[l]].x === point[edge_bank[l]].x < vertex2.x))) {
599- deltas.push({diff: 0,
600- v1: Math.min(vertices[j], vertices[k]),
601- v2: Math.max(vertices[j], vertices[k]),
602- edge: edge_bank[l]});
603- }
604- }
605- }
606- } else {
591+ }
592+ if (!not_connected) {
607593 for (let l = 0; l < edge_bank.length; l++) {
608- let delta = Math.abs(((vertex1.y - point[edge_bank[l]].y)*(vertex2.x - point[edge_bank[l]].x)) -
609- ((vertex1.x - point[edge_bank[l]].x)*(vertex2.y - point[edge_bank[l]].y)));
610- if ((!off_centered && (Math.abs(vertex1.x + vertex2.x - 2*point[edge_bank[l]].x) < 0.001) && (Math.abs(vertex1.y + vertex2.y - 2*point[edge_bank[l]].y) < 0.001) ) ||
611- (off_centered && (vertex1.x < point[edge_bank[l]].x === point[edge_bank[l]].x < vertex2.x) && (vertex1.y < point[edge_bank[l]].y === point[edge_bank[l]].y < vertex2.y))) {
594+ let delta = this.distance_to_line(vertex1, vertex2, point[edge_bank[l]]);
595+ if (this.between_points(vertex1, vertex2, point[edge_bank[l]])) {
612596 deltas.push({diff: delta,
613- v1: Math.min(vertices[j], vertices[k]),
614- v2: Math.max(vertices[j], vertices[k]),
615- edge: edge_bank[l]});
597+ v1: Math.min(vertices[j], vertices[k]),
598+ v2: Math.max(vertices[j], vertices[k]),
599+ edge: edge_bank[l]});
616600 }
617601 }
618602 }
@@ -624,12 +608,6 @@ class Puzzle {
624608 for (let j = 0; j < vertices.length; j++) {
625609 // Fill in the edge_to_vertex data, and add the cell to the edge's neighbour
626610 point[deltas[j].edge].edge_to_vertex = [deltas[j].v1, deltas[j].v2];
627- if (point[deltas[j].v1].edge_to_vertex.indexOf(deltas[j].edge) < 0) {
628- point[deltas[j].v1].edge_to_vertex.push(deltas[j].edge);
629- }
630- if (point[deltas[j].v2].edge_to_vertex.indexOf(deltas[j].edge) < 0) {
631- point[deltas[j].v2].edge_to_vertex.push(deltas[j].edge);
632- }
633611 point[deltas[j].edge].neighbor.push(parseInt(i));
634612 edges.push(deltas[j].edge);
635613 }
@@ -649,10 +627,15 @@ class Puzzle {
649627 }
650628 }
651629 // Fix cells adjacent
652- if (edge.neighbor.length == 2 && fix_adjacent ) {
630+ if (edge.neighbor.length == 2) {
653631 point[edge.neighbor[j]].adjacent.push(parseInt(edge.neighbor[(j + 1) % 2]));
654632 }
655633 }
634+ // Fix vertices' edge_to_vertex
635+ if (!!edge.edge_to_vertex) {
636+ for (let j = 0; j < edge.edge_to_vertex.length; j++)
637+ point[edge.edge_to_vertex[j]].edge_to_vertex.push(parseInt(i));
638+ }
656639 }
657640 }
658641 return point;
@@ -667,14 +650,18 @@ class Puzzle {
667650 let vertices = edge.edge_to_vertex;
668651 if (vertices.length == 2) {
669652 for (let j = 0; j < cells.length; j++) {
670- point[this.corner_table[cells[j]][vertices[0]]].adjacent.push(parseInt(this.corner_table[cells[j]][vertices[1]]));
671- point[this.corner_table[cells[j]][vertices[1]]].adjacent.push(parseInt(this.corner_table[cells[j]][vertices[0]]));
653+ if (!!point[this.corner_table[cells[j]][vertices[0]]] && !!point[this.corner_table[cells[j]][vertices[1]]]) {
654+ point[this.corner_table[cells[j]][vertices[0]]].adjacent.push(parseInt(this.corner_table[cells[j]][vertices[1]]));
655+ point[this.corner_table[cells[j]][vertices[1]]].adjacent.push(parseInt(this.corner_table[cells[j]][vertices[0]]));
656+ }
672657 }
673658 }
674659 if (cells.length == 2) {
675660 for (let j = 0; j < 2; j++) {
676- point[this.corner_table[cells[1]][vertices[j]]].adjacent.push(parseInt(this.corner_table[cells[0]][vertices[j]]));
677- point[this.corner_table[cells[0]][vertices[j]]].adjacent.push(parseInt(this.corner_table[cells[1]][vertices[j]]));
661+ if (!!point[this.corner_table[cells[0]][vertices[j]]] && !!point[this.corner_table[cells[1]][vertices[j]]]) {
662+ point[this.corner_table[cells[1]][vertices[j]]].adjacent.push(parseInt(this.corner_table[cells[0]][vertices[j]]));
663+ point[this.corner_table[cells[0]][vertices[j]]].adjacent.push(parseInt(this.corner_table[cells[1]][vertices[j]]));
664+ }
678665 }
679666 }
680667 }
@@ -687,7 +674,7 @@ class Puzzle {
687674 let cells = [];
688675 let corners = [];
689676 for (var i in point) {
690- if (this.types[0].indexOf(point[i].type) !== -1 && point[i].use !== -1 ) {
677+ if (this.types[0].indexOf(point[i].type) !== -1) {
691678 cells.push(parseInt(i));
692679 }
693680 if (this.types[3].indexOf(point[i].type) !== -1) {
@@ -702,13 +689,12 @@ class Puzzle {
702689 let cell = point[cells[i]];
703690 for (let j = 0; j < cell.surround.length; j++) {
704691 let vertex = point[cell.surround[j]];
705- let min = Number.MAX_VALUE ;
692+ let min = 1 ;
706693 let corner = 0;
707694 for (let k = 0; k < corners.length; k++) {
708695 let corner_point = point[corners[k]];
709- let diff = Math.abs((cell.y - vertex.y)*corner_point.x - (cell.x - vertex.x)*corner_point.y + (cell.x * vertex.y) - (cell.y * vertex.x)) /
710- Math.sqrt((cell.y - vertex.y)**2 + (cell.x - vertex.x)**2);
711- if ((min > diff) && (cell.x > point[corners[k]].x === point[corners[k]].x > vertex.x) && (cell.y > point[corners[k]].y === point[corners[k]].y > vertex.y)) {
696+ let diff = this.distance_to_line(cell, vertex, corner_point);
697+ if ((min > diff) && (Math.min(vertex.use, cell.use) !== -1) && this.between_points(vertex, cell, corner_point)) {
712698 min = diff;
713699 corner = corners[k];
714700 }
@@ -717,13 +703,30 @@ class Puzzle {
717703 point[corner].surround.push(parseInt(cell.surround[j]));
718704 point[corner].neighbor.push(parseInt(cells[i]));
719705 this.corner_table[cells[i]][cell.surround[j]] = corner;
720- this.remove_from_array(corners, corner);
721706 }
722707 }
723708 }
724709 return point;
725710 }
726711
712+ // Helper functions
713+ distance_to_line(line1, line2, point) {
714+ if (!line1 || !line2 || !point) {
715+ return Number.MAX_VALUE;
716+ }
717+ return Math.abs((line1.y - line2.y)*point.x - (line1.x - line2.x)*point.y + (line1.x * line2.y) - (line1.y * line2.x)) /
718+ Math.sqrt((line1.y - line2.y)**2 + (line1.x - line2.x)**2);
719+ }
720+
721+ between_points(p1, p2, test) {
722+ if (!p1 || !p2 || !test) {
723+ return false;
724+ }
725+ return (Math.min(p1.x,p2.x) <= (test.x + 0.00001)) && ((test.x - 0.00001) <= Math.max(p1.x, p2.x)) &&
726+ (Math.min(p1.y,p2.y) <= (test.y + 0.00001)) && ((test.y - 0.00001) <= Math.max(p1.y, p2.y));
727+ }
728+
729+
727730 // Create corners to be used by the puzzle
728731 create_corners(point, radius, k) {
729732 for (var i in point) {
@@ -9624,9 +9627,9 @@ class Puzzle {
96249627
96259628
96269629 let line_style = this.mode[this.mode.qa][this.mode[this.mode.qa].edit_mode][1];
9627- // Find if any cell of the new cage (if square grid) has outside half grid cells then skip
9630+ // Find if any cell of the new cage has outside half grid cells then skip
96289631 for (let i = 0; i < this.cageselection.length; i++) {
9629- if (this.cell_outside_for_square (this.cageselection[i])) {
9632+ if (this.cell_outside (this.cageselection[i])) {
96309633 cageexist_status = true;
96319634 skip_cages = true;
96329635 break;
@@ -9834,7 +9837,7 @@ class Puzzle {
98349837 while (cage_queue.length > 0) {
98359838 let cell = cage_queue.shift();
98369839 found_cage.push(cell);
9837- if (this.cell_outside_for_square (cell) || !this.corner_table[cell]) {
9840+ if (this.cell_outside (cell) || !this.corner_table[cell]) {
98389841 not_in_cage = true;
98399842 break;
98409843 }
@@ -9883,7 +9886,7 @@ class Puzzle {
98839886 while (flood_queue.length > 0) {
98849887 let cell = flood_queue.shift();
98859888 context.push(cell);
9886- if (this.cell_outside_for_square (cell)) {
9889+ if (this.cell_outside (cell)) {
98879890 full = true;
98889891 break;
98899892 }
@@ -9928,7 +9931,7 @@ class Puzzle {
99289931 while (temp_queue.length > 0) {
99299932 let cell = temp_queue.shift();
99309933 temp_area.push(cell);
9931- if (this.cell_outside_for_square (cell) || !this.corner_table[cell]) {
9934+ if (this.cell_outside (cell) || !this.corner_table[cell]) {
99329935 reached_outside = true;
99339936 break;
99349937 }
@@ -9962,15 +9965,13 @@ class Puzzle {
99629965 return output;
99639966 }
99649967
9965- // Returns true if a cell is partly outside on a square grid
9966- cell_outside_for_square(cell) {
9967- if (this.grid_is_square()) {
9968- let row_size = parseInt(this.ny0 - 4);
9969- let col_size = parseInt(this.nx0 - 4);
9970- let col_num = (cell % (this.nx0)) - 2;
9971- let row_num = parseInt(cell / this.nx0) - 2;
9972-
9973- if ((row_num < 0) || (row_num >= row_size) || (col_num < 0) || (col_num >= col_size)) {
9968+ // Returns true if a cell is partly outside
9969+ cell_outside(cell) {
9970+ if (!cell) {
9971+ return true;
9972+ }
9973+ for (let i = 0; i < this.point[cell].surround.length; i++) {
9974+ if (!this.between_points({x: -1, y: -1}, {x: this.canvasx + 1, y: this.canvasy + 1}, this.point[this.point[cell].surround[i]])) {
99749975 return true;
99759976 }
99769977 }
@@ -13023,11 +13024,19 @@ class Puzzle {
1302313024 // i1-j1 and i2-j2 can define lines. Find the intersection of both lines, and connect the intersection to i1, then the intersection to i2
1302413025 let pi1 = this.get_cage_coordinates(i1, r);
1302513026 let pi2 = this.get_cage_coordinates(i2, r);
13026- let pj1 = this.get_cage_coordinates(j1, r) ;
13027- let pj2 = this.get_cage_coordinates(j2, r) ;
13027+ let pj1, pj2, denom ;
13028+ let skip = false ;
1302813029 let intersect = [];
13029-
13030- let denom = ((pj2[1] - pi2[1]) * (pj1[0] - pi1[0])) - ((pj2[0] - pi2[0]) * (pj1[1] - pi1[1]));
13030+ if (!this.point[j1] || !this.point[j2]) {
13031+ // Cannot find the other points for some reason
13032+ skip = true;
13033+ denom = 0;
13034+ }
13035+ if (!skip) {
13036+ pj1 = this.get_cage_coordinates(j1, r);
13037+ pj2 = this.get_cage_coordinates(j2, r);
13038+ denom = ((pj2[1] - pi2[1]) * (pj1[0] - pi1[0])) - ((pj2[0] - pi2[0]) * (pj1[1] - pi1[1]));
13039+ }
1303113040 if (Math.abs(denom) < 0.0001 ) {
1303213041 // Undefined intersection, just take midpoint
1303313042 intersect = [(pi1[0] + pi2[0]) / 2, (pi1[1] + pi2[1]) / 2];
0 commit comments