如何计算沿线的镜像点?

Ada*_*Lee 8 algorithm math geometry computational-geometry

在2D平面中,我有一个点和一条线.如何沿着这条线获得镜像点?

AnT*_*AnT 18

当这样的事情在计算机程序中完成时,您可能必须处理的问题之一是仅使用整数运算(或尽可能多)执行这些计算,假设输入是整数.尽可能以整数形式执行此操作是一个单独的问题,我在此不会介绍.

以下是"数学"解决方案,如果按字面实现将需要浮点计算.我不知道你的情况是否可以接受.您可以自己根据自己的喜好进行优化.

(1)代表的线L通过

A * x + B * y + C = 0
Run Code Online (Sandbox Code Playgroud)

方程.请注意,vector (A, B)是此行的法线向量.

例如,如果线通过两个点来定义X1(x1, y1)X2(x2, y2),然后

A = y2 - y1
B = -(x2 - x1)
C = -A * x1 - B * y1
Run Code Online (Sandbox Code Playgroud)

(2)通过将所有系数除以向量的长度来归一化方程(A, B).即计算长度

M = sqrt(A * A + B * B)
Run Code Online (Sandbox Code Playgroud)

然后计算值

A' = A / M
B' = B / M
C' = C / M
Run Code Online (Sandbox Code Playgroud)

等式

A' * x + B' * y + C' = 0
Run Code Online (Sandbox Code Playgroud)

仍然是你的线的等价方程,L除了现在法线向量(A', B')是单位向量.

(3)拿你的观点P(px, py)来计算价值

D = A' * px + B' * py + C'
Run Code Online (Sandbox Code Playgroud)

这将为您提供从您的点到您的线的签名距离.换句话说,这是距离最近点的距离(我们并不真正关心最近点本身,我们只需要距离).DPLPL

牌子上写着其线的LP位于.如果P位于同一侧,则向量(A', B')指向("正"侧),距离为正.如果P位于另一侧("负"侧),则距离为负.

(4)为了找到你的镜像点,P'(px', py')你需要将你的点移动到线P的绝对距离到另一边.|2 * D|L

"跨越线"真的意味着如果点P位于"正"侧L,那么我们必须将它向矢量方向移动(A', B')到"负"侧.反之亦然,如果点P位于"负"侧L,那么我们必须将它向矢量方向移动(A', B')到"正"侧.

这可以简单地表示为将点移动到-2 * D向量方向上(注意减去)(A', B').

这意味着

px' = px - 2 * A' * D
py' = py - 2 * B' * D
Run Code Online (Sandbox Code Playgroud)

给你镜像点P'(px', py').


另外,您也可以使用基于寻找实际的最近点的方法N就行L,然后体现自己的点P与关系N.这已在其他答案中提出,我将描述我是如何做到的.

(1)建立一个等式

A*x + B*y + C = 0
Run Code Online (Sandbox Code Playgroud)

为您的线路L在上述步骤1中精确描述.没有必要对这个等式进行标准化.

(2)建立通过的垂直线的方程P.假设垂直线表示为

D*x + E*y + F = 0
Run Code Online (Sandbox Code Playgroud)

DE系数马上知道

D = B
E = -A
Run Code Online (Sandbox Code Playgroud)

F可以通过将点代P入等式来计算

F = -D*px - E*py
Run Code Online (Sandbox Code Playgroud)

(3)通过求解两个线性方程组来求出这两条线的交点

A*x + B*y = -C
D*x + E*y = -F
Run Code Online (Sandbox Code Playgroud)

在这种情况下,克莱默的规则非常有效.维基百科中的Line intersection文章中给出的公式只不过是将Cramer规则应用于此系统.

该解决方案为您提供了N(nx, ny)我们寻找的最近点.

(4)现在算一算

px' = nx + (nx - px)
py' = ny + (ny - py)
Run Code Online (Sandbox Code Playgroud)

找到你的观点P'(px', py').

请注意,此方法几乎可以完全以整数实现.可能失去精确度的唯一步骤是在步骤3中克莱默规则内部的划分.当然,像往常一样,你必须为"几乎整体"解决方案付出的代价是需要大量算术.甚至系数CF可以溢出,甚至没有提到Cramer规则公式中的计算.

  • 比我认为标记的支票更好的编程答案. (2认同)

Ted*_*opp 7

细节取决于您的线的表示方式.如果你将它表示为线上的任意点P以及沿线的单位列向量n,则镜像点Q '到任意点Q由下式给出:

Q '= Q + 2(I - nn T)(P - Q)

(在此,I是2×2单位矩阵,Ñ Ť是的转置Ñ(治疗Ñ为2×1矩阵),以及NN Ť是通过标准矩阵乘法形成的2×2矩阵ÑÑ Ť.)这不是太硬表明如果你将P移动到任何地方,Q '将不会改变.

将其他线表示转换为点/单位矢量表示并不困难.


060*_*002 6

假设线的方程是ax + by + c = 0.现在想象一条垂直于它的线,它可以表示为-bx + ay + d = 0(两条垂直线的斜率的乘积为-1).现在的问题是找到d.将点的坐标放在第二行,您将d轻松获得值.

第二部分是,在第二行找到一个与第一行等距离等距的点.为此,您可以找到两条线的交点.计算的差异xy给定的点和交会点的.现在将它们添加到交叉点的xy值.这给出了你需要的点(你可能需要否定差异 - 这取决于你使用的减法顺序).