繁体   English   中英

3D线段和平面相交-续

[英]3D Line Segment and Plane Intersection - Contd

根据krlzlx的建议,我将其发布为新问题。

从这里:

3D线段和平面相交

我对此算法有疑问,我已经这样实现了:

template <class T>
class AnyCollision {
   public:
    std::pair<bool, T> operator()(Point3d &ray, Point3d &rayOrigin, Point3d &normal, Point3d &coord) const {

    // get d value
    float d = (normal.x * coord.x) + (normal.y * coord.y) + (normal.z * coord.z);

    if (((normal.x * ray.x) + (normal.y * ray.y) + (normal.z * ray.z)) == 0) {
        return std::make_pair(false, T());
    }

    // Compute the X value for the directed line ray intersecting the plane
    float a = (d - ((normal.x * rayOrigin.x) + (normal.y * rayOrigin.y) + (normal.z * rayOrigin.z)) / ((normal.x * ray.x) + (normal.y * ray.y) + (normal.z * ray.z)));

    // output contact point
    float rayMagnitude = (sqrt(pow(ray.x, 2) + pow(ray.y, 2) + pow(ray.z, 2)));
    Point3d rayNormalised((ray.x / rayMagnitude), (ray.y / rayMagnitude), (ray.z / rayMagnitude));
    Point3d contact((rayOrigin.x + (rayNormalised.x * a)), (rayOrigin.y + (rayNormalised.y * a)), (rayOrigin.z + (rayNormalised.z * a))); //Make sure the ray vector is normalized
    return std::make_pair(true, contact);

};

Point3d定义为:

class Point3d {
   public:
    double x;
    double y;
    double z;

    /**
     * constructor
     *
     * 0 all elements
     */
    Point3d() {
        x = 0.0;
        y = 0.0;
        z = 0.0;
    }

我被迫使用这种结构,因为在较大的系统中,我在其中运行的组件是这样定义的,无法更改。

我的代码可以正常编译,但是测试得出该点的值不正确。 x,y,z的比率是正确的,但幅度是错误的。

例如,如果:

rayOrigin.x = 0;
rayOrigin.y = 0;
rayOrigin.z = 0;

ray.x = 3;
ray.y = -5;
ray.z = 12;

normal.x = -3;
normal.y = 12;
normal.z = 0;

coord.x = 7;
coord.y = -5;
coord.z = 10;

我希望重点是:

(0.63, 1.26, 1.89)

但是,它是:

(3.52, -5.87, 14.09)

5.09的大小太大。

而且我还测试了:

rayOrigin.x = 0;
rayOrigin.y = 0;
rayOrigin.z = 0;

ray.x = 2;
ray.y = 3;
ray.z = 3;

normal.x = 4;
normal.y = 1;
normal.z = 0;

p0.x = 2;
p0.y = 1;
p0.z = 5;

我希望重点是:

(1.64, 2.45, 2.45)

但是,它是:

(3.83761, 5.75642, 5.75642)

2.34的幅度太大吗?

伪代码(不需要向量归一化):

 Diff = PlaneBaseCoordinate - RayOrigin
 d = Normal.dot.Diff
 e = Normal.dot.RayVector 

if (e)
   IntersectionPoint = RayOrigin + RayVector * d / e
otherwise
  ray belongs to the plane or is parallel

快速检查:

Ray (0,0,0)  (2,2,2)    //to catch possible scale issues
Plane (0,1,0) (0,3,0)   //plane y=1
Diff = (0,1,0)
d = 3
e = 6
IntersectionPoint = (0,0,0) + (2,2,2) * 3 / 6 = (1, 1, 1) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM