@tscircuit/curvy-trace-solver 0.0.5 → 0.0.7
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/index.d.ts +3 -1
- package/dist/index.js +124 -109
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,8 @@ interface CurvyTraceProblem {
|
|
|
16
16
|
bounds: Bounds;
|
|
17
17
|
waypointPairs: WaypointPair[];
|
|
18
18
|
obstacles: Obstacle[];
|
|
19
|
-
|
|
19
|
+
preferredTraceToTraceSpacing: number;
|
|
20
|
+
preferredObstacleToTraceSpacing: number;
|
|
20
21
|
}
|
|
21
22
|
interface OutputTrace {
|
|
22
23
|
waypointPair: WaypointPair;
|
|
@@ -44,6 +45,7 @@ declare class CurvyTraceSolver extends BaseSolver {
|
|
|
44
45
|
private initializeTraces;
|
|
45
46
|
private updateSampledTraces;
|
|
46
47
|
private updateSingleTraceSample;
|
|
48
|
+
private updateControlPointsFromDistances;
|
|
47
49
|
private updateCollisionPairs;
|
|
48
50
|
private computeTotalCost;
|
|
49
51
|
private computeCostForTrace;
|
package/dist/index.js
CHANGED
|
@@ -932,16 +932,27 @@ function getPerimeterT(p, bounds) {
|
|
|
932
932
|
if (Math.abs(p.x - minX) < eps) return 2 * W + H + (p.y - minY);
|
|
933
933
|
return 0;
|
|
934
934
|
}
|
|
935
|
-
function
|
|
935
|
+
function getInwardPerpendicular(p, bounds) {
|
|
936
936
|
const { minX, maxX, minY, maxY } = bounds;
|
|
937
|
-
const
|
|
938
|
-
const
|
|
939
|
-
const
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
if (
|
|
943
|
-
if (
|
|
944
|
-
return { x:
|
|
937
|
+
const eps = 1e-6;
|
|
938
|
+
const onTop = Math.abs(p.y - maxY) < eps;
|
|
939
|
+
const onBottom = Math.abs(p.y - minY) < eps;
|
|
940
|
+
const onRight = Math.abs(p.x - maxX) < eps;
|
|
941
|
+
const onLeft = Math.abs(p.x - minX) < eps;
|
|
942
|
+
if (onTop && onRight) return { x: -Math.SQRT1_2, y: -Math.SQRT1_2 };
|
|
943
|
+
if (onTop && onLeft) return { x: Math.SQRT1_2, y: -Math.SQRT1_2 };
|
|
944
|
+
if (onBottom && onRight) return { x: -Math.SQRT1_2, y: Math.SQRT1_2 };
|
|
945
|
+
if (onBottom && onLeft) return { x: Math.SQRT1_2, y: Math.SQRT1_2 };
|
|
946
|
+
if (onTop) return { x: 0, y: -1 };
|
|
947
|
+
if (onBottom) return { x: 0, y: 1 };
|
|
948
|
+
if (onRight) return { x: -1, y: 0 };
|
|
949
|
+
if (onLeft) return { x: 1, y: 0 };
|
|
950
|
+
const cx = (minX + maxX) / 2;
|
|
951
|
+
const cy = (minY + maxY) / 2;
|
|
952
|
+
const dx = cx - p.x;
|
|
953
|
+
const dy = cy - p.y;
|
|
954
|
+
const len = Math.hypot(dx, dy);
|
|
955
|
+
return len > 0 ? { x: dx / len, y: dy / len } : { x: 0, y: -1 };
|
|
945
956
|
}
|
|
946
957
|
function sampleCubicBezierInline(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, points, numSamples) {
|
|
947
958
|
for (let i = 0; i <= numSamples; i++) {
|
|
@@ -1103,21 +1114,14 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1103
1114
|
}
|
|
1104
1115
|
const maxDepth = Math.max(...Array.from(nestingDepth.values()), 1);
|
|
1105
1116
|
this.traces = tracesWithT.map(({ pair, t1, t2, idx }) => {
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
const
|
|
1113
|
-
const
|
|
1114
|
-
x: pair.start.x + (pair.end.x - pair.start.x) * 0.33,
|
|
1115
|
-
y: pair.start.y + (pair.end.y - pair.start.y) * 0.33
|
|
1116
|
-
};
|
|
1117
|
-
const pLinear2 = {
|
|
1118
|
-
x: pair.start.x + (pair.end.x - pair.start.x) * 0.67,
|
|
1119
|
-
y: pair.start.y + (pair.end.y - pair.start.y) * 0.67
|
|
1120
|
-
};
|
|
1117
|
+
const perpDir1 = getInwardPerpendicular(pair.start, bounds);
|
|
1118
|
+
const perpDir2 = getInwardPerpendicular(pair.end, bounds);
|
|
1119
|
+
const chordLength = Math.hypot(
|
|
1120
|
+
pair.end.x - pair.start.x,
|
|
1121
|
+
pair.end.y - pair.start.y
|
|
1122
|
+
);
|
|
1123
|
+
const depth = nestingDepth.get(idx) || 0;
|
|
1124
|
+
const normalizedDepth = depth / maxDepth;
|
|
1121
1125
|
const midPoint = {
|
|
1122
1126
|
x: (pair.start.x + pair.end.x) / 2,
|
|
1123
1127
|
y: (pair.start.y + pair.end.y) / 2
|
|
@@ -1128,23 +1132,31 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1128
1132
|
);
|
|
1129
1133
|
const maxDist = Math.hypot(W / 2, H / 2);
|
|
1130
1134
|
const spatialDepth = 1 - distToCenter / maxDist;
|
|
1131
|
-
const
|
|
1132
|
-
const
|
|
1133
|
-
const
|
|
1134
|
-
const
|
|
1135
|
+
const baseFactor = 0.25 + spatialDepth * 0.15;
|
|
1136
|
+
const depthAdjustment = 1 - normalizedDepth * 0.3;
|
|
1137
|
+
const initialDist = chordLength * baseFactor * depthAdjustment;
|
|
1138
|
+
const minDist = Math.min(W, H) * 0.05;
|
|
1139
|
+
const d1 = Math.max(minDist, initialDist);
|
|
1140
|
+
const d2 = Math.max(minDist, initialDist);
|
|
1141
|
+
const ctrl1 = {
|
|
1142
|
+
x: pair.start.x + d1 * perpDir1.x,
|
|
1143
|
+
y: pair.start.y + d1 * perpDir1.y
|
|
1144
|
+
};
|
|
1145
|
+
const ctrl2 = {
|
|
1146
|
+
x: pair.end.x + d2 * perpDir2.x,
|
|
1147
|
+
y: pair.end.y + d2 * perpDir2.y
|
|
1148
|
+
};
|
|
1135
1149
|
return {
|
|
1136
1150
|
waypointPair: pair,
|
|
1137
|
-
ctrl1
|
|
1138
|
-
|
|
1139
|
-
y: pLinear1.y * (1 - pullAmount) + pPerim1.y * pullAmount
|
|
1140
|
-
},
|
|
1141
|
-
ctrl2: {
|
|
1142
|
-
x: pLinear2.x * (1 - pullAmount) + pPerim2.x * pullAmount,
|
|
1143
|
-
y: pLinear2.y * (1 - pullAmount) + pPerim2.y * pullAmount
|
|
1144
|
-
},
|
|
1151
|
+
ctrl1,
|
|
1152
|
+
ctrl2,
|
|
1145
1153
|
networkId: pair.networkId,
|
|
1146
1154
|
t1,
|
|
1147
|
-
t2
|
|
1155
|
+
t2,
|
|
1156
|
+
perpDir1,
|
|
1157
|
+
perpDir2,
|
|
1158
|
+
d1,
|
|
1159
|
+
d2
|
|
1148
1160
|
};
|
|
1149
1161
|
});
|
|
1150
1162
|
this.sampledPoints = this.traces.map(
|
|
@@ -1199,9 +1211,17 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1199
1211
|
OPT_SAMPLES + 1
|
|
1200
1212
|
);
|
|
1201
1213
|
}
|
|
1214
|
+
// Update control points from perpendicular distances
|
|
1215
|
+
updateControlPointsFromDistances(i) {
|
|
1216
|
+
const trace = this.traces[i];
|
|
1217
|
+
trace.ctrl1.x = trace.waypointPair.start.x + trace.d1 * trace.perpDir1.x;
|
|
1218
|
+
trace.ctrl1.y = trace.waypointPair.start.y + trace.d1 * trace.perpDir1.y;
|
|
1219
|
+
trace.ctrl2.x = trace.waypointPair.end.x + trace.d2 * trace.perpDir2.x;
|
|
1220
|
+
trace.ctrl2.y = trace.waypointPair.end.y + trace.d2 * trace.perpDir2.y;
|
|
1221
|
+
}
|
|
1202
1222
|
// Determine which trace pairs could possibly collide based on bounding boxes
|
|
1203
1223
|
updateCollisionPairs() {
|
|
1204
|
-
const { preferredSpacing } = this.problem;
|
|
1224
|
+
const { preferredTraceToTraceSpacing: preferredSpacing } = this.problem;
|
|
1205
1225
|
this.collisionPairs = [];
|
|
1206
1226
|
for (let i = 0; i < this.traces.length; i++) {
|
|
1207
1227
|
for (let j = i + 1; j < this.traces.length; j++) {
|
|
@@ -1216,8 +1236,9 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1216
1236
|
}
|
|
1217
1237
|
}
|
|
1218
1238
|
computeTotalCost() {
|
|
1219
|
-
const {
|
|
1220
|
-
const
|
|
1239
|
+
const { preferredTraceToTraceSpacing, preferredObstacleToTraceSpacing } = this.problem;
|
|
1240
|
+
const traceSpacingSq = preferredTraceToTraceSpacing ** 2;
|
|
1241
|
+
const obstacleSpacingSq = preferredObstacleToTraceSpacing ** 2;
|
|
1221
1242
|
let cost = 0;
|
|
1222
1243
|
for (const [i, j] of this.collisionPairs) {
|
|
1223
1244
|
const pi = this.sampledPoints[i], pj = this.sampledPoints[j];
|
|
@@ -1228,10 +1249,10 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1228
1249
|
const b1x = pj[b * 2], b1y = pj[b * 2 + 1];
|
|
1229
1250
|
const b2x = pj[(b + 1) * 2], b2y = pj[(b + 1) * 2 + 1];
|
|
1230
1251
|
const distSq = segmentDistSq(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y);
|
|
1231
|
-
if (distSq <
|
|
1252
|
+
if (distSq < traceSpacingSq) {
|
|
1232
1253
|
const dist = Math.sqrt(distSq);
|
|
1233
|
-
cost += (
|
|
1234
|
-
if (distSq < 1e-18) cost += 20 *
|
|
1254
|
+
cost += (preferredTraceToTraceSpacing - dist) ** 2;
|
|
1255
|
+
if (distSq < 1e-18) cost += 20 * traceSpacingSq;
|
|
1235
1256
|
}
|
|
1236
1257
|
}
|
|
1237
1258
|
}
|
|
@@ -1250,16 +1271,16 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1250
1271
|
const oy2 = this.obstacleSegments[obsBase + 3];
|
|
1251
1272
|
const obsMinX = Math.min(ox1, ox2), obsMaxX = Math.max(ox1, ox2);
|
|
1252
1273
|
const obsMinY = Math.min(oy1, oy2), obsMaxY = Math.max(oy1, oy2);
|
|
1253
|
-
if (bi.maxX +
|
|
1274
|
+
if (bi.maxX + preferredObstacleToTraceSpacing < obsMinX || obsMaxX + preferredObstacleToTraceSpacing < bi.minX || bi.maxY + preferredObstacleToTraceSpacing < obsMinY || obsMaxY + preferredObstacleToTraceSpacing < bi.minY)
|
|
1254
1275
|
continue;
|
|
1255
1276
|
for (let a = 0; a < OPT_SAMPLES; a++) {
|
|
1256
1277
|
const a1x = pi[a * 2], a1y = pi[a * 2 + 1];
|
|
1257
1278
|
const a2x = pi[(a + 1) * 2], a2y = pi[(a + 1) * 2 + 1];
|
|
1258
1279
|
const distSq = segmentDistSq(a1x, a1y, a2x, a2y, ox1, oy1, ox2, oy2);
|
|
1259
|
-
if (distSq <
|
|
1280
|
+
if (distSq < obstacleSpacingSq) {
|
|
1260
1281
|
const dist = Math.sqrt(distSq);
|
|
1261
|
-
cost += (
|
|
1262
|
-
if (distSq < 1e-18) cost += 20 *
|
|
1282
|
+
cost += (preferredObstacleToTraceSpacing - dist) ** 2;
|
|
1283
|
+
if (distSq < 1e-18) cost += 20 * obstacleSpacingSq;
|
|
1263
1284
|
}
|
|
1264
1285
|
}
|
|
1265
1286
|
}
|
|
@@ -1267,8 +1288,9 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1267
1288
|
return cost;
|
|
1268
1289
|
}
|
|
1269
1290
|
computeCostForTrace(traceIdx) {
|
|
1270
|
-
const {
|
|
1271
|
-
const
|
|
1291
|
+
const { preferredTraceToTraceSpacing, preferredObstacleToTraceSpacing } = this.problem;
|
|
1292
|
+
const traceSpacingSq = preferredTraceToTraceSpacing ** 2;
|
|
1293
|
+
const obstacleSpacingSq = preferredObstacleToTraceSpacing ** 2;
|
|
1272
1294
|
const trace = this.traces[traceIdx];
|
|
1273
1295
|
const pi = this.sampledPoints[traceIdx];
|
|
1274
1296
|
const bi = this.traceBounds[traceIdx];
|
|
@@ -1279,7 +1301,7 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1279
1301
|
if (trace.networkId && other.networkId && trace.networkId === other.networkId)
|
|
1280
1302
|
continue;
|
|
1281
1303
|
const bj = this.traceBounds[j];
|
|
1282
|
-
if (bi.maxX +
|
|
1304
|
+
if (bi.maxX + preferredTraceToTraceSpacing < bj.minX || bj.maxX + preferredTraceToTraceSpacing < bi.minX || bi.maxY + preferredTraceToTraceSpacing < bj.minY || bj.maxY + preferredTraceToTraceSpacing < bi.minY)
|
|
1283
1305
|
continue;
|
|
1284
1306
|
const pj = this.sampledPoints[j];
|
|
1285
1307
|
for (let a = 0; a < OPT_SAMPLES; a++) {
|
|
@@ -1289,10 +1311,10 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1289
1311
|
const b1x = pj[b * 2], b1y = pj[b * 2 + 1];
|
|
1290
1312
|
const b2x = pj[(b + 1) * 2], b2y = pj[(b + 1) * 2 + 1];
|
|
1291
1313
|
const distSq = segmentDistSq(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y);
|
|
1292
|
-
if (distSq <
|
|
1314
|
+
if (distSq < traceSpacingSq) {
|
|
1293
1315
|
const dist = Math.sqrt(distSq);
|
|
1294
|
-
cost += (
|
|
1295
|
-
if (distSq < 1e-18) cost += 20 *
|
|
1316
|
+
cost += (preferredTraceToTraceSpacing - dist) ** 2;
|
|
1317
|
+
if (distSq < 1e-18) cost += 20 * traceSpacingSq;
|
|
1296
1318
|
}
|
|
1297
1319
|
}
|
|
1298
1320
|
}
|
|
@@ -1307,16 +1329,16 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1307
1329
|
const oy2 = this.obstacleSegments[obsBase + 3];
|
|
1308
1330
|
const obsMinX = Math.min(ox1, ox2), obsMaxX = Math.max(ox1, ox2);
|
|
1309
1331
|
const obsMinY = Math.min(oy1, oy2), obsMaxY = Math.max(oy1, oy2);
|
|
1310
|
-
if (bi.maxX +
|
|
1332
|
+
if (bi.maxX + preferredObstacleToTraceSpacing < obsMinX || obsMaxX + preferredObstacleToTraceSpacing < bi.minX || bi.maxY + preferredObstacleToTraceSpacing < obsMinY || obsMaxY + preferredObstacleToTraceSpacing < bi.minY)
|
|
1311
1333
|
continue;
|
|
1312
1334
|
for (let a = 0; a < OPT_SAMPLES; a++) {
|
|
1313
1335
|
const a1x = pi[a * 2], a1y = pi[a * 2 + 1];
|
|
1314
1336
|
const a2x = pi[(a + 1) * 2], a2y = pi[(a + 1) * 2 + 1];
|
|
1315
1337
|
const distSq = segmentDistSq(a1x, a1y, a2x, a2y, ox1, oy1, ox2, oy2);
|
|
1316
|
-
if (distSq <
|
|
1338
|
+
if (distSq < obstacleSpacingSq) {
|
|
1317
1339
|
const dist = Math.sqrt(distSq);
|
|
1318
|
-
cost += (
|
|
1319
|
-
if (distSq < 1e-18) cost += 20 *
|
|
1340
|
+
cost += (preferredObstacleToTraceSpacing - dist) ** 2;
|
|
1341
|
+
if (distSq < 1e-18) cost += 20 * obstacleSpacingSq;
|
|
1320
1342
|
}
|
|
1321
1343
|
}
|
|
1322
1344
|
}
|
|
@@ -1325,9 +1347,11 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1325
1347
|
optimizeStep() {
|
|
1326
1348
|
const { bounds } = this.problem;
|
|
1327
1349
|
const { minX, maxX, minY, maxY } = bounds;
|
|
1350
|
+
const minDim = Math.min(maxX - minX, maxY - minY);
|
|
1328
1351
|
const progress = this.optimizationStep / this.maxOptimizationSteps;
|
|
1329
1352
|
const baseStep = 3.5 * (1 - progress) + 0.5;
|
|
1330
|
-
const
|
|
1353
|
+
const minDist = minDim * 0.02;
|
|
1354
|
+
const maxDist = minDim * 1.5;
|
|
1331
1355
|
const traceCosts = [];
|
|
1332
1356
|
for (let i = 0; i < this.traces.length; i++) {
|
|
1333
1357
|
traceCosts.push({ idx: i, cost: this.computeCostForTrace(i) });
|
|
@@ -1338,74 +1362,65 @@ var CurvyTraceSolver = class extends BaseSolver {
|
|
|
1338
1362
|
const trace = this.traces[i];
|
|
1339
1363
|
const steps = [baseStep, baseStep * 1.5, baseStep * 0.5];
|
|
1340
1364
|
for (const step of steps) {
|
|
1341
|
-
const
|
|
1342
|
-
{ dx: step, dy: 0 },
|
|
1343
|
-
{ dx: -step, dy: 0 },
|
|
1344
|
-
{ dx: 0, dy: step },
|
|
1345
|
-
{ dx: 0, dy: -step },
|
|
1346
|
-
{ dx: step * SQRT1_2, dy: step * SQRT1_2 },
|
|
1347
|
-
{ dx: -step * SQRT1_2, dy: -step * SQRT1_2 },
|
|
1348
|
-
{ dx: step * SQRT1_2, dy: -step * SQRT1_2 },
|
|
1349
|
-
{ dx: -step * SQRT1_2, dy: step * SQRT1_2 }
|
|
1350
|
-
];
|
|
1365
|
+
const deltas = [step, -step, step * 2, -step * 2];
|
|
1351
1366
|
let bestCost = this.computeCostForTrace(i);
|
|
1352
|
-
let
|
|
1353
|
-
let
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
const
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
const origCtrl2y = trace.ctrl2.y;
|
|
1360
|
-
for (const dir of directions) {
|
|
1361
|
-
trace.ctrl1.x = Math.max(minX, Math.min(maxX, origCtrl1x + dir.dx));
|
|
1362
|
-
trace.ctrl1.y = Math.max(minY, Math.min(maxY, origCtrl1y + dir.dy));
|
|
1367
|
+
let bestD1 = trace.d1;
|
|
1368
|
+
let bestD2 = trace.d2;
|
|
1369
|
+
const origD1 = trace.d1;
|
|
1370
|
+
const origD2 = trace.d2;
|
|
1371
|
+
for (const delta of deltas) {
|
|
1372
|
+
trace.d1 = Math.max(minDist, Math.min(maxDist, origD1 + delta));
|
|
1373
|
+
this.updateControlPointsFromDistances(i);
|
|
1363
1374
|
this.updateSingleTraceSample(i);
|
|
1364
1375
|
const cost1 = this.computeCostForTrace(i);
|
|
1365
1376
|
if (cost1 < bestCost) {
|
|
1366
1377
|
bestCost = cost1;
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
bestCtrl2x = origCtrl2x;
|
|
1370
|
-
bestCtrl2y = origCtrl2y;
|
|
1378
|
+
bestD1 = trace.d1;
|
|
1379
|
+
bestD2 = origD2;
|
|
1371
1380
|
}
|
|
1372
|
-
trace.
|
|
1373
|
-
|
|
1374
|
-
trace.
|
|
1375
|
-
|
|
1381
|
+
trace.d1 = origD1;
|
|
1382
|
+
this.updateControlPointsFromDistances(i);
|
|
1383
|
+
trace.d2 = Math.max(minDist, Math.min(maxDist, origD2 + delta));
|
|
1384
|
+
this.updateControlPointsFromDistances(i);
|
|
1376
1385
|
this.updateSingleTraceSample(i);
|
|
1377
1386
|
const cost2 = this.computeCostForTrace(i);
|
|
1378
1387
|
if (cost2 < bestCost) {
|
|
1379
1388
|
bestCost = cost2;
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
bestCtrl2x = trace.ctrl2.x;
|
|
1383
|
-
bestCtrl2y = trace.ctrl2.y;
|
|
1389
|
+
bestD1 = origD1;
|
|
1390
|
+
bestD2 = trace.d2;
|
|
1384
1391
|
}
|
|
1385
|
-
trace.
|
|
1386
|
-
|
|
1387
|
-
trace.
|
|
1388
|
-
trace.
|
|
1389
|
-
|
|
1390
|
-
trace.ctrl2.y = Math.max(minY, Math.min(maxY, origCtrl2y + dir.dy));
|
|
1392
|
+
trace.d2 = origD2;
|
|
1393
|
+
this.updateControlPointsFromDistances(i);
|
|
1394
|
+
trace.d1 = Math.max(minDist, Math.min(maxDist, origD1 + delta));
|
|
1395
|
+
trace.d2 = Math.max(minDist, Math.min(maxDist, origD2 + delta));
|
|
1396
|
+
this.updateControlPointsFromDistances(i);
|
|
1391
1397
|
this.updateSingleTraceSample(i);
|
|
1392
1398
|
const cost3 = this.computeCostForTrace(i);
|
|
1393
1399
|
if (cost3 < bestCost) {
|
|
1394
1400
|
bestCost = cost3;
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1401
|
+
bestD1 = trace.d1;
|
|
1402
|
+
bestD2 = trace.d2;
|
|
1403
|
+
}
|
|
1404
|
+
trace.d1 = origD1;
|
|
1405
|
+
trace.d2 = origD2;
|
|
1406
|
+
this.updateControlPointsFromDistances(i);
|
|
1407
|
+
trace.d1 = Math.max(minDist, Math.min(maxDist, origD1 + delta));
|
|
1408
|
+
trace.d2 = Math.max(minDist, Math.min(maxDist, origD2 - delta));
|
|
1409
|
+
this.updateControlPointsFromDistances(i);
|
|
1410
|
+
this.updateSingleTraceSample(i);
|
|
1411
|
+
const cost4 = this.computeCostForTrace(i);
|
|
1412
|
+
if (cost4 < bestCost) {
|
|
1413
|
+
bestCost = cost4;
|
|
1414
|
+
bestD1 = trace.d1;
|
|
1415
|
+
bestD2 = trace.d2;
|
|
1399
1416
|
}
|
|
1400
|
-
trace.
|
|
1401
|
-
trace.
|
|
1402
|
-
|
|
1403
|
-
trace.ctrl2.y = origCtrl2y;
|
|
1417
|
+
trace.d1 = origD1;
|
|
1418
|
+
trace.d2 = origD2;
|
|
1419
|
+
this.updateControlPointsFromDistances(i);
|
|
1404
1420
|
}
|
|
1405
|
-
trace.
|
|
1406
|
-
trace.
|
|
1407
|
-
|
|
1408
|
-
trace.ctrl2.y = bestCtrl2y;
|
|
1421
|
+
trace.d1 = bestD1;
|
|
1422
|
+
trace.d2 = bestD2;
|
|
1423
|
+
this.updateControlPointsFromDistances(i);
|
|
1409
1424
|
this.updateSingleTraceSample(i);
|
|
1410
1425
|
if (bestCost < currentCost * 0.9) break;
|
|
1411
1426
|
}
|