Polygon2d Polygon2d::maketri(int a,int b,int c) { List<V2d> tmp; tmp.add(vs.num(a)); tmp.add(vs.num(b)); tmp.add(vs.num(c)); return Polygon2d(tmp); }
Polygon2d Polygon2d::subpath(int a,int b) { List<V2d> tmp; bool finished=false; for (int i=a;!finished;i=wrap(i+1,1,vs.len)) { tmp.add(vs.num(i)); if (i==b) finished=true; } return Polygon2d(tmp); }
void UpdateHitboxes(std::vector<Polygon2d> &polygons, sf::Vector2f position, int layer, int col, int row, TileSet &tileSet, TileMap &tileMap) { if(tileSet.IsDirty()) return; const int vertexPos = layer * tileMap.GetColumnsCount() * tileMap.GetRowsCount() + col * tileMap.GetRowsCount() + row; const int tileWidth = tileSet.tileSize.x; const int tileHeight = tileSet.tileSize.y; if(tileMap.GetTile(layer, col, row) != -1 && tileSet.GetTileHitbox(tileMap.GetTile(layer, col, row)).collidable) { polygons[vertexPos] = tileSet.GetTileHitbox(tileMap.GetTile(layer, col, row)).hitbox; } else { polygons[vertexPos] = Polygon2d(); } polygons[vertexPos].Move(position.x + col * tileWidth, position.y + row * tileHeight); }
Polygon2d Polygon2d::fromlist(List<V2d> l) { return Polygon2d(l); }
void quadsearch(List<QuadsLine2d *> *q,List<bool> *www,List<List<QuadsLine2d> > *qs) { // printf("%i",q->len); if (key[KEY_ESC]) exit(0); if (q->len==4) { // Check last line meets first, and 2 and 4 are parallel int cl=( www->num(4) ? 1 : 2 ); int cf=( www->num(1) ? 2 : 1 ); V2d l=q->num(4)->end(cl); V2d f=q->num(1)->end(cf); if (withinrange(f,l) && parallelenough(*q->num(2),*q->num(4),www->num(2),www->num(4)) && !badintersection(q->num(4),q->num(1),cl,cf)) { // Realise the potential polygon by intersecting edges bool bad=false; List<V2d> realise=List<V2d>(4); // List<QuadsLine2d> realise=List<QuadsLine2d>(4); for (int i=1;i<=4;i++) { QuadsLine2d a=*q->num(i); // printf("\n%s",a.toString()); QuadsLine2d b=*q->wrapnum(i+1); if (www->num(i)) a.swapends(); if (www->wrapnum(i+1)) b.swapends(); V2d i=a.findintersection(b); if (!withinrange(i,a.b) || !withinrange(i,b.a)) bad=true; realise.add(i); /* QuadsLine2d *at=q->num(i); QuadsLine2d a=QuadsLine2d(at->a,at->b); if (www->num(i)) a.swapends(); realise.add(a);*/ } // Check no vertices make concave corners Polygon2d p=Polygon2d(realise); bool concave=false; for (int i=1;i<=4;i++) { Polygon2d q=p.subpath(wrap(i+1,4),wrap(i-1,4)); if (q.contains(p.vs.num(i))) concave=true; } if (!concave && !bad) { // qs->add(realise); List<QuadsLine2d> tmp=List<QuadsLine2d>(4); for (int i=1;i<=4;i++) { tmp.add(QuadsLine2d(realise.num(i),realise.wrapnum(i+1))); // printf("\n%s",tmp.num(tmp.len).toString()); } qs->add(tmp); fq.add(*q); fwww.add(*www); printf("."); } } } else { bool goahead=true; // If just added line 3, check 3 and 1 are parallel if (q->len==3) if (!parallelenough(*q->num(1),*q->num(3),www->num(1),www->num(3))) goahead=false; if (goahead) { QuadsLine2d *l=q->num(q->len); int wv=( www->num(q->len) ? 1 : 2 ); List<QuadsLine2d *> *ls=l->ls.p2num(wv); List<int> *es=l->es.p2num(wv); // printf("(%i):[",ls->len); // Consider neighbours of last line for (int i=1;i<=ls->len;i++) { QuadsLine2d *o=ls->num(i); int e=es->num(i); bool ok=true; // Check if the line has already been fully searched if (o->allusedup) ok=false; // Check it isn't one already in the quad, and it doesn't cross any previous for (int j=1;j<=q->len;j++) { QuadsLine2d *t=q->num(j); if (t==o || o->crosses(t)) ok=false; } // Check the intersections of last and next line are not inside if (badintersection(l,o,wv,e)) ok=false; if (ok) { // jbmp.line(4.8*o->a,4.8*o->b,15); // jbmp.display(); q->add(o); www->add(( e==2 ? true : false )); quadsearch(q,www,qs); q->removenum(q->len); www->removenum(www->len); // jbmp.line(4.8*o->a,4.8*o->b,0); } } } } }
void main(int argc,String *argv) { ArgParser a=ArgParser(argc,argv); String fname=a.argafter("-i","GF lines filename","ls.gf"); cdclip=a.floatafter("-ed","Maximum end distance of lines",30); creepintoline=a.floatafter("-ic","Intersection can creep in this much of a the line",0.02); dotabove=a.floatafter("-pd","Parallelity: dot product must be above this",0.5); minlen=a.floatafter("-ml","Minimum length of a line",20); bool displaying=!a.argexists("nod","Don't display"); String imname=a.argafter("-oi","Original image","none"); // float oiscale=a.floatafter("-ois","Scale to original image",1); // Read list from file FILE *fp=fopen(fname,"r"); List<QuadsLine2d> l=List<QuadsLine2d>(); String s; while (!Seq(Sleft(s,4),"@SET")) { s=getlinefromfile(fp); } s=getlinefromfile(fp); s=getlinefromfile(fp); s=getlinefromfile(fp); while (!Seq(Sleft(s,1),"@")) { // Dummies int n,w; float t,r,sx,sy,ex,ey,p; sscanf(s,"%i %f %f %f %f %f %f %i %f",&n,&t,&r,&sx,&sy,&ex,&ey,&w,&p); l.add(QuadsLine2d(V2d(sx,sy),V2d(ex,ey))); // printf("%s\n",l.num(l.len).toString()); s=getlinefromfile(fp); } fclose(fp); // Generate random list // randomise(); // List<QuadsLine2d> l=List<QuadsLine2d>(); /* for (int i=1;i<=100;i++) { V2d a=V2d(myrnd()*100*64/48,myrnd()*100); V2d b=V2d(myrnd()*100*64/48,myrnd()*100); l.add(QuadsLine2d(a,b)); jbmp.line(QuadsLine2d(a,b)*4.8,15); }*/ printf("%i lines\n",l.len); // Strip out small lines for (int i=1;i<=l.len;i++) { if (l.num(i).length<minlen) { l.removenum(i); i--; } } printf("Stripped small lines, now %i\n",l.len); // display(&l); // Build graph printf("Building graph (%i)\n",l.len); float ave=0; for (int i=1;i<=l.len;i++) { // jbmp.clear(); printf("."); QuadsLine2d *p=l.p2num(i); jbmp.line(p,15); int cnt=0; for (int j=i+1;j<=l.len;j++) { QuadsLine2d *q=l.p2num(j); cnt+=tryjoint(p,q,p->a,q->a,1,1); cnt+=tryjoint(p,q,p->a,q->b,1,2); cnt+=tryjoint(p,q,p->b,q->a,2,1); cnt+=tryjoint(p,q,p->b,q->b,2,2); } ave=ave+cnt; // jbmp.writetoscreen(); // do { } while (!key[KEY_SPACE]); } printf("\n"); ave=2.0*ave/(float)l.len; // 2.0 since each connection only counts once, but has two end vertices printf("Average connection of a line is %f\n",ave); /* // Display each line and its neighbours for (int i=1;i<=l.len;i++) { QuadsLine2d *p=l.p2num(i); jbmp.clear(); jbmp.line(p,5); for (int j=1;j<=2;j++) { List<QuadsLine2d *> ls=p->ls.num(j); for (int k=1;k<=ls.len;k++) { jbmp.line(ls.num(k),15); } } jbmp.writetoscreen(); waitforkeypress(); }*/ // Find quadrilaterals List<List<QuadsLine2d> > qs=List<List<QuadsLine2d> >(); for (int i=1;i<=l.len;i++) { printf("*"); List<QuadsLine2d *> q=List<QuadsLine2d *>(4); List<bool> www=List<bool>(4); q.add(l.p2num(i)); www.add(false); quadsearch(&q,&www,&qs); // Should now remove line l.num(i) from further searches l.p2num(i)->allusedup=true; /* // Needn't do this since symettrical q=List<QuadsLine2d *>(4); www=List<bool>(4); q.add(&l.num(i)); www.add(true); quadsearch(&q,&www,&qs); */ } printf("\n"); for (int i=1;i<=qs.len;i++) { List<QuadsLine2d> *q=qs.p2num(i); if (q!=NULL) { // Join corners /* for (int i=1;i<=q->len;i++) { int j=1+(i%q->len); q->num(i).b.print(); printf(","); q->num(j).a.print(); printf(" = "); q->p2num(i)->b=(q->num(i).b+q->num(j).a)/2.0; q->num(i).b.print(); // printf(" && "); q->p2num(j)->a=q->p2num(i)->b; // q->num(j).a.print(); printf("\n"); }*/ List<V2d> vs; vs.add(q->num(1).a); vs.add(q->num(2).a); vs.add(q->num(3).a); vs.add(q->num(4).a); Polygon2d p=Polygon2d(vs); // printf("%s\n",p.toString()); // printf("Quad found! %f\n",p.area()); // printf("<%i>",p.vs.len); } } /* for (int i=1;i<=qs.len;i++) { List<QuadsLine2d> *q=qs.p2num(i); for (int j=1;j<=q->len;j++) { q->num(j).a.print(); printf(" - "); q->num(j).b.print(); printf("\n"); } }*/ Map2d<bool> jb=Map2d<bool>(640,480,15); for (int i=1;i<=qs.len && !key[KEY_ESC];i++) { // jb.clear(); List<QuadsLine2d> *l=qs.p2num(i); for (int j=1;j<=l->len;j++) { QuadsLine2d m=l->num(j); jb.line(m.a,m.b,0); } } jb.writefile("quads.bmp"); // Recover text List<RGBmp *> rec; if (!Seq(imname,"none")) { RGBmp *oi=RGBmp::readfile(imname); // oi->display(); float oiscale=2.0; for (int i=1;i<=qs.len;i++) { List<QuadsLine2d> *l=qs.p2num(i); RGBmp *n=oi->recoverquad(l,oiscale); n->writefile(getnextfilename("recquad","bmp")); // n->getgreyscale()->adaptivethreshold(0.3)->display(); rec.add(n); } } if (displaying) { jbmp.display(); jb.display(); for (int i=1;i<=rec.len;i++) rec.num(i)->display(); } allegro_exit(); printf("%i quadrilaterals found\n",qs.len); }
void main() { float minlen=10.0; float cornerdist=2.0; // Generate random list // randomise(); List<QuadsLine2d> l=List<QuadsLine2d>(); for (int i=1;i<=100;i++) { V2d a=V2d(myrnd()*100*64/48,myrnd()*100); V2d b=V2d(myrnd()*100*64/48,myrnd()*100); l.add(QuadsLine2d(a,b)); jbmp.line(QuadsLine2d(a,b)*4.8,15); } printf("%i lines\n",l.len); // Strip out small lines for (int i=1;i<=l.len;i++) { if (l.num(i).length<minlen) { l.removenum(i); i--; } } printf("Stripped small lines, now %i\n",l.len); // display(&l); // Build graph printf("Building graph (%i)\n",l.len); float ave=0; for (int i=1;i<=l.len;i++) { // jbmp.clear(); printf("."); QuadsLine2d *p=l.p2num(i); jbmp.line(p,15); int cnt=0; for (int j=i+1;j<=l.len;j++) { QuadsLine2d *q=l.p2num(j); cnt+=tryjoint(p,q,p->a,q->a,1,1); cnt+=tryjoint(p,q,p->a,q->b,1,2); cnt+=tryjoint(p,q,p->b,q->a,2,1); cnt+=tryjoint(p,q,p->b,q->b,2,2); } ave=ave+cnt; // jbmp.writetoscreen(); // do { } while (!key[KEY_SPACE]); } printf("\n"); ave=2.0*ave/(float)l.len; // 2.0 since each connection only counts once, but has two end vertices printf("Average connection of a line is %f\n",ave); /* // Display each line and its neighbours for (int i=1;i<=l.len;i++) { QuadsLine2d *p=l.p2num(i); jbmp.clear(); jbmp.line(p,5); for (int j=1;j<=2;j++) { List<QuadsLine2d *> ls=p->ls.num(j); for (int k=1;k<=ls.len;k++) { jbmp.line(ls.num(k),15); } } jbmp.writetoscreen(); waitforkeypress(); }*/ // Find quadrilaterals List<List<QuadsLine2d> > qs=List<List<QuadsLine2d> >(); for (int i=1;i<=l.len;i++) { printf("*"); List<QuadsLine2d *> q=List<QuadsLine2d *>(4); List<bool> www=List<bool>(4); q.add(l.p2num(i)); www.add(false); quadsearch(&q,&www,&qs); // Should now remove line l.num(i) from further searches l.p2num(i)->allusedup=true; /* // Needn't do this since symettrical q=List<QuadsLine2d *>(4); www=List<bool>(4); q.add(&l.num(i)); www.add(true); quadsearch(&q,&www,&qs); */ } printf("\n"); for (int i=1;i<=qs.len;i++) { List<QuadsLine2d> *q=qs.p2num(i); if (q!=NULL) { // Join corners /* for (int i=1;i<=q->len;i++) { int j=1+(i%q->len); q->num(i).b.print(); printf(","); q->num(j).a.print(); printf(" = "); q->p2num(i)->b=(q->num(i).b+q->num(j).a)/2.0; q->num(i).b.print(); // printf(" && "); q->p2num(j)->a=q->p2num(i)->b; // q->num(j).a.print(); printf("\n"); }*/ List<V2d> vs; vs.add(q->num(1).a); vs.add(q->num(2).a); vs.add(q->num(3).a); vs.add(q->num(4).a); Polygon2d p=Polygon2d(vs); // printf("%s\n",p.toString()); // printf("Quad found! %f\n",p.area()); printf("<%i>",p.vs.len); } } /* for (int i=1;i<=qs.len;i++) { List<QuadsLine2d> *q=qs.p2num(i); for (int j=1;j<=q->len;j++) { q->num(j).a.print(); printf(" - "); q->num(j).b.print(); printf("\n"); } }*/ // jbmp.display(); JBmp jb=JBmp(640,480,15); for (int i=1;i<=qs.len && !key[KEY_ESC];i++) { // jb.clear(); List<QuadsLine2d> *l=qs.p2num(i); for (int j=1;j<=l->len;j++) { QuadsLine2d m=l->num(j); jb.line(m.a*4.8,m.b*4.8,i); } } jb.display(); do { } while (!key[KEY_SPACE]); allegro_exit(); printf("%i quadrilaterals found\n",qs.len); }