如何在飞机上获得三个非共线点? - C ++ [英] How do I get three non-colinear points on a plane? - C++

查看:155
本文介绍了如何在飞机上获得三个非共线点? - C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在线平面交集算法中实现。根据维基百科,我需要三个非共线点在飞机上这样做。



因此,我尝试实施但是,使用C ++的算法。事情绝对是错误的,因为它没有任何意义,我可以选择任何x和y坐标,他们将适合在飞机上。如果平面是垂直的并且沿着x轴怎么办?没有点y = 1会在平面中。



我意识到这个问题已经在StackOverflow上发布了很多,我看到很多解决方案,其中飞机由3个点定义。但我只有一个正常和一个位置。在我整理出非共线点搜索器之前,我不能测试我的线平面交点算法。

现在的问题是,我除以normal.z,当normal.z为0时,显然不会工作。



我用这个飞机测试:Plane * p = new Plane ),Vec3d(0.0,0.0,0.0),Vec3d(0.0,1.0,0.0)); //第二个参数:position,第三个参数:normal



当前代码给出了不正确的答案:

  {0,0,0} //好吧,这是原来的
{12.8377,17.2728,-inf} //显然这不是给定平面上的非共线点

这是我的代码:

  std :: vector< Vec3d> * Plane :: getThreeNonColinearPoints(){
std :: vector< Vec3d> * v = new std :: vector< Vec3d>

v-> push_back(Vec3d(position.x,position.y,position.z)); //原始位置可以作为三个非共线点之一。

srandom(time(NULL));

double rx,ry,rz,start;

rx = Plane :: fRand(10.0,20.0);
ry = Plane :: fRand(10.0,20.0);
//这里的公式:http://en.wikipedia.org/wiki/Plane_(geometry)#Definition_with_a_point_and_a_normal_vector
// nx(x-x0)+ ny(y-y0)+ nz z-z0)= 0
// | ----------------- | < - 这是开始
//我将尝试插入位置为x0,y0,z0,正常为nx,ny,nz,并求解等式
start = normal.x * (rx-position.x)+ normal.y *(ry-position.y);
// nz(z-z0)= -start
start = -start;
//(z-z0)= start / nz
start / = normal.z; //除以零
// z = start + z0
start + = position.z;
rz = start;

v-> push_back(Vec3d(rx,ry,rz));

// TODO一点

return v;
}

我意识到我可能会试图解决这个问题。如果是这样,请链接具体的实现。我确信它必须存在,当我看到这么多的线平面交集的实现。



提前感谢。

解决方案

飞机可以用几种方法定义。通常使用平面上的点和法线向量。要从三个点获得法向量( P1 P2 P3 )取三角形边的叉积

  P1 = {x1,y1,z1} 
P2 = {x2,y2,z2};
P3 = {x3,y3,z3};

N = UNIT(CROSS(P2-P1,P3-P1));
Plane P = {P1,N}

code> P1 和正常 N 到三个点,从任何方向开始 G DOT(G,N)!= 0 沿着正常 N >。沿着平面的两个正交方向是

  // try G = {0,0,1}或{0,1 ,0}或{1,0,0} 
