通过一条直线反射一个点的算法

23

给定一个点 (x1, y1) 和一条直线的方程式 (y=mx+c),我需要一些伪代码来确定该点在这条直线上的对称点 (x2, y2)。花了大约一个小时试图想出解决方法,但没有成功!

请参见此处的可视化效果 - http://www.analyzemath.com/Geometry/Reflection/Reflection.html


2
其实不算是一个算法,但我写了一些解释:http://martin-thoma.com/reflecting-a-point-over-a-line/ - Martin Thoma
感谢@moose的文章。如果有一个例子会更好。 - Ayan Biswas
9个回答

40

好的,我将为您提供一种烹饪书方法来完成这个任务。如果您对我是如何得出它感兴趣,请查看http://www.sdmath.com/math/geometry/reflection_across_line.html#formulasmb

给定点(x1, y1)和通过(x2,y2)(x3,y3)的一条线,我们可以首先将该线定义为y=mx+c,其中:

斜率 m(y3-y2)/(x3-x2)

截距 c(x3*y2-x2*y3)/(x3-x2)

如果我们想要通过该线反射点(x1,y1) ,得到新的点(x4, y4),则:

设置d = (x1 + (y1 - c)*m)/(1 + m^2)然后:

x4 = 2*d - x1
y4 = 2*d*m - y1 + 2*c

1
你使用 y 作为点坐标和公式来描述线有点令人困惑。 - Qbyte
请问您能否澄清一下,在您的d方程中,哪个x和哪个y是指哪一个? - retrovius
1
我已经编辑了这个答案,以解释如何从问题所询问的两个坐标中获取标准线公式。很少有程序员能够心算出将由两个点定义的线段转换为 f(x) = ax+b 形式。他们可以计算出斜率,但是 y 截距...不行 =) - Mike 'Pomax' Kamermans
取决于你使用的编程语言?它们可以是同一件事,但是 ^ 是标准文本符号(除了使用正确的 m²)。原始帖子想要伪代码,而不是任何特定的语言,许多编程语言实际上不支持 **:有些支持,但有时你会得到 pow(),有时是 Math.pow(),有时你只能用 m*m - Mike 'Pomax' Kamermans
2
斜率在竖直线上未定义(在斜率计算中存在零除法),因此您可能需要单独处理此情况。 - StrandedKitty

20
这是Il-Bhima解决方案的简单解释。诀窍是要注意你想要在该线上正交投影那个点,将其移动那么多,然后再沿着同一方向移动它一次。
对于这些类型的问题,使用略微冗余的表示法表示一条线会更容易。让我们用在线上的一个点p和一个指向线方向的向量d来代替y = m x + b。让我们称这个点为p = (0, b),向量为d = (1, m),输入点为p1。线上的投影点将是pl,您的输出点p2,则为p1 + 2 * (pl - p1) = 2 * pl - p1
您需要的公式是将向量v投影到通过原点的方向为d的线上。它由d * / 给出,其中是两个向量之间的点积。
要找到pl,我们必须使整个问题移动以便该线通过原点,通过从p1中减去p,使用上述公式并将其移回。然后,pl = p + (d *

/ ),所以pl_x = p_x + (b * p1_x) / (1 + m * m),pl_y = p_y + (m * p1_x) / (1 + m * m),然后使用p2 = 2 * pl - p1获取最终值。


2

参考此处的图形。

我们想要找到点A(p,q)关于直线L1,方程为y = m*x + c的对称点。假设对称点为A'(p',q')

假设: 连接A和A'的直线为L2,方程为:y = m'*x + c' L1和L2相交于M(a,b)。

