我之前问过这个问题,但没有表达清楚,所以请原谅我的重复。这应该更好。
给定三个其他坐标和 2 个斜率,我需要计算一个坐标的位置。基本上是两条线的交点。但是,我没有通常可用于解决此问题的所有信息。
我有一个由一堆顶点定义的任意形状。用户可以在这些顶点之间拖动一条线,形状应如下图所示做出反应。
所以在第一个例子中,用户将线 EF 从左边的位置拖到右边的位置(线 E2F2)。需要发生的是线 EF 增长/缩小,使其斜率保持不变,并且它的开始和结束坐标分别保持在线 DE 和 AF 上。这显示为 E2F2 行。
这需要足够通用,才能处理我扔给它的任何奇怪或规则的角度。第二组形状显示了一种更简单的方法。用户将线 CD 拖到 C2D2 的位置。注意斜坡是如何保持不变的,D2 基本上沿着对角线滑动,B2C2 和 C2D2 都在长度上延伸。结果是所有 3 个斜率都保持不变,但线 B2C2 和 C2D2 的长度会增加以保持连接,而线 D2E2 会缩小。
您需要了解,当拖动线 EF 时,您实际上是在移动坐标“E”。因此,计算第一个坐标很容易。前一个和下一个永远不会改变。所以我基本上有 3 条相关线的斜率和 4 个必要坐标中的 3 个。我需要第四个,所以在我的例子中,F2 或 D2。
每次坐标移动时,都会在事件上调用此代码。假设我们正在拖动线 EF - 那么坐标是 E。
var next = this.model.get("next"), // coordinate F
nextNext = next.get("next"), // coordinate A
nextDx = nextNext.get("x") - next.get("x"), // delta X of AF
nextDy = nextNext.get("y") - next.get("y"), // delta Y of AF
prev = this.model.get("prev"), // coordinate D
prevDx = prev.get("x") - this.model.get("x"), // delta X of DF
prevDy = prev.get("y") - this.model.get("y"), // delta Y of DF
selfDx = next.get("x") - this.model.get("x"), // delta X of EF
selfDy = next.get("y") - this.model.get("y"), // delta Y of EF
selfX = this.initialCoords.x + this.shape.getX(), // the new position of E
selfY = this.initialCoords.y + this.shape.getY(),
selfM, selfB, prevM, prevB, nextM, nextB, m, x, y, b;
// check for would-be infinities
if (selfDx == 0) {
// **** THIS WHOLE BLOCK IS CORRECT ****
// i'm vertical
// we can safely assume prev/next aren't also vertical. i think? right?
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myX = selfX,
myY = prevM * myX + prevB;
this.model.set({
x: myX,
y: myY
});
nextM = next.get("slope");
nextB = next.get("y") - nextM * next.get("x");
var nextX = selfX,
nextY = nextM * nextX + nextB;
next.set({
x: nextX,
y: nextY
});
} else if (selfDy == 0) {
//***** THIS WHOLE BLOCK IS CORRECT **** //
// i'm horizontal
if (prevDx == 0) {
// prev is a vertical line
this.model.set({
y: selfY
});
} else {
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myY = selfY,
myX = (selfY - prevB) / prevM;
this.model.set({
x: myX,
y: myY
});
}
if (nextDx == 0) {
// next is a vertical line
next.set({
y: selfY
});
} else {
nextM = next.get("slope");
nextB = next.get("y") - nextM * next.get("x");
var nextY = selfY,
nextX = (selfY - nextB) / nextM;
next.set({
x: nextX,
y: nextY
});
}
} else {
// HELP HERE - you've chosen to drag an arbitrarily angled line. Figure out the "next" coordinate given the "current" one.
selfM = this.model.get("slope");
selfB = this.model.get("y") - this.model.get("slope") * this.model.get("x");
if (selfM < 0) {
prevM = prev.get("slope");
prevB = prev.get("y") - prevM * prev.get("x");
var myY = selfY,
myX = (selfY - prevB) / prevM;
// CORRECT, but need "next" position based on this
this.model.set({
x: myX,
y: myY
});
} else {
// CORRECT but need "next" position based on this.
var myX = selfX;
this.model.set({
x: myX
});
}
}