Example #1
0
  List<Polygon2d> Polygon2d::splittotris() {
    List<Polygon2d> ps;
    if (vs.len==3) {
      ps.add(*this);
      return ps;
    }
    for (int p=1;p<=vs.len;p++)
    for (int q=1;q<=vs.len;q++) {
      // Ensure we don't have the same or adjacent vertices
      if (p!=q && abs(p-q)>1 && abs(p-q)<vs.len) {
        Line2d l=Line2d(vs.num(p),vs.num(q));
        // Check it doesn't cross the perimeter
        bool cross=false;
        for (int i=1;i<=vs.len && !cross;i++) {
          Line2d tl=Line2d(vs.num(i),vs.numwrap(i+1));
          V2d *v=tl.findintersectionornull(l);
          if (v==NULL)
            cross=true;
        }
        if (!cross) {
          // We make two new polygons out of this one, and find their areas.
          ps.add(this->subpath(p,q).splittotris());
          ps.add(this->subpath(q,p).splittotris());
          return ps;
        }
      }
    }
    error("splittotris: Could not split polygon without crossing lines.\n");
//    return NULL;
  }
Example #2
0
  float Polygon2d::area() {
//    printf("Finding area of polygon %i\n",vs.len);
    if (vs.len==3) {
      // Find area of triangle.
      // Split vertically into two
      // Get middle vertically
      vs.sort(&(V2d::gety));
      V2d a=vs.num(1);
      V2d b=vs.num(2);
      V2d c=vs.num(3);
      // Find where vertical line crosses the horizontal of the middle point
      // i = A + k(C-A)
      // i = (l,B.y)
      // l = Ax+k(Cx-Ax)
      // By = Ay+k(Cy-Ay)
      float k=(b.y-a.y)/(c.y-a.y);
      V2d i=a+k*(c-a);
      float wid=floatabs(b.x-i.x);
      float ha=floatabs(a.y-b.y);
      float hc=floatabs(c.y-b.y);
//      a.print(); b.print(); c.print();
//      printf("%f %f %f\n",wid,ha,hc);
      return 1.0/2.0*wid*(ha+hc);
    }
    // If larger than a triangle, need to split
    // Find a line between two vertices that does not cross the perimiter.
    for (int p=1;p<=vs.len;p++)
    for (int q=1;q<=vs.len;q++) {
      // Ensure we don't have the same or adjacent vertices
      if (p!=q && abs(p-q)>1 && abs(p-q)<vs.len) {
//        printf("Checking %i %i\n",p,q);
        Line2d l=Line2d(vs.num(p),vs.num(q));
//        l.a.print(); l.b.print();
        // Check it doesn't cross the perimeter
        bool cross=false;
        for (int i=1;i<=vs.len && !cross;i++) {
//          printf("%i\n",i);
          Line2d tl=Line2d(vs.num(i),vs.numwrap(i+1));
          V2d *v=tl.findintersectionornull(l);
          if (v==NULL)
            cross=true;
//          printf("'\n");
          //free(v);
        }
        if (!cross) {
//          printf("no crossing for %i %i\n",p,q);
          // We make two new polygons out of this one, and find their areas.
          Polygon2d tmpa=this->subpath(p,q);
          Polygon2d tmpb=this->subpath(q,p);
          return tmpa.area()+tmpb.area();
        }
//        printf("Cross\n");
      }
    }
    error("area: Could not split polygon without crossing lines.\n");
  }
Example #3
0
 bool Polygon2d::contains(V2d v) {
   Line2d toinf=Line2d(v,V2d(10000,v.y));
   int count=0;
   for (int i=1;i<=vs.len;i++) {
     Line2d t=Line2d(vs.num(i),vs.numwrap(i+1));
     if (t.crosses(toinf))
       count++;
   }
   return (intmod(count,2)==1);
 }
Example #4
0
 V3d *intersection(Line3d o) {
   //printf("\nTrying to find intersection %s-%s with %s-%s\n",a.toString(),b.toString(),o.a.toString(),o.b.toString());
   Line2d la=Line2d(a.dropz(),b.dropz());
   Line2d lb=Line2d(o.a.dropz(),o.b.dropz());
   float f=la.findintersectionnum(lb);
   V3d lah=a+f*(b-a);
   float g=lb.findintersectionnum(la);
   V3d lbh=o.a+g*(o.b-o.a);
   //printf("Intersection (%f) %s == %s (%f) ?\n",f,lah.toString(),lbh.toString(),g);
   return new V3d(lah.x,lah.y,lah.z);
   if (lah==lbh)
     return new V3d(lah.x,lah.y,lah.z);
   //printf("Intersection failed.\n");
     return NULL;
 }
