LiftSurface.component
This package holds more than this page lists. See all of its files in its world.
README.md
LiftSurface
A flat surface on a rigid body that the flow over it lifts and drags inside every physics step: a wing, a spoiler pressing a car down at speed, a sail, a rudder, a keel, a hydrofoil, a kite, a fin, an aileron or an elevator. It acts on the body of its entity or of the nearest ancestor holding one, at its entity's origin, so a plane carries its wings, tail and rudder as entities placed where each stands on the fuselage. One entity carries several, each further one under a name of its own.
normal is the side the surface lifts toward and forward the way its leading edge faces, both in the entity's own frame. The angle of attack is the angle the flow meets it at across its span. Lift acts across the flow and drag along it, each 0.5 * density * area * speed^2 times its coefficient at that angle, so downforce grows with the square of the speed. With no curve, lift grows by liftSlope per radian up to stallAngle either way, and past it the surface stalls into a flat plate. curve states lift and drag by angle instead, { { angle = degrees, lift, drag }, ... } in order of angle.
deflection (degrees) adds to the angle of attack, and deflectionValue names a named value (values.set) whose number adds to it too: a control stick written once moves every surface that follows it, with no script per step. In water a surface takes the water's density and flow, in the air the air's and the wind's.
Public fields: area (m², default 1), normal (default {0, 1, 0}), forward (default {0, 0, 1}), liftSlope (per radian, default 2 pi), stallAngle (degrees, default 15), dragMin (default 0.02), dragMax (default 1.2), curve, deflection (degrees), deflectionValue.
Physics.fluidForces(id).surfaces reads each surface's lift, drag, angleOfAttack, stalled, inWater and speed on the last step.
-- a rear wing pressing a car down
local wing = entity.spawn("rearWing", { parent = car, position = { 0, 1.1, -2 } })
wing.component.add("LiftSurface", { area = 0.9, normal = { 0, -1, 0 }, deflection = 10 })
-- a glider's wing and an elevator that follows the stick
glider.component.add("LiftSurface", { area = 12, liftSlope = 5.2 })
local tail = entity.spawn("elevator", { parent = glider, position = { 0, 0, -4 } })
tail.component.add("LiftSurface", { area = 2, deflectionValue = "pitch" })
glider.values.set("pitch", -3)
-- a sail stated by its own curve, and a keel in the water below it
mast.component.add("LiftSurface", { area = 10, normal = { 1, 0, 0 }, curve = {
{ angle = -40, lift = -0.9, drag = 0.7 }, { angle = 0, lift = 0, drag = 0.05 },
{ angle = 20, lift = 1.3, drag = 0.2 }, { angle = 40, lift = 0.9, drag = 0.7 } } })
keel.component.add("LiftSurface", { area = 1.5, normal = { 1, 0, 0 } })