简体   繁体   中英

3D Line Segment and Plane Intersection - Contd

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

From here:

3D Line Segment and Plane Intersection

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 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.

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.

For example if:

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;

I expect the point to be:

(0.63, 1.26, 1.89)

However, it is:

(3.52, -5.87, 14.09)

A magnitude of 5.09 too big.

And I also tested:

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;

I expect the point to be:

(1.64, 2.45, 2.45)

However, it is:

(3.83761, 5.75642, 5.75642)

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

Quick check:

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) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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