unit RayTr; { Everything-independent super ultra ray-tracing by Brion Vibber, 12-13-92, based on lots of stuff last revised 12-31-92, unless I forget to change this line. 12-25-92: set for Doubles 12-31-92: Totally changed to compete with POV-Ray } interface {$N+,E-,G+,X+} { Heck, I'm only going to use it here } uses Objects; { For TCollection, a super-useful thingy } const MinReal = 5.0e-324; MaxReal = 1.7e308; DarnSmall = 0.0001; type PUniverse = ^TUniverse; PObject3d = ^TObject3d; PLightSource = ^TLightSource; PPoint3d = ^TPoint3d; PRayInfo = ^TRayInfo; PTexture = ^TTexture; {PPolygon3d = ^TPolygon3d; PPolygonList = ^TPolygonList;} TPoint3d = object x,y,z: Double; procedure SetTo(ax,ay,az: Double); procedure MakeUnit; procedure Cross(v: TPoint3d); function Dot(v: TPoint3d): Double; procedure Add(v: TPoint3d); procedure Sub(v: TPoint3d); procedure Scale(s: Double); function Length: Double; procedure RotateFrom(v: TPoint3d); procedure RotateTo(v: TPoint3d); procedure RotateX(d: Double); procedure RotateY(d: Double); procedure RotateZ(d: Double); procedure Rotate(x,y,z: Double); end; TRay = object o,d: TPoint3d; end; TColor = object r,g,b,a: Double; { 0 - 1 } { a[lpha] is transparency } end; TTexture = object(TObject) end; function Power(x,y: Double): Double; function Log(x,y: Double): Double; function ArcSin(x: Double): Double; function ArcCos(x: Double): Double; function Tan(x: Double): Double; implementation procedure MakeTrip(r,g,b: Double; var c: RgbTriple); begin c.r := r; c.g := g; c.b := b; end; function Power(x,y: Double): Double; var i: Integer; x1: Double; begin {Power := Exp(y * Ln(x));} x1 := x; for i := 1 to Trunc(y)-1 do x1 := x1 * x; Power := x; end; function Log(x,y: Double): Double; begin Log := Ln(x) / Ln(y); end; function ArcSin(x: Double): Double; begin ArcSin := ArcTan(x / Sqrt(1 - (x*x))); end; function ArcCos(x: Double): Double; begin ArcCos := ArcTan(Sqrt(1 - Sqr(x)) / x); end; function Tan(x: Double): Double; begin Tan := Sin(x) / Cos(x); end; procedure TPoint3d.SetTo(ax,ay,az: Double); begin x := ax; y := ay; z := az; end; procedure TPoint3d.MakeUnit; var d: Double; begin d := Sqrt(Sqr(x)+Sqr(y)+Sqr(z)); if d <> 0 then begin x := x / d; y := y / d; z := z / d; end; end; procedure TPoint3d.Cross(v: TPoint3d); var xa,ya: Double; begin xa := y*v.z - z*v.y; ya := z*v.x - x*v.z; z := x*v.y - y*v.x; x := xa; y := ya; end; function TPoint3d.Dot(v: TPoint3d): Double; begin Dot := x*v.x + y*v.y + z*v.z; end; procedure TPoint3d.Add(v: TPoint3d); begin x := x + v.x; y := y + v.y; z := z + v.z; end; procedure TPoint3d.Sub(v: TPoint3d); begin x := x - v.x; y := y - v.y; z := z - v.z; end; procedure TPoint3d.Scale(s: Double); begin x := x * s; y := y * s; z := z * s; end; function TPoint3d.Length: Double; begin Length := Sqrt(Sqr(x)+Sqr(y)+Sqr(z)); end; procedure TPoint3d.RotateFrom(v: TPoint3d); var d,xa,ya,za,cos1,sin1: Double; begin v.MakeUnit; d := Sqrt(Sqr(v.y)+Sqr(v.z)); cos1 := v.z/d; sin1 := v.y/d; ya := y*cos1-z*sin1; z := y*sin1+z*cos1; y := ya; cos1 := d; sin1 := -v.x; za := z*cos1-x*sin1; x := z*sin1+x*cos1; z := za; end; procedure TPoint3d.RotateTo(v: TPoint3d); var d,xa,ya,za,cos1,sin1: Double; begin v.MakeUnit; d := Sqrt(Sqr(v.y)+Sqr(v.z)); cos1 := -v.z/d; sin1 := -v.y/d; ya := y*cos1-z*sin1; z := y*sin1+z*cos1; y := ya; cos1 := -d; sin1 := v.x; za := z*cos1-x*sin1; x := z*sin1+x*cos1; z := za; end; end.