-
Notifications
You must be signed in to change notification settings - Fork 0
/
processingGravity.pde
164 lines (125 loc) · 3.91 KB
/
processingGravity.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//----------------------------------------------------------
// gravity and planetary bodies.
// [email protected] 2024-03-23
//----------------------------------------------------------
// draws things bigger, makes forces stronger, easier to see what is going on.
float scale=3;
//normally the gravitational constant is 6.67430e-11 m^3 kg^−1 s^−2
float gravity = 60*scale;
// a class to describe a point mass with physical properties.
class PhysicsBody {
float mass;
float radius;
color myColor;
PImage image;
boolean canMove=true;
PVector position = new PVector();
PVector velocity = new PVector();
PVector acceleration = new PVector();
PhysicsBody(float mass,float radius,color myColor) {
this.mass = mass;
this.radius = radius;
this.myColor = myColor;
}
void draw() {
if(image==null) {
fill(myColor);
stroke(myColor);
} else {
noFill();
stroke(255,255,255,64);
image(this.image,
position.x-radius,
position.y-radius,
radius*2,
radius*2);
}
circle(position.x,position.y,radius*2);
noFill();
pushMatrix();
translate(position.x,position.y);
// draw velocity
stroke(255,0,0);
line(0,0,velocity.x,velocity.y);
// draw acceleration
stroke(255,255,255);
line(0,0,acceleration.x,acceleration.y);
popMatrix();
}
void move(float dt) {
if(!canMove) return;
velocity.add(PVector.mult(acceleration,dt));
position.add(PVector.mult(velocity,dt));
}
};
ArrayList<PhysicsBody> bodies = new ArrayList<>();
void setup() {
size(800,800);
addBodies();
}
void addBodies() {
PhysicsBody sun = new PhysicsBody(100*scale,30*scale,color(255,255,0));
bodies.add(sun);
sun.canMove=false;
sun.image = loadImage("sun.jpg");
PhysicsBody earth = new PhysicsBody(10*scale,10*scale,color(0,0,255));
bodies.add(earth);
earth.position.x = 100*scale;
earth.image = loadImage("earth.jpg");
PhysicsBody ship = new PhysicsBody(1.0*scale,1*scale,color(0,255,0));
bodies.add(ship);
ship.position.x = 115*scale;
earth.velocity.y = initialVelocity(sun,earth);
ship.velocity.y = initialVelocity(earth,ship)
+ earth.velocity.y; // because the ship moves relative to the earth.
}
// find the velocity of B such that it will travel in a circular path around A.
// assumes the object starts at the east position (y=0, x>0) and moves only vertically.
float initialVelocity(PhysicsBody a,PhysicsBody b) {
float r = PVector.sub(a.position,b.position).mag();
return sqrt(gravity * a.mass / r);
}
void draw() {
drawBodies();
doPhysics();
}
void drawBodies() {
background(0);
translate(width/2,height/2);
for(PhysicsBody b : bodies) {
b.draw();
}
}
void doPhysics() {
float dt = 1.0/30.0; // fixed timestep every frame. assumes 30 fps.
calculateAllForces();
for(PhysicsBody b : bodies) {
b.move(dt);
}
}
// calculate gravity forces using Newton's Universal Law of Gravitation
void calculateAllForces() {
for(PhysicsBody a : bodies) {
a.acceleration.set(0,0);
}
for(int i=0; i<bodies.size(); ++i) {
PhysicsBody a = bodies.get(i);
// start at i+1 so we never repeat any two pairs of bodies.
for(int j=i+1; j<bodies.size();++j) {
PhysicsBody b = bodies.get(j);
calculateGravityForce(a,b);
}
}
}
// the force between bodies A and B.
void calculateGravityForce(PhysicsBody a,PhysicsBody b) {
PVector direction = PVector.sub(b.position,a.position);
float distance = direction.mag();
if(distance<a.radius+b.radius) return;
direction.normalize();
float forceMagnitude = ( gravity * a.mass * b.mass ) / ( distance * distance );
PVector force = PVector.mult(direction,forceMagnitude);
// add the acceleration, taking their relative masses into account.
a.acceleration.add(PVector.div(force,a.mass));
b.acceleration.sub(PVector.div(force,b.mass));
}