stable collisions

This commit is contained in:
max
2026-09-03 17:27:52 +02:00
parent 815bd2d260
commit d8758f98dc
8 changed files with 151 additions and 452 deletions

View File

@@ -34,8 +34,6 @@ namespace PhysicsEngine
TorqueAccumulator += torque;
}
// --- Impulse Methods ---
public void ApplyImpulse(Vector2 impulse)
{
if (IsStatic) return;
@@ -46,10 +44,8 @@ namespace PhysicsEngine
{
if (IsStatic) return;
// Direct linear velocity change
Velocity += impulse * InverseMass;
// Rotate local offset into world space based on body rotation
float cos = MathF.Cos(Rotation);
float sin = MathF.Sin(Rotation);
Vector2 worldOffset = new Vector2(
@@ -57,7 +53,6 @@ namespace PhysicsEngine
localOffset.X * sin + localOffset.Y * cos
);
// 2D Cross product for torque: r x J
float torque = worldOffset.X * impulse.Y - worldOffset.Y * impulse.X;
AngularVelocity += torque * InverseInertia;
}
@@ -66,19 +61,14 @@ namespace PhysicsEngine
{
if (IsStatic) return;
// Direct linear velocity change
Velocity += impulse * InverseMass;
// Offset from center of mass in world space
Vector2 worldOffset = worldPosition - Position;
// 2D Cross product for torque: r x J
float torque = worldOffset.X * impulse.Y - worldOffset.Y * impulse.X;
AngularVelocity += torque * InverseInertia;
}
// --- Other Useful Methods to Consider ---
public void ApplyForceAtWorldPosition(Vector2 force, Vector2 worldPosition)
{
if (IsStatic) return;

View File

@@ -39,34 +39,27 @@ namespace PhysicsEngine
float speed = Velocity.Length();
if (speed < 0.01f) return;
// 1. Oncoming relative wind direction (opposite to velocity)
Vector2 windDir = -Velocity / speed;
float cos = MathF.Cos(Rotation);
float sin = MathF.Sin(Rotation);
// Box local axes transformed into world space (Assuming Size.Y is length/major axis)
Vector2 worldAxisY = new Vector2(-sin, cos); // Major axis vector
Vector2 worldAxisX = new Vector2(cos, sin); // Minor axis vector
// 2. Calculate effective frontal width (projected area in 2D) based on current orientation
Vector2 windPerp = new Vector2(-windDir.Y, windDir.X);
float projX = MathF.Abs(Vector2.Dot(worldAxisX, windPerp));
float projY = MathF.Abs(Vector2.Dot(worldAxisY, windPerp));
float effectiveWidth = Size.X * projX + Size.Y * projY;
// 3. Translational Drag Force (scales with dynamic pressure and current effective width)
float dragMagnitude = 0.5f * airDensity * speed * speed * DragCoefficient * effectiveWidth;
Vector2 dragForce = windDir * dragMagnitude;
ApplyForce(dragForce);
// 4. Weathercock / Fin-Effect Restoring Torque
// Measures angular misalignment between the box's major axis and the wind direction
float cross = worldAxisY.X * windDir.Y - worldAxisY.Y * windDir.X;
float restoringTorque = cross * 0.5f * airDensity * speed * speed * DragCoefficient * Size.X * Size.Y;
ApplyTorque(restoringTorque);
// 5. Angular Damping (Quadratic Rotational Drag)
float angularSpeed = MathF.Abs(AngularVelocity);
if (angularSpeed > 0.0001f)
{