简体   繁体   中英

3D line hits a 3D point?

I want to create a function wich knows if a line hits a point. Is there any function like that? I also want to set the size of my 3D-points in centimetre and dont know how to do that.

I appreciate your help.

For example: 在此处输入图片说明

Assuming that the points have an radius and the lines wouldnt hit the point exact in the middle, is the a function that shows me if a line hit the point?

I think what you actually want to compute is the distance between point and line in 3d

see: Point-Line Distance

and when the distance is smaller than the radius of the sphere around your point, you have a match.

Ok, I have classical solution that work in any dimensions.

First of all, you got sphere and a line, and you need to have good model of them. Sphere is easy you just have a Vector .center and .diameter .

class Sphere:
    def __init__( sphere, center, diameter ):
       sphere.center=Vector(center)
       sphere.diameter=float(diameter)

Line could be more problematic for beginners because it could be defined in many ways. The most useful comes from parametric equation, you have a direction in Vector .direction and some staring point .center . We assume that .direction is unit length, and .center is the nearest point on line from (0,0). In most cases we need to create a line, having to points Vectors:

def line_on_two_points( A, B ):
    return Line( direction= Vector(B)-A, center=A )

So we have to fix the direction and center in the constructor. .direction is easy to fix wee need just to make it unit length. To find .center , we need scalar projection . Here is as vector to D: 从(0,0)开始的线上最近点

Having .direction as unit length A to B and center as from C to A, we could init our line as:

class Line:
   def __init__( line, direction, center ):
        line.direction= Vector(direction) / length(direction)
        line.center= center - line.direction*dot(center,line.direction)

If we don't have a line, just two points we could just do:

#class Sphere:
def colide_line_on_two_points( sphere, A, B ):
    line=line_on_two_points( A-sphere.center, B-sphere.center)
    return length(line.center) < sphere.diameter

But when we have a line we try to optimize it as:

#class Sphere:
def colide_line( sphere, line ):
    return line.distance_to(sphere.center) < sphere.diameter

The .distance_to() function is a bit tricky:

从线到点的向量

#class Line:

   def vector_to( line, P ):
       return line.center + line.direction * dot(line.direction,P) - P

   def distance_to( line, P ):
       return length( line.center + line.direction * dot(line.direction,P) - P )

   def move_to( line, P ):
       line.center += line.direction * dot(line.direction,P) - P

The last but not least is the Vector type, I try numpy, but it's rather slow for 2D,3D:

from numpy import array as Vector
from numpy import dot
from numpy.linalg import norm as length

What you are looking for is an algorithm to find intersections between a line and a sphere. This is a problem commonly found in graphics programming, and there are a lot of articles that probably explain it a lot better than I could. There is one at http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/

The basic idea is that you project the sphere onto the line, and then solve the resulting right triangle , formed by the point of intersection, the sphere's center, and the projected point, using the Pythagorean theorem.

Here is the code I used in my pathtracing renderer:

hitdata intersectwith(Sphere sphere)
{
    d3Vector projected;

    float t = V.dot(sphere.pos.subtract(O));
    projected = V.normalize().scalarmultiply(t); //the projected vector
    float distnce = (projected.subtract(sphere.pos.subtract(O))).magnitude();
    //the length between the center of your sphere and the projected point
    hitdata outdata; // a class containing the results of the intersection
    outdata.hit = false;
    outdata.t = 110;
    if(t<=0)
    {
        return outdata;
    }
    if(distnce<sphere.r)
    {// the line is less distant from the center of the sphere than the surface
        outdata.hit = true;
        float deltaT = sqrtf((sphere.r*sphere.r)-(distnce*distnce));//Pythagorean theorem
        outdata.coord = O.add(V.scalarmultiply(t-deltaT));
        //calculating intersection coordinates
        outdata.normal = outdata.coord.subtract(sphere.pos);
        outdata.normal = outdata.normal.normalize();//calculating surface normals
        outdata.material = sphere.material;
        outdata.t = t-deltaT;
    }
    return outdata;
}

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