Example #5
0
Line2d Segment2d::getLine() const {
	float y = _end.getY() - _begin.getY();
	float x = _end.getX() - _begin.getX();
	Vector2d v(x, y);

	return Line2d(v, _begin);
}
Example #6
0
void Line2d :: GetNormal (Line2d & n) const
{
  double 	ax  = P2().X()-P1().X(),
    ay  = P2().Y()-P1().Y();
  Point2d 	mid(P1().X()+.5*ax, P1().Y()+.5*ay);
 
 n=Line2d(mid,Point2d(mid.X()+ay,mid.Y()-ax)) ;
}
Example #7
0
  Line2d line() {
//    Region::list=NULL;
    Blob::remakelist();
    float a=angle();
//    printf("%f\n",a);
    V2d v=V2d(sin(a+pi/2.0),cos(a+pi/2.0))*(float)sqrt(Region::list->len);
    V2d c=centroid();
//    printf("Made proper line length %f List %i\n",v.mod(),Region::list->len);
    return Line2d(c-v,c+v);
  }
Example #8
0
  Line2d intersection(Plane p) {
    Viewpoint v=orientor();
    Plane pp=bring(v);
    // Where does pp meet this plane?
    // (X-PPP).PPN=0
    // X=(x,y,0)
    // (x-pppx)*pppnx+(y-pppy)*pppny+pppz*pppnz=0
    // y=(-pppz*pppnz+(pppx-x)*pppnx)/pppny+pppy
    #define yfrom(i) (-pp.pos.z*pp.nor.z+(pp.pos.x-(i))*pp.nor.x)/pp.nor.y+pp.pos.y
    Line2d l=Line2d(V2d(-100.0,yfrom(-100.0)),V2d(100.0,yfrom(100.0)));
//    Line3d t=Line3d(l);
//    t=t.orient(v);
    return l;
  }
Example #9
0
void main(int argc,String *argv) {
  
  ArgParser a=ArgParser(argc,argv);
  int w=a.intafter("-w","width",275);
  int h=a.intafter("-h","height",116);
  int numpts=a.intafter("-n","number of points",100);
  a.done();


  FILE *file=fopen("region.txt","wa");
  fprintf(file,"[Normal]\n");
  fprintf(file,"Numpoints=%i\n",numpts);

  V2d cen=V2d((float)w/2.0,(float)h/2.0);

  for (int i=0;i<numpts;i++) {

    V2d a=10.0*(w+h)*V2d::angle(-pi/4.0+2.0*pi*(float)i/(float)numpts);

    a=a+cen;

    if (a.x<0)
      a=Line2d(cen,a).intersect(Line2d(V2d(0,0),V2d(0,1)));
    if (a.y<0)
      a=Line2d(cen,a).intersect(Line2d(V2d(0,0),V2d(1,0)));
    if (a.x>w)
      a=Line2d(cen,a).intersect(Line2d(V2d(w,0),V2d(w,1)));
    if (a.y>h)
      a=Line2d(cen,a).intersect(Line2d(V2d(0,h),V2d(1,h)));

    a=a-cen;
    float rnd=myrnd();
    a=a*rnd;

    a=a+cen;

    fprintf(file,"%i,%i",(int)a.x,(int)a.y);
    if (i<numpts-1)
      fprintf(file,", ");

  }

  fprintf(file,"\n");

  fclose(file);

}
Example #10
0
  void line(int x1, int y1, int x2, int y2,CT r) {
    Line2d l=Line2d(V2d(x1,y1),V2d(x2,y2));
    String s=Sformat("Clipping %s...\n",l.toString());
//    l.clipbyrectangle(0,0,width-1,height-1);
//    printf("  got %s...\n",l.toString());
    x1=l.a.x;
    x2=l.b.x;
    y1=l.a.y;
    y2=l.b.y;

//    if (inbmp(x1,y1) && inbmp(x2,y2)) {
      List<Pixel> ps=Pixel::line(Pixel(x1,y1),Pixel(x2,y2));
      for (int i=1;i<=ps.len;i++) {
//        printf("Setting pixel %s\n",ps.num(i).toString());
        setpixel(ps.num(i),r);
      }
      ps.freedom();
//    } else
//      printf("%sDidn't write line because got %s when clipped\n",s,l.toString());

    free(s);
  }
