feat: add option to show constraint forces in pendulum simulation
This commit is contained in:
parent
0d3b84cc28
commit
d16d99d2fd
2 changed files with 18 additions and 3 deletions
|
@ -80,13 +80,17 @@ export function drawConstraint(ctx: CanvasRenderingContext2D, ball1: BallState,
|
||||||
|
|
||||||
export function drawWorld(ctx: CanvasRenderingContext2D,
|
export function drawWorld(ctx: CanvasRenderingContext2D,
|
||||||
world: PhysicalWorldState,
|
world: PhysicalWorldState,
|
||||||
ballDrawers: BallDrawer[]
|
ballDrawers: BallDrawer[],
|
||||||
|
{
|
||||||
|
showForces = false
|
||||||
|
} = {}
|
||||||
) {
|
) {
|
||||||
for (const constraint of world.constraints) {
|
for (const constraint of world.constraints) {
|
||||||
const b1 = world.balls[constraint.p1Idx];
|
const b1 = world.balls[constraint.p1Idx];
|
||||||
const b2 = world.balls[constraint.p2Idx];
|
const b2 = world.balls[constraint.p2Idx];
|
||||||
drawConstraint(ctx, b1, b2);
|
drawConstraint(ctx, b1, b2);
|
||||||
// Draw force vectors for debugging
|
// Draw force vectors for debugging
|
||||||
|
if (!showForces) continue;
|
||||||
const scale = 100; // Scale for visibility
|
const scale = 100; // Scale for visibility
|
||||||
if (constraint.p1ConstraintForce) {
|
if (constraint.p1ConstraintForce) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
|
|
@ -7,6 +7,7 @@ export default function Pendulum() {
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const [subStep, setSubStep] = useState(10); // number of sub-steps per frame
|
const [subStep, setSubStep] = useState(10); // number of sub-steps per frame
|
||||||
const [constraintIterations, setConstraintIterations] = useState(1); // number of constraint iterations per sub-step
|
const [constraintIterations, setConstraintIterations] = useState(1); // number of constraint iterations per sub-step
|
||||||
|
const [showForces, setShowForces] = useState(false); // whether to show constraint forces
|
||||||
|
|
||||||
// refs to hold pendulum instances and animation state so we can reset from UI
|
// refs to hold pendulum instances and animation state so we can reset from UI
|
||||||
const worldRef = useRef<WorldState | null>(null);
|
const worldRef = useRef<WorldState | null>(null);
|
||||||
|
@ -45,7 +46,9 @@ export default function Pendulum() {
|
||||||
}
|
}
|
||||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||||
if (worldRef.current) {
|
if (worldRef.current) {
|
||||||
drawWorld(ctx, worldRef.current, worldRef.current.ballDrawers);
|
drawWorld(ctx, worldRef.current, worldRef.current.ballDrawers, {
|
||||||
|
showForces,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
rafRef.current = requestAnimationFrame(animate);
|
rafRef.current = requestAnimationFrame(animate);
|
||||||
};
|
};
|
||||||
|
@ -119,7 +122,7 @@ export default function Pendulum() {
|
||||||
window.removeEventListener("pointermove", onPointerMove);
|
window.removeEventListener("pointermove", onPointerMove);
|
||||||
window.removeEventListener("pointerup", onPointerUp);
|
window.removeEventListener("pointerup", onPointerUp);
|
||||||
};
|
};
|
||||||
}, [constraintIterations, subStep]);
|
}, [constraintIterations, showForces, subStep]);
|
||||||
|
|
||||||
// reset handler to re-create pendulums and avoid large dt on next frame
|
// reset handler to re-create pendulums and avoid large dt on next frame
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
|
@ -159,6 +162,14 @@ export default function Pendulum() {
|
||||||
className="ml-2 w-16 px-2 py-1 border border-gray-300 rounded focus:outline-none"
|
className="ml-2 w-16 px-2 py-1 border border-gray-300 rounded focus:outline-none"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
<label className="ml-4 text-sm">
|
||||||
|
디버그 힘 보기:
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
onChange={(e) => setShowForces(e.target.checked)}
|
||||||
|
className="ml-2 w-4 h-4"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 min-h-0">
|
<div className="flex-1 min-h-0">
|
||||||
<canvas
|
<canvas
|
||||||
|
|
Loading…
Add table
Reference in a new issue