G = {0,0,1};
if(MAG(CROSS(G,N)) if(MAG(CROSS(G,N)) U = UNIT(CROSS(N,G));
V = CROSS(U,N);
P2 = P1 + U;
P3 = P1 + V;

线由点和方向定义。通常两点( Q1 Q2 )定义行

  Q1 = {x1,y1,z1}; 
Q2 = {x2,y2,z2};
E = UNIT(Q2-Q1);
Line L = {Q1,E}

定义线和平面的交点通过与所述平面相交的线 r = Q1 + t * E 上的点使得 DOT(r-P1,N) code>。这是为标量距离 t 沿线解决的

  t = DOT(P1-Q1,N)/ DOT(E,N); 

且位置为

  r = Q1 +(t * E); 

注意: DOT()两个向量的小点积, CROSS()交叉乘积和 UNIT()单位向量(P,Q)= P [0] * Q [0] + P [1] * Q [1] + P [2] * Q [2];
CROSS(P,Q)= {P [1] * Q [2] -P [2] * Q [1],P [2] * Q [0] -P [0] * Q [2 ],P [0] * Q [1] -P [1] * Q [0]};
UNIT(P)= {P [0] / sqrt(DOT(P,P)),P [1] / sqrt(DOT(P,P)),P [2] / sqrt ,P))};
t * P = {t * P [0],t * P [1],t * P [2]
MAG(P)= sqrt(P [0] * P [0] + P [1] * P [1] + P [2] * P [2]);


I'm trying to implement at line-plane intersection algorithm. According to Wikipedia I need three non-colinear points on the plane to do that.

I therefore tried implementing this algorithm in C++, however. Something is definitely wrong, cause it makes no sense that I can choose whatever x and y coordinates and they'll fit in the plane. What if the plane is vertical and along the x-axis? No point with y=1 would then be in the plane.

I realize that this problem has been posted a lot on StackOverflow, and I see lots of solutions where the plane is defined by 3 points. But I only have a normal and a position. And I can't test my line-plane intersection algorithm before I sort out my non-colinear point finder.

The problem right now, is that I'm dividing by normal.z, and that obviously won't work when normal.z is 0.

I'm testing with this plane: Plane* p = new Plane(Color(), Vec3d(0.0,0.0,0.0), Vec3d(0.0,1.0,0.0)); // second parameter : position, third parameter : normal

The current code gives this incorrect answer:

{0 , 0 , 0} // alright, this is the original
{12.8377 , 17.2728 , -inf} // obviously this is not a non-colinear point on the given plane

Here's my code:

std::vector<Vec3d>* Plane::getThreeNonColinearPoints() {
    std::vector<Vec3d>* v = new std::vector<Vec3d>();

    v->push_back(Vec3d(position.x, position.y, position.z)); // original position can serve as one of the three non-colinear points.

    srandom(time(NULL));

    double rx, ry, rz, start;

    rx = Plane::fRand(10.0, 20.0);
    ry = Plane::fRand(10.0, 20.0);
    // Formula from here: http://en.wikipedia.org/wiki/Plane_(geometry)#Definition_with_a_point_and_a_normal_vector
    // nx(x-x0) + ny(y-y0) + nz(z-z0) = 0
    // |-----------------| <- this is "start"
    //I'll try to insert position as x0,y0,z0 and normal as nx,ny,nz, and solve the equation
    start = normal.x * (rx - position.x) + normal.y * (ry - position.y);
    // nz(z-z0) = -start
    start = -start;
    // (z-z0) = start/nz
    start /= normal.z; // division by zero
    // z = start+z0
    start += position.z;
    rz = start;

    v->push_back(Vec3d(rx, ry, rz));

    // TODO one more point

    return v;
}

I realize that I might be trying to solve this totally wrong. If so, please link a concrete implementation of this. I'm sure it must exist, when I see so many line-plane intersection implementations.

Thanks in advance.

解决方案

A plane can be defined with several ways. Typically a point on the plane and a normal vector is used. To get the normal vector from three points (P1, P2, P3 ) take the cross product of the side of the triangle

P1 = {x1, y1, z1};
P2 = {x2, y2, z2};
P3 = {x3, y3, z3};

N = UNIT( CROSS( P2-P1, P3-P1 ) );
Plane P = { P1, N }

The reverse, to go from a point P1 and normal N to three points, you start from any direction G not along the normal N such that DOT(G,N)!=0. The two orthogonal directions along the plane are then

//try G={0,0,1} or {0,1,0} or {1,0,0}
G = {0,0,1};
if( MAG(CROSS(G,N))<TINY ) { G = {0,1,0}; }
if( MAG(CROSS(G,N))<TINY ) { G = {1,0,0}; }
U = UNIT( CROSS(N, G) );  
V = CROSS(U,N);
P2 = P1 + U;
P3 = P1 + V;

A line is defined by a point and a direction. Typically two points (Q1, Q2) define the line

Q1 = {x1, y1, z1};
Q2 = {x2, y2, z2};
E = UNIT( Q2-Q1 );
Line L = { Q1, E }

The intersection of the line and plane are defined by the point on the line r=Q1+t*E that intersects the plane such that DOT(r-P1,N)=0. This is solved for the scalar distance t along the line as

t = DOT(P1-Q1,N)/DOT(E,N);

and the location as

r = Q1+(t*E);

NOTE: The DOT() returns the dot-product of two vector, CROSS() the cross-product, and UNIT() the unit vector (with magnitude=1).

DOT(P,Q) = P[0]*Q[0]+P[1]*Q[1]+P[2]*Q[2];
CROSS(P,Q) = { P[1]*Q[2]-P[2]*Q[1], P[2]*Q[0]-P[0]*Q[2], P[0]*Q[1]-P[1]*Q[0] };
UNIT(P) = {P[0]/sqrt(DOT(P,P)), P[1]/sqrt(DOT(P,P)), P[2]/sqrt(DOT(P,P))};
t*P =  { t*P[0], t*P[1], t*P[2] };
MAG(P) = sqrt(P[0]*P[0]+P[1]*P[1]+P[2]*P[2]);

这篇关于如何在飞机上获得三个非共线点? - C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