【发布时间】:2020-03-01 17:55:50
【问题描述】:
这是基本的图形几何和/或三角函数,我觉得问它很愚蠢,但我不记得这是怎么回事。所以:
- 我有一条由两个点 (x1, y1) 和 (x2, y2) 定义的线。
- 我有第三个点 (xp, yp),它位于其他地方。
我想计算位于#1 中某处的点 (x', y'),这样,当与 #2 中的点连接时,会创建一条与第一条线垂直的新线。
谢谢。
【问题讨论】:
这是基本的图形几何和/或三角函数,我觉得问它很愚蠢,但我不记得这是怎么回事。所以:
我想计算位于#1 中某处的点 (x', y'),这样,当与 #2 中的点连接时,会创建一条与第一条线垂直的新线。
谢谢。
【问题讨论】:
在这种计算几何中,一个有用的经验法则是,您应该尽可能长时间地使用向量,仅在万不得已时才切换到笛卡尔坐标。所以让我们用向量代数来解决这个问题。假设你的线从 p 到 p + r,另一点是 q。
现在,线上的任何点,包括您要查找的点(称为 s),都可以表示为 s = p + λ r 表示标量参数 λ。
现在从 q 到 s 的向量必须垂直于 r。因此
(q - (p + λ r)) · r = 0
其中·是dot product operator。展开产品:
(q - p) · r = λ (r · r)
然后划分:
λ = (q - p) · r / r · r
来实现的时候需要检查r·r是否=0,避免被零除。
【讨论】:
您可以通过首先考虑从(x1, y1) 到(x2, y2) 的直线上的通用点(x, y) 来找到该点:
x = x1 + t*(x2 - x1)
y = y1 + t*(y2 - y1)
以及计算从该点到(xp, yp)的(平方)距离
E = (x - xp)**2 + (y - yp)**2
替换x 和y 的定义给出
E = (x1 + t*(x2 - x1) - xp)**2 +
(y1 + t*(y2 - y1) - yp)**2
然后找到这个距离变化的最小值t 我们推导出E 相对于t
dE/dt = 2*(x1 + t*(x2 - x1) - xp)*(x2 - x1) +
2*(y1 + t*(y2 - y1) - yp)*(y2 - y1)
经过一些计算后给出
dE/dt = 2*((x1 - xp)*(x2 - x1) + (y1 - yp)*(y2 - y1) +
t*((x2 - x1)**2 + (y1 - y2)**2))
寻找这个导数何时为零,我们得到t 的显式方程
t = ((xp - x1)*(x2 - x1) + (yp - y1)*(y2 - y1)) /
((x2 - x1)**2 + (y2 - y1)**2)
因此可以使用(x, y) 定义中t 的值来计算最终点。
使用矢量符号,这与 Gareth 建议的公式完全相同...
t = <p - p1, p2 - p1> / <p2 - p1, p2 - p1>
其中符号<a, b> 表示点积运算ax*bx + ay*by。
还要注意,同样的公式也适用于 n 维空间。
【讨论】:
t 是线的参数方程的“参数”。它是一个实数,因此当 t=0 时点为 (x1, y1),当 t=1 时点为 (x2, y2),t=0.5 时点为中点,依此类推(t1 点“之后”(x2,y2))。
致所有寻找使用向量的具体示例的可怜人......在这里,我建立在 Gareth 的答案之上。
你有一个从 p 到 r(从 0,0 到 50,-50)的向量和另一个点 q,它位于 (50, 0) 处。 q 与 p 到 r 的向量的直角交点为 { x: 25. y: -25 } ,用下面的代码推导出来。
const p = [0, 0];
const r = [50, -50];
const q = [50, 0];
const l = math.add(p, r);
const m = math.dot(math.subtract(q, p), r) / math.dot(r, r);
console.log('intersecting point', math.multiply(l, m));
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.1.2/math.js"></script>
【讨论】:
答案是:
y=ax+b
where a=(x1-x2)/(y2-y1)
b=yp-(x1-x2)*xp/(y2-y1)
结果是如何获得的:
1) slope for the original line: (y2-y1)/(x2-x1)
2) slope for the answer: -1/((y2-y1)/(x2-x1)) = (x1-x2)/(y2-y1)
3) Plug this into (xp,yp) we can have the result line.
从后面的行中计算答案(这太长了……我饿了)。
【讨论】:
y1=y2(除以零)。实际上,在处理真正的二维问题时,不应使用基于“斜率”的公式。公式 y=mx+q 仅在处理 1.5 维问题(即图形 y=y(x))时才能很好地工作。
let x1, x2, y1, y2, slope, xp, yp, m, x, y
x1 = 0
y1 = 0
x2 = 50
y2 = -50
xp = 50
yp = 0
slope = (y1 - y2) / (x1 - x2)
m = -1 / slope
x = (m * xp - yp - slope * x1 + y1) / (m - slope)
y = m * x - m * xp + yp
console.log('x: ', x, ', y: ', y )
【讨论】:
您可以求解连接(x1, y1) 和(x2, y2) 的直线的斜率。然后你就知道垂直线的斜率是它的负数。
要找到 y 截距,请使用斜率查看直线在 y 中从 x=0 到 x1 的距离。
b + (x1 - x0) * m = y1
b + (x1 - 0) * m = y1
b + (x1 * m) = y1
b = y1 - x1 * m
然后,您可以获得两点之间的线和来自(xp, yp) 的线与上述斜率的公式。对于给定的 x,它们具有相等的 y,因此您可以求解 x,然后将其代入 y 的任一公式。
m = slope_from_1_to_2 = (y2 - y1) / (x2 - x1)
n = slopePerpendicular = (-1) / m
b = intercept_for_1_to_2 = y1 - x1 * m
c = intercept_for_p = yp - xp * n
因此,线的方程具有以下形式
y = mx + b
第 1 点和第 2 点:
y(x) = mx + b
点p:
y(x) = nx + c
设置他们的y'等于找到x'
mx' + b = nx' + c
(m-n)x' = c - b
x' = (c - b) / (m - n)
因此使用任一公式来计算 y'
y' = mx' + b
【讨论】:
y(x) = mx + y2——你为什么用y2代替b?
b 应该是 y 轴截距,直线与 y 轴相交。 y2不一定是这样,让我看看我的数学。
y = m*x + q 意味着寻找麻烦。你不能用这种方法处理垂直线;最好改用参数方程x = x(t), y = y(t)。