From a3dca19cc6f77a6a9ea6c346fdf67a3b49954d17 Mon Sep 17 00:00:00 2001 From: Army Date: Thu, 2 Jan 2025 14:22:21 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=8D=E5=90=8C=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E7=82=B9=E6=8B=96=E6=8B=BD=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/control/Geometry.ts | 28 +++++++++++++++------------- src/control/Listener.ts | 8 ++++---- src/math/bezier.ts | 7 ++----- src/math/equation.ts | 11 +++++++++++ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/control/Geometry.ts b/src/control/Geometry.ts index 0d025423..b7dbec7a 100644 --- a/src/control/Geometry.ts +++ b/src/control/Geometry.ts @@ -34,7 +34,7 @@ export default class Geometry { let oy = 0; let w = 1; let h = 1; - let diff = { tx: 0, ty: 0, fx: 0, fy: 0, d: 0 }; // 按下记录control和点的差值 + let diff = { tx: 0, ty: 0, fx: 0, fy: 0, td: 0, fd: 0 }; // 按下记录control和点的差值,拖拽时计算用 panel.addEventListener('mousedown', (e) => { if (e.button !== 0 || listener.spaceKey) { @@ -179,12 +179,12 @@ export default class Geometry { const p = node.props.points[idx]; if (target.classList.contains('f')) { isControlF = true; - diff.d = Math.sqrt(Math.pow(p.x - p.tx, 2) + Math.pow(p.y - p.tx, 2)); } else { isControlT = true; - diff.d = Math.sqrt(Math.pow(p.x - p.fx, 2) + Math.pow(p.y - p.fx, 2)); } + diff.td = Math.sqrt(Math.pow(p.x - p.tx, 2) + Math.pow(p.y - p.tx, 2)); + diff.fd = Math.sqrt(Math.pow(p.x - p.fx, 2) + Math.pow(p.y - p.fx, 2)); } else { listener.emit(Listener.SELECT_POINT, -1); @@ -222,24 +222,26 @@ export default class Geometry { p.ty = y; } // 镜像和非对称需更改对应点 - if (p.curveMode === CURVE_MODE.MIRRORED) { + if (p.curveMode === CURVE_MODE.MIRRORED || p.curveMode === CURVE_MODE.ASYMMETRIC) { + let ratio = 1; if (isControlF) { + if (p.curveMode === CURVE_MODE.ASYMMETRIC) { + ratio = diff.fd / Math.sqrt(Math.pow(p.fx - p.x, 2) + Math.pow(p.fy - p.y, 2)) * diff.td; + } const dx = p.fx - p.x; const dy = p.fy - p.y; - p.tx = p.x - dx; - p.ty = p.y - dy; + p.tx = p.x - dx * ratio; + p.ty = p.y - dy * ratio; } else { + if (p.curveMode === CURVE_MODE.ASYMMETRIC) { + ratio = diff.td / Math.sqrt(Math.pow(p.tx - p.x, 2) + Math.pow(p.ty - p.y, 2)) * diff.fd; + } const dx = p.tx - p.x; const dy = p.ty - p.y; - p.fx = p.x - dx; - p.fy = p.y - dy; - } - } - else if (p.curveMode === CURVE_MODE.ASYMMETRIC) { - if (isControlF) { + p.fx = p.x - dx * ratio; + p.fy = p.y - dy * ratio; } - else {} } node.refresh(); this.updateVertex(node); diff --git a/src/control/Listener.ts b/src/control/Listener.ts index f21950cd..8d0867fc 100644 --- a/src/control/Listener.ts +++ b/src/control/Listener.ts @@ -1152,10 +1152,10 @@ export default class Listener extends Event { if (this.options.disabled?.editGeom) { return; } - // this.select.hideSelect(); - // this.geometry.show(node); - // this.state = State.EDIT_GEOM; - // this.emit(Listener.STATE_CHANGE, State.NORMAL, this.state); + this.select.hideSelect(); + this.geometry.show(node); + this.state = State.EDIT_GEOM; + this.emit(Listener.STATE_CHANGE, State.NORMAL, this.state); } this.emit(Listener.SELECT_NODE, this.selected.slice(0)); } diff --git a/src/math/bezier.ts b/src/math/bezier.ts index bc321d9b..cf20d747 100644 --- a/src/math/bezier.ts +++ b/src/math/bezier.ts @@ -1,4 +1,4 @@ -import equation, { getRoots, pointSlope2General, twoPoint2General } from './equation'; +import equation, { getRoots, lineSlope, pointSlope2General, twoPoint2General } from './equation'; import { includedAngle } from './vector'; /** @@ -555,10 +555,7 @@ export function bezierSlope(points: { x: number, y: number }[], t = 0) { if (points.length === 2) { const { x: x1, y: y1 } = points[0]; const { x: x2, y: y2 } = points[1]; - if (x1 === x2) { - return Infinity; - } - return (y2 - y1) / (x2 - x1); + return lineSlope(x1, y1, x2, y2); } if (points.length === 3) { return bezier2Slope(points, t); diff --git a/src/math/equation.ts b/src/math/equation.ts index 0ee950ca..ab01c3b7 100644 --- a/src/math/equation.ts +++ b/src/math/equation.ts @@ -226,8 +226,19 @@ export function pointSlope2General(x1: number, y1: number, k: number) { return [k, -1, y1 - k * x1]; } +export function lineSlope(x1: number, y1: number, x2: number, y2: number) { + if (y1 === y2) { + return 0; + } + if (x1 === x2) { + return y2 > y1 ? Infinity : -Infinity; + } + return (y2 - y1) / (x2 - x1); +} + export default { getRoots, twoPoint2General, pointSlope2General, + lineSlope, };