Search content:

 

Personal Menu
Username:
Password:
Save password

Become a member

Forgot Password?

 

Don't miss these
MP3 Player
Toggle Button
Catpure Source Read And Save ASF File
Media Make & Go
Wait for explode to finish
cXtraPrintRTF
OnStage Media for Director
Get CD ROM Drive letter
Text Box Xtra
DaoX
MediaMacros Xtras Mall
 

 

 

Behavior Trigonometry Class v0.6

Added on 12/3/2003

 

Compatibilities:
D6_5 D7 D8 D8_5 D9 Mac Parent PC Shockwave

This item has not yet been rated

Author: drZool (website)

Trigonometry class collection, Fast precalculated tables. Good set of basic functions for use in gamephysics amongst others. openLingo material.

-- @Name trigmath
-- @Version 1.6
-- @Type Parent
-- @Author Christoffer Enedahl
-- @Home www.enedahl.com
-- @Home www.openlingo.org

-- @History Added    v1.6 2003-10-27 GetFarAngle, InvCos, pAtan1
-- @History Added    v1.5 2003-03-20 vectorToAngle(), vectorToDegree() Lazy use of atan
-- @History Added    v1.4 2003-02-26 isPointInQuad()
-- @History Removed  v1.4 2003-02-21 atan2, it turns out that this function is an undoc'd lingofunction. use: atan(y,x)
-- @History Added    v1.3 2003-02-19 atan2
-- @History Optimize v1.2 2003-02-12 Using 3d functions for normalize2d and others
-- @History Added    v1.2 2003-02-12 magnitude2d
-- @History Added    v1.1 2003-01-16 vector functions
-- @History Created  v1.0 2003-01-15
--
-- @Description Precalculate sin-, cos- and radtables for fast calculations
-- @Description Some angle operations on points.
--
-- @Dependencies olmath.ls sgn bitshiftleft bitshiftright
--
--Usage
--  p = trigmath.rotatePoint     ( point(3,5), trigmath.angleToRad(-45) )
--  p = trigmath.rotatePointFast ( point(3,5), 315 )
--
-- @Todo Lots of trigonometry, feel free to contribute.

property pDegToRad
property pCosTable --index is degrees 1-360
property pSinTable --index is degrees 1-360
property pRadTable --index is degrees 1-360
property pAtan1    --Precalced Atan(1)

on new me
  
  pDegToRad = pi / 180.0
  pAtan1    = atan(1)
  
  --Precalculate sin-, cos- and radtables for fast calculations
  pCosTable = []
  pSinTable = []
  pRadTable = []
  repeat with i = 1 to 360
    pRadTable.append( me.degreeToRad(i) )
    pCosTable.append( cos( pRadTable[i] ) )
    pSinTable.append( sin( pRadTable[i] ) )
  end repeat
  
  return me
end

on degreeToRad(me, aDegree)
  return aDegree * pDegToRad
end

on radToDegree (me, aRadian)
  return aRadian / pDegToRad
end

on degreeToRadFast (me, aDegree)
  -- aDegre must be an integer degree between 1 - 360
  return pRadTable.getAt(aDegree)
end

on rotatePoint (me, aPoint, aTheta)
  -- aTheta is a radian number.
  p = point(.0,.0)
  
  vCos = cos(aTheta)
  vSin = sin(aTheta)
  
  p[1] = vCos*aPoint[1] - vSin*aPoint[2]
  p[2] = vSin*aPoint[1] + vCos*aPoint[2]
  
  return p
end

--aTheta must be an integer degree between 1 - 360
on rotatePointFast (me, aPoint, aTheta)
  p = point(0,0)
  
  p[1] = pCosTable[aTheta]*aPoint[1] - pSinTable[aTheta]*aPoint[2]
  p[2] = pSinTable[aTheta]*aPoint[1] + pCosTable[aTheta]*aPoint[2]
  
  return p
end

on distance2d (me,aPoint1,aPoint2)
  vVector = vector( aPoint1[1] - aPoint2[1], aPoint1[2] - aPoint2[2], 0)
  return vVector.magnitude
end

on distance2dFast (me,aPoint1,aPoint2)
  -- Remember the returned distance is squared the actual distance!
  -- it about 5-10% faster than distance2d
  d1 = aPoint1[1] - aPoint2[1]
  d2 = aPoint1[2] - aPoint2[2]
  return (d1*d1) + (d2*d2)
end

on approxDistance2d ( me, aPoint1, aPoint2)
  
  dx = abs( aPoint2.loch - aPoint2.loch )
  dy = abs( aPoint2.locv - aPoint2.locv )
  
  if dx < dy then
    vMin = dx
    vMax = dy
  else
    vMin = dy
    vMax = dx
  end if
  
  approx = ( vMax * 1007 ) + ( vMin * 441 )
  if ( vMax < ( bitshiftleft(vMin,4) )) then approx = approx - ( vMax * 40 )
  
  -- add 512 for proper rounding
  return ( bitshiftright( approx + 512, 10 ) )
end

on vector2d (me,aPoint1,aPoint2)
  return aPoint2 - aPoint1
end

on normalize2d (me,aPoint)
  vVector = vector( the loch of aPoint, the locv of aPoint, 0)
  vVector.normalize()
  return point( vVector[1], vVector[2])
end

on magnitude2d me, aPoint
  vVector = vector( aPoint[1], aPoint[2], 0)
  return vVector.magnitude
end

on magnitude2dFast me, aPoint
  -- Remember the returned distance is squared the actual distance!
  -- it about 5-10% faster than magnitude2d
  a = aPoint[1]
  b = aPoint[2]
  return (a*a) + (b*b)
end

on get2dNormal me, aVector
  -- the resulting vector is the normal, but it is not normalized.
  -- all that happens is a rotate by 90 degrees.
  
  p = point(0,0)
  p[1] = pCosTable[90]*aVector[1] - pSinTable[90]*aVector[2]
  p[2] = pSinTable[90]*aVector[1] + pCosTable[90]*aVector[2]
  
  return p
end

on vectorToDegree (me,aVector)
  --Lazy use of atan
   return me.radToDegree( atan(aVector.locv, aVector.loch) )
end

on vectorToAngle (me,aVector)
  --Lazy use of atan
   return atan(aVector.locv, aVector.loch)
end

on angleToVector (me, aTheta)
   return point( cos(aTheta), sin(aTheta) )
end

on dotproduct2d (me, a ,b)
  return dotproduct( vector( a[1],a[2],0), vector( b[1],b[2],0) )
end

on lineToQuad (me, aA, aB, aLineWidth, aEndLineWidth)
  -- makes a quad, to use for example with copyPixels, then you can draw lines with the ability to blend it.
  -- aEndLineWidth is optional
  
  vQuad = [aA,aA,aB,aB]
  
  vNormal = me.normalize2d( me.get2dNormal( me.vector2d(aA,aB) ) )
  
  if voidP(aEndLineWidth) then
    vNormal = vNormal * (aLineWidth/2.0)
    
    vQuad[1] = vQuad[1] + vNormal
    vQuad[2] = vQuad[2] - vNormal
    vQuad[3] = vQuad[3] - vNormal
    vQuad[4] = vQuad[4] + vNormal
  else
    vNormalEnd = vNormal * (aEndLineWidth/2.0)
    vNormal    = vNormal * (aLineWidth   /2.0)
    
    vQuad[1] = vQuad[1] + vNormal
    vQuad[2] = vQuad[2] - vNormal
    vQuad[3] = vQuad[3] - vNormalEnd
    vQuad[4] = vQuad[4] + vNormalEnd
  end if
  
  return vQuad
end