Example #11
0
int Polygon2d :: IsOn (const Point2d & p) const
{
  int i;
  for (i = 1; i <= points.Size(); i++)
    {
      const Point2d & p1 = points.Get(i);
      const Point2d & p2 = points.Get(i%points.Size()+1);
      if (IsOnLine (Line2d(p1, p2), p)) return 1;
    }
  return 0;
  /*
  CURSOR c;
  Point2d * p1, * p2;
  
  p2 = points[points.Last()];
  for (c = points.First(); c != points.Head(); c++)
    {
      p1 = p2;
      p2 = points[c];
      if (IsOnLine (Line2d(*p1, *p2), p)) return 1;
    }
  return 0;
  */
}
Example #12
0
Line2d Correlator::line() {
  V2d c=centroid();
  V2d o=ori();
  return Line2d(c,c+o);
}
Example #13
0
float affinity(Region *a,Region *b) {
  Line2d l=Line2d(a->centroid(),b->centroid());
  return affinity(a,l)*affinity(b,l);
}
Example #14
0
 Line2d Polygon2d::linefrom(int i) {
   return Line2d(vs.wrapnum(i),vs.wrapnum(i+1));
 }
Example #15
0
int TRIANGLE2D :: IsOn (const Point2d & p) const
  {
  return IsOnLine (Line2d (p1, p2), p) ||
         IsOnLine (Line2d (p1, p3), p) ||
         IsOnLine (Line2d (p2, p3), p);
  }
