GC Lab5
GC Lab5
AL REPUBLICII MOLDOVA
Universitatea Tehnică a Moldovei
Facultatea Calculatoare, Informatică şi Microelectronică
Departamentul Inginerie Software s, i Automatică
REPORT
Laboratory work n.7
of Computer Graphics
Checked by:
Olga Grosu, university assistant
DISA, FCIM, UTM
2. Simulate Realistic Physics: Assign physical properties to the creatures, including density, friction, and
restitution (bounciness). Use these properties to simulate realistic interactions, such as gravity, collisions,
and forces.
3. Experiment with Joints: Build creature skeletons using Box2D distance joints and revolute joints. Simu-
late realistic appendage movements by combining these joints.
4. Interact and Control: Implement user interaction by allowing control of one or more creatures via key-
board or mouse input. Alternatively, program forces to simulate natural movements for the creatures.
5. Test in Varied Environments: Create multiple environments or obstacles to observe and analyze how the
creatures interact and adapt within these scenarios.
6. Compare Frameworks: Develop a report comparing the use of Processing’s native tools (e.g., PVectors,
forces, oscillations, particle systems) against the Box2D library for handling physics-based interactions.
Reflect on the strengths and challenges of each approach.
2. The Condition
Create an interactive Processing sketch using Box2D to simulate physics-based creatures with dynamic behaviors.
Your sketch should demonstrate the following:
1. Collision Detection and Event Triggering: Implement collision detection between the creatures and trig-
ger events upon collision.
2. Creature Design: Create your own creature by combining multiple shapes attached to a single body. Use
the PolygonShape class to create custom polygon designs, and explore making concave shapes by combin-
ing more than one polygon. You are not limited to the basic shape-drawing functions in Processing—feel
free to add images, colors, or even hair using lines to make your creature visually interesting. Box2D shapes
should be used as skeletons for your design, enhancing the creative aspects of the creature.
3. Creature Multiplication and Interaction: Multiply your creature design and use Box2D to allow for
interactions and collisions between multiple creatures. Consider using Box2D to augment the design, such
as building a skeleton with distance joints or creating appendages with revolute joints.
4. Assigning Physical Properties: Assign properties such as density, friction, and restitution (bounciness) to
your creatures. Make sure the creatures react realistically to forces, gravity, and collisions.
5. User Control and Movement Simulation: Allow the user to control one or more creatures via keyboard
or mouse input. Alternatively, apply forces to simulate natural movement and behaviors of the creatures.
1
6. Multiple Environments and Obstacles: Design multiple environments or obstacles for the creatures to
interact with. This will test how they adapt and react to various conditions within the simulation.
7. Box2D Example: Refer to examples in the Box2D library for guidance and inspiration in setting up the
physics and interactions for your creatures.
8. Final Report: In your report, describe the differences between using simple Processing with your own
creature using PVectors, forces, oscillation, and particle systems versus incorporating the Box2D library.
Conclude by discussing your own sketch, reflecting on the challenges and creative aspects of your design.
1 // Box2D
2 import shiffman.box2d.*;
3 import org.jbox2d.collision.shapes.*;
4 import org.jbox2d.common.*;
5 import org.jbox2d.dynamics.*;
6 import org.jbox2d.dynamics.contacts.*;
7
8 // Box2D
9 Box2DProcessing box2d;
10
11 //
12 ArrayList<Particle> particles;
13 ArrayList<Lollipop> pops;
14 ArrayList<Boundary> boundaries;
15
16 //
17 Portal portal;
18
19 void setup() {
20 size(640, 640);
21
22 // Box2D
23 box2d = new Box2DProcessing(this);
24 box2d.createWorld();
25 box2d.listenForCollisions(); //
26
27 //
28 particles = new ArrayList<Particle>();
29 pops = new ArrayList<Lollipop>();
30 boundaries = new ArrayList<Boundary>();
31
32 //
33 boundaries.add(new Boundary(width / 4, height - 5, width / 2 - 50, 10, 0));
2
34 boundaries.add(new Boundary(3 * width / 4, height - 50, width / 2 - 50, 10, 0));
35 boundaries.add(new Boundary(width - 5, height / 2, 10, height, 0));
36 boundaries.add(new Boundary(5, height / 2, 10, height, 0));
37
38 //
39 portal = new Portal();
40 }
41 void draw() {
42 background(0);
43
44 //
45 portal.display();
46 portal.update();
47
48 // Box2D
49 box2d.step();
50
51 //
52 for (int i = particles.size() - 1; i >= 0; i--) {
53 Particle p = particles.get(i);
54 p.display();
55 if (p.done()) {
56 particles.remove(i);
57 }
58 }
59
60 //
61 for (int i = pops.size() - 1; i >= 0; i--) {
62 Lollipop pop = pops.get(i);
63 pop.display();
64 if (pop.done()) {
65 pops.remove(i);
66 }
67 }
68
69 //
70 for (Boundary b : boundaries) {
71 b.display();
72 }
73 }
74
75 void mousePressed() {
76 //
77 pops.add(new Lollipop(mouseX, mouseY));
78 }
79 //
80 void beginContact(Contact cp) {
81 Fixture f1 = cp.getFixtureA();
82 Fixture f2 = cp.getFixtureB();
3
83 Body b1 = f1.getBody();
84 Body b2 = f2.getBody();
85
86 Object o1 = b1.getUserData();
87 Object o2 = b2.getUserData();
88
89 //
90 if (o1 != null) {
91 if (o1 instanceof Particle) {
92 ((Particle) o1).changeColor();
93 }
94 if (o1 instanceof Lollipop) {
95 ((Lollipop) o1).changeColor();
96 }
97 }
98 if (o2 != null) {
99 if (o2 instanceof Particle) {
100 ((Particle) o2).changeColor();
101 }
102 if (o2 instanceof Lollipop) {
103 ((Lollipop) o2).changeColor();
104 }
105 }
106 }
107
108 // (Boundary)
109 class Boundary {
110 float x, y, w, h;
111 Body b;
112
113 Boundary(float x_, float y_, float w_, float h_, float a) {
114 x = x_;
115 y = y_;
116 w = w_;
117 h = h_;
118
4
131
146
147 // (Particle)
148 class Particle {
149 Body body;
150 float r;
151 color col;
152
5
180 return true;
181 }
182 return false;
183 }
184
200 body.createFixture(fd);
201 }
202 }
203
224 // ( )
225 fill(150, 100, 255); //
226 noStroke();
227 rect(0, 0, bodyWidth, bodyHeight);
228
6
229 // ( )
230 fill(col);
231 ellipse(0, -bodyHeight / 2 - r, r * 2, r * 2);
232
240 //
241 fill(0);
242 ellipse(-5, -bodyHeight / 2 - r - 5, 4, 4);
243 ellipse(5, -bodyHeight / 2 - r - 5, 4, 4);
244
245 //
246 noFill();
247 stroke(0);
248 strokeWeight(1.5);
249 arc(0, -bodyHeight / 2 - r, 10, 6, 0, PI);
250
251 popMatrix();
252 }
253
273 // ( )
274 CircleShape circle = new CircleShape();
275 circle.m_radius = box2d.scalarPixelsToWorld(r);
276 Vec2 offset = new Vec2(0, -bodyHeight / 2 - r); //
7
277 offset = box2d.vectorPixelsToWorld(offset);
278 circle.m_p.set(offset.x, offset.y);
279
280 // ( )
281 PolygonShape bodyShape = new PolygonShape();
282 float box2dW = box2d.scalarPixelsToWorld(bodyWidth / 2); //
283 float box2dH = box2d.scalarPixelsToWorld(bodyHeight / 2); //
284 bodyShape.setAsBox(box2dW, box2dH, new Vec2(0, -bodyHeight / 2), 0); //
285
286 //
287 body.createFixture(circle, 1.0);
288 body.createFixture(bodyShape, 1.0);
289
290 //
291 body.setLinearVelocity(new Vec2(random(-3, 3), random(2, 5)));
292 body.setAngularVelocity(random(-2, 2));
293 }
294 }
295
296 //
297 class Portal {
298 PVector pos;
299 float size;
300
310 Portal() {
311 pos = new PVector(width / 2, height / 2);
312 size = (width + height) / 4;
313
8
325 for (int i = 0; i < stars.length; i++)
326 stars[i] = new Star();
327 }
328
335 pushMatrix();
336 translate(pos.x, pos.y);
337 shearX(shearTheta);
338
339 noFill();
340 for (float s = 0; s < size; s += 10) {
341 stroke(fillColor, (size - s) / size * 255);
342 strokeWeight(abs(cos((frameCount + (size - s) / size * 10) / 600.0)) * 10);
343
9
373 float end;
374
385 Orb() {
386 pos = new PVector(width/2, height/2);
387 size = random(1, (width+height)/4);
388
407 pushMatrix();
408 rotate(theta);
409
420
10
422 PVector pos;
423 PVector vel;
424
431 Star() {
432 pos = new PVector(random(width), random(height));
433 vel = PVector.random2D();
434
453
458
459
464 if (pos.x > width || pos.x < 0 || pos.y > height || pos.y < 0) {
465 pos = new PVector(width/2, height/2);
466 size = random(1, 10);
467
468 alpha = 0;
469 origAlpha = random(255);
11
470 }
471 //
472 for (int i = pops.size() - 1; i >= 0; i--) {
473 Lollipop pop = pops.get(i);
474 if (intersects(pop)) {
475 pops.remove(i); //
476 }
477 }
478 }
479 }
12
Using Simple Processing
In Processing, creating creatures with dynamic behaviors is often done using basic programming techniques such
as:
• PVectors: These are used to represent the position, velocity, and acceleration of the creature, allowing for
simple movement simulations.
• Forces: Custom forces like gravity, wind, or user interaction can be applied manually to the creature. These
forces are typically added or subtracted from the creature’s velocity in each frame of the sketch.
• Oscillation: Creatures can be made to oscillate by applying periodic forces, such as sine or cosine functions,
to simulate motion like bouncing, swinging, or floating.
• Particle Systems: Complex behaviors such as fluids or systems of interacting particles can be simulated,
but the behavior is often simplified compared to what would be expected in a full physics engine.
These techniques are useful for basic simulations but require significant manual calculations, especially when
it comes to interactions, collisions, or more complex behaviors.
In contrast, the Box2D library offers a more comprehensive solution for simulating physical interactions. By using
Box2D, the following benefits are achieved:
• Realistic Physics Engine: Box2D automatically handles the complexities of real-world physics, including
forces, gravity, friction, restitution (bounciness), and collision detection. This allows for much more realistic
and less error-prone simulations compared to hand-written physics code.
• Advanced Shape Handling: Unlike Processing, which requires you to manually manage and update the
positions of shapes, Box2D provides built-in shape classes (like circles, polygons, and chains) with their
own properties that automatically update in response to forces and collisions.
• Joints and Constraints: Box2D enables the use of joints and constraints, such as revolute joints or distance
joints, which allow the creation of complex structures like creatures with appendages or articulated bodies.
This is something that would be very difficult to manage manually in simple Processing.
• Collision Detection: The Box2D library simplifies collision detection and response. It can detect when two
objects interact, automatically calculating the appropriate response (e.g., bounce, stop, slide) based on their
physical properties.
• Performance Optimization: Box2D is optimized for handling many interacting objects efficiently, whereas
manual calculations in Processing may become slower as the number of creatures or interactions grows.
13
Key Differences
• Complexity: Simple Processing offers more flexibility for creating custom behaviors, but requires more
code and manual calculations for physics and interactions. Box2D abstracts away much of this complexity,
providing automatic solutions for many physical behaviors.
• Realism: Box2D provides more realistic simulations of physics-based interactions (collisions, forces, and
movement) than basic Processing, which relies on simpler mathematical models.
• Creativity and Control: While Box2D offers more realistic simulations, it might restrict creativity be-
cause you need to work within the constraints of the Box2D system (e.g., certain shapes, joints). Simple
Processing gives you more freedom to create custom behaviors, but at the cost of additional effort and less
automatic handling of physical interactions.
• Use Case: Simple Processing is well-suited for simpler, more artistic, or abstract simulations, while Box2D
is ideal for applications that require detailed and realistic physics, such as games or simulations involving
complex objects and interactions.
In conclusion, using Processing with PVectors and forces gives the user full control over the behavior of
objects, but can become cumbersome when managing complex interactions or larger simulations. Box2D provides
a more powerful and realistic approach for handling physics simulations, but it can be more rigid and requires
understanding of the physics engine’s structure.
6. Conclusion
In this lab, I studied a new libraries Box2D and what is it. (Processing for simulating physics-based creatures
with dynamic behaviors). I am able to create more realistic and complex simulations of creature movement,
collisions, and interactions than what could be achieved using simple Processing with PVectors and manual force
applications.
Throughout the lab, I designed creatures using multiple shapes and joints, allowing us to explore the capabil-
ities of Box2D for creating a simple boy with hairs who fly through black hole. The use of physical properties
such as density, and restitution enabled our creatures to react naturally to gravity, forces, and collisions, offering
an engaging and interactive experience.
The ability to multiply creatures and simulate interactions. How I add my simple boys. I initialize the array and
using the add function I add them and when they collide with white stars I remove it from the list so it disappears
PolygonShape how do I create it? I customized it and create it using a dictionary. I can add sides by passing
the parameters of the point where it should be located to the dictionary.
In conclusion, I understood how to work with libraries and how to integrate all this into processing. I was also
interested in understanding how to install libraries and how to integrate them into processing (even in two ways).
14