Notifications
Clear all

[Closed] Intersection of a Line and a Sphere

Hello!

Math is not my favorite I would be very grateful if can someone share maxscript function with Line-Circle/Sphere Intersection (something like this http://paulbourke.net/geometry/sphereline/ ).

3 Replies

can’t you just port the “C Code example” in the link you posted to mxs ? you don’t even have to understand the maths.


/*
Intersection of a Line anda Sphere (or circle)
Written by Paul Bourke
 http://paulbourke.net/geometry/sphereline/ 

   Calculate the intersection of a ray and a sphere
   The line segment is defined from p1 to p2
   The sphere is of radius r and centered at sc
   There are potentially two points of intersection given by
   p = p1 + mu1 (p2 - p1)
   p = p1 + mu2 (p2 - p1)
   Return FALSE if the ray doesn't intersect the sphere.
*/

fn RaySphere p1 p2 sc r =
(
local mu1
local mu2
local pt1 = undefined
local pt2 = undefined
local dp = [0,0,0]
local EPS = 0.00001

   dp.x = p2.x - p1.x
   dp.y = p2.y - p1.y
   dp.z = p2.z - p1.z
   a = dp.x * dp.x + dp.y * dp.y + dp.z * dp.z
   b = 2.0 * (dp.x * (p1.x - sc.x) + dp.y * (p1.y - sc.y) + dp.z * (p1.z - sc.z))
   c = sc.x * sc.x + sc.y * sc.y + sc.z * sc.z
   c += p1.x * p1.x + p1.y * p1.y + p1.z * p1.z
   c -= 2.0 * (sc.x * p1.x + sc.y * p1.y + sc.z * p1.z)
   c -= r * r
   bb4ac = b * b - 4.0 * a * c

	if bb4ac < 0.0 then format "No intersections
"
	-- no intersections
    
	if bb4ac == 0.0 then 
	(
    --   one intersection
		local pt = [0,0,0]
        pt1.x = 1.0
		mu1 = -b / (2.0 * a)
		pt1 = [p1.x + mu * (p2.x - p1.x),p1.y + mu * (p2.y - p1.y), p1.z + mu * (p2.z - p1.z)]
	)

	if bb4ac > 0.0 then
	(
	-- first intersection
	mu1 = (-b + sqrt(bb4ac)) / (2.0 * a)
	pt1 = [p1.x + mu1 * (p2.x - p1.x),p1.y + mu1 * (p2.y - p1.y), p1.z + mu1 * (p2.z - p1.z)]

	-- second intersection		
    mu2 = (-b - sqrt(bb4ac)) / (2.0 * a)
	pt2 = [p1.x + mu2 * (p2.x - p1.x), p1.y + mu2 * (p2.y - p1.y), p1.z + mu2 * (p2.z - p1.z)]

	)

format "Intersections Point1: %, Point2: %
" pt1 pt2
res = #(pt1,pt2)
res
)

It seems I made it. :wip:

nice one, you can simplify a wee bit, my version for rays though using returns is bad form.

fn InterectRaySphere rayEye rayDir sphereCentre sphereRadius &tval &pnt =
 (
 	m = rayEye - sphereCentre;
 
 	b = dot m rayDir;
 	c = (dot m m)  - sphereRadius * sphereRadius;
 	
 -- exit if rays origin is outside s (c > 0) and r is pointing away from s (b > 0)	
 
 	if c > 0.0 and b > 0.0 then return 0;
 		
 -- a negative discriminant corresponds to ray missing the sphere
 
 	discr = b * b - c;
 
 	if 	discr < 0.0 then return 0;
 		
 -- so we have an intersection get smallest t
 
 	tval = -b - (sqrt discr );
 	
 	if tval < 0.0 then tval = 0.0;
 		
 -- computer the point on ray
 
 	pnt = rayEye + tval	* rayDir;
 )