-
Notifications
You must be signed in to change notification settings - Fork 0
/
Box.java
163 lines (131 loc) · 4.32 KB
/
Box.java
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
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Class representing the box object
*
* @author Austin
* @version 0
*/
public class Box extends RigidBody {
private final int groundLevel = 71;
private Force normal;
private Force friction;
private Force gravity;
private Ramp ramp;
private double mu;
/**
* Constructor for Box
*
* @param ramp The ramp which the box is linked to
*/
public Box(Ramp ramp) {
super(0, 0, 1);
this.gravity = new Force(0, -9.8);
this.ramp = ramp;
this.position = new Position(0, ramp.getHeight());
this.mu = 0;
createImage();
}
/**
* Update the position while running, else give visual feedback for sliders
*/
public void act() {
if (!paused) {
updatePosition();
time += dt;
} else {
position = new Position(0, ramp.getHeight());
// Match angle of the ramp
setRotation((int) Math.toDegrees(ramp.getAngle()));
}
setLocation((int) position.getX(), getWorld().getHeight() - (int) position.getY() - groundLevel);
// Draw free body diagram if required
if (forceVisible) {
drawForce();
}
}
/**
* Draws all the forces (friction, normal, gravity and nett) acting on the box
*/
@Override
public void drawForce() {
double angle = friction.getAngle();
double length = friction.getMagnitude() * 10;
drawLine(length, Math.toDegrees(angle), Color.BLACK);
angle = gravity.getAngle();
length = gravity.getMagnitude() * 10;
drawLine(length, Math.toDegrees(angle), Color.BLACK);
angle = normal.getAngle();
length = normal.getMagnitude() * 10;
drawLine(length, Math.toDegrees(angle), Color.BLACK);
angle = force.getAngle();
length = force.getMagnitude() * 10;
drawLine(length, Math.toDegrees(angle), Color.RED);
}
/**
* Updates the forces acting on the box and updates its position
*/
@Override
protected void updatePosition() {
normal = calculateNormal();
friction = calculateFriction();
force = gravity.add(normal).add(friction);
acceleration = force.getAcceleration(mass);
velocity.updateWithAcceleration(acceleration, dt);
position.updateWithVelocity(velocity, dt);
// Add the bottom, set the rotation to 0 and hide the forces
if (position.getY() == 0) {
setRotation(0);
hideForces();
velocity.setY(0);
}
}
/**
* Rescale the image to 44 x 44 pixels
*/
protected void createImage() {
getImage().scale(44, 44);
}
/**
* Add the box to the world, accounting for ground
*
* @param world The world to add the box to
*/
@Override
public void addToWorld(World world) {
world.addObject(this, (int) position.getX(), world.getHeight() - groundLevel - (int) position.getY());
}
/**
* Calculate the normal (reactive) force on the box by the ramp
*
* @return The normal force
*/
private Force calculateNormal() {
double theta = ramp.getAngle();
double magnitude = mass * 9.8 * Math.cos(theta);
double x = magnitude * Math.sin(theta);
double y = magnitude * Math.cos(theta);
return new Force(x, y);
}
/**
* Calculate the frictional on the box by the ramp,
* based on the coefficient of friction (mu)
*
* @return The frictional force
*/
private Force calculateFriction() {
double theta = Math.PI - ramp.getAngle();
double magnitude = mu * calculateNormal().getMagnitude();
magnitude = Math.min(Math.abs(gravity.getMagnitude() * Math.sin(theta)), magnitude);
double x = magnitude * Math.cos(theta);
double y = magnitude * Math.sin(theta);
return new Force(x, y);
}
/**
* Sets the coefficient of friction
*
* @param mu The coefficient of friction between the ramp and box
*/
public void setMu(double mu) {
this.mu = mu;
}
}