8

I have seen the great tutorial by Peter Colling Ridge on
http://www.petercollingridge.co.uk/pygame-physics-simulation/
and I am extending the PyParticles script
The code is available on the site(for free), I am using PyParticles4.py

Classes used in the tutorial

The Particle Class
Circular 2d objects with radius,mass,velocity,location
The Spring Class
A spring that binds 2 objects (Particles) and uses the Hooke's law (F = -kx) to determine the interaction between them
The Environment Class
The Environment where the Particles interact

I was wondering if I could to use 2 Particles and make a 'Rod' class (like the Spring class in the tutorial) that had a specific length and didn't allow the particles to come closer go further than that (specified) length.
Also,
Appling a force (when needed) to each Particle such that if one is pulled toward the left, so does the other, but Realistically..
Much like if a 2 different types of balls were joined(from the center) using a steel rod, but in 2-d..
And I don't want to use 3rd party modules

Thanks in advance..

EDIT/UPDATE:
Tried to apply constraint theorem (it failed)
Here's the code:

class Rod:
    def __init__(self, p1, p2, length=50):
        self.p1 = p1
        self.p2 = p2
        self.length = length

    def update(self):
        'Updates The Rod and Particles'
        # Temp store of co-ords of Particles involved
        x1 = self.p1.x
        x2 = self.p2.x
        ###### Same for Y #######
        y1 = self.p1.y
        y2 = self.p2.y

        # Calculation of d1,d2,d3 and final values (x2,y2) 
        # from currently known values(x1,y1)...
        # From Constraint algorithm(see @HristoIliev's comment)
        dx1 = x2 - x1
        dy1 = y2 - y1
        # the d1, d2, d3
        d1 = math.hypot(dx1,dy1)
        d2 = abs(d1)
        d3 = (d2-self.length)/d2
        x1 = x1 + 0.5*d1*d3
        x2 = x2 - 0.5*d1*d3
        y1 = y1 + 0.5*d1*d3
        y2 = y1 - 0.5*d1*d3

        # Reassign next positions
        self.p1.x = x1
        self.p2.x = x2
        ###### Same for Y #######
        self.p1.y = y1
        self.p2.y = y2
pradyunsg
  • 18,287
  • 11
  • 43
  • 96
  • 1
    Why don't you just use a very strong spring? – Dennis Jaheruddin Jan 03 '13 at 10:58
  • Nope the objects just keep moving randomly, they don't behave the way I want them to and Python raises an error "OverflowError: Python int too large to convert to C long" – pradyunsg Jan 03 '13 at 11:06
  • 2
    Hard joints such as rods are holonomic constraints. These are usually treated by special [constraint algorithms](http://en.wikipedia.org/wiki/Constraint_algorithm) or by modelling them as infinitely stiff springs and explicitly finding the form of the corrections that have to be applied to an unconstrained system (see [here](http://en.wikipedia.org/wiki/Verlet_integration#Constraints) for an example). – Hristo Iliev Jan 03 '13 at 16:40
  • @HristoIliev what are x1,x2? Could you explain the last 2 equations, i understand i will have to apply them to both x and y components. – pradyunsg Jan 03 '13 at 18:04
  • Obviously `x1` and `x2` are the coordinates of the first and the second particle. The equations are written for 1-d system and are specific to the Verlet integrator. The framework that you refer to uses a different integration scheme and hence the equations would have different form (honestly, I don't know what it would be). – Hristo Iliev Jan 04 '13 at 15:41
  • @HristoIliev What is t+delta(t)? – pradyunsg Jan 05 '13 at 16:35
  • 1
    @HristoIliev Nope i tried a test code, it didn't work. Used the Constraint Algorithm, it didn't simulate realistically, and collisions made the particles behave abnormally... It was the python implementation of [this](http://en.wikipedia.org/wiki/Verlet_integration#Constraints) – pradyunsg Jan 06 '13 at 09:14
  • @BartlomiejLewandowski Actually I want to make my own physics engine on top of the PyParticles module. – pradyunsg Jan 21 '13 at 12:16
  • You can get some inspiration from similar implementation in javascript: https://github.com/kennethkufluk/js-mindmap There is a demo here: http://kenneth.kufluk.com/google/js-mindmap/ – Thava Jan 30 '13 at 21:06
  • A couple of things don't look right to me. First, is the reassignment of y2 directly after the computation of d1, d2, and d3 correct? Second, the constructor takes two points at arbitrary positions and imposes a distance constraint (fixing the length). That seems overdetermined. Is the update method meant to initially bring them into compliance with the length restriction? Because it doesn't. In fact, if the y2 assignment should be y2 = y2 - ..., rather than y2 = y1 - ..., the differences x2-x1 and y2-y1 are the same before and after the call. I don't think that's what you want. – Rick Goldstein Jan 30 '13 at 22:38
  • @RickGoldstein Sorry, a typo, still no change, but yes that's what it seems to be... Also, on careful reading, I saw this line [here](http://en.wikipedia.org/wiki/Verlet_integration#Collision_reactions) | *this is not guaranteed to do so in a way that is consistent with collision physics* | which is what I would like to have, and if you think I made a mistake in my implementation, pls atleast point me toward what I should do. – pradyunsg Jan 31 '13 at 10:03
  • @Thava they are similar (not same) to the springs,see the python code or [this](http://www.youtube.com/watch?v=gJFoqtmAg2Y) – pradyunsg Jan 31 '13 at 10:09

1 Answers1

3

A rod in 2D has 3 degrees of freedom (2 velocities/positions + 1 rotation/angular freq).
I would represent the position of the center which is modified by forces in the usual way and calculate the position of the particles using the rotation (for simplicity, about the center of the system) variable.
The rotation is modified by forces by

ang_accel = F * r * sin (angle(F,r)) / (2*M * r^2)

Where

ang_accel is the angular acceleration

F is a force acting on a particular ball so there is 2 torques* that add up as there is two forces that add up (vector-wise) in order to update the position of the center.

r is half of the length
angle(F,r) is the angle between the force vector and the radius vector (from the center to the particle that suffers the force),

So that
F * r * sin (angle(F,r)) is the torque about the center, and
2*M * r^2 is the moment of inertia of the system of two points around the center.

Zah
  • 6,394
  • 1
  • 22
  • 34
  • is there a typo? `ang_accel` and `dang_accel`?? – pradyunsg Jan 31 '13 at 09:45
  • Yes, typo. And as said I would do it this way rather than based on the particles. You have 3 degrees of freedom and this approach is the most natural for eliminating one of the four that a 2 free particle system would have. – Zah Feb 01 '13 at 01:17
  • the masses of the particles is not the same. – pradyunsg Feb 01 '13 at 09:45
  • You could adjust the anglular acceleration formula to account for mass variation by altering the moment of inertia. – m.brindley Feb 01 '13 at 11:50