@leafer-in/linker 2.3.3 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/linker.cjs +166 -152
- package/dist/linker.esm.js +166 -152
- package/dist/linker.esm.min.js +1 -1
- package/dist/linker.esm.min.js.map +1 -1
- package/dist/linker.js +162 -152
- package/dist/linker.min.cjs +1 -1
- package/dist/linker.min.cjs.map +1 -1
- package/dist/linker.min.js +1 -1
- package/dist/linker.min.js.map +1 -1
- package/package.json +1 -1
- package/src/helper/drawPolyline.ts +177 -177
package/dist/linker.cjs
CHANGED
|
@@ -226,7 +226,7 @@ function getPolylineDirectionIndex(direction) {
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
function getPolylinePorts(direction, point, target, bounds, targetBounds
|
|
229
|
+
function getPolylinePorts(direction, point, target, bounds, targetBounds) {
|
|
230
230
|
const data = directionData[getPolylineDirectionIndex(direction)];
|
|
231
231
|
const dx = Math.sign(data.x - .5), dy = Math.sign(data.y - .5);
|
|
232
232
|
const cx = bounds ? bounds.x + bounds.width / 2 : point.x;
|
|
@@ -234,39 +234,27 @@ function getPolylinePorts(direction, point, target, bounds, targetBounds, ports)
|
|
|
234
234
|
const tx = targetBounds ? targetBounds.x + targetBounds.width / 2 : target.x;
|
|
235
235
|
const ty = targetBounds ? targetBounds.y + targetBounds.height / 2 : target.y;
|
|
236
236
|
const deltaX = tx - cx, deltaY = ty - cy;
|
|
237
|
-
const
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
ports[0] = xPort;
|
|
243
|
-
return 1;
|
|
244
|
-
}
|
|
245
|
-
if (dy && !dx) {
|
|
246
|
-
ports[0] = yPort;
|
|
247
|
-
return 1;
|
|
248
|
-
}
|
|
249
|
-
if (Math.abs(deltaX) >= Math.abs(deltaY)) {
|
|
250
|
-
ports[0] = xPort;
|
|
251
|
-
ports[1] = yPort;
|
|
252
|
-
} else {
|
|
253
|
-
ports[0] = yPort;
|
|
254
|
-
ports[1] = xPort;
|
|
255
|
-
}
|
|
256
|
-
return 2;
|
|
237
|
+
const xPort = (dx || (deltaX >= 0 ? 1 : -1)) > 0 ? 1 : 0;
|
|
238
|
+
const yPort = (dy || (deltaY >= 0 ? 1 : -1)) > 0 ? 3 : 2;
|
|
239
|
+
if (dx && !dy) return [ xPort ];
|
|
240
|
+
if (dy && !dx) return [ yPort ];
|
|
241
|
+
return Math.abs(deltaX) >= Math.abs(deltaY) ? [ xPort, yPort ] : [ yPort, xPort ];
|
|
257
242
|
}
|
|
258
243
|
|
|
259
|
-
function getPolylineExit(point, bounds, port, clearance
|
|
244
|
+
function getPolylineExit(point, bounds, port, clearance) {
|
|
260
245
|
const axis = port >> 1, sign = port & 1 ? 1 : -1;
|
|
261
246
|
if (axis === POLYLINE_X) {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
247
|
+
const x = bounds ? bounds.x + (sign > 0 ? bounds.width : 0) : point.x;
|
|
248
|
+
return {
|
|
249
|
+
x: x + sign * clearance,
|
|
250
|
+
y: point.y
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const y = bounds ? bounds.y + (sign > 0 ? bounds.height : 0) : point.y;
|
|
254
|
+
return {
|
|
255
|
+
x: point.x,
|
|
256
|
+
y: y + sign * clearance
|
|
257
|
+
};
|
|
270
258
|
}
|
|
271
259
|
|
|
272
260
|
function isPolylinePointBlocked(x, y, bounds, clearance) {
|
|
@@ -320,45 +308,69 @@ function getPolylineMidpointAxis(startPort, endPort, sx, sy, ex, ey) {
|
|
|
320
308
|
return Math.abs(ex - sx) >= Math.abs(ey - sy) ? POLYLINE_X : POLYLINE_Y;
|
|
321
309
|
}
|
|
322
310
|
|
|
323
|
-
function
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (midpointAxis === POLYLINE_X) {
|
|
328
|
-
result.push(midpointX, sy, midpointX, ey);
|
|
329
|
-
} else {
|
|
330
|
-
result.push(sx, midpointY, ex, midpointY);
|
|
331
|
-
}
|
|
332
|
-
result.push(ex, ey, endPoint.x, endPoint.y);
|
|
333
|
-
for (let i = 4; i < result.length - 2; i += 2) {
|
|
334
|
-
const x1 = result[i - 2], y1 = result[i - 1];
|
|
335
|
-
const x2 = result[i], y2 = result[i + 1];
|
|
336
|
-
if (isPolylineSegmentBlocked(x1, y1, x2, y2, startBounds, clearance) || isPolylineSegmentBlocked(x1, y1, x2, y2, endBounds, clearance)) return Infinity;
|
|
337
|
-
}
|
|
338
|
-
return getPolylineScore(result, clearance);
|
|
311
|
+
function isPolylinePortAligned(port, stub, dx, dy) {
|
|
312
|
+
const offset = port >> 1 === POLYLINE_X ? dx : dy;
|
|
313
|
+
const sign = port & 1 ? 1 : -1;
|
|
314
|
+
return Math.abs(offset) <= POLYLINE_EPSILON ? stub > POLYLINE_EPSILON : offset * sign > 0;
|
|
339
315
|
}
|
|
340
316
|
|
|
341
|
-
function
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
317
|
+
function isPolylineMidpointAligned(port, stub, dx, dy, axis) {
|
|
318
|
+
if (port === undefined) return true;
|
|
319
|
+
if (axis === POLYLINE_X && Math.abs(dx / 2) > POLYLINE_EPSILON) return isPolylinePortAligned(port, stub, dx, 0);
|
|
320
|
+
if (axis === POLYLINE_Y && Math.abs(dy / 2) > POLYLINE_EPSILON) return isPolylinePortAligned(port, stub, 0, dy);
|
|
321
|
+
if (Math.abs(dx) <= POLYLINE_EPSILON && Math.abs(dy) <= POLYLINE_EPSILON) return true;
|
|
322
|
+
return isPolylinePortAligned(port, stub, dx, dy);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function isPolylineApproachAligned(points, port) {
|
|
326
|
+
if (port === undefined) return true;
|
|
327
|
+
const last = points.length - 2, x = points[last], y = points[last + 1];
|
|
328
|
+
for (let i = last - 2; i >= 0; i -= 2) {
|
|
329
|
+
const dx = points[i] - x, dy = points[i + 1] - y;
|
|
330
|
+
if (Math.abs(dx) > POLYLINE_EPSILON || Math.abs(dy) > POLYLINE_EPSILON) return isPolylinePortAligned(port, 1, dx, dy);
|
|
331
|
+
}
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, startBounds, endBounds, clearance, strictPorts, approachPort) {
|
|
336
|
+
const startExit = getPolylineExit(startPoint, startBounds, startPort, clearance);
|
|
337
|
+
const endExit = endPort === undefined ? endPoint : getPolylineExit(endPoint, endBounds, endPort, clearance);
|
|
338
|
+
const {x: sx, y: sy} = startExit, {x: ex, y: ey} = endExit;
|
|
348
339
|
const startStub = Math.abs(sx - startPoint.x) + Math.abs(sy - startPoint.y);
|
|
349
340
|
const endStub = Math.abs(ex - endPoint.x) + Math.abs(ey - endPoint.y);
|
|
350
341
|
if (isPolylineSegmentBlocked(startPoint.x, startPoint.y, sx, sy, endBounds, clearance) || isPolylineSegmentBlocked(endPoint.x, endPoint.y, ex, ey, startBounds, clearance)) return Infinity;
|
|
351
|
-
|
|
352
|
-
const
|
|
353
|
-
|
|
342
|
+
if (endPort === undefined && (isPolylinePointBlocked(ex, ey, startBounds, clearance) || isPolylinePointBlocked(ex, ey, endBounds, clearance))) return Infinity;
|
|
343
|
+
const axis = endPort === undefined ? startPort >> 1 : getPolylineMidpointAxis(startPort, endPort, sx, sy, ex, ey);
|
|
344
|
+
const dx = ex - sx, dy = ey - sy;
|
|
345
|
+
result.length = 0;
|
|
346
|
+
result.push(startPoint.x, startPoint.y, sx, sy);
|
|
347
|
+
if ((!strictPorts || isPolylineMidpointAligned(startPort, startStub, dx, dy, axis) && isPolylineMidpointAligned(endPort, endStub, -dx, -dy, axis)) && isPolylineMidpointAligned(approachPort, 1, -dx, -dy, axis)) {
|
|
348
|
+
const mx = (sx + ex) / 2, my = (sy + ey) / 2;
|
|
349
|
+
if (axis === POLYLINE_X) result.push(mx, sy, mx, ey); else result.push(sx, my, ex, my);
|
|
350
|
+
result.push(ex, ey, endPoint.x, endPoint.y);
|
|
351
|
+
for (let i = 4; i < result.length - 2; i += 2) {
|
|
352
|
+
if (isPolylineSegmentBlocked(result[i - 2], result[i - 1], result[i], result[i + 1], startBounds, clearance) || isPolylineSegmentBlocked(result[i - 2], result[i - 1], result[i], result[i + 1], endBounds, clearance)) {
|
|
353
|
+
result.length = 4;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (result.length > 4 && isPolylineApproachAligned(result, approachPort)) return getPolylineScore(result, clearance);
|
|
358
|
+
result.length = 4;
|
|
359
|
+
}
|
|
360
|
+
const score = findPolylineGridRoute(result, startExit, endExit, startPort, endPort, startBounds, endBounds, clearance, axis, startStub, endStub, strictPorts, approachPort);
|
|
361
|
+
if (score === Infinity) return score;
|
|
362
|
+
result.push(endPoint.x, endPoint.y);
|
|
363
|
+
return isPolylineApproachAligned(result, approachPort) ? score + startStub + endStub : Infinity;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function findPolylineGridRoute(result, startExit, endExit, startPort, endPort, startBounds, endBounds, clearance, midpointAxis, startStub, endStub, strictPorts, approachPort) {
|
|
367
|
+
const {x: sx, y: sy} = startExit, {x: ex, y: ey} = endExit;
|
|
354
368
|
const margin = Math.max(clearance, POLYLINE_MIN_SEGMENT) * 2;
|
|
355
369
|
const xs = [ sx, ex, (sx + ex) / 2 ], ys = [ sy, ey, (sy + ey) / 2 ];
|
|
356
370
|
addPolylineBoundsCoordinates(xs, ys, startBounds, clearance, margin);
|
|
357
371
|
addPolylineBoundsCoordinates(xs, ys, endBounds, clearance, margin);
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
xs.push(minX - margin * 2, maxX + margin * 2);
|
|
361
|
-
ys.push(minY - margin * 2, maxY + margin * 2);
|
|
372
|
+
xs.push(Math.min(...xs) - margin * 2, Math.max(...xs) + margin * 2);
|
|
373
|
+
ys.push(Math.min(...ys) - margin * 2, Math.max(...ys) + margin * 2);
|
|
362
374
|
sortPolylineCoordinates(xs);
|
|
363
375
|
sortPolylineCoordinates(ys);
|
|
364
376
|
const nx = xs.length, ny = ys.length;
|
|
@@ -372,53 +384,49 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
|
|
|
372
384
|
previous.fill(-1);
|
|
373
385
|
const startState = startNode * 3;
|
|
374
386
|
distance[startState] = 0;
|
|
387
|
+
const pending = [ startState ];
|
|
375
388
|
const turnCost = Math.max(POLYLINE_MIN_SEGMENT, clearance * POLYLINE_TURN_WEIGHT);
|
|
389
|
+
const preferredCoordinate = midpointAxis === POLYLINE_X ? (sx + ex) / 2 : (sy + ey) / 2;
|
|
376
390
|
let currentState = -1, currentNode = -1, currentAxis = 0;
|
|
377
391
|
let currentX = 0, currentY = 0, currentDistance = 0;
|
|
378
|
-
const relax = (nextXIndex, nextYIndex, axis
|
|
392
|
+
const relax = (nextXIndex, nextYIndex, axis) => {
|
|
379
393
|
const nextX = xs[nextXIndex], nextY = ys[nextYIndex];
|
|
380
394
|
const nextNode = nextYIndex * nx + nextXIndex;
|
|
381
|
-
|
|
382
|
-
if (
|
|
383
|
-
if (
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
} else if (startStub <= POLYLINE_EPSILON) return;
|
|
387
|
-
}
|
|
388
|
-
if (nextNode === endNode) {
|
|
389
|
-
if (axis === endAxis + 1) {
|
|
390
|
-
if (sign !== -endSign) return;
|
|
391
|
-
} else if (endStub <= POLYLINE_EPSILON) return;
|
|
392
|
-
}
|
|
395
|
+
const dx = nextX - currentX, dy = nextY - currentY;
|
|
396
|
+
if (nextNode === startNode) return;
|
|
397
|
+
if (approachPort !== undefined && nextNode === endNode && !isPolylinePortAligned(approachPort, 1, -dx, -dy)) return;
|
|
398
|
+
if (strictPorts && (currentState === startState && !isPolylinePortAligned(startPort, startStub, dx, dy) || endPort !== undefined && nextNode === endNode && !isPolylinePortAligned(endPort, endStub, -dx, -dy))) return;
|
|
399
|
+
if (isPolylinePointBlocked(nextX, nextY, startBounds, clearance) || isPolylinePointBlocked(nextX, nextY, endBounds, clearance) || isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, startBounds, clearance) || isPolylineSegmentBlocked(currentX, currentY, nextX, nextY, endBounds, clearance)) return;
|
|
393
400
|
const nextState = nextNode * 3 + axis;
|
|
394
401
|
if (visited[nextState]) return;
|
|
395
|
-
|
|
396
|
-
let cost = currentDistance + segmentLength;
|
|
402
|
+
let cost = currentDistance + (Math.abs(dx) + Math.abs(dy));
|
|
397
403
|
if (currentAxis && currentAxis !== axis) {
|
|
398
404
|
cost += turnCost;
|
|
399
405
|
const turnCoordinate = currentAxis === POLYLINE_X + 1 ? currentX : currentY;
|
|
400
|
-
const preferredCoordinate = midpointAxis === POLYLINE_X ? (sx + ex) / 2 : (sy + ey) / 2;
|
|
401
406
|
if (Math.abs(turnCoordinate - preferredCoordinate) > POLYLINE_EPSILON) cost += turnCost * 2;
|
|
402
407
|
}
|
|
403
408
|
if (cost < distance[nextState]) {
|
|
409
|
+
if (distance[nextState] === Infinity) pending.push(nextState);
|
|
404
410
|
distance[nextState] = cost;
|
|
405
411
|
previous[nextState] = currentState;
|
|
406
412
|
}
|
|
407
413
|
};
|
|
408
414
|
let bestState = -1;
|
|
409
|
-
|
|
410
|
-
let
|
|
411
|
-
for (let i =
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
+
while (pending.length) {
|
|
416
|
+
let index = 0, state = pending[0];
|
|
417
|
+
for (let i = 1; i < pending.length; i++) {
|
|
418
|
+
const next = pending[i];
|
|
419
|
+
if (distance[next] < distance[state] || distance[next] === distance[state] && next < state) {
|
|
420
|
+
index = i;
|
|
421
|
+
state = next;
|
|
415
422
|
}
|
|
416
423
|
}
|
|
417
|
-
|
|
424
|
+
pending[index] = pending[pending.length - 1];
|
|
425
|
+
pending.pop();
|
|
418
426
|
currentState = state;
|
|
419
427
|
currentNode = Math.floor(state / 3);
|
|
420
428
|
currentAxis = state % 3;
|
|
421
|
-
currentDistance =
|
|
429
|
+
currentDistance = distance[state];
|
|
422
430
|
visited[state] = 1;
|
|
423
431
|
if (currentNode === endNode) {
|
|
424
432
|
bestState = state;
|
|
@@ -427,10 +435,10 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
|
|
|
427
435
|
const xIndex = currentNode % nx, yIndex = Math.floor(currentNode / nx);
|
|
428
436
|
currentX = xs[xIndex];
|
|
429
437
|
currentY = ys[yIndex];
|
|
430
|
-
if (xIndex > 0) relax(xIndex - 1, yIndex, POLYLINE_X + 1
|
|
431
|
-
if (xIndex < nx - 1) relax(xIndex + 1, yIndex, POLYLINE_X + 1
|
|
432
|
-
if (yIndex > 0) relax(xIndex, yIndex - 1, POLYLINE_Y + 1
|
|
433
|
-
if (yIndex < ny - 1) relax(xIndex, yIndex + 1, POLYLINE_Y + 1
|
|
438
|
+
if (xIndex > 0) relax(xIndex - 1, yIndex, POLYLINE_X + 1);
|
|
439
|
+
if (xIndex < nx - 1) relax(xIndex + 1, yIndex, POLYLINE_X + 1);
|
|
440
|
+
if (yIndex > 0) relax(xIndex, yIndex - 1, POLYLINE_Y + 1);
|
|
441
|
+
if (yIndex < ny - 1) relax(xIndex, yIndex + 1, POLYLINE_Y + 1);
|
|
434
442
|
}
|
|
435
443
|
if (bestState < 0) return Infinity;
|
|
436
444
|
const reverse = [];
|
|
@@ -442,59 +450,83 @@ function getPolylineRoute(result, startPoint, endPoint, startPort, endPort, star
|
|
|
442
450
|
state = previous[state];
|
|
443
451
|
}
|
|
444
452
|
if (state !== startState) return Infinity;
|
|
445
|
-
result.length = 0;
|
|
446
|
-
result.push(startPoint.x, startPoint.y, sx, sy);
|
|
447
453
|
for (let i = reverse.length - 4; i >= 0; i -= 2) result.push(reverse[i], reverse[i + 1]);
|
|
448
|
-
|
|
449
|
-
return distance[bestState] + startStub + endStub;
|
|
454
|
+
return distance[bestState];
|
|
450
455
|
}
|
|
451
456
|
|
|
452
|
-
function
|
|
453
|
-
const
|
|
454
|
-
if (
|
|
455
|
-
|
|
457
|
+
function getPolylineFallback(start, end, port, startBounds, endBounds) {
|
|
458
|
+
const {x: sx, y: sy} = start, {x: ex, y: ey} = end;
|
|
459
|
+
if (sx === ex || sy === ey) return [ sx, sy, ex, ey ];
|
|
460
|
+
const horizontal = port >> 1 === POLYLINE_X;
|
|
461
|
+
const crosses = (x, y) => {
|
|
462
|
+
let count = 0;
|
|
463
|
+
if (isPolylineSegmentBlocked(sx, sy, x, y, startBounds, 0)) count++;
|
|
464
|
+
if (isPolylineSegmentBlocked(x, y, ex, ey, startBounds, 0)) count++;
|
|
465
|
+
if (isPolylineSegmentBlocked(sx, sy, x, y, endBounds, 0)) count++;
|
|
466
|
+
if (isPolylineSegmentBlocked(x, y, ex, ey, endBounds, 0)) count++;
|
|
467
|
+
return count;
|
|
468
|
+
};
|
|
469
|
+
const xy = crosses(ex, sy), yx = crosses(sx, ey);
|
|
470
|
+
return xy < yx || xy === yx && horizontal ? [ sx, sy, ex, sy, ex, ey ] : [ sx, sy, sx, ey, ex, ey ];
|
|
456
471
|
}
|
|
457
472
|
|
|
458
|
-
function
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
473
|
+
function getBestPolyline(startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, approachPort) {
|
|
474
|
+
const startPorts = getPolylinePorts(startDirection, startPoint, endPoint, startBounds, endDirection === undefined ? undefined : endBounds);
|
|
475
|
+
const endPorts = endDirection === undefined ? [ undefined ] : getPolylinePorts(endDirection, endPoint, startPoint, endBounds, startBounds);
|
|
476
|
+
let candidate = [], best = [], bestScore = Infinity;
|
|
477
|
+
for (let pass = clearance ? 0 : 1; pass < 3 && !best.length; pass++) {
|
|
478
|
+
const gap = pass ? 0 : clearance;
|
|
479
|
+
for (let i = 0; i < startPorts.length; i++) {
|
|
480
|
+
for (let j = 0; j < endPorts.length; j++) {
|
|
481
|
+
const score = getPolylineRoute(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, gap, pass < 2, approachPort);
|
|
482
|
+
if (score < bestScore) {
|
|
483
|
+
bestScore = score;
|
|
484
|
+
const previous = best;
|
|
485
|
+
best = candidate;
|
|
486
|
+
candidate = previous;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
468
489
|
}
|
|
469
490
|
}
|
|
470
|
-
|
|
491
|
+
if (!best.length) return getPolylineFallback(startPoint, endPoint, startPorts[0], startBounds, endBounds);
|
|
492
|
+
simplifyPolyline(best);
|
|
493
|
+
const last = best.length - 2;
|
|
494
|
+
if (best[last] !== endPoint.x || best[last + 1] !== endPoint.y) best.push(endPoint.x, endPoint.y);
|
|
495
|
+
return best;
|
|
471
496
|
}
|
|
472
497
|
|
|
473
|
-
function
|
|
474
|
-
if (
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
+
function getPolylineEditSide(point, waypoint, direction, bounds, otherBounds, clearance, points, index, step) {
|
|
499
|
+
if (point.x === waypoint.x && point.y === waypoint.y) return [];
|
|
500
|
+
let approachPort;
|
|
501
|
+
for (let i = index + step; i >= 0 && i < points.length; i += step) {
|
|
502
|
+
const dx = points[i] - waypoint.x, dy = points[i + 1] - waypoint.y;
|
|
503
|
+
if (Math.abs(dx) <= POLYLINE_EPSILON && Math.abs(dy) <= POLYLINE_EPSILON) continue;
|
|
504
|
+
if (Math.abs(dy) <= POLYLINE_EPSILON) approachPort = dx > 0 ? 0 : 1; else if (Math.abs(dx) <= POLYLINE_EPSILON) approachPort = dy > 0 ? 2 : 3;
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
const side = getBestPolyline(point, waypoint, direction, undefined, bounds, otherBounds, clearance, approachPort);
|
|
508
|
+
side.length -= 2;
|
|
509
|
+
return side;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function drawPolylineEditPath(path, startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, points) {
|
|
513
|
+
const length = points.length, last = length - 2;
|
|
514
|
+
if (length % 2) return false;
|
|
515
|
+
for (let i = 0; i < length; i++) if (!Number.isFinite(points[i])) return false;
|
|
516
|
+
const start = getPolylineEditSide(startPoint, {
|
|
517
|
+
x: points[0],
|
|
518
|
+
y: points[1]
|
|
519
|
+
}, startDirection, startBounds, endBounds, clearance, points, 0, 2);
|
|
520
|
+
const end = getPolylineEditSide(endPoint, {
|
|
521
|
+
x: points[last],
|
|
522
|
+
y: points[last + 1]
|
|
523
|
+
}, endDirection, endBounds, startBounds, clearance, points, last, -2);
|
|
524
|
+
const first = start.length ? start : points;
|
|
525
|
+
moveTo$1(path, first[0], first[1]);
|
|
526
|
+
for (let i = 2; i < start.length; i += 2) lineTo$1(path, start[i], start[i + 1]);
|
|
527
|
+
for (let i = start.length ? 0 : 2; i < length; i += 2) lineTo$1(path, points[i], points[i + 1]);
|
|
528
|
+
for (let i = end.length - 2; i >= 0; i -= 2) lineTo$1(path, end[i], end[i + 1]);
|
|
529
|
+
return true;
|
|
498
530
|
}
|
|
499
531
|
|
|
500
532
|
function getPolylineScore(points, clearance) {
|
|
@@ -537,26 +569,8 @@ function drawPolyline(path, startPoint, endPoint, startDirection, endDirection,
|
|
|
537
569
|
if (startBounds && (!Number.isFinite(startBounds.x) || !Number.isFinite(startBounds.y) || !Number.isFinite(startBounds.width) || !Number.isFinite(startBounds.height) || startBounds.width < 0 || startBounds.height < 0)) return false;
|
|
538
570
|
if (endBounds && (!Number.isFinite(endBounds.x) || !Number.isFinite(endBounds.y) || !Number.isFinite(endBounds.width) || !Number.isFinite(endBounds.height) || endBounds.width < 0 || endBounds.height < 0)) return false;
|
|
539
571
|
clearance = Number.isFinite(clearance) ? Math.max(0, clearance) : 8;
|
|
540
|
-
|
|
541
|
-
const
|
|
542
|
-
const endCount = getPolylinePorts(endDirection, endPoint, startPoint, endBounds, startBounds, endPorts);
|
|
543
|
-
const candidate = [], best = [];
|
|
544
|
-
let bestScore = Infinity;
|
|
545
|
-
for (let pass = 0; pass < 2 && bestScore === Infinity; pass++) {
|
|
546
|
-
const currentClearance = pass === 0 ? clearance : 0;
|
|
547
|
-
for (let i = 0; i < startCount; i++) {
|
|
548
|
-
for (let j = 0; j < endCount; j++) {
|
|
549
|
-
const score = points !== undefined ? getPolylineEditPath(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, points, currentClearance) : getPolylineRoute(candidate, startPoint, endPoint, startPorts[i], endPorts[j], startBounds, endBounds, currentClearance);
|
|
550
|
-
if (score < bestScore) {
|
|
551
|
-
bestScore = score;
|
|
552
|
-
best.length = 0;
|
|
553
|
-
for (let k = 0; k < candidate.length; k++) best.push(candidate[k]);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
if (!best.length) return false;
|
|
559
|
-
if (points === undefined) simplifyPolyline(best);
|
|
572
|
+
if (points === null || points === void 0 ? void 0 : points.length) return drawPolylineEditPath(path, startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance, points);
|
|
573
|
+
const best = getBestPolyline(startPoint, endPoint, startDirection, endDirection, startBounds, endBounds, clearance);
|
|
560
574
|
moveTo$1(path, best[0], best[1]);
|
|
561
575
|
for (let i = 2; i < best.length; i += 2) lineTo$1(path, best[i], best[i + 1]);
|
|
562
576
|
return true;
|