// Scene.cpp -- Mondrian scene // // // DESCRIPTION // Mondrian scene consisting of fronto-parallel colored polygons. // // SEE ALSO // Scene.h - definition of classes // // Copyright © Daniel Scharstein, 2003. // /////////////////////////////////////////////////////////////////////////// #include #include "Image.h" #include "Color.h" //#include "Polygon.h" #include "Scene.h" #include "Utils.h" // destructor CScene::~CScene() { for (int i = 0; i < size(); i++) { //delete region[i]; } } void CScene::makeRandomScene(int nregions, int imsize, bool xonly, bool someTriangles) { region.resize(nregions); sorted = false; for (int i = 0; i < nregions; i++) { CVec2 p0, p1, p2, vel; vel.randomize(-5, 5); // use integer velocities for now: vel.x = (float)((int)vel.x); vel.y = (float)((int)vel.y); float z = randIn(1, 100); CCol c(i+1); // start with color 1 (black) since 0 (white) is background int alpha = __min(255, 100+rand() % 400); //c.A = alpha; // use this to get transparent surfaces if (!someTriangles || i%2 == 0 || xonly) { //rectangle p0.randomize(-50.0f, (float)imsize); p1.randomize(20.0f, (float)(imsize/2)); if (xonly) { p0.y = 0; p1.y = 50; p1.x /= 3; p1.x=(float)(int)p1.x; p2.x=(float)(int)p2.x; vel.y = 0; } region[i] = new CRect(p0, p1, vel, z, c); } else { // triangle p0.randomize(0, (float)imsize); p1.randomize(-0.4f*imsize, 0.4f*imsize); p2.randomize(-0.4f*imsize, 0.4f*imsize); region[i] = new CTri(p0, p0+p1, p0+p2, vel, z, c); } } } void CScene::makeApproximateScene(int nregions, int imsize, bool xonly, bool someTriangles) { region.resize(nregions); sorted = false; for (int i = 0; i < nregions; i++) { CVec2 p0, p1, p2, vel; vel.randomize(-5, 5); float z = randIn(1, 100); CCol c(i+1); // start with color 1 (black) since 0 (white) is background int alpha = __min(255, 100+rand() % 400); //c.A = alpha; // use this to get transparent surfaces if (!someTriangles || i%2 == 0 || xonly) { //rectangle p0.randomize(-50.0f, (float)imsize); p1.randomize(20.0f, (float)(imsize/2)); if (xonly) { p0.y = 0; p1.y = 50; p1.x /= 3; p1.x=p1.x; p2.x=p2.x; vel.y = 0; } region[i] = new CRect(p0, p1, vel, z, c); } else { // triangle p0.randomize(0, (float)imsize); p1.randomize(-0.4f*imsize, 0.4f*imsize); p2.randomize(-0.4f*imsize, 0.4f*imsize); region[i] = new CTri(p0, p0+p1, p0+p2, vel, z, c); } } } void CScene::makeTwoDScene(int nregions, int imsize) { region.resize(nregions); sorted = false; for (int i = 0; i < nregions; i++) { CVec2 p0, p1, p2, vel; vel.randomize(-5, 5); //int velocities at the moment vel.x = vel.x; vel.y = vel.y; float z = randIn(1, 200); CCol c(i+1); // start with color 1 (black) since 0 (white) is background int alpha = __min(255, 100+rand() % 400); //c.A = alpha; // use this to get transparent surfaces vel.y = 0; // p0.randomize(-(float)imsize/2.0, (float)imsize); // p1.randomize((float)(imsize/2.0), (float)(imsize)); // region[i] = new CConvex(p0, p1, vel, z, c); //if(i%20==0){ p0.randomize(-(float)(imsize/4.0f), (float)imsize); p1.randomize((float)(imsize/4.0f), (float)(imsize)/2.0f); region[i] = new CConvex(p0, p1, vel, z, c); /*}else{ p0.randomize(0, (float)imsize); p1.randomize(4,20); region[i] = new CConvex(p0, p1, vel, z, c); } */ } } void CScene::makeStereoScene(int nregions, int imsize) { region.resize(nregions); sorted = false; for (int i = 0; i < nregions; i++) { CVec2 p0, p1, p2, vel; vel.randomize(10, 70); float z=100.0f/vel.x; CCol c(i+1); // start with color 1 (black) since 0 (white) is background vel.y = 0; vel.x/=10; p0.randomize(-(float)(imsize/4.0f), (float)imsize); p1.randomize((float)(imsize/4.0f), (float)(imsize)/2.0f); region[i] = new CConvex(p0, p1, vel, z, c); } } void CScene::makeTestScene(int imsize) { region.resize(3); sorted = false; CVec2 p0(50, 50); CVec2 p1(150, 100); CVec2 p2(100, 150); CVec2 diag((float)(imsize/4), (float)(imsize/4)); CVec2 vel(2.0f, 0); region[0] = new CRect(p0, diag, vel, 5, CCol(1)); region[1] = new CRect(p1, diag, vel, 1, CCol(2)); region[2] = new CRect(p2, diag, vel, 3, CCol(3)); } void CScene::makeTestScene2(int imsize) { int n=5; region.resize(n); sorted = false; CVec2 p0(10, 0); CVec2 p1(200, 100); CVec2 vel(2.0f, 0); for (int i=0; iz, p2->z); if (p1->z < p2->z) return -1; else if (p1->z > p2->z) return 1; else { printf("warning: two regions have same depth\n"); return 0; } } void CScene::sortByDepth() { if (!sorted) { // Sort regions by depth using Quicksort algorithm qsort((void *)(®ion[0]), size(), sizeof(CPoly *), compareByDepth); } sorted = true; } // draw scene CByteImage CScene::drawScene(CByteImage im, float time) { // make white image im.FillPixels(255); // sort by increasing depth sortByDepth(); // draw from back to front for (int i = size()-1; i >= 0; i--) { region[i]->draw(im, time); } return im; } // print scene description void CScene::printDescription(bool floats) { printf("\nCorrect order:\n"); for (int i=0; i < size(); i++) { printf(" "); //printf("depth = %g", region[i]->z); region[i]->color.printName(); if(!floats){ printf(" vel = %2d ", (int)(region[i]->vel.x)); printf(" len = %2d ", (int)(((CRect*)region[i])->diag.x)); }else{ printf(" vel = %2f ", region[i]->vel.x); printf(" len = %2f ", ((CRect*)region[i])->diag.x); } printf("\n"); } } CRect CScene::getByID(int id) { for (int i=0; i < size(); i++) { if(region[i]->color.getId()==id){ //printf("GOT IT! %d\n",id); CRect rect=*(CRect*)(region[i]); //printf("expected id=%d actual id=%d\n",id,rect.color.getId()); return rect; } } printf("FAIL: %d\n",id); CCol(id).printName(); return *(CRect*)(region[0]); }