void Voronoi::InsertParabola(Vec2d * p){ if(!root){root = new VParabola(p); return;} if(root->isLeaf && root->site->y - p->y < 1){ // degenerovaný pripad - obì spodní místa ve stejné výce Vec2d * fp = root->site; root->isLeaf = false; root->SetLeft( new VParabola(fp) ); root->SetRight(new VParabola(p) ); //Vec2d * s = new Vec2d( (p->x + fp->x)/2, height ); // zaèátek hrany uprostøed míst Vec2d * s = new Vec2d(); s->set( (p->x + fp->x)/2, height ); // zaèátek hrany uprostøed míst points.push_back(s); if(p->x > fp->x) root->edge = new VEdge(s, fp, p); // rozhodnu, který vlevo, který vpravo else root->edge = new VEdge(s, p, fp); edges->push_back(root->edge); return; } VParabola * par = GetParabolaByX(p->x); if(par->cEvent) { deleted.insert(par->cEvent); par->cEvent = 0; } //Vec2d * start = new Vec2d(p->x, GetY(par->site, p->x)); Vec2d * start = new Vec2d(); start->set( p->x, GetY(par->site, p->x) ); points.push_back(start); VEdge * el = new VEdge(start, par->site, p); VEdge * er = new VEdge(start, p, par->site); el->neighbour = er; edges->push_back(el); // pøestavuju strom .. vkládám novou parabolu par->edge = er; par->isLeaf = false; VParabola * p0 = new VParabola(par->site); VParabola * p1 = new VParabola(p); VParabola * p2 = new VParabola(par->site); par->SetRight(p2); par->SetLeft(new VParabola()); par->Left()->edge = el; par->Left()->SetLeft(p0); par->Left()->SetRight(p1); CheckCircle(p0); CheckCircle(p2); }
void draw() { // draw Points glColor3f( 0.3,0.3,0.3 ); for ( int i=0; i<n; i++ ) { draw_Vec2d( ps[i] ); }; // draw map.points.hits for ( int i=0; i<map.points.capacity; i++ ) { draw_Segment2d( {-0.5+i*pixsz,-0.5}, { -0.5+i*pixsz, -0.5 + map.points.hits[i] * 3*pixsz } ); } Vec2d pmouse; pmouse.set( (mouseX-WIDTH_HALF)*pixsz, (HEIGHT_HALF-mouseY)*( pixsz*ASPECT_RATIO ) ); int ix = map.getIx( pmouse.x ); int iy = map.getIy( pmouse.y ); int index = map.getBoxIndex( ix, iy ); //colorHash( map.getBoxIndex( ix, iy ) ); glColor3f( 0.9,0.7,0.8 ); draw_Rect2d( { map.getX(ix), map.getY(iy) }, { map.getX(ix+1), map.getY(iy+1) } ); //printf( " rect X Y %i %i %f %f \n", ix, iy, map.getX(ix), map.getY(iy) ); //printf( " mouse X Y %i %i \n", mouseX, mouseY ); paint_Vec2d( pmouse, 0.01 ); int nloaded = map.loadPointsIn( pmouse ); for ( int i=0; i<nloaded; i++ ) { int ii = map.tempi[i]; Vec2d* pp = map.points.store[ ii ]; paint_Vec2d( *pp, 0.0025 ); }; if( index != lastIndex ) printf( " ix iy index %i %i %i iters %i \n", ix, iy, index, map.points.DEBUG_counter ); lastIndex = index; };
void Voronoi::CheckCircle(VParabola * b){ VParabola * lp = VParabola::GetLeftParent (b); VParabola * rp = VParabola::GetRightParent(b); VParabola * a = VParabola::GetLeftChild (lp); VParabola * c = VParabola::GetRightChild(rp); if(!a || !c || a->site == c->site) return; Vec2d * s = 0; s = GetEdgeIntersection(lp->edge, rp->edge); if(s == 0) return; double dx = a->site->x - s->x; double dy = a->site->y - s->y; double d = std::sqrt( (dx * dx) + (dy * dy) ); if(s->y - d >= ly) { return;} Vec2d * newv = new Vec2d(); newv->set( s->x, s->y - d ); VEvent * e = new VEvent( newv, false); //VEvent * e = new VEvent( new Vec2d(s->x, s->y - d), false); points.push_back(e->point); b->cEvent = e; e->arch = b; queue.push(e); }
void NBodyWorldApp::pickParticle( Particle2D*& picked ){ Particle2D* screenObjects[256]; // mouse picking double rmax = 2.0d; double r2max = rmax*rmax; Vec2d vmouse; vmouse.set( mouse_begin_x, mouse_begin_y ); UINT mfound = world.map.getObjectsInRect( (float)(vmouse.x - rmax ), (float)(vmouse.y - rmax ), (float)(vmouse.x + rmax ), (float)(vmouse.y + rmax ), &(screenObjects[0]) ); //printf( "mfound %i \n", mfound ); int imin = -1; double r2min = 1e+300; for( int i=0; i<mfound; i++ ){ Particle2D* p = screenObjects[i]; Vec2d d; d.set_sub( p->pos, vmouse ); double r2 = d.norm2(); if( r2 < r2max ){ if( r2 < r2min ){ r2min = r2; imin = i; } } //printf( " r2 %3.3f r2max %3.3f r2min %3.3f imin %i \n", r2, r2max, r2min, imin ); } if( imin >= 0 ){ picked = screenObjects[imin]; }else{ picked = NULL; } //if( world.picked != NULL ) printf( " MOUSE picked (%f,%f) \n", world.picked->pos.x, world.picked->pos.y ); }
void Voronoi::FinishEdge(VParabola * n){ if(n->isLeaf) {delete n; return;} double mx; if(n->edge->direction->x > 0.0){ mx = std::max(width, n->edge->start->x + 10 ); } else { mx = std::min(0.0, n->edge->start->x - 10 ); } //Vec2d * end = new Vec2d(mx, mx * n->edge->f + n->edge->g); Vec2d * end = new Vec2d(); end->set( mx, mx * n->edge->f + n->edge->g ); n->edge->end = end; points.push_back(end); FinishEdge(n->Left() ); FinishEdge(n->Right()); delete n; }
Vec2d * Voronoi::GetEdgeIntersection(VEdge * a, VEdge * b){ double x = (b->g-a->g) / (a->f - b->f); double y = a->f * x + a->g; if((x - a->start->x)/a->direction->x < 0) return 0; if((y - a->start->y)/a->direction->y < 0) return 0; if((x - b->start->x)/b->direction->x < 0) return 0; if((y - b->start->y)/b->direction->y < 0) return 0; //Vec2d * p = new Vec2d(x, y); Vec2d * p = new Vec2d(); p->set(x, y); points.push_back(p); return p; }
void Voronoi::RemoveParabola(VEvent * e){ VParabola * p1 = e->arch; VParabola * xl = VParabola::GetLeftParent(p1); VParabola * xr = VParabola::GetRightParent(p1); VParabola * p0 = VParabola::GetLeftChild(xl); VParabola * p2 = VParabola::GetRightChild(xr); if(p0 == p2) std::cout << "chyba - pravá a levá parabola má stejné ohnisko!\n"; if(p0->cEvent){ deleted.insert(p0->cEvent); p0->cEvent = 0; } if(p2->cEvent){ deleted.insert(p2->cEvent); p2->cEvent = 0; } //Vec2d * p = new Vec2d(e->point->x, GetY(p1->site, e->point->x)); Vec2d * p = new Vec2d(); p->set( e->point->x, GetY(p1->site, e->point->x) ); points.push_back(p); xl->edge->end = p; xr->edge->end = p; VParabola * higher; VParabola * par = p1; while(par != root) { par = par->parent; if(par == xl) higher = xl; if(par == xr) higher = xr; } higher->edge = new VEdge(p, p0->site, p2->site); edges->push_back(higher->edge); VParabola * gparent = p1->parent->parent; if(p1->parent->Left() == p1) { if(gparent->Left() == p1->parent) gparent->SetLeft ( p1->parent->Right() ); if(gparent->Right() == p1->parent) gparent->SetRight( p1->parent->Right() ); }else{ if(gparent->Left() == p1->parent) gparent->SetLeft ( p1->parent->Left() ); if(gparent->Right() == p1->parent) gparent->SetRight( p1->parent->Left() ); } delete p1->parent; delete p1; CheckCircle(p0); CheckCircle(p2); }
void setup() { // === Map2D indexing /* for (int i=0; i<10; i++ ){ double x = randf( -10,10 ); double y = randf( -10,10 ); short int ix = map.getIx( x ); short int iy = map.getIx( y ); unsigned int index = map.getIndex( ix, iy ); printf( " %i %f %f %i %i %i \n", i, x, y, ix, iy, index ); } */ // === HashMap test /* hashmap.init( power+1 ); printf( " n %i capacity %i \n ", n, hashmap.capacity ); for ( int i=0; i<n; i++ ){ ints[i] = rand(); hashmap.insert( &ints[i], i ); } for ( int i=0; i<hashmap.capacity; i++ ){ if ( hashmap.store[i] != NULL ) { printf( " %i hash %i box %i \n", i, hashmap.hashs[i], hashmap.iboxs[i] ); } else { printf( " %i NULL\n", i ); } } */ // === save random points into Map2D for ( int i=0; i<n; i++ ) { ps[i].set( randf( -1.0,1.0 ), randf( -1.0,1.0 ) ); //colorHash( i ); draw_Vec2d( p ); //print( ps[i] ); map.insertPoint( ps[i] ); } printf( " power %i n %i capacity %i mask %i \n ", power, n, map.points.capacity, map.points.mask ); // === Performance test int ntest = 10000000; long long t1,t2; double checksum = 0; int counter; counter = 0; t1 = getCPUticks(); for ( int i =0; i < ntest; i++ ) { Vec2d p; p.set( randf( -1.0,1.0 ), randf( -1.0,1.0 ) ); map.loadPointsIn( p ); counter += map.points.DEBUG_counter; } t2 = getCPUticks(); printf( " map.loadPointsIn : checksum %f ticks/op %f iter/op %f \n", checksum, (t2-t1)/(double)ntest, counter/(double)ntest ); counter = 0; t1 = getCPUticks(); for ( int i =0; i < ntest; i++ ) { Vec2d p; p.set( randf( -1.0,1.0 ), randf( -1.0,1.0 ) ); map.loadPointsIn_noHash( p ); counter += map.points.DEBUG_counter; } t2 = getCPUticks(); printf( " map.loadPointsIn_noHash : checksum %f ticks/op %f iter/op %f \n", checksum, (t2-t1)/(double)ntest, counter/(double)ntest ); }
void TestAppTerrainCubic::draw(){ glClearColor( 1.0f, 1.0f, 1.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_DEPTH_TEST ); // ============== project to line Convex Polygons const int np = 7; double yLs [np]; double yRs [np]; double ys [np]; double xs [np]; Convex2d base( np ); //base.corners[0].set( -1.0, +1.0 ); //base.corners[1].set( +1.0, -1.5 ); //base.corners[2].set( +2.0, 0.5 ); base.corners[0].set( -1.0, -1.0 ); base.corners[1].set( +1.0, -1.0 ); base.corners[2].set( +2.0, 0.0 ); base.corners[3].set( +1.0, +1.0 ); base.corners[4].set( -1.0, +1.0 ); base.corners[5].set( -1.5, +0.5 ); base.corners[6].set( -1.5, -0.5 ); glColor3f( 0.5f, 0.5f, 0.5f ); Draw2D::drawConvexPolygon( base.n, base.corners, false ); //Vec2d dir; dir.set( +1.0, 0.1 ); dir.normalize( ); double angle = M_PI * ( ( frameCount % 600 ) / 300.0 ) + 0.5; Vec2d dir; dir.set( cos( angle ), sin( angle ) ); base.projectToLine( dir, xs, yLs, yRs ); //printArray( base.n, xs ); //printArray( base.n, yLs ); //printArray( base.n, yRs ); VecN::sub( np, yLs, yRs, ys ); PolyLinear1d pline( np, xs, ys ); //pline.n = np; //pline.xs = xs; //pline.ys = ys; //double V = pline.integrate( -1000.0, 1000.0 ); double V = pline.integrate_ibounds( 0, pline.n ); double Vtarget = V*0.1; double xhalf = pline.x_of_integral( Vtarget ); double Vhalf = pline.integrate( -1000.0, xhalf ); printf( " V %f xhalf %f Vhalf %f Vtarget %f \n", V, xhalf, Vhalf, Vtarget ); double watterline; double moment = integrate_moment( np, xs, yLs, yRs, Vtarget, watterline ); printf( " V %f xtarget %f %f Vtarget %f %f moment %f \n", V, xhalf, watterline, Vhalf, Vtarget, moment ); pline.detach(); glColor3f( 0.2f, 0.9f, 0.2f ); Draw2D::drawLine( { xhalf, -10.0 }, { xhalf, +10.0 } ); glColor3f( 0.5f, 0.5f, 0.5f ); Draw2D::drawLine( { 0.0, -10.0 }, { 0.0, +10.0 } ); Draw2D::drawLine( {-10.0, 0.0 }, {+10.0, 0.0 } ); glColor3f( 0.9f, 0.2f, 0.2f ); Draw2D::plot( base.n, xs, yLs ); glColor3f( 0.2f, 0.2f, 0.9f ); Draw2D::plot( base.n, xs, yRs ); glColor3f( 0.0f, 0.0f, 0.0f ); Draw2D::plot( base.n, xs, ys ); // ============== Mouse Raycast Convex Polygons /* //printf( " mouse x,y : %i %i %f %f \n", mouseX, mouseY, mouseRight(mouseX), mouseUp(mouseY) ); Vec2d mvec; mvec.set( mouseRight(mouseX), mouseUp(mouseY) ); //mvec.set( 0.0, 0.0 ); Draw2D::drawPointCross_d( mvec, 1.0 ); for( auto isle : isles ) { //printf( "draw isle: %i %f %f \n ", isle->n, isle->corners[0].x, isle->corners[0].y ); if( isle->pointIn( mvec ) ){ glColor3f( 1.0f, 0.2f, 0.2f ); //printf( " mouse in isle \n " ); }else{ glColor3f( 0.2f, 0.2f, 0.2f ); } Draw2D::drawConvexPolygon( isle->n, isle->corners, true ); //exit(0); } */ // ============== Cut Convex Polygon /* Convex2d base( 5 ); //base.corners[0].set( -1.0, +1.0 ); //base.corners[1].set( +1.0, -1.5 ); //base.corners[2].set( +2.0, 0.5 ); base.corners[0].set( -1.0, -1.0 ); base.corners[1].set( +1.0, -1.0 ); base.corners[2].set( +2.0, 0.0 ); base.corners[3].set( +1.0, +1.0 ); base.corners[4].set( -1.0, +1.0 ); glColor3f( 0.9f, 0.9f, 0.9f ); Draw2D::drawConvexPolygon( base.n, base.corners, false ); Vec2d Acut,Bcut; Acut.set( -1.0, -5.0 ); Bcut.set( +3.0, +5.0 ); Line2d cutline; cutline.set( Acut, Bcut ); glColor3f( 0.2f, 0.9f, 0.2f ); Draw2D::drawLine_d( Acut, Bcut ); Convex2d left; Convex2d right; base.cut( cutline, left, right ); glColor3f( 0.9f, 0.2f, 0.9f ); Draw2D::drawPointCross_d( left.corners[0], 0.3 ); glColor3f( 0.2f, 0.9f, 0.9f ); Draw2D::drawPointCross_d( left.corners[1], 0.3 ); glColor3f( 0.9f, 0.2f, 0.2f ); Draw2D::drawConvexPolygon( left.n, left.corners, true ); glColor3f( 0.2f, 0.2f, 0.9f ); Draw2D::drawConvexPolygon( right.n, right.corners, true ); */ STOP = true; };