![]() |
Jupyter at Bryn Mawr College |
|
|
Public notebooks: /services/public/dblank / CS110 Intro to Computing / 2015-Spring / Assignments |
Due before start of class on Monday, April 6, 2015.
Task: Create a Simulated Creature that roams around a Simulated World:
Specifics:
Grading:
Hand in:
For this assignment, your mission is to create a SimCreature that will live in a sim world.
For an example of this, I will use Dog
.
Dog should have at least four methods:
The basic prototype would therefore look like:
class Dog {
...
Dog() {
...
}
Dog(float x, float y, float z) {
...
}
void update() {
...
}
void draw() {
...
}
}
Where there are ellipses, you will fill out the code.
To make a bunch of these objects, we need to do three things:
That might look like this:
Dog [] dogs;
void setup() {
dogs = new Dog[5];
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
}
In this example, I created a global array named dogs
, then created an array of length 5, and then created 5 instances of the Dog
class. Note that the global array is created outside any function, but the creation of the array, and instances occurs in the setup()
function.
Finally, we need to update and redraw the dogs. We do that
void draw() {
for (int i = 0; i < dogs.length; i++) {
dogs[i].update();
dogs[i].draw();
}
}
Now, a bit of a wrinkle. The location of these objects will roam around a new coordinate system that has x from -1 to 1, y from -1 to 1, and z from -1 to 1. (-1,-1,-1) will be in the front, bottom, left-hand corner, and (1,1,1) will be in the back, top, right-hand corner. Furthermore, as you go back further on the z axis, the object will get smaller.
So, the further away (higher z value) the smaller the object will appear.
We add two more methods to make this easy on us:
In the following simulations, click and drag to change the view. Dragging up (closer) and down (further away) changes the viewer distance; dragging left (smaller) and right (larger) changes the field of view/vision.
Dog [] dogs;
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float fov = 100;
float viewer_distance = 1.5;
class Dog {
float x;
float y;
float z;
Dog(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
Dog() {
this.x = random(2) - 1;
this.y = -1;
this.z = random(2) - 1;
}
void update() {
// ...
}
void draw() {
// get the screen coordinates of the object:
float [] pos = this.coordinates(this.x, this.y, this.z);
// normally, just ellipse(x, y, 20, 20);
// but, scaling sizes and putting in correct location:
ellipse(pos[0],
pos[1],
this.scale(20, this.z),
this.scale(20, this.z));
}
float scale(float size, float depth) {
float factor = fov / (viewer_distance + depth);
return size * factor/100.0;
}
float [] coordinates(float x1, float y1, float z1) {
// Transforms this 3D point to 2D using a perspective projection.
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float factor = fov / (viewer_distance + z1);
x2 = x1 * factor + width / 2;
y2 = -y1 * factor + height / 2;
return new float [] {x2, y2};
}
}
void setup() {
size(500, 500);
dogs = new Dog[20];
/*
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
*/
dogs[0] = new Dog(-1, -1, 1);
dogs[1] = new Dog(-1, -1, 0.5);
dogs[2] = new Dog(-1, -1, 0.0);
dogs[3] = new Dog(-1, -1, -0.5);
dogs[4] = new Dog(-1, -1, -1);
dogs[5] = new Dog(-1, 1, 1);
dogs[6] = new Dog(-1, 1, 0.5);
dogs[7] = new Dog(-1, 1, 0.0);
dogs[8] = new Dog(-1, 1, -0.5);
dogs[9] = new Dog(-1, 1, -1);
dogs[10] = new Dog(1, 1, 1);
dogs[11] = new Dog(1, 1, 0.5);
dogs[12] = new Dog(1, 1, 0.0);
dogs[13] = new Dog(1, 1, -0.5);
dogs[14] = new Dog(1, 1, -1);
dogs[15] = new Dog(1, -1, 1);
dogs[16] = new Dog(1, -1, 0.5);
dogs[17] = new Dog(1, -1, 0.0);
dogs[18] = new Dog(1, -1, -0.5);
dogs[19] = new Dog(1, -1, -1);
}
float m_x;
float m_y;
float m_fov;
float m_viewer_distance;
void mousePressed() {
m_x = mouseX;
m_y = mouseY;
m_fov = fov;
m_viewer_distance = viewer_distance;
}
void mouseDragged() {
fov = m_fov + m_fov * (mouseX - m_x)/width;
viewer_distance = m_viewer_distance + m_viewer_distance * (mouseY - m_y)/height;
}
void draw() {
background();
for (int i = 0; i < dogs.length; i++) {
dogs[i].update();
dogs[i].draw();
}
}
Dog [] dogs;
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float fov = 100;
float viewer_distance = 1.5;
class Dog {
float x;
float y;
float z;
Dog(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
Dog() {
this.x = random(2) - 1;
this.y = -1;
this.z = random(2) - 1;
}
void update() {
// ...
}
void draw() {
// get the screen coordinates of the object:
float [] pos = this.coordinates(this.x, this.y, this.z);
// normally, just ellipse(x, y, 20, 20);
// but, scaling sizes and putting in correct location:
ellipse(pos[0],
pos[1],
this.scale(20, this.z),
this.scale(20, this.z));
}
float scale(float size, float depth) {
float factor = fov / (viewer_distance + depth);
return size * factor/100.0;
}
float [] coordinates(float x1, float y1, float z1) {
// Transforms this 3D point to 2D using a perspective projection.
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float factor = fov / (viewer_distance + z1);
x2 = x1 * factor + width / 2;
y2 = -y1 * factor + height / 2;
return new float [] {x2, y2};
}
}
void setup() {
size(500, 500);
dogs = new Dog[100];
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
}
float m_x;
float m_y;
float m_fov;
float m_viewer_distance;
void mousePressed() {
m_x = mouseX;
m_y = mouseY;
m_fov = fov;
m_viewer_distance = viewer_distance;
}
void mouseDragged() {
fov = m_fov + m_fov * (mouseX - m_x)/width;
viewer_distance = m_viewer_distance + m_viewer_distance * (mouseY - m_y)/height;
}
void draw() {
background();
for (int i = 0; i < dogs.length; i++) {
dogs[i].update();
dogs[i].draw();
}
}
Dog [] dogs;
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float fov = 100;
float viewer_distance = 1.5;
class Dog {
float x;
float y;
float z;
Dog(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
Dog() {
this.x = random(2) - 1;
this.y = -1;
this.z = random(2) - 1;
}
void update() {
// ...
}
void draw() {
// get the screen coordinates of the object:
float [] pos = this.coordinates(this.x, this.y, this.z);
// normally, just ellipse(x, y, 20, 20);
// but, scaling sizes and putting in correct location:
ellipse(pos[0],
pos[1],
this.scale(20, this.z),
this.scale(20, this.z));
}
float scale(float size, float depth) {
float factor = fov / (viewer_distance + depth);
return size * factor/100.0;
}
float [] coordinates(float x1, float y1, float z1) {
// Transforms this 3D point to 2D using a perspective projection.
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float factor = fov / (viewer_distance + z1);
x2 = x1 * factor + width / 2;
y2 = -y1 * factor + height / 2;
return new float [] {x2, y2};
}
}
float m_x;
float m_y;
float m_fov;
float m_viewer_distance;
void mousePressed() {
m_x = mouseX;
m_y = mouseY;
m_fov = fov;
m_viewer_distance = viewer_distance;
}
void mouseDragged() {
fov = m_fov + m_fov * (mouseX - m_x)/width;
viewer_distance = m_viewer_distance + m_viewer_distance * (mouseY - m_y)/height;
}
void sortDogs() {
for (int i = 0; i < dogs.length - 1; i++) {
for (int j = i + 1; j < dogs.length; j++) {
if (dogs[i].z < dogs[j].z) {
Dog tmp = dogs[i];
dogs[i] = dogs[j];
dogs[j] = tmp;
}
}
}
}
void setup() {
size(500, 500);
background();
dogs = new Dog[100];
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
}
void draw() {
background();
for (int i = 0; i < dogs.length; i++) {
dogs[i].update();
sortDogs();
dogs[i].draw();
}
}
Dog [] dogs;
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float fov = 100;
float viewer_distance = 1.5;
class Dog {
float x;
float y;
float z;
Dog(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
Dog() {
this.x = random(2) - 1;
this.y = -1;
this.z = random(2) - 1;
}
void update() {
// ...
//this.x += .01;
}
void draw() {
// get the screen coordinates of the object:
float [] pos = this.coordinates(this.x, this.y, this.z);
// normally, just ellipse(x, y, 20, 20);
// but, scaling sizes and putting in correct location:
rectMode(CENTER);
fill(255);
w = this.scale(40, this.z);
h = this.scale(20, this.z);
u = this.scale(5, this.z);
rect(pos[0],
pos[1],
w,
h);
rect(pos[0] - w/2 + u,
pos[1] + h/2 + u,
u,
2 * u);
}
float scale(float size, float depth) {
float factor = fov / (viewer_distance + depth);
return size * factor/100.0;
}
float [] coordinates(float x1, float y1, float z1) {
// Transforms this 3D point to 2D using a perspective projection.
// fov is the “field of vision/view”. Suggest values between 128 and 256.
// view_distance is the distance from the object to the viewer.
float factor = fov / (viewer_distance + z1);
x2 = x1 * factor + width / 2;
y2 = -y1 * factor + height / 2;
return new float [] {x2, y2};
}
}
float m_x;
float m_y;
float m_fov;
float m_viewer_distance;
void mousePressed() {
m_x = mouseX;
m_y = mouseY;
m_fov = fov;
m_viewer_distance = viewer_distance;
}
void mouseDragged() {
fov = m_fov + m_fov * (mouseX - m_x)/width;
viewer_distance = m_viewer_distance + m_viewer_distance * (mouseY - m_y)/height;
}
void sortDogs() {
for (int i = 0; i < dogs.length - 1; i++) {
for (int j = i + 1; j < dogs.length; j++) {
if (dogs[i].z < dogs[j].z) {
Dog tmp = dogs[i];
dogs[i] = dogs[j];
dogs[j] = tmp;
}
}
}
}
void setup() {
fov = 100;
viewer_distance = 1.5;
size(500, 500);
background();
dogs = new Dog[10];
for (int i = 0; i < dogs.length; i++) {
dogs[i] = new Dog();
}
}
void draw() {
background();
float [] c1 = dogs[0].coordinates(-1, -1, -1);
float [] c2 = dogs[0].coordinates(-1, 1, -1);
float [] c3 = dogs[0].coordinates( 1, -1, -1);
float [] c4 = dogs[0].coordinates( 1, 1, -1);
line(c1[0], c1[1], c2[0], c2[1]);
line(c2[0], c2[1], c4[0], c4[1]);
line(c3[0], c3[1], c4[0], c4[1]);
line(c1[0], c1[1], c3[0], c3[1]);
float [] b1 = dogs[0].coordinates(-1, -1, 1);
float [] b2 = dogs[0].coordinates(-1, 1, 1);
float [] b3 = dogs[0].coordinates( 1, -1, 1);
float [] b4 = dogs[0].coordinates( 1, 1, 1);
line(b1[0], b1[1], b2[0], b2[1]);
line(b2[0], b2[1], b4[0], b4[1]);
line(b3[0], b3[1], b4[0], b4[1]);
line(b1[0], b1[1], b3[0], b3[1]);
line(b1[0], b1[1], c1[0], c1[1]);
line(b2[0], b2[1], c2[0], c2[1]);
line(b3[0], b3[1], c3[0], c3[1]);
line(b4[0], b4[1], c4[0], c4[1]);
for (int i = 0; i < dogs.length; i++) {
dogs[i].update();
sortDogs();
dogs[i].draw();
}
}
As shown in the last example, you can use any of the Processing drawing functions (polygon, rect, oval, etc) but you must use this.coordinates() to get the location of any x,y point.