Example #16
0
int PTRIANGLE2D :: IsOn (const Point2d & p) const
{
  return IsOnLine (Line2d (*p1, *p2), p) ||
         IsOnLine (Line2d (*p1, *p3), p) ||
         IsOnLine (Line2d (*p2, *p3), p);
}
Example #17
0
void lookforparagraphs() {
  for (int i=1;i<=bs.len;i++) {
    Blob *b=bs.p2num(i);
    if (!b->blobbed && b->gettype()==Paragraph && b->sentcnt>=3) {
      printf("Inspecting a paragraph...\n");
      // Is it expandable?  (Are there any other blobs within 2*line spacing?)
      float ld=LineSpace*b->linedist();
      bool found=false;
      for (int j=1;j<=bs.len && !found;j++)
        if (j!=i && !bs.p2num(j)->blobbed)
          if (closestdist(i,j)<ld)
            found=true;
      if (!found) {
        // Recover paragraph
        b->type=Block;

        RGBmp out=RGBmp(rm.width,rm.height);
        b->plot(&out);

        // An early bit of the VVP function
        // Find vertical line through centres of text lines
        Correlator c=Correlator();
        for (int i=1;i<=b->lines.len;i++)
          c.add(bs.p2num(b->lines.num(i))->centroid);
        Line2d l=Line2d(c.centroid(),c.centroid()+c.ori().norm());
        c.freedom();
        out.line(l.a,l.a+(l.b-l.a)*200,myRGB::red);

        printf("Finding HVP...\n");
        // Intersect all lines in paragraph with each other and cluster (by averaging!)
        V2d hvpl=V2d(0,0);
        V2d hvpr=V2d(0,0);
        int cnte=b->lines.len*(b->lines.len-1)/2;
        int cntl=0;
        int cntr=0;
        int cntt=0;
        for (int i=1;i<=b->lines.len;i++) {
          Line2d la=bs.p2num(b->lines.num(i))->line();
          out.line(la,myRGB::yellow);
          for (int j=1;j<=b->lines.len;j++) {
            if (i!=j) {
              Line2d lb=bs.p2num(b->lines.num(j))->line();
              V2d li=la.findintersection(lb);
              if ((li-b->centroid).mag()<10000000) {
                out.line(la.center(),li,myRGB::white*0.5);
                out.line(lb.center(),li,myRGB::white*0.5);
                if (l.whichsideis(li)<0) {
                  cntl++;
                  hvpl=hvpl+li/(float)cnte;
                } else {
                  cntr++;
                  hvpr=hvpr+li/(float)cnte;
                }
              }
              cntt++;
              printf("Intersect distance: %.2f\n",(li-b->centroid).mag());
            }
          }
        }
        V2d hvp=( cntl>cntr ? hvpl : hvpr );
        int cnt=( cntl>cntr ? cntl : cntr );
        printf("Intersections on left %i right %i\n",cntl,cntr);
        if (cntl>cntr)
          printf("HPP found on left with %i intersections out of %i\n",cntl,cntt);
        else
          printf("HPP found on right with %i intersections out of %i\n",cntl,cntt);
        if (cnt!=cnte) {
          printf("Got count %i for HVP wrong, actually used %i intersections!\n",cnte,cnt);
          hvp=hvp*(float)cnte;
          hvp=hvp/(float)cnt;
        }
        printf("HVP=%s\n",hvp.toString());
        float zh=(b->centroid-hvp).mag();
        printf("Distance to HVP: %f\n",zh);
        if (!(zh<bigfloat*10.0)) {
          zh=bigfloat*10.0;
          hvp=b->centroid+(hvp-b->centroid).norm()*zh;
          zh=(b->centroid-hvp).mag();
          if (!(zh<bigfloat*10.0)) {
            zh=bigfloat*10.0;
            hvp=b->centroid+V2d(-1,0)*zh;
          }
          printf("  too large: now %f %s\n",zh,hvp.toString());
        }
//        printf("Plotting lines...");
        for (int i=1;i<=b->lines.len;i+=b->lines.len-1)
          out.line(hvp,bs.p2num(b->lines.num(i))->centroid,myRGB::green);

        printf("Finding VVP...\n");

        // Estimate distance of vanishing point
        Correlator c2=Correlator();
        V2d lineori=b->lineori();

        // *** Try average base size in a line

        // Doing linear correlation with line width
        float scale=1.0;
        for (int i=1;i<=b->lines.len;i++) {
          V2d cen=bs.p2num(b->lines.num(i))->centroid;
          float x=(cen-l.a).dot((l.b-l.a).norm());
          float y=bs.p2num(b->lines.num(i))->width(); // Area of region! (used to be ->height()) // (used to be ->area())
          printf("%f , %f\n",x,y);
          out.cross(l.a+(l.b-l.a).norm()*x+lineori*y*scale,5,myRGB::white);
          c2.add(x,y);
        }

/*        float scale=5.0;
        for (int i=1;i<=b->lines.len-1;i++) { // not -1 for height
          V2d cen=bs.p2num(b->lines.num(i))->centroid;
          float x=(cen-l.a).dot((l.b-l.a).norm());
//          float y=bs.p2num(b->lines.num(i))->height(); // line (character) height
          float y=b->linedist(i); // line spacing
          if (y>0.5) { // Bodge to ensure two lines which should be the same are not used
          printf("%f , %f\n",x,y);
          out.cross(l.a+(l.b-l.a).norm()*x+lineori*y*scale,5,myRGB::white);
          c2.add(x,y);
          }
        }*/

        // Doing linear correlation with base sizes. Too noisy!
/*        float scale=3.0;
        for (int i=1;i<=b->bases.len;i++) {
          V2d cen=bs.p2num(b->bases.num(i))->centroid;
          float x=(cen-l.a).dot((l.b-l.a).norm());
          float y=bs.p2num(b->bases.num(i))->area; // Area of region! (used to be ->height())
          printf("%f , %f\n",x,y);
          if (y>10) {
            out.cross(l.a+(l.b-l.a).norm()*x+lineori*y*scale,5,myRGB::white);
            c2.add(x,y);
          } else {
            out.cross(l.a+(l.b-l.a).norm()*x+lineori*y*scale,5,myRGB::green*0.5);
          }
        }*/

        float z=c2.crossesyxoutliers();

        // Check the line we get is worth anything by plotting it!
        float tx=(bs.p2num(b->lines.num(1))->centroid-l.a).dot((l.b-l.a).norm());
        float ty=c2.yforx(tx);
        printf("First should be approx %f,%f\n",tx,ty);
        V2d lin1=l.a+(l.b-l.a).norm()*tx+lineori*ty*scale;
        tx=(bs.p2num(b->lines.num(b->lines.len))->centroid-l.a).dot((l.b-l.a).norm());
        ty=c2.yforx(tx);
        printf("Last should be approx %f,%f\n",tx,ty);
        V2d lin2=l.a+(l.b-l.a).norm()*tx+lineori*ty*scale;
        out.line(lin1,lin2,myRGB::white);

        if (!(z>=-bigfloat && z<=bigfloat)) {
          printf("VP too far away (areas suggested %f)!\n",z);
          z=bigfloat;
        }
        printf("Distance to VVP: %f (originally %f)\n",z,z);
        c2.freedom();
        V2d vvp=l.a+(l.b-l.a).norm()*z;
        printf("VVP=%s\n",vvp.toString());
        Line2d enil=bs.p2num(b->lines.num(1))->line();
        out.line(vvp,enil.a,myRGB::magenta);
        out.line(vvp,enil.b,myRGB::magenta);
        enil=bs.p2num(b->lines.num(b->lines.len))->line();
        out.line(vvp,enil.a,myRGB::magenta);
        out.line(vvp,enil.b,myRGB::magenta);

        float hva=(b->centroid-hvp).angle();
        float hvb=hva;
        float vva=(b->centroid-vvp).angle();
        float vvb=vva;
        printf("Centre angles: H=%.2f V=%.2f\n",hva*rad2deg,vva*rad2deg);
        for (int i=1;i<=b->bpixs.len;i++) {
          V2d v=V2d(b->bpixs.num(i));
          float ha=(v-hvp).angle();
          float va=(v-vvp).angle();
          if (angleless(ha,hva))
            hva=ha;
          if (angleless(hvb,ha))
            hvb=ha;
          if (angleless(va,vva))
            vva=va;
          if (angleless(vvb,va))
            vvb=va;
//          printf("Angles: H: %.2f< %.2f >%.2f V: %.2f< %.2f >%.2f\n",hva,ha,hvb,vva,va,vvb);
        }
        printf("Edge angles: H: %.2f-%.2f V: %.2f-%.2f\n",hva*rad2deg,hvb*rad2deg,vva*rad2deg,vvb*rad2deg);

        float vd=b->parawidth()*0.2/myabs(z);
        printf("Vertical margin angle %f degrees.\n",vd*360.0/2.0/pi);
        Line2d left=Line2d(vvp,vvp+V2d::angle(vvb+vd)*zh);
        Line2d right=Line2d(vvp,vvp+V2d::angle(vva-vd)*zh);
        float hd=b->paraheight()*0.2/zh;
        printf("Horizontal margin angle %f degrees.\n",hd*360.0/2.0/pi);
        Line2d top=Line2d(hvp,hvp+V2d::angle(hva-hd)*z);
        Line2d bottom=Line2d(hvp,hvp+V2d::angle(hvb+hd)*z);
        printf("Outer lines are\nleft=%s\nright=%s\ntop=%s\nbottom=%s\n",left.toString(),right.toString(),top.toString(),bottom.toString());
        V2d tl=top.intersect(left);
        V2d tr=top.intersect(right);
        V2d bl=bottom.intersect(left);
        V2d br=bottom.intersect(right);
        printf("Outer corners are\ntl=%s\ntr=%s\nbr=%s\nbl=%s\n",tl.toString(),tr.toString(),br.toString(),bl.toString());
        out.line(tl,tr,myRGB::yellow);
        out.line(tr,br,myRGB::yellow);
        out.line(br,bl,myRGB::yellow);
        out.line(bl,tl,myRGB::yellow);

        blockswritten++;
        out.writefile(Sformat("block%i.bmp",blockswritten));
//        rm.applyfn(&finddad)->hueify().writefile(Sformat("block%ilines.bmp",blockswritten));
        out.freedom();

/*        printf("Recovering quad...\n");
        List<V2d> qs;
        qs.add(tl); qs.add(tr); qs.add(br); qs.add(bl);
        RGBmp *n=image->recoverquad(&qs,1,600);
        n->writefile(Sformat("recover%i.bmp",blockswritten));
        printf("  done\n");  */

        printf("Recovering quad...\n");
        List<V2d> qs;
        qs.add(tl*origimage->width/image->width); qs.add(tr*origimage->width/image->width); qs.add(br*origimage->width/image->width); qs.add(bl*origimage->width/image->width);
        RGBmp *n=origimage->recoverquad(&qs,1,600);
        n->writefile(Sformat("recover%i.bmp",blockswritten));
        printf("  done\n");

        // Write quadrilateral point to text file (0,0)-(1,1)
        List<String> qd;
        qd.add("Quad points {topleft,topright,bottomright,bottomleft}");
        qd.add(Sformat("%f %f",tl.x/image->width,tl.y/image->height));
        qd.add(Sformat("%f %f",tr.x/image->width,tr.y/image->height));
        qd.add(Sformat("%f %f",br.x/image->width,br.y/image->height));
        qd.add(Sformat("%f %f",bl.x/image->width,bl.y/image->height));
        writelinestofile(qd,Sformat("quad%i.dat",blockswritten));

        // Remove paragraph from blobs
        b->blobbed=true;
      }
    }
  }
}
Example #18
0
 Line2d line() {
   V2d o=ori()*width();
   return Line2d(centroid-o,centroid+o);
 }
Example #19
0
Line2d Line2d::getPerpendicular(const Vector2d &point) const {
	Vector2d v(1, _b / _a);

	return Line2d(v, point);
}
Example #20
0
Line2d Viewpoint::lookAtLine3D(const Line3d& l3d){
	return Line2d(lookAtPoint3D(l3d.p1), lookAtPoint3D(l3d.p2));
}