3D线段和平面相交

3D线段和平面相交

本文介绍了3D线段和平面相交-续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在收到krlzlx的建议后,我将其发布为新问题.

After advice from krlzlx I have posted it as a new question.

从这里:

3D线段和平面相交

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

I have a problem with this algorithm, I have implemented it like so:

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定义为:

Point3d is defined as:

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

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

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

I am forced to use this structure, because in the larger system my component runs in it is defined like this and it cannot be changed.

我的代码可以很好地编译,但是测试得出该点的值不正确. x,y,z之比是正确的,但幅值是错误的.

My code compiles fine, but testing I get incorrect values for the point. The ratio of x, y, z is correct but the magnitude is wrong.

例如,如果:

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的幅度太大.

A magnitude of 5.09 too big.

我还测试了

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的大小太大了吗?

A magnitude of 2.34 too big?

推荐答案

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

Pseudocode (does not require vector normalization):

 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)

这篇关于3D线段和平面相交-续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-14 23:09