- Joined
- Mar 15, 2012

- Messages
- 2,853

[jass=]

library ThreeDimSpin

globals

constant real HALF_PI = bj_PI/2

constant real PI = bj_PI

endglobals

struct Vector

real x

real y

real z

public static method create takes real facing, real tilt returns Vector

local Vector newVec = .allocate()

local real sinTilt = Sin(tilt)

set newVec.x = Cos(facing) * sinTilt

set newVec.y = Sin(facing) * sinTilt

set newVec.z = Cos(tilt)

return newVec

endmethod

public static method createXYZ takes real x, real y, real z returns Vector

local Vector newVec = .allocate()

set newVec.x = x

set newVec.y = y

set newVec.z = z

return newVec

endmethod

endstruct

function ComputePosition takes real facing, real tilt, real spin, real radius, real height returns Vector

local real sinFacing = Sin(facing)

local real cosFacing = Cos(facing)

local real sinTilt = Sin(tilt)

local real cosTilt = Cos(tilt)

local real bComponent // used later

local real cComponent // used later

// let A be the vector of our axis of rotation

local Vector a = Vector.create(facing, tilt)

local Vector b

local Vector c

// let B be the perpendicular to our axis, with:

// - a tilt of "HALF_PI - tilt" which you can think of a 90 deg minus tilt

// - and a facing of "facing + PI" which is just 180 degrees in the other direction

local real facingB = facing + PI

local real tiltB = HALF_PI - tilt

// maybe this will result in a negative tiltB

if tiltB < 0 then

set tiltB = tiltB + PI

set facingB = facing

endif

// now we have the direction data for a perpendicular vector (no distance yet)

set b = Vector.create(facingB, tiltB)

// then we take their cross product

set c = Vector.createXYZ(a.y * b.z - b.y * a.z, b.x * a.z - a.x * b.z, a.x * b.y - b.x * a.y)

// then we will add b * Sin(spin) * radius + c * Cos(spin) * radius

// make sure to compute everything only once, so I create a local for bComponent and cComponent

set bComponent = Sin(spin) * radius

set cComponent = Cos(spin) * radius

set a.x = b.x * bComponent + c.x * cComponent

set a.y = b.y * bComponent + c.y * cComponent

set a.z = b.z * bComponent + c.z * cComponent + height

call b.destroy()

call c.destroy()

return a

endfunction

endlibrary

[/code]

Last edited: