Unfortunately I didn't get the other member's code but here's my math assembled in a module.
Hopefully the previous postings from the other members will reappear.
Have fun.
(EnableExplicit - corrected - again
![Smile :-)](./images/smilies/icon_smile.gif)
Code: Select all
DeclareModule _Math
EnableExplicit
#GRAVITY = 9.81
#KM_TO_MILES = 1.609
#MILES_TO_KM = 0.621
#KM_TO_METERS = 1000
#METER_TO_INCH = 39.37
#METER_TO_FEET = 3.281
#INCH_TO_CM = 2.54
#FOOT_TO_CM = 30.48
#YARD_TO_CM = 91.44
#CM_TO_INCH = 0.39370
#DAYS_TO_WEEK = 7
#HOURS_TO_DAY = 24
#HOURS_TO_MIN = 60
#HOURS_TO_SEC = 3600
#MIN_TO_SEC = 60
#MINIMUM_CELCIUS = -273.16
#KILO_TONNE = 1000
#KILO_GRAMS = 1000
#OZ_TO_GRAMS = 28.375
#GRAMS_TO_OZ = 0.035
#POUND_TO_KILO = 0.454
#KILO_TO_POUND = 2.204
#KILOBYTE_BYTE = 1024
#NAUTICMILE_TO_MILE = 1.151 ;(length of a minute of longitude at equator)
#NAUTICMILE_TO_FEET = 6076.115
#FATHOM_TO_FEET = 6
#KB = 102928
#MB = 103000
#GB = 103001
#TB = 103002
Structure vector2D
x.f
y.f
EndStructure
Structure pt2d
x.d
y.d
EndStructure
Structure _2Dvector_pol
mag.f
dir.f
EndStructure
Structure vector3D
x.f
y.f
z.f
EndStructure
Structure pt3f
x.i
y.i
z.i
EndStructure
Structure quaternion
x.f
y.f
z.f
w.f
EndStructure
Structure _Sphere
x.f
y.f
z.f
radius.f
EndStructure
Structure _RGB
R.i
G.i
B.i
EndStructure
Structure LINE_Vec2D_Rotate
midPointX.i
midPointY.i
LineLen.i
Rotate.i
EndPosX.i
EndPosY.i
EndStructure
Declare.d ColorDistance(*col1._RGB, *col2._RGB)
Declare.d Distance(*p.POINT, *q.POINT)
Declare.i FindDist2VertLine(px.f, lx.f)
Declare.i FindDist2HorizLine(py.f, ly.f)
Declare.f FindSlopeOfLine(*p1.POINT, *p2.POINT)
Declare.f CalculateAccelerationSeconds(startVelocity.f, finalVelocity.f , time.f)
Declare.f EqOne_vf(vi.f, a.f, t.f)
Declare.f EqTwo_x(vf.f, vi.f, t.f)
Declare.f EqThree_x(vi.f, t.f, a.f)
Declare CheckForMotion(angle.f, weight.f, fric_coeff.f)
Declare.f CalcAccel(angle.f, weight.f, fric_coeff.f, mass.f)
Declare.f CalculateWork(force.f, friction.f, displacement.f)
Declare.f CalculateKineticEnergy(mass.f, speed.f)
Declare.f CalculateAngledWork(*obj.vector2D, friction.f, displacement.f)
Declare.f CalculatePotentialEnergy(mass.f ,height.f)
Declare Projectile_Trajectory(Screen_Bottom.i, Initial_vel.f, Initial_Angle.f)
Declare V2Dvector_comp_PolarToCompConversion(*vec._2Dvector_pol)
Declare V2Dvector_polar_CompToPolarConversion(*vec.vector2D)
Declare.f AngleDisplacement(arc.f, radius.f)
Declare.f AvgAngularVelocity(arcStart.f, arcEnd.f, time.f, radius.f)
Declare.f AvgAngAcceleration(angVelBegin.f, angVelEnd.f, time.f)
Declare.f TangVelocity(omega.f, radius.f)
Declare.f LinearSpeed(mass.f, initialHeight.f, inertia.f)
Declare EulerToQuat(roll.f, pitch.f, yaw.f, *quat.quaternion)
Declare.f SlopeBetweenPoints(*P1.POINT, *P2.POINT)
Declare FindThe2DMidPoint(*P1.POINT, *P2.POINT)
Declare.f FindThe3DMidPoint(*P1.vector3D, *P2.vector3D)
Declare CollisionBetweenSpheres(*S1._Sphere, *S2._Sphere)
Declare.f CalculateAngle2D(*P1.POINT, *P2.POINT, rad.d)
Declare CalcWeight3D(*obj.vector3D, mass.f, gravi.f)
Declare.f Momentum(velocity.f, mass.f)
Declare.f CalcDisplacement(velocity.f, _time.f)
Declare.f CalcPosition(oldPosition.f, velocity.f, _time.f)
Declare.f CalcAverageVelocity(_start.f , _End.f, time.f)
Declare.f Ohm_Law(value1.f, value2.f, CalcType.i = 0)
Declare ConvertDaysToSeconds(Days.i)
Declare.f ConvertMilesToMeters(Miles.f)
Declare.f ConvertSpeedFromMiles(Miles.f)
Declare.f ConvertAccelerationMilesToMeters(Miles.f)
Declare.f CelciusToFahrenheit(cels.f)
Declare.f FarenheitToCelcius(Fahren.f)
Declare.d Fibonacci()
Declare.f CalculateEnergyForWaterToBoil(Liters.f, InitTemp.f, FinalTemp.f)
Declare.f RandomF(Min.f, Max.f, Res.i = 100000)
Declare.i RandomI(min.i, Max.i, Res.i = 100000)
Declare.i Random32bit()
Declare.i AbsI(num.i)
Declare.f AbsF(num.f)
Declare OrbitCalc3D(*ReturnVec.Vector3D, CenterX.f, CenterY.f, CenterZ.f, AngleX.f, AngleY.f, Radius.i)
Declare EOrbitCalc3D(*ReturnVec.Vector3D, CenterX.f, CenterY.f, CenterZ.f, AngleX.f, AngleY.f, RadiusX.i, RadiusY.i, RadiusZ.i )
Declare.f FastDist(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f)
Declare.f calculateRelativeAngle2D(*origin.POINT, *P1.POINT)
Declare.d radtodeg(Rad.d)
Declare.d PointDirection(x.d, y.d, x2.d, y2.d)
Declare OrbitCalc2D(*ReturnVec.vector2D, CenterX.f, CenterY.f, AngleX.f, AngleY.f, Radius.i)
Declare.i CircularMovement2D(StartPosX.i, StartPosY.i, Angle.f, Radius.i, *xp.POINT)
Declare.f PercentageRemain(Value.f, Percent.f)
Declare.f PercentageTaken(Value.f, Percent.f)
Declare.f GetCubicVolume(Width.f, Height.f, Depth.f)
Declare.f GetSquare(Width.f, Height.f)
Declare.f GetAverage(List p.f())
Declare.q Convert(Bytes.q, this = #KB)
Declare.i LineRotationEndPosition2D(*o.LINE_Vec2D_Rotate)
Declare.i TriangleCtr(*PtCtr.pt3f, *Pt1.pt3f, *Pt2.pt3f, *Pt3.pt3f)
Declare.i RotatePt2d(*pt1.pt2d, *pt2.pt2d, dAng.d)
EndDeclareModule
Module _Math
Procedure.q Convert(Bytes.q, this = #KB)
Protected res.q
Select this
Case #KB
res = Bytes / 1024
Case #MB
res = (Bytes / 1024) / 1024
Case #GB
res = ((Bytes / 1024) / 1024) / 1024
Case #TB
res = (((Bytes / 1024) / 1024) / 1024)/ 1024
EndSelect
ProcedureReturn res
EndProcedure
Procedure.f GetAverage(List p.f())
Protected res.f
ForEach p()
res + p()
Next
ProcedureReturn res / ListSize(P())
EndProcedure
Procedure.f GetSquare(Width.f, Height.f)
ProcedureReturn width * Height
EndProcedure
Procedure.f GetCubicVolume(Width.f, Height.f, Depth.f)
ProcedureReturn Width * Height * Depth
EndProcedure
Procedure.f PercentageRemain(Value.f, Percent.f)
ProcedureReturn value - (value * Percent / 100)
EndProcedure
Procedure.f PercentageTaken(Value.f, Percent.f)
ProcedureReturn value * Percent / 100
EndProcedure
Procedure.i CircularMovement2D(StartPosX.i, StartPosY.i, Angle.f, Radius.i, *xp.POINT)
*xp\x = StartPosX + Cos(Angle) * Radius
*xp\y = StartPosY + Sin(Angle) * Radius
ProcedureReturn #True
EndProcedure
Procedure.i AbsI(num.i)
If num < 0
ProcedureReturn num * -1
EndIf
ProcedureReturn num
EndProcedure
Procedure.f AbsF(num.f)
If num < 0
ProcedureReturn num * -1
EndIf
ProcedureReturn num
EndProcedure
Procedure.d radtodeg(Rad.d)
ProcedureReturn Rad * 180 / #PI
EndProcedure
Procedure.d PointDirection(x.d, y.d, x2.d, y2.d)
ProcedureReturn Degree(ATan2(y-y2, x2-x))
EndProcedure
Procedure.d ColorDistance(*col1._RGB, *col2._RGB)
ProcedureReturn Sqr(Pow(*col1\R - *col2\R, 2) + Pow(*col1\G - *col2\G, 2) + Pow(*col1\B - *col2\B, 2))
EndProcedure ;purpose: To calculate the angle of an object from an arbitrary point (origin) in 2D space
;input: origin - the location of the origin
; P1 - the location of the object
;output: the angle from the origin to the object in degrees
Procedure.f calculateRelativeAngle2D(*origin.POINT, *P1.POINT)
Protected ang.f, calc.f
calc = (*P1\y - *origin\y) / (*P1\x - *origin\x)
ang = Degree(ATan(calc))
If *P1\y < *origin\y And *P1\x > *origin\x
ProcedureReturn ang ;angle is in the first quadrant
ElseIf (*P1\y < *origin\y And *P1\x < *origin\x) Or (*P1\y > *origin\y And *P1\x < *origin\x)
ProcedureReturn ang + 180 ;angle is in the second Or third quadrant
Else
ProcedureReturn ang + 360 ;angle is in the fourth quadrant
EndIf
EndProcedure
;The center inside a triangle
Procedure TriangleCtr(*PtCtr.pt3f, *Pt1.pt3f, *Pt2.pt3f, *Pt3.pt3f)
;#-----------------------------------------------------------------
*PtCtr\x = ( (*Pt1\x + *Pt2\x + *Pt3\x) / 3)
*PtCtr\y = ( (*Pt1\y + *Pt2\y + *Pt3\y) / 3)
*PtCtr\z = ( (*Pt1\z + *Pt2\z + *Pt3\z) / 3)
EndProcedure
;rotate one point around another point
Procedure RotatePt2d(*pt1.pt2d, *pt2.pt2d, dAng.d)
;#-----------------------------------------------
;Rotate pt2 Anti-Clockwise about pt1
Protected dAngRad.d = Radian(dAng)
Protected dDx.d, dDy.d
dDx = (*pt2\x - *pt1\x)
dDy = (*pt2\y - *pt1\y)
*pt2\x = Cos(dAngRad) * dDx - Sin(dAngRad) * dDy + *pt1\x
*pt2\y = Sin(dAngRad) * dDx + Cos(dAngRad) * dDy + *pt1\y
EndProcedure
;Returns the distance between two objects in 3D space
Procedure.f FastDist(x1.f, y1.f, z1.f, x2.f, y2.f, z2.f)
Protected x3.f, y3.f, z3.f, dist.f
x3.f = x1-x2:x3 = x3*x3
y3.f = y1-y2:y3 = y3*y3
z3.f = z1-z2:z3 = z3*z3
dist.f = x3+y3+z3
ProcedureReturn dist
EndProcedure
;returns the distance between two supplied points p and q
Procedure.d Distance(*p.POINT, *q.POINT)
Protected dx.d , dy.d, dist.d
dx = *p\x - *q\x ;horizontal difference
dy = *p\y - *q\y ;vertical difference
dist = Sqr(dx*dx + dy*dy ) ;distance using Pythagoras theorem
ProcedureReturn dist
EndProcedure
;distance from a point to a vertical line
Procedure.i FindDist2VertLine(px.f, lx.f)
Protected distance.i
distance = Abs(Px) - Abs(Lx)
ProcedureReturn distance
EndProcedure
;distance from a point to a horizontal line
Procedure.i FindDist2HorizLine(py.f, ly.f)
Protected distance.i
distance = Abs(Py) - Abs(Ly)
ProcedureReturn distance
EndProcedure
;Find the slope of a line
Procedure.f FindSlopeOfLine(*p1.POINT, *p2.POINT)
Protected slope.f
slope.f = (*p1\y - *p2\y) / (*p1\x + *p2\x)
ProcedureReturn slope
EndProcedure
;This function will calculate the acceleration in seconds.
Procedure.f CalculateAccelerationSeconds(startVelocity.f, finalVelocity.f , time.f)
ProcedureReturn (finalVelocity-startVelocity) / time
EndProcedure
;purpose: calculate final velocity, given initial velocity, acceleration and time
; input: vi initial velocity
; a acceleration
; t time
; output: our final velocity
Procedure.f EqOne_vf(vi.f, a.f, t.f)
ProcedureReturn vi + a * t
EndProcedure
;purpose: calculate change in distance, given final velocity, initial velocity And time
; input: vf final velocity
; vi initial velocity
; t time
; output: our change in distance
Procedure.f EqTwo_x(vf.f, vi.f, t.f)
ProcedureReturn 0.5 * (vf - vi) / t
EndProcedure
;purpose: calculate change in distance, given initial velocity, acceleration and time
; input: vi initial velocity
; t time
; a acceleration
; output: our change in distance
Procedure.f EqThree_x(vi.f, t.f, a.f)
ProcedureReturn vi * t + 0.5 * a * t * t
EndProcedure
;purpose: To determine whether an object on an incline will slide
; input: angle - the current angle of the incline
; weight - the weight of the object
; fric_coeff - the coefficient of Static friction between surfaces
; output: true If the object should slide, Else false
Procedure CheckForMotion(angle.f, weight.f, fric_coeff.f)
Protected normal.f, perpForce.f, stat_friction.f
; Calculate the normal force being exerted by the ramp
normal = weight * Cos(angle * #PI / 180)
; Calculate the force perpendicular To the normal
perpForce = weight * Sin(angle * #PI / 180)
; Calculate the amount of Static friction keeping the object at rest
stat_friction = fric_coeff * normal
; Return true If the object should slide, Else false
If perpForce > stat_friction
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;purpose: To determine whether an object on an incline will slide
; and how fast the object should accelerate
; input: angle - the current angle of the incline
; weight - the weight of the object
; fric_coeff - the coefficient of kinetic friction between surfaces
; mass - the mass of the object
; output: the acceleration of the object
Procedure.f CalcAccel(angle.f, weight.f, fric_coeff.f, mass.f)
Protected normal.f, perpForce.f, kin_friction.f, total_force.f
;Calculate the normal force being exerted by the object
normal = weight * Cos(angle * #PI / 180)
; Calculate the force perpendicular To the normal
perpForce = weight * Sin(angle * #PI / 180)
;Calculate the amount of Static friction keeping the object at rest
kin_friction = fric_coeff * normal
;Calculate the sum of forces acting upon the object
total_force = perpForce - kin_friction
;Return the acceleration of the object
ProcedureReturn total_force / mass
EndProcedure
;Here is a procedure that returns the amount of work done given a force,
;a friction force, And a displacement
Procedure.f CalculateWork(force.f, friction.f, displacement.f)
Protected netForce.f, temp.f
;calculate the difference of the forces.
netForce.f = force-friction
;multiply by displacement
temp.f = displacement * netForce
; Returns the value of the work in Joules
ProcedureReturn temp
EndProcedure
Procedure.f CalculateKineticEnergy(mass.f, speed.f)
Protected KE.f = (mass/2)*(Pow(speed,2))
ProcedureReturn KE
EndProcedure
Procedure.f CalculateAngledWork(*obj.vector2D, friction.f, displacement.f)
Protected temp.f, horizForce.f, work.f
;don't forget to convert to rads....
temp.f = Cos(Radian(*obj\y))
;calculate the horizontal force;
horizForce.f = *obj\x * temp
work.f = calculateWork(horizForce,friction, displacement) ; Procedure is above an previous post
ProcedureReturn work ;return the amount of work done considering an angled force:
EndProcedure
;calculation For potential energy
; Example: A book weighs 1.5 pounds, and it is raised 2 meters off the ground
; formula: 1.5lbs (1N/0.2248lbs) - 1N = 1kg*m/s2
Procedure.f CalculatePotentialEnergy(mass.f ,height.f)
;PE = Potential energy
Protected PE.f = mass * #GRAVITY * height
ProcedureReturn PE
EndProcedure
Procedure.i Random32bit()
ProcedureReturn (Random($FFFF) << 16) | Random($FFFF)
EndProcedure
;Negative and positive extremes allowed
Procedure.f RandomF(Min.f, Max.f, Res.i = 100000)
ProcedureReturn (Min + (Max - Min) * Random(Res) / Res)
EndProcedure
;Negative and positive extremes allowed
Procedure.i RandomI(min.i, Max.i, Res.i = 100000)
ProcedureReturn (Min + (Max - Min) * Random(Res) / Res)
EndProcedure
;Circular orbilat calculations 2D
Procedure OrbitCalc2D(*ReturnVec.vector2D, CenterX.f, CenterY.f, AngleX.f, AngleY.f, Radius.i)
*ReturnVec\X = CenterX + Radius*Cos(AngleY)*Cos(AngleX)
*ReturnVec\Y = CenterY + Radius*Sin(AngleX)
EndProcedure
;Circular orbital calculations
Procedure OrbitCalc3D(*ReturnVec.Vector3D, CenterX.f, CenterY.f, CenterZ.f, AngleX.f, AngleY.f, Radius.i)
*ReturnVec\X = CenterX + Radius*Cos(AngleY)*Cos(AngleX)
*ReturnVec\Y = CenterY + Radius*Sin(AngleX)
*ReturnVec\Z = CenterZ + Radius*Sin(AngleY)*Cos(AngleX)
EndProcedure
;Elliptic orbital calculations
Procedure EOrbitCalc3D(*ReturnVec.Vector3D, CenterX.f, CenterY.f, CenterZ.f, AngleX.f, AngleY.f, RadiusX.i, RadiusY.i, RadiusZ.i )
*ReturnVec\X = CenterX + RadiusX*Cos(AngleY)*Cos(AngleX)
*ReturnVec\Y = CenterY + RadiusY*Sin(AngleX)
*ReturnVec\Z = CenterZ + RadiusZ*Sin(AngleY)*Cos(AngleX)
EndProcedure
;Example for Projectile Trajectory
Procedure Projectile_Trajectory(Screen_Bottom.i, Initial_vel.f, Initial_Angle.f)
Protected x_pos.f = 0 ;starting point of projectile
Protected y_pos.f = Screen_Bottom ;bottom of screen
Protected y_velocity.f = 0 ;initial y velocity
Protected x_velocity.f = 0 ;constant x velocity
Protected gravity.f = 1 ;do want To fall too fast
Protected velocity.f = Initial_vel ;whatever
Protected angle.f = Initial_Angle ;whatever, must be in radians
;compute velocities in x,y
x_velocity = velocity*Cos(angle)
y_velocity = velocity*Sin(angle)
;do projectile loop Until object hits
;bottom of screen at Screen_Bottom
While(y_pos < Screen_Bottom)
; update position
x_pos + x_velocity
y_pos + y_velocity
;update velocity
y_velocity + gravity
Wend
EndProcedure
;purpose: To convert a vector from magnitude/direction To component form
;input: vec- a vector in magnitude/direction form
;output: our converted vector
Procedure V2Dvector_comp_PolarToCompConversion(*vec._2Dvector_pol)
;temporary variable which will hold the answer
Protected temp.vector2D
;Fill in our values
temp\x = *vec\mag * Cos(*vec\dir * #PI / 180)
temp\y = *vec\mag * Sin(*vec\dir * #PI / 180)
ProcedureReturn @temp
EndProcedure
;purpose: To convert a vector from component To magnitude/direction form
;input: vec- a vector in component form
;output: our converted vector
Procedure V2Dvector_polar_CompToPolarConversion(*vec.vector2D)
;temporary variable which will hold our answer
Protected temp._2Dvector_pol
;Calculate our magnitude using the Pythagorean theorom
temp\mag = Sqr(*vec\x * *vec\x + *vec\y * *vec\y)
;Error check To prevent a divide-by-zero
If temp\mag = 0
ProcedureReturn @temp
EndIf
;Calculate our angle. We are using ASin() which will Return an angle
;in either the 1st Or the 4th quadrant
temp\dir = (180 / #PI) * ASin(*vec\y / temp\mag)
;Adjust our angle in the event that it lies in the 2nd Or 3rd quadrant
If *vec\x < 0
temp\dir + 180
;Adjust our angle in the event that it lies in the 4th quadrant
ElseIf *vec\x > 0 And *vec\y < 0
temp\dir + 360
EndIf
ProcedureReturn @temp
EndProcedure
;calculate the angular displacement given the arc length and radius
Procedure.f AngleDisplacement(arc.f, radius.f)
Protected theta.f = arc/radius
ProcedureReturn theta
EndProcedure
;Average Angular Velocity
Procedure.f AvgAngularVelocity(arcStart.f, arcEnd.f, time.f, radius.f)
Protected initialDisplacement.f, endDisplacement.f,omega.f
;calculate the angular displacement.
initialDisplacement = arcStart/radius
endDisplacement = arcEnd/radius
omega = (endDisplacement - initialDisplacement) / time
ProcedureReturn omega
EndProcedure
;Average angular acceleration
Procedure.f AvgAngAcceleration(angVelBegin.f, angVelEnd.f, time.f)
Protected alpha.f
alpha = (angVelEnd - angVelBegin)/time
ProcedureReturn alpha
EndProcedure
;Tangential velocity
Procedure.f TangVelocity(omega.f, radius.f)
Protected velT.f
velT = omega*radius
ProcedureReturn velT
EndProcedure
Procedure.f LinearSpeed(mass.f, initialHeight.f, inertia.f)
Protected energy.f = 0.0, halfMass.f, halfInertiaMass.f, linearSpeed.f ,temp.f = 0.0
;first figure out what is known For sure.
energy = mass*initialHeight*#GRAVITY ; Define GRAVITY yourself..
;this term is used To hold the math equivalent of 1/2(m)vf^2
halfMass = mass/2
;this term hold on To the formula equivalent of
;1/2(inertia)*(mass) r^2 * wf^2
halfInertiaMass = inertia*mass/2
;make a holding place.
temp = energy/(halfMass+halfInertiaMass)
;take the square root To find the speed in m/s
linearSpeed = Sqr(temp)
ProcedureReturn linearSpeed
EndProcedure
;here is a procedure that converts from Euler angles (roll, pitch, And yaw) To quaternion
Procedure EulerToQuat(roll.f, pitch.f, yaw.f, *quat.quaternion)
Protected cr.f, cp.f, cy.f, sr.f, sp.f, sy.f, cpcy.f, spsy.f
;compute all trigonometric values used To compute the quaternion
cr = Cos(roll/2)
cp = Cos(pitch/2)
cy = Cos(yaw/2)
sr = Sin(roll/2)
sp = Sin(pitch/2)
sy = Sin(yaw/2)
cpcy = cp * cy
spsy = sp * sy
;combine values To generate the vector And scalar For the quaternion
*quat\w = cr * cpcy + sr * spsy
*quat\x = sr * cpcy - cr * spsy
*quat\y = cr * sp * cy + sr * cp * sy
*quat\z = cr * cp * sy - sr * sp * cy
EndProcedure
;input: P1 - representing point 1
; P2 - representing point 2
;output: The slope between our 2 points
Procedure.f SlopeBetweenPoints(*P1.POINT, *P2.POINT)
Protected temp.f
temp = (*P2\y - *P1\y) / (*P2\x - *P1\x)
ProcedureReturn temp
EndProcedure
;purpose: calculate the midpoint of a line segment
;input: P1 - representing point 1
; P2 - representing point 2
;output: midpoint between the two points
Procedure FindThe2DMidPoint(*P1.POINT, *P2.POINT)
Protected temp.POINT
;Calculate our midpoint
temp\x = (*P1\x + *P2\x) / 2.0
temp\y = (*P1\y + *P2\y) / 2.0
ProcedureReturn @temp
EndProcedure
;purpose: calculate the midpoint of a line segment in 3D
;input: P1- point 1 (x,y,z)
; P2- point 2
;output: the midpoint between the two points
Procedure.f FindThe3DMidPoint(*P1.vector3D, *P2.vector3D)
Protected temp.vector3D
;Calculate our midpoint
temp\x = (*P1\x + *P2\x) / 2.0
temp\y = (*P1\y + *P2\y) / 2.0
temp\z = (*P1\z + *P2\z) / 2.0
ProcedureReturn @temp
EndProcedure
;purpose: To detect a collision between 2 spheres
;input : S1 - our first sphere
; S2 - our second sphere
;output : True if there is a collision othewise False
Procedure CollisionBetweenSpheres(*S1._Sphere, *S2._Sphere)
If (Pow(*S2\x - *S1\x,2) + Pow(*S2\y - *S1\y,2) + Pow(*S2\z - *S1\z,2) < Pow(*S1\radius + *S2\radius,2))
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
;purpose: To calculate the angle between 2 objects in 2D space
;input: P1 - the location of the first object
; P2 - the location of the second object
; output: the angle between the objects in degrees
Procedure.f CalculateAngle2D(*P1.POINT, *P2.POINT, rad.d)
Protected ang.f = 0.0, calc.f = 0.0
calc = (*P2\y - *P1\y) / (*P2\x - *P1\x)
ang = ATan(calc) * Degree(rad)
;In the event that the angle is in the first quadrant
If *P2\y < *P1\y And *P2\x > *P1\x
ProcedureReturn ang
ElseIf (*P2\y < *P1\y And *P2\x < *P1\x) Or (*P2\y > *P1\y And *P2\x < *P1\x)
;In the event of second Or third quadrant
ProcedureReturn ang + 180
Else
;If none of the above, it must be in the fourth
ProcedureReturn ang + 360
EndIf
EndProcedure
;purpose: To calculate the weight of an object based on its mass
;input: mass - the mass of the object
; grav - the amount of constant acceleration due To gravity
;output: an structure with 3 floats representing the vector of weight
Procedure CalcWeight3D(*obj.vector3D, mass.f, gravi.f)
;The value in y will be the only number changed, since gravity
;is only applied along the Y axis
;Calculate the weight, it is assumed that grav(ity) is a negative number
*obj\y = mass * gravi
EndProcedure
;Purpose: To find the momentum of object with a given mass,travelling at a certain velocity
Procedure.f Momentum(velocity.f, mass.f)
Protected momentum.f
momentum = mass * velocity
ProcedureReturn momentum
EndProcedure
;Pass velocity And time and return resulting displacement.
Procedure.f CalcDisplacement(velocity.f, _time.f)
ProcedureReturn velocity * _time
EndProcedure
;Pass the old position , velocity And time and return new position specified by time.
Procedure.f CalcPosition(oldPosition.f, velocity.f, _time.f)
ProcedureReturn oldPosition + (velocity * _time)
EndProcedure
Procedure.f CalcAverageVelocity(_start.f , _End.f, time.f)
ProcedureReturn (_End - _start) / time
EndProcedure
;Work = Force * Distance moved in the direction of the force
;Ohms law procedure
Procedure.f Ohm_Law(value1.f, value2.f, CalcType.i = 0)
Protected result.f
Select CalcType
Case 0 ;Voltage - value1 = current : value2 = resistance
result = value1 * value2
Case 1 ;Current - value1 = voltage : value2 = resistance
result = value1 / value2
Case 2 ;Resistance - value1 = voltage : value2 = current
result = value1 / value2
EndSelect
ProcedureReturn result
EndProcedure
Procedure ConvertDaysToSeconds(Days.i)
Protected seconds = Days * #HOURS_TO_DAY * #HOURS_TO_MIN * #MIN_TO_SEC
ProcedureReturn seconds
EndProcedure
Procedure.f ConvertMilesToMeters(Miles.f)
Protected meters.f = Miles * #KM_TO_MILES * #KM_TO_METERS
ProcedureReturn meters
EndProcedure
Procedure.f ConvertSpeedFromMiles(Miles.f)
Protected meters.f = (Miles * #KM_TO_MILES * #KM_TO_METERS) / (#HOURS_TO_MIN * #MIN_TO_SEC)
ProcedureReturn meters
EndProcedure
Procedure.f ConvertAccelerationMilesToMeters(Miles.f)
Protected aclMet.f = (Miles * #KM_TO_MILES * #KM_TO_METERS) / (#HOURS_TO_MIN * #MIN_TO_SEC * #HOURS_TO_MIN *#MIN_TO_SEC)
ProcedureReturn aclMet
EndProcedure
Procedure.f CelciusToFahrenheit(cels.f)
Protected fahren.F
If cels < #MINIMUM_CELCIUS
ProcedureReturn -1
Else
fahren = (9.0 / 5.0) * cels + 32
ProcedureReturn fahren
EndIf
EndProcedure
Procedure.f FarenheitToCelcius(Fahren.f)
Protected celsius = ((Fahren - 32) * 5) / 9
ProcedureReturn celsius
EndProcedure
Procedure.d Fibonacci()
Protected x, sum
Protected TheNext.d = 0
Protected TheLast.d = 1
For x = 0 To 45
sum = TheNext + Thelast
TheNext = Thelast
TheLast = sum
Debug TheLast
Next x
EndProcedure
Procedure.f CalculateEnergyForWaterToBoil(Liters.f, InitTemp.f, FinalTemp.f)
;Energy = Joules
Protected Energy.f = Liters * (FinalTemp - InitTemp) * 4184.0
ProcedureReturn Energy
EndProcedure
Procedure.i LineRotationEndPosition2D(*o.LINE_Vec2D_Rotate)
Protected cDgr = 360 - *o\Rotate + 180
*o\EndPosX = *o\midPointX + Sin(cDgr * (2 * #PI / 360))
*o\EndPosY = *o\midPointY + Cos(cDgr * (2 * #PI / 360))
If *o\LineLen > 0
*o\EndPosX * *o\LineLen
*o\EndPosY * *o\LineLen
EndIf
EndProcedure
EndModule
Code: Select all
; BY FOZ
; ################################################################### ;
;/
;/ Vector Maths
;/
; ################################################################### ;
Structure Vector
X.f
Y.f
Z.f
EndStructure
Procedure Vector_Add(*ReturnVector.Vector, *V1.Vector, *V2.Vector)
*ReturnVector\X = *V1\X + *V2\X
*ReturnVector\Y = *V1\Y + *V2\Y
*ReturnVector\Z = *V1\Z + *V2\Z
EndProcedure
Procedure Vector_Subtract(*ReturnVector.Vector, *V1.Vector, *V2.Vector)
*ReturnVector\X = *V1\X - *V2\X
*ReturnVector\Y = *V1\Y - *V2\Y
*ReturnVector\Z = *V1\Z - *V2\Z
EndProcedure
Procedure Vector_CrossProduct(*ReturnVector.Vector, *V1.Vector, *V2.Vector)
*ReturnVector\X = *V1\Y * *V2\Z - *V2\Y * *V1\Z
*ReturnVector\Y = *V1\Z * *V2\X - *V2\Z * *V1\X
*ReturnVector\Z = *V1\X * *V2\Y - *V2\X * *V1\Y
EndProcedure
Procedure.f Vector_DotProduct(*V1.Vector, *V2.Vector)
ProcedureReturn (*V1\X * *V2\X) + (*V1\Y * *V2\Y) + (*V1\Z * *V2\Z)
EndProcedure
Procedure.f Vector_Length(X.f, Y.f, Z.f)
ProcedureReturn Sqr(X * X + Y * Y + Z * Z)
EndProcedure
Procedure Vector_Normalize(*NormVector.Vector)
length.f = Vector_Length(*NormVector\X, *NormVector\Y, *NormVector\Z)
*NormVector\X = *NormVector\X / length
*NormVector\Y = *NormVector\Y / length
*NormVector\Z = *NormVector\Z / length
EndProcedure
; ################################################################### ;
;/
;/ Matrix Maths
;/
; ################################################################### ;
Structure Matrix4
W1.f
X1.f
Y1.f
Z1.f
W2.f
X2.f
Y2.f
Z2.f
W3.f
X3.f
Y3.f
Z3.f
W4.f
X4.f
Y4.f
Z4.f
EndStructure
Procedure Matrix_Multiply(*NewMatrix.Matrix4, *M.Matrix4, *L.Matrix4)
*NewMatrix\W1 = *M\W1 * *L\W1 + *M\X1 * *L\W2 + *M\Y1 * *L\W3 + *M\Z1 * *L\W4
*NewMatrix\X1 = *M\W2 * *L\W1 + *M\X2 * *L\W2 + *M\Y2 * *L\W3 + *M\Z2 * *L\W4
*NewMatrix\Y1 = *M\W3 * *L\W1 + *M\X3 * *L\W2 + *M\Y3 * *L\W3 + *M\Z3 * *L\W4
*NewMatrix\Z1 = *M\W4 * *L\W1 + *M\X4 * *L\W2 + *M\Y4 * *L\W3 + *M\Z4 * *L\W4
*NewMatrix\W2 = *M\W1 * *L\X1 + *M\X1 * *L\X2 + *M\Y1 * *L\X3 + *M\Z1 * *L\X4
*NewMatrix\X2 = *M\W2 * *L\X1 + *M\X2 * *L\X2 + *M\Y2 * *L\X3 + *M\Z2 * *L\X4
*NewMatrix\Y2 = *M\W3 * *L\X1 + *M\X3 * *L\X2 + *M\Y3 * *L\X3 + *M\Z3 * *L\X4
*NewMatrix\Z2 = *M\W4 * *L\X1 + *M\X4 * *L\X2 + *M\Y4 * *L\X3 + *M\Z4 * *L\X4
*NewMatrix\W3 = *M\W1 * *L\Y1 + *M\X1 * *L\Y2 + *M\Y1 * *L\Y3 + *M\Z1 * *L\Y4
*NewMatrix\X3 = *M\W2 * *L\Y1 + *M\X2 * *L\Y2 + *M\Y2 * *L\Y3 + *M\Z2 * *L\Y4
*NewMatrix\Y3 = *M\W3 * *L\Y1 + *M\X3 * *L\Y2 + *M\Y3 * *L\Y3 + *M\Z3 * *L\Y4
*NewMatrix\Z3 = *M\W4 * *L\Y1 + *M\X4 * *L\Y2 + *M\Y4 * *L\Y3 + *M\Z4 * *L\Y4
*NewMatrix\W4 = *M\W1 * *L\Z1 + *M\X1 * *L\Z2 + *M\Y1 * *L\Z3 + *M\Z1 * *L\Z4
*NewMatrix\X4 = *M\W2 * *L\Z1 + *M\X2 * *L\Z2 + *M\Y2 * *L\Z3 + *M\Z2 * *L\Z4
*NewMatrix\Y4 = *M\W3 * *L\Z1 + *M\X3 * *L\Z2 + *M\Y3 * *L\Z3 + *M\Z3 * *L\Z4
*NewMatrix\Z4 = *M\W4 * *L\Z1 + *M\X4 * *L\Z2 + *M\Y4 * *L\Z3 + *M\Z4 * *L\Z4
EndProcedure
Procedure Matrix_FromEuler(*ReturnMatrix.Matrix4, angle_x.f, angle_y.f, angle_z.f)
Protected.f A,b,C,D,E,f,AD,BD
A = Cos(angle_x)
b = Sin(angle_x)
C = Cos(angle_y)
D = Sin(angle_y)
E = Cos(angle_z)
f = Sin(angle_z)
AD = A * D
BD = b * D
*ReturnMatrix\W1 = C * E
*ReturnMatrix\X1 = -C * f
*ReturnMatrix\Y1 = D
*ReturnMatrix\W2 = BD * E + A * f
*ReturnMatrix\X2 = -BD * f + A * E
*ReturnMatrix\Y2 = -b * C
*ReturnMatrix\W3 = -AD * E + b * f
*ReturnMatrix\X3 = AD * f + b * E
*ReturnMatrix\Y3 = A * C
*ReturnMatrix\Z1 = 0
*ReturnMatrix\Z2 = 0
*ReturnMatrix\Z3 = 0
*ReturnMatrix\W4 = 0
*ReturnMatrix\X4 = 0
*ReturnMatrix\Y4 = 0
*ReturnMatrix\Z4 = 1
EndProcedure
; ################################################################### ;
;/
;/ Quaternion Maths
;/
; ################################################################### ;
Structure Vector
X.f
Y.f
Z.f
EndStructure
Structure Matrix4
W1.f
X1.f
Y1.f
Z1.f
W2.f
X2.f
Y2.f
Z2.f
W3.f
X3.f
Y3.f
Z3.f
W4.f
X4.f
Y4.f
Z4.f
EndStructure
Structure Quaternion
X.f
Y.f
Z.f
W.f
EndStructure
Procedure Quaternion_ToMatrix(*ReturnMatrix.Matrix4, *q.Quaternion)
*ReturnMatrix\W1 = 1.0 - 2.0 * ( *q\Y * *q\Y + *q\Z * *q\Z );
*ReturnMatrix\X1 = 2.0 * (*q\X * *q\Y + *q\Z * *q\w);
*ReturnMatrix\Y1 = 2.0 * (*q\X * *q\Z - *q\Y * *q\w);
*ReturnMatrix\Z1 = 0.0;
; Second row
*ReturnMatrix\W2 = 2.0 * ( *q\X * *q\Y - *q\Z * *q\w );
*ReturnMatrix\X2 = 1.0 - 2.0 * ( *q\X * *q\X + *q\Z * *q\Z );
*ReturnMatrix\Y2 = 2.0 * (*q\Z * *q\Y + *q\X * *q\w );
*ReturnMatrix\Z2 = 0.0;
; Third row
*ReturnMatrix\W3 = 2.0 * ( *q\X * *q\Z + *q\Y * *q\w );
*ReturnMatrix\X3 = 2.0 * ( *q\Y * *q\Z - *q\X * *q\w );
*ReturnMatrix\Y3 = 1.0 - 2.0 * ( *q\X * *q\X + *q\Y * *q\Y );
*ReturnMatrix\Z3 = 0.0;
; Fourth row
*ReturnMatrix\W4 = 0;
*ReturnMatrix\X4 = 0;
*ReturnMatrix\Y4 = 0;
*ReturnMatrix\Z4 = 1.0;
EndProcedure
Procedure Quaternion_ToEular(*ReturnEular.Vector, *q.Quaternion)
Protected test.f = *q\X * *q\Y + *q\Z * *q\w;
Protected.f heading, attitude, bank
If (test > 0.499) ; singularity at north pole
heading = 2 * ATan2(*q\X, *q\w);
attitude = #PI/2;
bank = 0;
ElseIf (test < -0.499) ; singularity at south pole
heading = -2 * ATan2(*q\X, *q\w);
attitude = - #PI/2;
bank = 0;
Else
Protected sqx.f = *q\X * *q\X;
Protected sqy.f = *q\Y * *q\Y;
Protected sqz.f = *q\Z * *q\Z;
heading = ATan2(2 * *q\Y * *q\w - 2 * *q\X * *q\Z, 1 - 2 * sqy - 2 * sqz);
attitude = ASin(2 * test);
bank = ATan2(2 * *q\X * *q\w - 2 * *q\Y * *q\Z, 1 - 2 * sqx - 2 * sqz)
EndIf
*ReturnEular\Z = heading
*ReturnEular\Y = bank - #PI/2
*ReturnEular\X = attitude
EndProcedure
Procedure.f Quaternion_Length(*TempQuat.Quaternion)
ProcedureReturn Sqr(*TempQuat\w * *TempQuat\w + *TempQuat\X * *TempQuat\X + *TempQuat\Y * *TempQuat\Y + *TempQuat\Z * *TempQuat\Z)
EndProcedure
Procedure Quaternion_Conjugate(*NewQuat.Quaternion, *Quat1.Quaternion)
*NewQuat\X = -1 * *Quat1\X
*NewQuat\Y = -1 * *Quat1\Y
*NewQuat\Z = -1 * *Quat1\Z
*NewQuat\w = *Quat1\w
EndProcedure
Procedure Quaternion_Multiply(*NewQuat.Quaternion, *Quat1.Quaternion, *Quat2.Quaternion)
*NewQuat\X = *Quat1\X * *Quat2\w + *Quat1\Y * *Quat2\Z - *Quat1\Z * *Quat2\Y + *Quat1\w * *Quat2\X
*NewQuat\Y = -*Quat1\X * *Quat2\Z + *Quat1\Y * *Quat2\W + *Quat1\Z * *Quat2\X + *Quat1\w * *Quat2\Y
*NewQuat\Z = *Quat1\X * *Quat2\Y - *Quat1\Y * *Quat2\X + *Quat1\Z * *Quat2\W + *Quat1\w * *Quat2\Z
*NewQuat\w = -*Quat1\X * *Quat2\X - *Quat1\Y * *Quat2\Y - *Quat1\Z * *Quat2\Z + *Quat1\w * *Quat2\w
EndProcedure
Procedure Quaternion_Normalize(*TempQuat.Quaternion)
TEMP_length.f = Quaternion_Length(*TempQuat)
*TempQuat\X = *TempQuat\X / TEMP_length
*TempQuat\Y = *TempQuat\Y / TEMP_length
*TempQuat\Z = *TempQuat\Z / TEMP_length
*TempQuat\w = *TempQuat\w / TEMP_length
EndProcedure
Procedure Quaternion_ApplyVector(*quat.Quaternion, *vecin.Vector, *vecout.Vector)
Protected vecQuat.Quaternion, qResult.Quaternion, qTemp.Quaternion
vecQuat\X = *vecin\X
vecQuat\Y = *vecin\Y
vecQuat\Z = *vecin\Z
vecQuat\w = 0
Quaternion_Conjugate(@qTemp, @vecQuat)
Quaternion_Multiply(@qResult, @vecQuat, @qTemp)
CopyStructure(@qResult, @qTemp, QUATERNION)
Quaternion_Multiply(@qResult, *Quat, @qTemp)
*vecout\X = qResult\X
*vecout\Y = qResult\Y
*vecout\Z = qResult\Z
EndProcedure
Procedure Quaternion_FromEuler(*TempQuat.Quaternion, Yaw.f, Pitch.f, Roll.f)
If Yaw = 0 And Pitch = 0 And Roll = 0
*TempQuat\X = 0
*TempQuat\Y = 0
*TempQuat\Z = 0
*TempQuat\w = 1
ProcedureReturn 0
EndIf
Roll = (Roll * 0.01745329) / 2
Pitch = (Pitch * 0.01745329) / 2
Yaw = (Yaw * 0.01745329) / 2
cosRoll.f = Cos(Roll)
cosPitch.f = Cos(Pitch)
cosYaw.f = Cos(Yaw)
sinRoll.f = Sin(Roll)
sinPitch.f = Sin(Pitch)
sinYaw.f = Sin(Yaw)
cosPitchYaw.f = cosPitch * cosYaw
sinPitchYaw.f = sinPitch * sinYaw
*TempQuat\X = sinRoll * cosPitchYaw - cosRoll * sinPitchYaw
*TempQuat\Y = cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw
*TempQuat\Z = cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw
*TempQuat\w = cosRoll * cosPitchYaw + sinRoll * sinPitchYaw
Quaternion_Normalize(*TempQuat)
EndProcedure
Procedure Quaternion_FromAngleAxis(*TempQuat.Quaternion, X.f, Y.f, Z.f, angleDegrees.f)
If X = 0 And Y = 0 And Z = 0
*TempQuat\X = 0
*TempQuat\Y = 0
*TempQuat\Z = 0
*TempQuat\w = 1
ProcedureReturn 0
EndIf
TEMP_angle.f = angleDegrees * 0.01745329
TEMP_angle = TEMP_angle / 2
TEMP_scale.f = Sin(TEMP_angle)
*TempQuat\X = X * TEMP_scale
*TempQuat\Y = Y * TEMP_scale
*TempQuat\Z = Z * TEMP_scale
*TempQuat\w = Cos(TEMP_angle)
Quaternion_Normalize(*TempQuat)
EndProcedure
; BY NITUVIOUS
; --------------------------------------------------------
; gl_MoveObjectToPointB(Object,X,Y)
; --------------------------------------------------------
; This function moves an object to an X Y point in all
; directions. Movement speed is based on the array's
; speed. If the point is reached then the procedure
; returns true.
; Object - Name of an array and its element
; ToX, ToY, - Destination of the object
; --------------------------------------------------------
Procedure gl_MoveObjectToPointB(*Object.objstruct,ToX.f,ToY.f)
Static Object.objstruct
Static distance.f
; -- Checking if we have reached our destination
If *Object\x >= ToX.f-*Object\h_speed And *Object\x <= ToX.f+*Object\h_speed
*Object\x = ToX.f
If *Object\y >= ToY.f-*Object\v_speed And *Object\y <= ToY.f+*Object\v_speed
*Object\y = ToY.f
ProcedureReturn #True ; -- Return true when destination has been reached
EndIf
EndIf
; -- Increment position until we're at our destination
distance.f=Sqr((ToX.f-*Object\x)*(ToX.f-*Object\x)+(ToY.f-*Object\y)*(ToY.f-*Object\y));
*Object\x=*Object\x+*Object\h_speed*(ToX.f-*Object\x)/distance.f
*Object\y=*Object\y+*Object\v_speed*(ToY.f-*Object\y)/distance.f
; x = x+speed * x2 / distance
EndProcedure
Procedure.f Frac(a.f)
result.f = a.f - Round(a.f,#PB_Round_Down)
ProcedureReturn result.f
EndProcedure
;Debug frac(2003.5)
;BY STARGÅTE
; SI-Prefix
#Yotta = 1e24
#Zetta = 1e21
#Exa = 1e18
#Peta = 1e15
#Tera = 1e12
#Giga = 1e9
#Mega = 1e6
#Kilo = 1e3
#Hecto = 1e2
#Deca = 1e1
#Deci = 1e-1
#Centi = 1e-2
#Milli = 1e-3
#Micro = 1e-6
#Nano = 1e-9
#Pico = 1e-12
#Femto = 1e-15
#Atto = 1e-18
#Zepto = 1e-21
#Yocto = 1e-24
; Binary-Prefix
#Kibi = 1<<10
#Mebi = 1<<20
#Gibi = 1<<30
#Tebi = 1<<40
#Pebi = 1<<50
#Exbi = 1<<60
; Time-Prefix
#Minute = 60
#Hour = 3600
#Day = 86400
#Week = 604800
; Gaussian Function
Procedure.f Gauss(x.f, Radius.f=1.0)
ProcedureReturn 0.3989422804014326779*Exp(-0.5*x*x/(Radius*Radius))/Radius
EndProcedure
; Error Function
Procedure.f Erf(x.f)
ProcedureReturn Sign(x)*Sqr(1-Exp(-x*x*(1.273239544735162686+0.1400122886866666060*x*x)/(1+0.1400122886866666060*x*x)))
EndProcedure
; Inverse Error Function
Procedure.f InvErf(x.f)
Protected Ln.f = Log(1-x*x)*0.5
ProcedureReturn Sign(x)*Sqr(Sqr((4.546884979448284327+Ln)*(4.546884979448284327+Ln)-Ln*14.28446044815250805)-4.546884979448284327-Ln)
EndProcedure
; Returns a random float in the interval [0.0, Maximum]
Macro RandomFloat(Maximum=1.0)
( Random(2147483647)*Maximum*4.6566128752457969241e-10 ) ; Random * 1/MaxRandom
EndMacro
; Returns a random sign {-1, 1}
Macro RandomSign()
( Random(1)*2-1 )
EndMacro
; Returns a random angle in radian in the interval [0.0, 2*Pi[
Macro RandomAngle()
( Random(2147483647)*2.9258361585343193621e-9 ) ; Random * 2*Pi/(MaxRandom+1)
EndMacro
; Returns a random float in normal distribution in the interval ]-Infinity, Infinity[
Macro RandomGaussian(Variance=1.0)
( InvErf(RandomFloat(2)-1)*Variance*1.414213562373095049 )
EndMacro
; BY DEMIVEC
;purpose: To calculate the angle of an object from an arbitrary point (origin) in 2D space
;input: origin - the location of the origin
; P1 - the location of the object
;output: the angle from the origin to the object in degrees
Procedure.f calculateRelativeAngle2D(*origin.POINT, *P1.POINT)
Protected ang.f, calc.f
calc = (*P1\y - *origin\y) / (*P1\x - *origin\x)
ang = Degree(ATan(calc))
If *P1\y < *origin\y And *P1\x > *origin\x
ProcedureReturn ang ;angle is in the first quadrant
ElseIf (*P1\y < *origin\y And *P1\x < *origin\x) Or (*P1\y > *origin\y And *P1\x < *origin\x)
ProcedureReturn ang + 180 ;angle is in the second Or third quadrant
Else
ProcedureReturn ang + 360 ;angle is in the fourth quadrant
EndIf
EndProcedure
; BY IDLE
;first 3 moments of inertia 2D
;
; 1st moment, center of a mass
; where
; sumx + x
; sum y + y
;
; cx = sumx / area
; cy = sumy / area
;
; 2nd moment, inertia of mass around axis
; where
; sumXX + (X*X)
; sumYY + (Y*Y)
; sumXY + (X*Y)
;
; IX = SumXX - (Area * (cx * cx))
; IY = SumYY - (Area * (cy * cy))
; IXY = Sumxy - (Area * (cx * cy))
;
; 3rd moments, ra,rb, rc or shape parameter
; *note the shape parameter is invariant to both scale and rotation for a given identical mass
; and can be used to identify shapes in some cases.
; ta= Sqr((2.0 * ix * iY) - (4.0 *( ixy * ixy))/2.0)
; Ra = (ix + iy) + ta
; Rb = (ix + iy) - ta
; Shape = (Ra / Rb)
;
; orientation of mass
;
; where
; mmx = Xmax - Xmin
; mmy = Ymax - Ymin
;
; If ix = iy
; orient = 45
; ElseIf mmx >= mmy
; orient = (0.5 * (ATan(2 * (Ixy / (Iy - ix))))) / (#PI / 180)
; Else
; orient = (0.5 * (ATan(2 * Ixy / (ix - Iy)))) / (#PI / 180)
; EndIf
;example below
Structure moments
;moments
;1st
cx.f
cy.f
;2nd
ix.f
iy.f
ixy.f
;3rd
ra.f
rb.f
shape.f
;orientation
orient.f
;elipse
majoraxis.f
minoraxis.f
;bounds
Xmin.i
Xmax.i
Ymin.i
Ymax.i
EndStructure
Procedure GetMoments(img,x1,x2,y1,y2,color,*mom.moments)
Protected x,y,px,area.f,sumX.f,sumY.f,sumXX.f,sumYY.f,sumXY.f
Protected ta.f,mmx.f,mmy.f,cmx.f,cmy.f,orient.f
*mom\Xmin = 99999
*mom\Ymin = 99999
If StartDrawing(ImageOutput(img))
For x = x1 To x2
For y = y1 To y2
px = Point(x,y)
If px = color
sumX + x
sumY + y
Area + 1
sumXX + (x*x)
sumYY + (y*y)
sumXY + (x*y)
If x < *mom\Xmin
*mom\Xmin = x
EndIf
If x > *mom\XMax
*mom\Xmax = x
EndIf
If y < *mom\Ymin
*mom\Ymin = y
EndIf
If y > *mom\Ymax
*mom\Ymax = y
EndIf
EndIf
Next
Next
StopDrawing()
;1st moments cx = centerX cy=centerY
*mom\cx = sumx / Area
*mom\cy = sumy / Area
;2nd moments Ix Iy Ixy
*mom\ix = SumXX - (Area * (cx * cx))
*mom\iY = SumYY - (Area * (cy * cy))
*mom\ixY = Sumxy - (Area * (cx * cy))
;3rd moment shape parameter invarent to scale and rotation
ta= Sqr((2.0 * *mom\ix * *mom\iY) - (4.0 *(*mom\ixy * *mom\ixy)) * 0.5)
*mom\Ra = (*mom\ix + *mom\iy) + ta
*mom\Rb = (*mom\ix + *mom\iy) - ta
*mom\Shape = (*mom\Ra / *mom\Rb)
mmx = (*mom\Xmax - *mom\Xmin)
mmy = (*mom\Ymax - *mom\Ymin)
cmx = (*mom\Xmax + *mom\Xmin) * 0.5
cmy = (*mom\Ymax + *mom\Ymin) * 0.5
dmx = *mom\cx - cmx
dmy = *mom\cy - cmy
;orientation
If *mom\ix = *mom\iy
orient = 45
ElseIf mmx >= mmy
orient = (0.5 * (ATan(2 * (*mom\Ixy / (*mom\iy - *mom\ix))))) / (#PI / 180)
*mom\majoraxis = (mmx / Cos(Abs(orient) / (180 / #PI))) * 0.5
*mom\minoraxis = (Area) / (#PI * *mom\majoraxis)
Else
orient = (0.5 * (ATan(2 * *mom\Ixy / (*mom\ix - *mom\Iy)))) / (#PI / 180)
*mom\majoraxis = (mmy / Cos(Abs(orient) / (180 / #PI))) * 0.5
*mom\minoraxis = (Area) / (#PI * *mom\majoraxis)
EndIf
If mmx = mmy And Abs(*mom\ix- *mom\iy) < 1000
orient = 0
EndIf
;messy fudge to output 0 to 360 degrees
If *mom\ixy > 0
If *mom\iy > *mom\ix
If dmx > dmy
orient = (360 + orient) / (180/#PI)
Else
orient = (180 + orient) / (180/#PI)
EndIf
Else
If dmx > dmy
orient = (90 - orient) / (180/#PI)
Else
orient = (270 - orient) / (180/#PI)
EndIf
EndIf
Else
If *mom\iy > *mom\ix
If dmy > dmx
orient = (180 + orient) / (180/#PI)
Else
orient = orient / (180/#PI)
EndIf
Else
If dmx > dmy
orient = (90 - orient) / (180/#PI)
Else
orient = (270 - orient) / (180/#PI)
EndIf
EndIf
EndIf
If orient < 0
orient = 0
EndIf
*mom\orient = orient
EndIf
EndProcedure
; BY StarBootics
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Plane - Module
; File Name : Plane - Module.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 09-03-2015
; Last Update : 02-06-2016
; PureBasic code : V5.42 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;
; This code is free to be use where ever you like
; but you use it at your own risk.
;
; The author can in no way be held responsible
; for data loss, damage or other annoying
; situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CompilerIf #PB_Compiler_IsMainFile
IncludeFile "Vector3 - Module.pb"
CompilerEndIf
DeclareModule Plane
Structure Plane
A.f
B.f
C.f
D.f
EndStructure
Declare Update(*PlaneA.Plane, P_A.f, P_B.f, P_C.f, P_D.f)
Declare Reset(*PlaneA.Plane)
Declare ReadPlane(FileID.l, *PlaneA.Plane)
Declare WritePlane(FileID.l, *PlaneA.Plane)
Declare.s Format(*PlaneA.Plane, Decimal.b = 3)
Declare UnFormat(*PlaneA.Plane, Formated.s)
CompilerIf Defined(Vector3, #PB_Module)
Declare.f Distance(*PlaneA.Plane, *VectorA.Vector3::Vector3)
Declare.f Evaluate(*PlaneA.Plane, *VectorA.Vector3::Vector3)
Declare FromPoints(*PlaneA.Plane, *VectorA.Vector3::Vector3, *VectorB.Vector3::Vector3, *VectorC.Vector3::Vector3)
Declare IsPointInside(*PlaneA.Plane, *VectorA.Vector3::Vector3)
CompilerEndIf
EndDeclareModule
Module Plane
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Update <<<<<
Procedure Update(*PlaneA.Plane, P_A.f, P_B.f, P_C.f, P_D.f)
*PlaneA\A = P_A
*PlaneA\B = P_B
*PlaneA\C = P_C
*PlaneA\D = P_D
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Reset <<<<<
Procedure Reset(*PlaneA.Plane)
*PlaneA\A = 0.0
*PlaneA\B = 0.0
*PlaneA\C = 0.0
*PlaneA\D = 0.0
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Lecture sur fichier Binaire <<<<<
Procedure ReadPlane(FileID.l, *PlaneA.Plane)
*PlaneA\A = ReadFloat(FileID)
*PlaneA\B = ReadFloat(FileID)
*PlaneA\C = ReadFloat(FileID)
*PlaneA\D = ReadFloat(FileID)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Écriture sur fichier Binaire <<<<<
Procedure WritePlane(FileID.l, *PlaneA.Plane)
WriteFloat(FileID, *PlaneA\A)
WriteFloat(FileID, *PlaneA\B)
WriteFloat(FileID, *PlaneA\C)
WriteFloat(FileID, *PlaneA\D)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Formatage de l'équation du plan <<<<<
Procedure.s Format(*PlaneA.Plane, Decimal.b = 3)
ProcedureReturn StrF(*PlaneA\A, Decimal) + "x + " + StrF(*PlaneA\B, Decimal) + "y + " + StrF(*PlaneA\C, Decimal) + "z = " + StrD(*PlaneA\D, Decimal)
EndProcedure
Procedure UnFormat(*PlaneA.Plane, Formated.s)
*PlaneA\A = ValF(StringField(Trim(StringField(Formated, 1, "+")), 1, "x"))
*PlaneA\B = ValF(StringField(Trim(StringField(Formated, 2, "+")), 1, "y"))
*PlaneA\C = ValF(StringField(Trim(StringField(StringField(Formated, 1, "="), 3, "+")), 1, "z"))
*PlaneA\D = ValF(Trim(StringField(Formated, 2, "=")))
EndProcedure
CompilerIf Defined(Vector3, #PB_Module)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Distance Point plan <<<<<
Procedure.f Distance(*PlaneA.Plane, *VectorA.Vector3::Vector3)
ProcedureReturn (*PlaneA\A * *VectorA\i + *PlaneA\B * *VectorA\j + *PlaneA\C * *VectorA\k + *PlaneA\D) / Sqr(*PlaneA\A * *PlaneA\A + *PlaneA\B * *PlaneA\B + *PlaneA\C * *PlaneA\C)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Évaluation du plan au point spécifié <<<<<
Procedure.f Evaluate(*PlaneA.Plane, *VectorA.Vector3::Vector3)
ProcedureReturn *PlaneA\A * *VectorA\i + *PlaneA\B * *VectorA\j + *PlaneA\C * *VectorA\k
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Un plan passant par 3 points <<<<<
Procedure FromPoints(*PlaneA.Plane, *VectorA.Vector3::Vector3, *VectorB.Vector3::Vector3, *VectorC.Vector3::Vector3)
Vector3::Minus(Alpha.Vector3::Vector3, *VectorB, *VectorA)
Vector3::Minus(Beta.Vector3::Vector3, *VectorC, *VectorA)
Vector3::CrossProduct(Normal.Vector3::Vector3, Alpha, Beta)
Vector3::Unit(Normal)
CopyMemory(Normal, *PlaneA, SizeOf(Vector3::Vector3))
*PlaneA\D = *PlaneA\A * *VectorA\i + *PlaneA\B * *VectorA\j + *PlaneA\C * *VectorA\k
EndProcedure
Procedure IsPointInside(*PlaneA.Plane, *VectorA.Vector3::Vector3)
If *PlaneA\A * *VectorA\i + *PlaneA\B * *VectorA\j + *PlaneA\C * *VectorA\k = *PlaneA\D
Result = #True
Else
Result = #False
EndIf
ProcedureReturn Result
EndProcedure
CompilerEndIf
EndModule
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.001 secondes (75000.00 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
CompilerIf #PB_Compiler_IsMainFile
Vector3::Update(P.Vector3::Vector3, 0.0, 0.0, 1.0)
Vector3::Update(Q.Vector3::Vector3, 4.0, 2.0, 3.0)
Vector3::Update(R.Vector3::Vector3, -3.0, 1.0, 1.0)
Vector3::Update(S.Vector3::Vector3, -9.0, -10.0, -25.0)
Vector3::Update(T.Vector3::Vector3, 9.0, 10.0, 25.0)
Plane::FromPoints(Plane.Plane::Plane, P, Q, R)
Debug Plane::Format(Plane)
Debug Plane::Evaluate(Plane, P)
Debug Plane::Evaluate(Plane, Q)
Debug Plane::Evaluate(Plane, R)
Debug ""
Debug Plane::IsPointInside(Plane, S)
Debug Plane::IsPointInside(Plane, T)
Debug ""
Debug Plane::Distance(Plane, S)
Debug Plane::Distance(Plane, T)
CompilerEndIf