找到点的对称点的算法如下: 1)由于L1和L2垂直,因此找到L2的斜率为-1/m 2)使用m'和A(x,y)找到L2的c'值 3)找到L1和L2的交点'M' 4)由于现在已经知道A和M的坐标,因此可以使用关系[ A(p,q)+A'(p',q') ]/2 = M(a,b)轻松获得A'的坐标。

以下是用FORTRAN编写的粗略代码,未经检查:

SUBROUTINE REFLECTION(R,p,q)

IMPLICIT NONE

REAL,INTENT(IN)     ::  p,q

REAL, INTENT(OUT)   ::  R(2)

REAL                ::  M1,M2,C1,C2,a,b

M2=-1./M1                       ! CALCULATE THE SLOPE OF THE LINE L2 

C2=S(3,1)-M2*S(3,2)             ! CALCULATE THE 'C' OF THE LINE L2  

q= (M2*C1-M1*C2)/(M2-M1)        ! CALCULATE THE MID POINT O

p= (q-C1)/M1

R(1)=2*a-p                      ! GIVE BACK THE REFLECTION POINTS COORDINATE

R(2)=2*b-q

END SUBROUTINE REFLECTION

1

反射可以分为两个步骤。首先将所有内容向下平移b个单位,使点变为V=(x,y-b),线变为y=mx。然后,在线内部计算向量L=(1,m)。现在通过原点计算该线的反射。

(x',y') = 2(V.L)/(L.L) * L - V

其中 V.LL.L 分别表示点积,* 表示标量乘法。

最后,通过添加 b 来将所有内容向上移动,最终答案为 (x',y'+b)

作为仿射变换,您可以将上述操作写成三个矩阵的组合(乘积),首先表示位移 y => y-b,然后是通过原点的线反射,最后是位移 y => y+b

[ 1 0 0] [(1-m^2)/(1+m^2)      2m/(1+m^2) 0] [ 1 0  0] [x]
[ 0 1 b] [     2m/(1+m^2) (m^2-1)/(1+m^2) 0] [ 0 1 -b] [y]
[ 0 0 1] [             0               0  1] [ 0 0  1] [1]

这种情况非常类似于仿射几何中的旋转矩阵。如果您已经有矩阵乘法例程可用,例如因为您还在进行旋转,那么这可能是实现反射最可维护的方式。

1
我有一种更简单、更易实现的方法来使用C++。
#include<graphics.h>
#include<iostream>
#include<conio.h>
using namespace std;

int main(){
cout<<"Enter the point";
float x,y;
int gm,gd=DETECT;
initgraph(&gd,&gm,"C:\\TC\\BGI");

cin>>x;
cin>>y;
putpixel(x,y,RED);
cout<<"Enter the line slop and intercept";
float a,c;
cin>>a;
cin>>c;
float x1,y1;
x1 = x-((2*a*x+2*c-y)/(1+a*a))*a;
y1=(2*a*x+2*c-y)/(1+a*a);
cout<<"x = "<<x1;
cout<<"y = "<<y1;

putpixel(x1,y1,BLUE);
getch();

}


0

点关于直线的对称点 给定点P(x,y)和直线L1,则P(X,Y)是直线L1上的对称点。 如果我们将点P连接到P'以得到L2,则L2的斜率= 1 / m1,其中m1是L1的斜率。 L1和L2彼此垂直。 获得L1和L2的交点,称为m(a,b) 由于m(a,b)是PP '即L2的中点,则M =
即 = 从此,我们可以获得的坐标 例子 在线路中找到点P(4,3)的映像
M1 = 1 M2将是-1 用点(4,3),(x,y)grad -1等式L2是

交点为M(a,b) 注意,L1 = L2; 然后 这给出了M的点,即M(6,1) 然后;

          This gives x = 8 and y = -1 hence,

P'(x,y) = P'(8,-1)


0

点A(x,y)关于直线y=mx+c的对称点。
给定点P(x,y)和一条直线L1 y=mx+c。
那么P(X,Y)是直线L1上的对称点。
如果我们连接点P到P'得到L2,则L2的斜率为-1/m1,其中m1是L1的斜率。

  L1 and L2 are perpendicular to each other.
        therefore,
    Get the point of intersection of L1 and L2 say m(a,b)
    Since m(a,b) is the midpoint of PP’ i.e. L2, then
    M= (A+A')/2 
    i.e. m(a,b)=(A(x,y)+ A^' (x^',y^' ))/2.
      from this we can get coordinates of  A^' (x^',y^' )

例子

Find the image of point P(4,3) under a reflection in the line  y=x-5
M1=1
M2 will be -1
Equ. L2 with points, (4,3) , (x ,y) grad -1 is
     y=-x+7
Point of intersection say, M(a ,b)
 Note that, L1 =L2 ;
  Then x-5=-x+7
  This gives the point for M that is M( 6,1)
      Then;
         M(6,1)=(P(4,3)+P^' (x^',y^' ))/2
          M(6,1)=[(4+x)/2  ,(3+y)/2]
              This gives x = 8 and y = -1 hence,
                  P^' (x^',y^' )=         P^' (8,-1)

0

这个链接包含了一个与你所尝试做的类似的算法:

即将一条光线反射到法线上。

alt text


-1:重新阅读问题 - 他想要一个关于一条线的反射。 - Paul R
2
请重新阅读我的回答:这就是为什么我说它是“SIMILAR”的原因。在英语中,这意味着相关或涉及。Normal具有与线相同的内部数据成员。而点也具有与向量相同的内部数据成员。这最终就是我说它是一个“SIMILAR”问题的原因。 - C.J.

0

找到给定直线的斜率。 假设它是m。 那么连接该点和其镜像的直线的斜率为-1/m。 使用斜率点式来找到直线的方程,并找到其与给定直线的交点。最后,在中点公式中使用交点以获得所需的点。 祝好, Shashank Deshpande


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接