This site requires JavaScript, please enable it in your browser!
Greenfoot back
ronald
ronald wrote ...

2020/4/2

double pendulum

ronald ronald

2020/4/2

#
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class DoublePendulum here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class DrawPendulum extends Actor
{
    
    private double angle1 = Math.PI / 2;
    private double angle2 = Math.PI / 2;
    private int length1;
    private int length2;
    double angleAccel1 = 0;
    double angleAccel2 = 0;
    double angleVelocity1 = 0;
    double angleVelocity2 = 0;
    double dt1 = 0.1;
    double dt2 = 0.2;
    
    public DrawPendulum(int length1, int length2) {
        this.length1 = length1;
        this.length2 = length2;
        
    }
    
    /**
     * Act - do whatever the DoublePendulum wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        // Add your action code here.
        drawDoublePendulum();
        run();
    } 
    
    public void drawDoublePendulum() {
        GreenfootImage gfim = new GreenfootImage(900, 600);
        
        gfim.setColor(Color.WHITE);
        gfim.fillRect(0, 0, gfim.getWidth(), gfim.getHeight());
        gfim.setColor(Color.BLACK);
        
        int anchorX1 = gfim.getWidth() / 2, anchorY1 = gfim.getHeight() / 4;
        int anchorX2 = gfim.getWidth() / 2, anchorY2 = gfim.getHeight() / 4;
        
        int ballX1 = anchorX1 + (int) (Math.sin(angle1) * length1);
        int ballY1 = anchorY1 + (int) (Math.cos(angle1) * length1);
        
        int ballX2 = ballX1 + (int) (Math.sin(angle2) * length2);
        int ballY2 = ballY1 + (int) (Math.cos(angle2) * length2);
        
        gfim.drawLine(anchorX1, anchorY1, ballX1, ballY1);
        gfim.drawLine(ballX1, ballY1, ballX2, ballY2);
        
        gfim.fillOval(anchorX1 - 3, anchorY1 - 4, 7, 7);
        gfim.fillOval(anchorX2 - 3, anchorY2 - 4, 7, 7);
        
        gfim.fillOval(ballX1 - 7, ballY1 - 7, 14, 14);
        gfim.fillOval(ballX2 - 7, ballY2 - 7, 14, 14);
        
        this.setImage(gfim);
    }
 
    public void run() 
    {
        
            angleAccel1 = -9.81 / length1 * Math.sin(angle1);
            angleVelocity1 += angleAccel1 * dt1;
            angle1 += angleVelocity1 * dt1;
            
            angleAccel2 = -9.81 / length2 * Math.sin(angle2);
            angleVelocity2 += angleAccel2 * dt2;
            angle2 += angleVelocity2 * dt2;
            
            
            
    }
}

can you tell me if the code is correct or coded, do you have any suggestions? this code works but I think I can do better, Thank you for your help
danpost danpost

2020/4/2

#
ronald wrote...
can you tell me if the code is correct or coded, do you have any suggestions? this code works but I think I can do better,
Well yes, the code "works". However, the behavior is not even close to true of a real double pendulum. Other forces are involved. Both length of the pendulum act on each other as one or both of them swing. The equations for the accelerations of the lengths are quite complicated. However, you can find them here.
ronald ronald

2020/4/2

#
yes I know processing and actually I was inspired by this code for the double pendulum in github I ask your opinion, I wonder how you would do without the other forces, I find that I repeat myself a little while coding
danpost danpost

2020/4/2

#
ronald wrote...
yes I know processing and actually I was inspired by this code for the double pendulum in github I ask your opinion, I wonder how you would do without the other forces, I find that I repeat myself a little while coding
Truthfully, I wouldn't. I have already done a double pendulum, however, it is one, of quite a few, that I have never uploaded.
ronald ronald

2020/4/2

#
well i will try to code with other forces see if i understand math
ronald ronald

2020/4/2

#
public void run() 
    {
         
            angleAccel1 = -9.81 / length1 * Math.sin(angle1);
            angleVelocity1 += angleAccel1 * dt1;
            angle1 += angleVelocity1 * dt1;
             
            angleAccel2 = -9.81 / length2 * Math.sin(angle2);
            angleVelocity2 += angleAccel2 * dt2;
            angle2 += angleVelocity2 * dt2;
             
             
             
    }
I wonder if I can do a for loop with this piece of code as it repeats What do you think ?
danpost danpost

2020/4/2

#
ronald wrote...
<< Code Omitted >> I wonder if I can do a for loop with this piece of code as it repeats What do you think ?
It does kind of repeat, but the variables used in lines 4 thru 6 are all different from those used in lines 8 thru 10. Maybe, by placing those variables in arrays you could then use a for loop to do both. That change, however, would not have much practical value.
danpost danpost

2020/4/2

#
One other way might be to create an Object subclass to contain the values for each arm (called Arm, possibly) and then you can iterate for each arm.
ronald ronald

2020/4/3

#
public void run() 
    {
            a1_numerator1 = -g*(2*mas1+mas2)*Math.sin(angle1); 
            a1_numerator2 = -mas2*g*Math.sin(angle1-2*angle2);
            a1_numerator3 = -2*Math.sin(angle1-angle2)*mas2;
            a1_numerator4 = angleVelocity2*angleVelocity2*length2+angleVelocity1*angleVelocity1*length1*Math.cos(angle1-angle2);
            a1_denominator = length1*(2*mas1+mas2-mas2*Math.cos(2*angle1-2*angle2));
            
            angleAccel1 = (a1_numerator1 + a1_numerator2 + a1_numerator3 * a1_numerator4) / a1_denominator;
            
            a2_numerator1 = 2*Math.sin(angle1-angle2);  
            a2_numerator2 = angleVelocity1*angleVelocity1*length1*(mas1+mas2);            
            a2_numerator3 = g*(mas1+mas2)*Math.cos(angle1);
            a2_numerator4 = angleVelocity2*angleVelocity2*length2*mas2*Math.cos(angle1-angle2);
            a2_denominator = length2*(2*mas1+mas2-mas2*Math.cos(2*angle1-2*angle2));
            
            angleAccel2 = (a2_numerator1 * (a2_numerator2 + a2_numerator3 + a2_numerator4)) / a2_denominator;
            
            angleAccel1 = -9.81 / length1 * Math.sin(angle1);
            angleVelocity1 += angleAccel1 * dt1;
            angle1 += angleVelocity1 * dt1;
            
            angleAccel2 = -9.81 / length2 * Math.sin(angle2);
            angleVelocity2 += angleAccel2 * dt2;
            angle2 += angleVelocity2 * dt2;
            
    }
I'll come back on it with for loop I added this calculation formula but it does nothing Thank you for your help
danpost danpost

2020/4/3

#
You have two lines each for assigning values to the accelerations. The 2nd destroys the work of the 1st for each.
ronald ronald

2020/4/3

#
ok thank you
You need to login to post a reply.