; Copyright (C) 2010 Dave Griffiths : See LICENCE file (include "../maths/vec.sc") (include "line.sc") (include "../maths/intersection.sc") (define (sphere p r) (list 'sphere p r)) (define (sphere? s) (eq? (car s) 'sphere)) (define (sphere-pos l) (list-ref l 1)) (define (sphere-radius l) (list-ref l 2)) (define (sphere/line-dist s l) (vdist (sphere-pos s) (line-closest-point l (sphere-pos s)))) (define (sphere/line-intersect? s l) (< (sphere/line-dist s l) (sphere-radius s))) (define (sphere/line-intersect s l) (if (sphere/line-intersect? s l) (let* ((lv (line-vec l)) (position (sphere-pos s)) (a (vsq lv)) (b (* 2 (+ (* (vx lv) (- (vx (line-start l)) (vx position))) (* (vy lv) (- (vy (line-start l)) (vy position))) (* (vz lv) (- (vz (line-start l)) (vz position)))))) (c (- (+ (vsq position) (vsq (line-start l))) (* 2 (+ (* (vx position) (vx (line-start l))) (* (vy position) (vy (line-start l))) (* (vz position) (vz (line-start l))))) (sq (sphere-radius s)))) (i (- (* b b) (* 4 a c)))) (cond ((< i 0) #f) (else (let ((t (if (eq? i 0) (/ (- b) (* 2 a)) ; grazing (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* 2 a))))) ; just first intersection (if (and (> t 0) (< t 1)) (let ((pos (vadd (line-start l) (vmul lv t)))) (intersection t pos (vnorm (vsub pos position)))) #f))))) #f))