Math 四边形内点的相对位置

Math 四边形内点的相对位置,math,geometry,computational-geometry,Math,Geometry,Computational Geometry,我试图找到最简单的方法来确定一个点在四边形中的相对位置。已知的是(见图)点1、2、3、4和5在xy坐标系中的位置:x1、y1、x2、y2、x3、y3、x4、y4、x5、y5 在ξ-η坐标系中,点1、2、3和4的位置也是已知的(见图) 根据这些数据,我想确定第5点的ξ和η 结果 谢谢你们所有的人!我发现@dbc和@agentp的解决方案类似。我还发现这个解决方案比@MBo的透视变换解决方案更好,因为我不必计算矩阵的逆(Ax=B-->x=inv(a)*B) 我得到以下结果: u = 0.5 * (

我试图找到最简单的方法来确定一个点在四边形中的相对位置。已知的是(见图)点1、2、3、4和5在xy坐标系中的位置:x1、y1、x2、y2、x3、y3、x4、y4、x5、y5

在ξ-η坐标系中,点1、2、3和4的位置也是已知的(见图)

根据这些数据,我想确定第5点的ξ和η

结果

谢谢你们所有的人!我发现@dbc和@agentp的解决方案类似。我还发现这个解决方案比@MBo的透视变换解决方案更好,因为我不必计算矩阵的逆(Ax=B-->x=inv(a)*B)

我得到以下结果:

u = 0.5 * (ξ + 1)
v = 0.5 * (η + 1)
在我的例子中,所有点都在矩形内,因此u>0和v>0


您需要计算透视变换矩阵,将源四边形的4个点映射到目标四边形的4个点(),然后将此变换应用到第5点的坐标(将矩阵乘以坐标向量)

这看起来像是标准的有限元参数化 (这个问题没有指定一个特定的映射,但我想可能有人对这个特定的案例感兴趣)

这可以用{eta,ci}的封闭形式来解决,但是表达式很难发布

实际上,计算这些常数:

 ax = p1x + p2x + p3x + p4x
 bx = p1x - p2x - p3x + p4x
 cx = p1x + p2x - p3x - p4x
 dx = p1x - p2x + p3x - p4x
 ay = p1y + p2y + p3y + p4y
 by = p1y - p2y - p3y + p4y
 cy = p1y + p2y - p3y - p4y;
 dy = p1y - p2y + p3y - p4y;
eta
求解此二次方程:

 (ax by - bx ay) - 4 (by  x - bx y) +
  eta (dx ay - cx by + bx  cy - ax dy + 4 (x dy - dx y)) +
  eta^2 (cx dy - dx cy) == 0
然后获取
ci
as:

 ci = ((-ax + eta cx + 4 x)/(-bx + eta dx))
如果多边形不是太扭曲,那么其中一个解决方案将满足
-1的要求。为简单起见,我们将其坐标更改为0到1的范围:

u = 0.5 * (ξ + 1)
v = 0.5 * (η + 1)
在这种情况下,曲面求值器可以表示为

F(u, v) = P1 + u * (P2 - P1) + v * ((P4 + u * (P3 - P4)) - (P1 + u * (P2 - P1)))
即,对于给定的
u
,构造一条穿过以下两点的线:

Pv0 = P1 + u * (P2 - P1);
Pv1 = P4 + u * (P3 - P4);
然后针对给定的
v

F(u, v) = Pv0 + v * (Pv1 - Pv0)
您所寻找的是
(u,v)
,这样
F(u,v)=P5
。当从
Pv0
Pv1
的行通过
P5
时,对于给定的
u
将发生这种情况,当
P5-Pv0
Pv1-Pv0
平行时,即当其为零时:

现在,两个2d向量的⨯ B
Ax*by-Ay*Bx
给出,因此方程

(x5 - (x1 + u * (x2 - x1))) * (y4 + u * (y3 - y4) - (y1 + u * (y2 - y1))) - (y5 - (y1 + u * (y2 - y1))) * (x4 + u * (x3 - x4) - (x1 + u * (x2 - x1))) = 0
,我们得到

现在这是一个在
u
上的二次方程,也可以是这样的。请注意,如果四边形的上边缘和下边缘平行,则二次曲线将退化为线性方程;你的二次方程求解器必须处理这个问题

        double a = (x1 * y3 - x1 * y4 - x2 * y3 + x2 * y4 + (-x3) * y1 + x3 * y2 + x4 * y1 - x4 * y2);
        double b = (-x1 * y3 + 2 * x1 * y4 - x1 * y5 - x2 * y4 + x2 * y5 + x3 * y1 - x3 * y5 - 2 * x4 * y1 + x4 * y2 + x4 * y5 + x5 * y1 - x5 * y2 + x5 * y3 - x5 * y4);
        double c = (-x1 * y4 + x1 * y5 + x4 * y1 - x4 * y5 - x5 * y1 + x5 * y4);

        double[] solutions = Quadratic.Solve(a, b, c);
可能有多种解决方案。退化四边形也可能没有解

求解了
u
的值后,找到等价的
v
很简单。给定点

Pv0 = P1 + u * (P2 - P1);
Pv1 = P4 + u * (P3 - P4);
你寻找
v
,使

v * (Pv1 - Pv0) = P5 - Pv0;
选择坐标索引0或1,使
|(Pv1-Pv0)[index]|
最大化。(如果两个坐标几乎都为零,那么放弃——对于这个特定的
u
,没有解决方案。然后设置

v = (P5 - Pv0)[index] / (Pv1 - Pv0)[index];
最后,如果您有多个解决方案,请在混合的
[u,v]
边界内选择一个解决方案。然后最后设置

ξ = 2 * u - 1;
η = 2 * v - 1;
参考@blaz的自我回答(请投票支持@blaze、@dbc和@agentp的答案)

对于不愿意手动复制公式的所有人,以下公式为C#代码:

double v_sqrt=Math.sqrt(
4 * (
(x3-x4)*(y1-y2)-(x1-x2)*(y3-y4))*(x4*(-1*y+y1)+x1*(y-y4)+x*(-1*y1+y4))+
数学,战俘(
(x3*y-x4*y-x3*y1+2*x4*y1-x4*y2+x1*(y+y3-2*y4)+x2*(-1*y+y4)+x*(-1*y1+y2-y3+y4))
, 2)
);
double u_sqrt=Math.sqrt(
4*((x3-x4)*(y1-y2)-(x1-x2)*(y3-y4))
* (
x4*(-1*y+y1)+x1*(y-y4)+x*(-1*y1+y4)
) +
数学,战俘(
(x3*y-x4*y-x3*y1+2*x4*y1-x4*y2+x1*(y+y3-2*y4)+x2*(-1*y+y4)+x*(-1*y1+y2-y3+y4))
, 2)
);
双k=1/(2*((x3-x4)*(y1-y2)-(x1-x2)*(y3-y4));
双l=1/(2*((x1-x4)*(y2-y3)-(x2-x3)*(y1-y4));
///////////////////////////////////////////////////////////////////////////////////////////////
双v1=l*
(x2*y-x3*y+x4*y+x*y1-2*x2*y1+x3*y1-x*y2-x4*y2+x*y3-x1*(y-2*y2+y3)-x*y4+x2*y4+
v_sqrt);
///////////////////////////////////////////////////////////////////////////////////////////////
双u1=-1*k*
(-x2*y+x3*y-x*y1-x3*y1+2*x4*y1+x*y2-x4*y2-x*y3+x1*(y+y3-2*y4)+x*y4+x2*y4+
u_sqrt);
双v2=-1*l*
(x1*y+x3*y-x4*y-x*y1-2*x3*y1+x*y2--2*x1*y2+x4*y2-x*y3+x1*y3+x*y4-x2*(y-2*y1+y4)+
v_sqrt);
/////////////////////////////////////////////////////////////////////////////////////////////////
双u2=k*
(x2*y-x3*y+x4*y+x*y1+x3*y1-2*x4*y1-x*y2+x4*y2+x*y3-x1*(y+y3-2*y4)-x*y4-x2*y4)+
u_sqrt);
在大多数情况下,它是u1和v1,因此不需要计算其他值

我用它在一张纸上校准Pegasus空气笔设备(超声波笔)的坐标。如果点1到5的坐标也>=0,它的效果最好


Sry感谢您将此作为答案发布,但它太长,无法发表评论,我认为这对我来说是一个有价值的帮助。

不幸的是,此公式在未知和
Pv0 = P1 + u * (P2 - P1);
Pv1 = P4 + u * (P3 - P4);
v * (Pv1 - Pv0) = P5 - Pv0;
v = (P5 - Pv0)[index] / (Pv1 - Pv0)[index];
ξ = 2 * u - 1;
η = 2 * v - 1;