mirror of
https://github.com/Doodle3D/Doodle3D-Slicer.git
synced 2024-11-22 05:37:55 +01:00
update example
This commit is contained in:
parent
e966bc89b2
commit
0f70855989
226
comb.js
226
comb.js
@ -1,6 +1,7 @@
|
|||||||
import earcut from 'earcut';
|
import earcut from 'earcut';
|
||||||
import { add, divide, distanceTo, normalize, subtract, normal, dot } from './src/sliceActions/helpers/vector2.js';
|
import { add, divide, distanceTo, normalize, subtract, normal, dot } from './src/sliceActions/helpers/vector2.js';
|
||||||
|
|
||||||
|
|
||||||
function lineIntersection(a1, a2, b1, b2) {
|
function lineIntersection(a1, a2, b1, b2) {
|
||||||
// source: http://mathworld.wolfram.com/Line-LineIntersection.html
|
// source: http://mathworld.wolfram.com/Line-LineIntersection.html
|
||||||
const intersection = {
|
const intersection = {
|
||||||
@ -93,100 +94,102 @@ function decompose(polygon) {
|
|||||||
return { vertices, convexPolygons };
|
return { vertices, convexPolygons };
|
||||||
}
|
}
|
||||||
|
|
||||||
function findClosestPath(convexPolygons, start, end, visited = [], path = []) {
|
// const distanceMap = new WeakMap();
|
||||||
if (start === end) return [];
|
// function findClosestPath(convexPolygons, start, end, visited = [], path = [], distance = 0) {
|
||||||
|
// if (start === end) return [];
|
||||||
|
//
|
||||||
|
// visited = [...visited, start];
|
||||||
|
//
|
||||||
|
// const { connects } = convexPolygons[start];
|
||||||
|
//
|
||||||
|
// const finish = connects.find(({ to }) => to === end);
|
||||||
|
// if (finish) return [...path, finish];
|
||||||
|
//
|
||||||
|
// const posibilities = [];
|
||||||
|
// for (let i = 0; i < connects.length; i ++) {
|
||||||
|
// const connect = connects[i];
|
||||||
|
// if (visited.includes(connect.to)) continue;
|
||||||
|
//
|
||||||
|
// const positibiltyDistance = distance + connect.distance;
|
||||||
|
// const posibility = findClosestPath(convexPolygons, connect.to, end, visited, [...path, connect], positibiltyDistance);
|
||||||
|
// if (posibility) {
|
||||||
|
// posibilities.push(posibility);
|
||||||
|
// distanceMap.set(posibility, positibiltyDistance);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (posibilities.length === 0) {
|
||||||
|
// return null;
|
||||||
|
// } else if (posibilities.length === 1) {
|
||||||
|
// return posibilities[0];
|
||||||
|
// } else if (posibilities.length > 1) {
|
||||||
|
// return posibilities.sort((a, b) => distanceMap.get(a) - distanceMap.get(b))[0];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
visited = [...visited, start];
|
const findKey = _key => ({ key }) => _key === key;
|
||||||
|
function findClosestPath(map, start, end) {
|
||||||
|
// dijkstra's algorithm
|
||||||
|
const distances = { [start]: 0 };
|
||||||
|
const open = [{ key: 0, nodes: [start] }];
|
||||||
|
const predecessors = {};
|
||||||
|
|
||||||
const { connects } = convexPolygons[start];
|
while (open.length !== 0) {
|
||||||
|
const key = Math.min(...open.map(n => n.key).sort());
|
||||||
|
const bucket = open.find(findKey(key));
|
||||||
|
const node = bucket.nodes.shift();
|
||||||
|
const currentDistance = key;
|
||||||
|
const { connects } = map[node];
|
||||||
|
|
||||||
const finish = connects.find(({ to }) => to === end);
|
if (bucket.nodes.length === 0) open.splice(open.indexOf(bucket), 1);
|
||||||
if (finish) return [...path, finish];
|
|
||||||
|
|
||||||
const posibilities = [];
|
for (let i = 0; i < connects.length; i ++) {
|
||||||
for (const connect of connects) {
|
const { distance, to } = connects[i];
|
||||||
if (visited.includes(connect.to)) continue;
|
const totalDistance = distance + currentDistance;
|
||||||
|
const vertexDistance = distances[to];
|
||||||
|
|
||||||
const posibility = findClosestPath(convexPolygons, connect.to, end, visited, [...path, connect]);
|
if ((typeof vertexDistance === 'undefined') || (vertexDistance > totalDistance)) {
|
||||||
if (posibility) posibilities.push(posibility);
|
distances[to] = totalDistance;
|
||||||
|
|
||||||
|
let openNode = open.find(findKey(totalDistance));
|
||||||
|
if (!openNode) {
|
||||||
|
openNode = { key: totalDistance, nodes: [] };
|
||||||
|
open.push(openNode);
|
||||||
|
}
|
||||||
|
openNode.nodes.push(to);
|
||||||
|
|
||||||
|
predecessors[to] = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (posibilities.length === 0) {
|
if (typeof distances[end] === 'undefined') return null;
|
||||||
return null;
|
|
||||||
} else if (posibilities.length === 1) {
|
const nodes = [];
|
||||||
return posibilities[0];
|
let node = end;
|
||||||
} else if (posibilities.length > 1) {
|
while (typeof node !== 'undefined') {
|
||||||
const distanceMap = new WeakMap();
|
nodes.push(node);
|
||||||
for (const posibility of posibilities) {
|
node = predecessors[node];
|
||||||
const distance = posibility.reduce((totalDistance, connect) => totalDistance + connect.distance, 0);
|
}
|
||||||
distanceMap.set(posibility, distance);
|
nodes.reverse();
|
||||||
|
|
||||||
|
const path = [];
|
||||||
|
for (let i = 1; i < nodes.length; i ++) {
|
||||||
|
const from = nodes[i - 1];
|
||||||
|
const to = nodes[i];
|
||||||
|
|
||||||
|
const connection = map[from].connects.find(connect => connect.to === to);
|
||||||
|
path.push(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return posibilities.sort((a, b) => distanceMap.get(a) - distanceMap.get(b))[0];
|
return path;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const parse = string => parseFloat(string);
|
|
||||||
// function findClosestPath(map, start, end) {
|
|
||||||
// // dijkstra's algorithm
|
|
||||||
// const costs = { [start]: 0 };
|
|
||||||
// const open = { [0]: [start] };
|
|
||||||
// const predecessors = {};
|
|
||||||
//
|
|
||||||
// while (open) {
|
|
||||||
// const keys = Object.keys(open).map(parse);
|
|
||||||
// if (keys.length === 0) break;
|
|
||||||
// keys.sort();
|
|
||||||
//
|
|
||||||
// const [key] = keys;
|
|
||||||
// const bucket = open[key];
|
|
||||||
// const node = bucket.shift();
|
|
||||||
// const currentCost = key;
|
|
||||||
// const { connects } = map[node];
|
|
||||||
//
|
|
||||||
// if (!bucket.length) delete open[key];
|
|
||||||
//
|
|
||||||
// for (const { distance, to } of connects) {
|
|
||||||
// const totalCost = distance + currentCost;
|
|
||||||
// const vertexCost = costs[to];
|
|
||||||
//
|
|
||||||
// if ((typeof vertexCost === 'undefined') || (vertexCost > totalCost)) {
|
|
||||||
// costs[to] = totalCost;
|
|
||||||
//
|
|
||||||
// if (!open[totalCost]) open[totalCost] = [];
|
|
||||||
// open[totalCost].push(to);
|
|
||||||
//
|
|
||||||
// predecessors[to] = node;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (typeof costs[end] === 'undefined') return null;
|
|
||||||
//
|
|
||||||
// const nodes = [];
|
|
||||||
// let node = end;
|
|
||||||
// while (typeof node !== 'undefined') {
|
|
||||||
// nodes.push(node);
|
|
||||||
// node = predecessors[node];
|
|
||||||
// }
|
|
||||||
// nodes.reverse();
|
|
||||||
//
|
|
||||||
// const path = [];
|
|
||||||
// for (let i = 1; i < nodes.length; i ++) {
|
|
||||||
// const from = nodes[i - 1];
|
|
||||||
// const to = nodes[i];
|
|
||||||
//
|
|
||||||
// const connection = map[from].connects.find(connect => connect.to === to);
|
|
||||||
// path.push(connection);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return path;
|
|
||||||
// }
|
|
||||||
|
|
||||||
function containLineInPath(path, start, end, vertices) {
|
function containLineInPath(path, start, end, vertices) {
|
||||||
const line = [start];
|
const line = [start];
|
||||||
|
|
||||||
for (const { edge: [indexA, indexB] } of path) {
|
for (let i = 0; i < path.length; i ++) {
|
||||||
|
const { edge: [indexA, indexB] } = path[i];
|
||||||
const vertexA = vertices[indexA];
|
const vertexA = vertices[indexA];
|
||||||
const vertexB = vertices[indexB];
|
const vertexB = vertices[indexB];
|
||||||
|
|
||||||
@ -204,6 +207,7 @@ function containLineInPath(path, start, end, vertices) {
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
canvas.width = 610;
|
canvas.width = 610;
|
||||||
@ -281,38 +285,38 @@ function compute() {
|
|||||||
context.fillStyle = 'lightgray';
|
context.fillStyle = 'lightgray';
|
||||||
context.fill();
|
context.fill();
|
||||||
|
|
||||||
// context.fillStyle = 'black';
|
context.fillStyle = 'black';
|
||||||
// context.strokeStyle = 'black';
|
context.strokeStyle = 'black';
|
||||||
// context.textAlign = 'center';
|
context.textAlign = 'center';
|
||||||
// context.textBaseline = 'middle';
|
context.textBaseline = 'middle';
|
||||||
// context.lineWidth = 1;
|
context.lineWidth = 1;
|
||||||
// context.font = '14px arial';
|
context.font = '14px arial';
|
||||||
// for (let i = 0; i < convexPolygons.length; i ++) {
|
for (let i = 0; i < convexPolygons.length; i ++) {
|
||||||
// const { face, center } = convexPolygons[i];
|
const { face, center } = convexPolygons[i];
|
||||||
//
|
|
||||||
// context.beginPath();
|
|
||||||
// for (const index of face) {
|
|
||||||
// const vertex = vertices[index];
|
|
||||||
// context.lineTo(vertex.x, vertex.y);
|
|
||||||
// }
|
|
||||||
// context.closePath();
|
|
||||||
// context.stroke();
|
|
||||||
//
|
|
||||||
// context.fillText(i, center.x, center.y);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (path) {
|
context.beginPath();
|
||||||
// context.beginPath();
|
for (const index of face) {
|
||||||
// for (const { edge: [indexA, indexB] } of path) {
|
const vertex = vertices[index];
|
||||||
// const pointA = vertices[indexA];
|
context.lineTo(vertex.x, vertex.y);
|
||||||
// const pointB = vertices[indexB];
|
}
|
||||||
// context.moveTo(pointA.x, pointA.y);
|
context.closePath();
|
||||||
// context.lineTo(pointB.x, pointB.y);
|
context.stroke();
|
||||||
// }
|
|
||||||
// context.strokeStyle = 'blue';
|
context.fillText(i, center.x, center.y);
|
||||||
// context.lineWidth = 3;
|
}
|
||||||
// context.stroke();
|
|
||||||
// }
|
if (path) {
|
||||||
|
context.beginPath();
|
||||||
|
for (const { edge: [indexA, indexB] } of path) {
|
||||||
|
const pointA = vertices[indexA];
|
||||||
|
const pointB = vertices[indexB];
|
||||||
|
context.moveTo(pointA.x, pointA.y);
|
||||||
|
context.lineTo(pointB.x, pointB.y);
|
||||||
|
}
|
||||||
|
context.strokeStyle = 'blue';
|
||||||
|
context.lineWidth = 3;
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
if (line) {
|
if (line) {
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
|
Loading…
Reference in New Issue
Block a user