Ray-sphere Detection of collision detection

Source: Internet
Author: User

Feed

Recently a series of physics related, first of all to summarize some of the things written last year, and then see if you can masturbate a physics engine out.

Ray detection in the previous write Ray tracking when there are some written, but at that time is relatively simple to write, just recently work on the use of these, so good to write.

Write Ray Sphere's collision detection today.

Environment:

Unity5.2.3 Windows10 64bit


Start

Define a class to record the intersecting information

public class Raycasthitinfo    {public        Vector3 point;        public Vector3 normal;        public float distance;    }


The first is the intersection, and the normal of the intersection, and finally the distance from the beam.


Define the underlying shape

    Public enum Geometrytype    {        Sphere,        Box,        Capsule,        Plane,        Cylinder,        Cone,    }    public class Ngeometry    {        [hideininspector] public        geometrytype type;        Public Ngeometry (Geometrytype _type)        {            type = _type;        }    }    public class Sphere:ngeometry    {public        Vector3 Center;        public float radius;        Public Sphere (): Base (geometrytype.sphere) {} public        Sphere (Vector3 _center, float _radius)            : Base ( Geometrytype.sphere)        {            Center = _center;            radius = _radius;        }        public bool Contains (Vector3 p)        {            return (p-center). Magnitude <= radius * radius;        }    }


The quickest way to understand the three-dimensional collision algorithm is to first understand the two-dimensional algorithm.

First look at the position of the ray and the circle in the two-dimensional space.



There are three species, intersecting, tangent, and absent.

Here the ray and the sphere intersect, the basic and the two-dimensional situation is no different, can be seen as a ray and the sphere of a plane intersection.


Core code

public static bool Raycast (Ray Ray, float distance, Sphere Sphere, out Raycasthitinfo hitinfo) {if (!    Intersectrayspherebasic (ray, distance, sphere, out Hitinfo)) {return false;    } hitinfo.normal = Hitinfo.point-sphere.center;    HitInfo.normal.Normalize (); return true;}  public static bool Intersectrayspherebasic (Ray Ray, float distance, Sphere Sphere, out Raycasthitinfo hitinfo) {Hitinfo    = new Raycasthitinfo ();    Vector3 offset = sphere.center-ray.origin;    float raydist = Vector3.dot (ray.direction, offset);    float off2 = Vector3.dot (offset, offset);    float rad2 = Sphere.radius * Sphere.radius;        We ' re in the sphere if (off2 <= rad2) {hitinfo.point = Ray.origin;        Hitinfo.normal = Vector3.zero;        Hitinfo.distance = 0.0f;    return true; }//moving away from object or too far away if (raydist <= 0 | |    (raydist-distance) > Sphere.radius) {return false;    }//Find hit distance squaredRay passes by Sphere without hitting float d = rad2-(off2-raydist * raydist);    if (d < 0.0f) {return false;    }//Get the distance along the ray hitinfo.distance = Raydist-mathf.sqrt (d);    if (Hitinfo.distance > Distance) {//Hit point beyond length return false;    } hitinfo.point = Ray.origin + ray.direction * hitinfo.distance; return true;}

Reminder point 1

float raydist = Vector3.dot (ray.direction, offset);

The dot multiplication, also called the inner product and quantity product of a vector, is the product of the length of a vector and its projection on another vector;

Since ray.direction is a unit vector, the projection length of offset in the ray direction is calculated here.


Reminder Point 2

Float d = rad2-(off2-raydist * raydist);

The d here calculates the position identified in the figure, and the Blue Line is the raydist of the above calculation.



Test code

Using unityengine;using system.collections;using Nphysx;public class Rayspheretester:monobehaviour {public GameObjec    T Sphere;    Sphere _sphere;    Use the this for initialization void Start () {_sphere = new sphere (Vector3.zero, 1f);            }//update is called once per framevoid update () {//ray sphere test.            Ray Ray = new Ray (Vector3.zero, New Vector3 (1,1,1));            _sphere.center = sphere.transform.position;            _sphere.radius = 0.5f * sphere.transform.localscale.x;            Raycasthitinfo Hitinfo;            float castdistance = 10f;  if (Nraycasttests.raycast (Ray, Castdistance, _sphere, out Hitinfo)) {Debug.drawline (Ray.origin,                Ray.direction * hitinfo.distance, color.red, 0, false);            Debug.drawline (_sphere.center, _sphere.center + hitinfo.normal, Color.green, 0, false); } else {debug.drawline (ray.origin, Ray.direction * castdistance, Color. Blue, 0, false); }    }}


Run results





Off Topic

A small problem is mentioned here, which is that due to the computational accuracy of floating-point counting units in the CPU,

The code solving the quadratic equation suffers from limited FPU accuracy and returns ' no intersection ' while there defini Tely is one. The "best" fix for Move the Ray origin closer to the target sphere.

Ray Sphere intersection results may be inaccurate, and some small optimizations have been made

public static bool Intersectraysphere (Ray Ray, float distance, Sphere Sphere, out Raycasthitinfo hitinfo) {Vector3 x = ray. Origin-sphere.center;float L = Vector3.dot (x, x)-sphere.radius-10.0f;l = Mathf.max (l, 0.0f);  Ray Tmpray = new Ray (Ray.origin + L * ray.direction, ray.direction); bool status = Intersectrayspherebasic (Tmpray, distance -L, Sphere, out Hitinfo);D Ebug.  Log ("L:" + L);//bool status = Intersectrayspherebasic (ray, distance, sphere, out hitinfo); if (status) {hitinfo.distance + = l;} return status;}

But for the time being I have not found this problem.


Reference

PhysX3.3 Source Code

Real Time Renderring 3rd

Ray-sphere Detection of collision detection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.