on isPointInQuad(me, aQuad, aPoint)
  --clockwize quad
  vNextPoint = [2,3,4,1]
  
  repeat with vVertexNum = 1 to 4
    vArea = me.TriangleAreaFast(aPoint, aQuad[ vVertexNum ], aQuad[ vNextPoint[ vVertexNum ] ] )
    if vArea < 0 then return 0
  end repeat
  
  return 1
end

on TriangleAreaFast(me, p, a, b )
  --This function does not produce an accurate area of an triangle, but fast results determing order of points. used in isPointInQuad,
  --if this result is negative: the points are counterclockwize, therefore the p lies outside of the line a-b
  return (a.loch-p.loch) * (b.locv-p.locv) - (b.loch-p.loch)*(a.locv-p.locv)
end

on terminate me
end

on GetFarAngle (me,c,a,b)
  --
  --   |
  --   |x
  -- a |   b
  --   |___
  --     c
  --
  -- return the radian angle of the far side of a triangle with known lengths
  -- the corner of the far side of c
  -- the triangle does not need to be a "right triangle"
  -- CosineStatement: a2 = b2 + c2 - 2bc · cos vA  
  --  
  --  x = a*a + b*b - c*c
  --  x = x / float(2*a*b)
  --  x = me.InvCos(x)  
  --  
  --  return x
  
  if a*b = 0 then return 0
  
  return me.InvCos( (a*a + b*b - c*c) / float(2*a*b) )
end

on InvCos me, X  
  y = Sqrt(-X * X + 1)
  if y = 0 then return 0 --y=NAN
  return atan(-X / y) + 2 * pAtan1
end

--Other functions to be lingolized
--Secant Sec(X) = 1 / Cos(X)
--Cosecant Cosec(X) = 1 / Sin(X)
--Cotangent Cotan(X) = 1 / Tan(X)
--Inverse Sine Arcsin(X) = Atn(X / Sqr(-X * X + 1))
--Inverse Cosine Arccos(X) = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1)
--Inverse Secant Arcsec(X) = Atn(X / Sqr(X * X – 1)) + Sgn((X) – 1) * (2 * Atn(1))
--Inverse Cosecant Arccosec(X) = Atn(X / Sqr(X * X - 1)) + (Sgn(X) – 1) * (2 * Atn(1))
--Inverse Cotangent Arccotan(X) = Atn(X) + 2 * Atn(1)
--Hyperbolic Sine HSin(X) = (Exp(X) – Exp(-X)) / 2  
--Hyperbolic Cosine HCos(X) = (Exp(X) + Exp(-X)) / 2
--Hyperbolic Tangent HTan(X) = (Exp(X) – Exp(-X)) / (Exp(X) + Exp(-X))
--Hyperbolic Secant HSec(X) = 2 / (Exp(X) + Exp(-X))
--Hyperbolic Cosecant HCosec(X) = 2 / (Exp(X) – Exp(-X))
--Hyperbolic Cotangent HCotan(X) = (Exp(X) + Exp(-X)) / (Exp(X) – Exp(-X))
--Inverse Hyperbolic Sine HArcsin(X) = Log(X + Sqr(X * X + 1))
--Inverse Hyperbolic Cosine HArccos(X) = Log(X + Sqr(X * X – 1))
--Inverse Hyperbolic Tangent HArctan(X) = Log((1 + X) / (1 – X)) / 2
--Inverse Hyperbolic Secant HArcsec(X) = Log((Sqr(-X * X + 1) + 1) / X)
--Inverse Hyperbolic Cosecant HArccosec(X) = Log((Sgn(X) * Sqr(X * X + 1) + 1) / X)
--Inverse Hyperbolic Cotangent HArccotan(X) = Log((X + 1) / (X – 1)) / 2
--Logarithm to base N LogN(X) = Log(X) / Log(N)

 


Upload Provided by ABCUpload ASP

Contact

MMI
22 West Court Sq
Suite 2C
Newnan, GA 30263
USA

Fax - (206) 339-5833

Send e-mail