|
@@ -1451,7 +1451,41 @@ export default class MathUtil {
|
|
|
}
|
|
|
|
|
|
getHitInfoForThreeBezier(position, curve, rang = 3) {
|
|
|
+ // 定义三次贝塞尔曲线的控制点和目标点
|
|
|
+ var p0 = curve.start;
|
|
|
+ var p1 = curve.controls[0];
|
|
|
+ var p2 = curve.controls[1];
|
|
|
+ var p3 = curve.end;
|
|
|
+ var target = position
|
|
|
+
|
|
|
+// 参数化方式在曲线上取一系列的点
|
|
|
+ var pointsOnCurve = [];
|
|
|
+ for (var t = 0; t <= 1; t += 0.01) {
|
|
|
+ var x = Math.pow(1 - t, 3) * p0.x + 3 * Math.pow(1 - t, 2) * t * p1.x + 3 * (1 - t) * Math.pow(t, 2) * p2.x + Math.pow(t, 3) * p3.x;
|
|
|
+ var y = Math.pow(1 - t, 3) * p0.y + 3 * Math.pow(1 - t, 2) * t * p1.y + 3 * (1 - t) * Math.pow(t, 2) * p2.y + Math.pow(t, 3) * p3.y;
|
|
|
+ pointsOnCurve.push({ x: x, y: y });
|
|
|
+ }
|
|
|
+
|
|
|
+// 计算每个点与目标点的距离
|
|
|
+ var shortestDistance = Number.MAX_VALUE;
|
|
|
+ var closestPoint;
|
|
|
+ for (var i = 0; i < pointsOnCurve.length; i++) {
|
|
|
+ var distance = Math.sqrt(Math.pow(pointsOnCurve[i].x - target.x, 2) + Math.pow(pointsOnCurve[i].y - target.y, 2));
|
|
|
+ if (distance < shortestDistance) {
|
|
|
+ shortestDistance = distance;
|
|
|
+ closestPoint = pointsOnCurve[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ position: closestPoint,
|
|
|
+ distance: shortestDistance,
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log("最短距离:", shortestDistance);
|
|
|
+ console.log("最近点:", closestPoint);
|
|
|
+
|
|
|
const { x: offsetX, y: offsetY } = position;
|
|
|
+ let results = []
|
|
|
// 用 x 求出对应的 t,用 t 求相应位置的 y,再比较得出的 y 与 offsetY 之间的差值
|
|
|
const tsx = this.getThreeBezierT(
|
|
|
curve.start.x,
|
|
@@ -1460,6 +1494,7 @@ export default class MathUtil {
|
|
|
curve.end.x,
|
|
|
offsetX
|
|
|
);
|
|
|
+ console.log(tsx)
|
|
|
for (let x = 0; x < 3; x++) {
|
|
|
if (tsx[x] <= 1 && tsx[x] >= 0) {
|
|
|
const point = this.getThreeBezierPoint(
|
|
@@ -1469,12 +1504,12 @@ export default class MathUtil {
|
|
|
curve.controls[1],
|
|
|
curve.end
|
|
|
);
|
|
|
- if (Math.abs(point.y - offsetY) < rang) {
|
|
|
- return {
|
|
|
+ // if (Math.abs(point.y - offsetY) < rang) {
|
|
|
+ results.push({
|
|
|
position: point,
|
|
|
distance: this.getDistance(point, position),
|
|
|
- };
|
|
|
- }
|
|
|
+ });
|
|
|
+ // }
|
|
|
}
|
|
|
}
|
|
|
// 如果上述没有结果,则用 y 求出对应的 t,再用 t 求出对应的 x,与 offsetX 进行匹配
|
|
@@ -1494,14 +1529,17 @@ export default class MathUtil {
|
|
|
curve.controls[1],
|
|
|
curve.end
|
|
|
);
|
|
|
- if (Math.abs(point.x - offsetX) < rang) {
|
|
|
- return {
|
|
|
+ // if (Math.abs(point.x - offsetX) < rang) {
|
|
|
+ results.push({
|
|
|
position: point,
|
|
|
distance: this.getDistance(point, position),
|
|
|
- };
|
|
|
- }
|
|
|
+ });
|
|
|
+ // }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ console.log(results)
|
|
|
+ return results.sort((a, b) => a.distance - b.distance)[0]
|
|
|
}
|
|
|
|
|
|
// 二次曲线
|
|
@@ -1515,6 +1553,7 @@ export default class MathUtil {
|
|
|
bezierData.push(curve.end.y);
|
|
|
const { isHit, getInfo } = bezierUtil.measureBezier(...bezierData);
|
|
|
const { point } = getInfo(position);
|
|
|
+
|
|
|
return {
|
|
|
position: {
|
|
|
x: point[0],
|