Skip to content

Instantly share code, notes, and snippets.

@WinterAlexander
Created May 1, 2020 21:56
Show Gist options
  • Select an option

  • Save WinterAlexander/580750a396f15d47a1888464f9c7f4b9 to your computer and use it in GitHub Desktop.

Select an option

Save WinterAlexander/580750a396f15d47a1888464f9c7f4b9 to your computer and use it in GitHub Desktop.
PBD quick matlab simul
classdef (Abstract) Constraint
methods(Abstract)
particles = project(this, particles, iterations)
end
end
classdef DistanceConstraint < Constraint
properties
ParticleAIndex
ParticleBIndex
Distance
Stiffness
end
methods
function particles=project(this, particles, iterations)
A = particles(this.ParticleAIndex);
B = particles(this.ParticleBIndex);
p1Minusp2 = norm(A.EstimatePosition - B.EstimatePosition);
coeff = 1 - (1 - this.Stiffness).^(1 ./ iterations);
particles(this.ParticleAIndex).EstimatePosition = A.EstimatePosition - coeff * A.InverseMass / (A.InverseMass + B.InverseMass) * (p1Minusp2 - this.Distance) * (A.EstimatePosition - B.EstimatePosition) / p1Minusp2;
particles(this.ParticleBIndex).EstimatePosition = B.EstimatePosition + coeff * B.InverseMass / (A.InverseMass + B.InverseMass) * (p1Minusp2 - this.Distance) * (A.EstimatePosition - B.EstimatePosition) / p1Minusp2;
end
end
end
stepsize = 1 / 60;
iterations = 10;
particles(2, 1) = Particle();
constraints(1, 1) = DistanceConstraint();
particles(1).Position = [-5, 0]';
particles(1).Index = 1;
particles(2).Position = [5, 0]';
particles(2).Index = 2;
constraints(1) = DistanceConstraint;
constraints(1).ParticleAIndex = 1;
constraints(1).ParticleBIndex = 2;
constraints(1).Distance = 2;
constraints(1).Stiffness = 0.5;
countParticles = size(particles, 1);
X = zeros(countParticles, 1);
Y = zeros(countParticles, 1);
continuous = 0;
time = 0;
while true
for i=1:countParticles
X(i) = particles(i).Position(1);
Y(i) = particles(i).Position(2);
end
clf;
hold on;
scatter(X, Y);
title(append("Time: ", string(time)));
for i=1:size(constraints, 1)
if isa(constraints(i), 'DistanceConstraint')
plot([particles(constraints(i).ParticleAIndex).Position(1), particles(constraints(i).ParticleBIndex).Position(1)], [particles(constraints(i).ParticleAIndex).Position(2), particles(constraints(i).ParticleBIndex).Position(2)], '-');
end
end
axis([-10 10 -10 10]);
hold off;
drawnow
if continuous == 0
prompt = 'Step forward = s, Continuous=t, Quit=q\n';
choice = input(prompt, 's');
if choice == 'q'
return
elseif choice == 't'
continuous = 1;
end
end
particles = pbd(stepsize, iterations, particles, constraints);
time = time + stepsize;
end
classdef Particle
properties
Index
Position
EstimatePosition
Velocity
ExternalForce
InverseMass
end
methods
function this = Particle()
this.Index = 0;
this.Position = zeros(2, 1);
this.EstimatePosition = zeros(2, 1);
this.Velocity = zeros(2, 1);
this.ExternalForce = zeros(2, 1);
this.InverseMass = 1;
end
end
end
function particles = pbd(stepsize, iterations, particles, constraints)
for i = 1:size(particles, 1)
particles(i).Velocity = particles(i).Velocity + stepsize * particles(i).InverseMass * particles(i).ExternalForce;
end
for i = 1:size(particles, 1)
particles(i).EstimatePosition = particles(i).Position + stepsize * particles(i).Velocity;
end
for i = 1:iterations
for j = 1:size(constraints, 1)
particles = constraints(j).project(particles, iterations);
end
end
for i = 1:size(particles, 1)
particles(i).Velocity = (particles(i).EstimatePosition - particles(i).Position) / stepsize;
particles(i).Position = particles(i).EstimatePosition;
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment