Code: Select all
//Lentokoneena: BAe Hawk
SCREEN 1000,600
Const PHYSICS_ACCURACY = 3
Const AIR_DENSITY = 1.225
//Skaalaus
Const PIXEL_TO_METER = 0.1186
Const METER_TO_PIXEL = 8.4317032040472175379426644182125
Const GRAVITY = 9.81
Const ELEVATOR_DISTANCE_FROM_CENTER_OF_MASS = 5.1
Const ELEVATOR_AREA = 0.8 //m^2
Const ELEVATOR_DRAG_COEFFICIENT = 10.0
Const ROTATION_DRAG_COEFFICIENT = 100.0 //
Const WING_AREA = 16.69 //m^2
Const PLANE_MASS = 4000 //Kg
Const PLANE_MOMENT_OF_INERTIA = 4000 //Kg *m^2 Miten tämän saisi selville? Heitetty päästä ominaisuuksiin sopivaksi
Const DRAG_COEFFICIENT_X = 2.3 //Kerrottuna pinta-alalla TODO: Näillä arvoilla toimii, mutta ne eivät vastaa todellisuutta...
Const DRAG_COEFFICIENT_Y = 10.0
Const LIFT_DF_COEFFICIENT = 1.6
Const MOTOR_MAX_FORCE = 29130 //N
Const LIFT_COEFFICIENT_COUNT = 72
Dim LiftCoefficient(LIFT_COEFFICIENT_COUNT) As Float
Dim ElevatorLiftCoefficient(LIFT_COEFFICIENT_COUNT) As Float
InitLiftCoefficient()
floor=MakeObjectFloor()
grid=LoadImage("whitegrid.bmp")
PaintObject floor,grid
plane = LoadObject("aircraft.png", 180)
planeVX# = 50 //m/s
planeVY# = 0 //m/s
planeVA# = 0 //deg/s
planeThrottle# = 1.0 //Kaasun asento
elevatorAngle# = 0
DrawToWorld ON
Repeat
planeThrottle# = Max(0.0,Min(1.0,planeThrottle+(UpKey()-DownKey())*0.01))
ElevatorAngle# = CurveAngle((RightKey()-LeftKey())*45.0,elevatorAngle#,30)
If KeyHit(cbKeyR) Then
planeVX# = 100 //m/s
planeVY# = 0 //m/s
planeVA# = 0 //deg
planeA# = 0
EndIf
planeA# = ObjectAngle(plane)
planeX# = ObjectX(plane)*PIXEL_TO_METER
planeY# = ObjectY(plane)*PIXEL_TO_METER
timestep# = 1.0/60.0/PHYSICS_ACCURACY
For physics_step = 1 To PHYSICS_ACCURACY
//Nollataan voimat
planeFX# = 0
planeFY# = 0
planeFA# = 0
//Suunta vektori
planeAX# = Cos(planeA#)
planeAY# = Sin(planeA#)
//Muunnettaan lentokoneen liike sen omaan koordinaatistoon
planeLVX# = planeVX#*planeAX# + planeVY#*planeAY#
planeLVY# = planeVY#*planeAX# - planeVX#*planeAY#
airspeed# = Distance(0,0,planeVX#,planeVY#)
AngleOfAttack# = WrapAngle(-GetAngle(0,0,planeLVX#,-planeLVY#))
//Lasketaan noste
lift# = CalcLift(AngleOfAttack,airspeed#)
df# = CalcDF(AngleOfAttack, airspeed#)
aoaAX# = Cos(angleOfAttack)
aoaAY# = Sin(angleOfAttack)
//Lasketaan ilmanvastus
airresistY# = 0.5*AIR_DENSITY*planeLVY#*planeLVY#*DRAG_COEFFICIENT_Y
airresistX# = 0.5*AIR_DENSITY*planeLVX#*planeLVX#*DRAG_COEFFICIENT_X
airresistA# = 0.5*AIR_DENSITY*planeVA#*planeVA#*ROTATION_DRAG_COEFFICIENT
//Ilmanvastuksen etumerkit oikein
If planeLVX# > 0.0 Then airresistX# = -airresistX#
If planeLVY# > 0.0 Then airresistY# = -airresistY#
If planeVA# > 0.0 Then airresistA# = -airresistA#
liftLVX# = lift# * aoaAY
liftLVY# = lift# * aoaAX#
planeLFY# = (liftLVY# + df# + airresistY#) //Noste + ilmanvastus
planeLFX# = (airresistX# + liftLVX# + planeThrottle*MOTOR_MAX_FORCE)//Ilmanvastus + moottorin voima
planeFA# = (airresistA# + CalcElevatorLift(angleOfAttack+elevatorAngle#,airspeed#)*ELEVATOR_DISTANCE_FROM_CENTER_OF_MASS)
planeFX# = planeLFX#*planeAX# - planeLFY#*planeAY#
planeFY# = planeLFX#*planeAY# + planeLFY#*planeAX# - GRAVITY * PLANE_MASS
planeVX# = planeVX# + (planeFX# / PLANE_MASS) * timestep#
planeVY# = planeVY# + (planeFY# / PLANE_MASS) * timestep#
planeVA# = planeVA# + (planeFA# / PLANE_MOMENT_OF_INERTIA) * timestep#
//LIsätään sijaintiin ja kulmaan liikkeet
planeX# = planeX# + planeVX#*timestep#
planeY# = planeY# + planeVY#*timestep#
planeA# = planeA# + planeVA#*timestep#
Next physics_step
Text 10,10,"VX#:"+LSet(Str(planeVX#) + "m/s" , 12)+" VY#:"+LSet(Str(planeVY#) + "m/s", 12)+" VA#:"+LSet(Str(planeVA#) +"deg/s", 13)+" Angle:"+LSet(Str(planeA#) + "deg", 13)+" Lift:"+LSet(Str(lift#) + "N", 10)
Text 10,20,"ARX:"+LSet(Str(airresistX#) + "N", 10)+" ARY:"+LSet(Str(airresistX#) + "N", 10)
Text 10,30,"LVX:"+planeLVX#
Text 10,40,"Throttle:"+planeThrottle#+" Elevator angle:"+DirAngle(ElevatorAngle#)
Text 10,50,"Elevator force:"+elevatorForce#+ "AoA:"+DirAngle(AngleOfAttack#)
Text 10,60,"FX#:"+planeFX#+" FY#:"+planeFY#+" FA#:"+planeFA#
Text 10,70,"FPS:" + FPS() + " Air speed:" + Distance(0, 0, planeVX#, planeVY#)
PositionObject plane,planeX#*METER_TO_PIXEL,planeY#*METER_TO_PIXEL
RotateObject plane,planeA#
CloneCameraPosition plane
DrawGame
DrawScreen
Forever
Function InitLiftCoefficient()
//http://en.wikipedia.org/wiki/File:Lift_curve.svg
//0deg
//For i = 0 To 72
// LiftCoefficient(i) = Sin(i * 5.0 + 10) * 1.6 * (1 - (i / 150))
//Next i
LiftCoefficient(0) = 0.6
LiftCoefficient(1) = 1.0
LiftCoefficient(2) = 1.5
LiftCoefficient(3) = 1.8
LiftCoefficient(4) = 1.6
LiftCoefficient(5) = 1.4
LiftCoefficient(6) = 1.25
LiftCoefficient(7) = 1.08
LiftCoefficient(8) = 0.9
LiftCoefficient(9) = 0.6
LiftCoefficient(10) = 0.4
LiftCoefficient(11) = 0.3
LiftCoefficient(12) = 0.2
LiftCoefficient(13) = 0.1
LiftCoefficient(14) = 0.05
LiftCoefficient(15) = -0.05
LiftCoefficient(16) = -0.1
LiftCoefficient(17) = -0.15
//90deg
LiftCoefficient(18) = -0.22
LiftCoefficient(19) = -0.3
LiftCoefficient(20) = -0.3
LiftCoefficient(21) = -0.25
LiftCoefficient(22) = -0.25
LiftCoefficient(23) = -0.3
LiftCoefficient(24) = -0.3
LiftCoefficient(25) = -0.3
LiftCoefficient(26) = -0.3
LiftCoefficient(27) = -0.3
LiftCoefficient(28) = -0.3
LiftCoefficient(29) = -0.3
LiftCoefficient(30) = -0.3
LiftCoefficient(31) = -0.3
LiftCoefficient(32) = -0.3
LiftCoefficient(33) = -0.3
LiftCoefficient(34) = -0.3
LiftCoefficient(35) = -0.3
//180deg
LiftCoefficient(36) = -0.3
LiftCoefficient(37) = -0.25
LiftCoefficient(38) = -0.20
LiftCoefficient(39) = -0.15
LiftCoefficient(40) = -0.10
LiftCoefficient(41) = -0.05
LiftCoefficient(42) = -0.0
LiftCoefficient(43) = -0.0
LiftCoefficient(44) = -0.0
LiftCoefficient(45) = -0.0
LiftCoefficient(46) = -0.0
LiftCoefficient(47) = 0
LiftCoefficient(48) = 0
LiftCoefficient(49) = 0
LiftCoefficient(50) = 0
LiftCoefficient(51) = 0
LiftCoefficient(52) = 0
LiftCoefficient(53) = 0
//270deg
LiftCoefficient(54) = 0
LiftCoefficient(55) = 0
LiftCoefficient(56) = 0
LiftCoefficient(57) = 0
LiftCoefficient(58) = 0
LiftCoefficient(59) = 0
LiftCoefficient(60) = 0
LiftCoefficient(61) = -1.0
LiftCoefficient(62) = -1.5
LiftCoefficient(63) = -1.4
LiftCoefficient(64) = -1.4
LiftCoefficient(65) = -1.4
LiftCoefficient(66) = -1.3
LiftCoefficient(67) = -1.2
LiftCoefficient(68) = -1.2
LiftCoefficient(69) = -0.9
LiftCoefficient(70) = -0.5
LiftCoefficient(71) = 0.1
//360deg
LiftCoefficient(72) = 0.6
LiftCoefficient(72) = 0.6
LiftCoefficient(71) = 0.0
LiftCoefficient(70) = -0.5
LiftCoefficient(69) = -0.9
LiftCoefficient(68) = -1.2
LiftCoefficient(67) = -1.9
LiftCoefficient(66) = -2.8
LiftCoefficient(65) = -3.3
LiftCoefficient(64) = -3.9
LiftCoefficient(63) = -4.8
LiftCoefficient(62) = -5.5
LiftCoefficient(61) = -5.5
LiftCoefficient(60) = -5.5
For i = 0 To 72
ElevatorLiftCoefficient(i) = -((1.0-Abs((i Mod 18)-9)/9.0))*ELEVATOR_DRAG_COEFFICIENT
If (i > 18 And i < 36) Or (i > 54) Then ElevatorLiftCoefficient(i)= -ElevatorLiftCoefficient(i)
ElevatorLiftCoefficient(i) = ElevatorLiftCoefficient(i)
Next i
//TODO: Tarkempi taulukko + enemmän arvoja
EndFunction
Function DirAngle(a#)
a = WrapAngle(a)
If a > 180 Then Return a - 360
Return a
EndFunction
Function CalcElevatorLift(AngleOfAttack#,airspeed#)
aoa# = WrapAngle(AngleOfAttack#)/360.0*LIFT_COEFFICIENT_COUNT
aoamin# = ElevatorLiftCoefficient(Int(Max(0,RoundDown(aoa#))))
aoamax# = ElevatorLiftCoefficient(Int(Min(LIFT_COEFFICIENT_COUNT,RoundUp(aoa#))))
Return 0.5*AIR_DENSITY*airspeed#*airspeed#*ELEVATOR_AREA*(aoamin+(aoamax-aoamin)*(((aoa#-RoundDown(aoa#)) / 4.0)/LIFT_COEFFICIENT_COUNT))
EndFunction
Function CalcDF(aoa#, airspeed#)
c# = Sin(aoa#) * LIFT_DF_COEFFICIENT
Return 0.5 * airspeed# * airspeed# * c# * WING_AREA * AIR_DENSITY
EndFunction
Function CalcLift(AngleOfAttack#,airspeed#)
aoa# = WrapAngle(AngleOfAttack#)/360.0*LIFT_COEFFICIENT_COUNT
aoamin# = LiftCoefficient(Int(Max(0,RoundDown(aoa#))))
aoamax# = LiftCoefficient(Int(Min(LIFT_COEFFICIENT_COUNT,RoundUp(aoa#))))
Return 0.5*AIR_DENSITY*airspeed#*airspeed#*WING_AREA*(aoamin+(aoamax-aoamin)*(((aoa#-RoundDown(aoa#)) / 4.0)/LIFT_COEFFICIENT_COUNT))
EndFunction