我试图找到最简单的方法来确定一个点在四边形内的相对位置。已知的是(见图)xy坐标系中的点1、2、3、4和5的位置: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。

最佳答案

您在这里拥有的是2d bilinear blended surface。为简单起见,让我们将其坐标范围从零更改为一:

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。当从uPv0的行通过Pv1时,对于给定的P5会发生这种情况,这在P5 - Pv0Pv1 - Pv0平行时发生-即当它们的2d cross为零时:

cross2d(P5 - Pv0, Pv1 - Pv0) = 0




cross2d(P5                 - (P1 + u * (P2 - P1)),
        P4 + u * (P3 - P4) - (P1 + u * (P2 - P1))) = 0


现在,两个二维向量A ⨯ B2d crossAx*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


Expanding this expression out and collecting collecting together terms in u,我们得到

    u^2 * (x1*y3 - x1*y4 - x2*y3 + x2*y4 + (-x3)*y1 + x3*y2 + x4*y1 - x4*y2)
  + u *   (-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)
  +       (-x1*y4 + x1*y5 + x4*y1 - x4*y5 - x5*y1 + x5*y4)
= 0


现在,这是在u上的二次方程,因此可以是solved。请注意,在四边形的顶部和底部边缘平行的情况下,二次方可分解为线性方程式;您的二次方程求解器必须处理此问题。

        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;

10-08 04:05