示例#1
0
void Poly::draw(int gl_type, double z, bool randomized) const
{
  Vector2d v;
  uint count = vertices.size();
  if (!closed && gl_type == GL_LINE_LOOP) {
    gl_type = GL_LINES;
    count--;
  }
  glBegin(gl_type);
  for (uint i=0; i < count; i++){
    v = getVertexCircular(i);
    if (randomized) v = random_displaced(v);
    glVertex3f(v.x(),v.y(),z);
    if ( gl_type == GL_LINES ) {
      Vector2d vn = getVertexCircular(i+1);
      if (randomized) vn = random_displaced(vn);
      glVertex3f(vn.x(),vn.y(),z);
    }
  }
  glEnd();
  // if (hole) {
  //   glBegin(GL_LINES);
  //   for (uint i=0; i < count; i++){
  //     glVertex3d(center.x(),center.y(),z);
  //     Vector2d vn = vertices[i];
  //     if (randomized) vn = random_displaced(vn);
  //     glVertex3d(vn.x(),vn.y(),z);
  //   }
  //   glEnd();
  // }
}
示例#2
0
文件: poly.cpp 项目: atoun/repsnapper
void Poly::calcHole()
{
  	if(vertices.size() == 0)
	  return;	// hole is undefined
	Vector2d p(-6000, -6000);
	int v=0;
	center = Vector2d(0,0);
	Vector2d q;
	for(size_t vert=0;vert<vertices.size();vert++)
	{
	  q = vertices[vert];
	  center += q;
	  if(q.x > p.x)
	    {
	      p = q;
	      v=vert;
	    }
	  else if(q.x == p.x && q.y > p.y)
	    {
	      p.y = q.y;
	      v=vert;
	    }
	}
	center /= vertices.size();

	// we have the x-most vertex (with the highest y if there was a contest), v 
	Vector2d V1 = getVertexCircular(v-1);
	Vector2d V2 = getVertexCircular(v);
	Vector2d V3 = getVertexCircular(v+1);

	Vector2d Va=V2-V1;
	Vector2d Vb=V3-V2;
	hole = Va.cross(Vb) > 0; 
	holecalculated = true;
}
示例#3
0
// Remove vertices that are on a straight line
void Poly::cleanup(double maxerror)
{ 
  if (vertices.size()<1) return;
  for (size_t v = 0; v < vertices.size() + 1; )
    {
      Vector2d p1 = getVertexCircular(v-1);
      Vector2d p2 = getVertexCircular(v); 
      Vector2d p3 = getVertexCircular(v+1);

      Vector2d v1 = (p2-p1);
      Vector2d v2 = (p3-p2);

      if (v1.lengthSquared() == 0 || v2.lengthSquared() == 0) 
	{
	  vertices.erase(vertices.begin()+(v % vertices.size()));	  
	  if (vertices.size() < 1) break;
	}
      else
	{
	  v1.normalize();
	  v2.normalize();
	  if ((v1-v2).lengthSquared() < maxerror)
	    {
	      vertices.erase(vertices.begin()+(v % vertices.size()));
	      if (vertices.size() < 1) break;
	    }
	  else
	    v++;
	}
    }
}
示例#4
0
/*
 * Iterate the vertices, and calculate whether this
 * shape is a hole or enclosed, based on whether the
 * segment normals point outward (a hole) or inward
 * (enclosing)
 */
void Poly::calcHole() const // hole is mutable
{
  	if(vertices.size() < 3)
	  return;	// hole is undefined
	Vector2d p(-INFTY, -INFTY);
	int v=0;
	center = Vector2d(0,0);
	Vector2d q;
	for(size_t vert=0;vert<vertices.size();vert++)
	{
	  q = vertices[vert];
	  center += q;
	  if(q.x() > p.x())
	    {
	      p = q;
	      v=vert;
	    }
	  else if(q.x() == p.x() && q.y() > p.y())
	    {
	      p.y() = q.y();
	      v=vert;
	    }
	}
	center /= vertices.size();

	// we have the x-most vertex (with the highest y if there was a contest), v
	Vector2d V1 = getVertexCircular(v-1);
	Vector2d V2 = getVertexCircular(v);
	Vector2d V3 = getVertexCircular(v+1);

	// Vector2d Va=V2-V1;
	// Vector2d Vb=V3-V2;
	hole = isleftof(V2, V3, V1); //cross(Vb,Va) > 0;
	holecalculated = true;
}
示例#5
0
文件: poly.cpp 项目: atoun/repsnapper
// add to lines starting with given index
// closed lines sequence if number of vertices > 2
void Poly::getLines(vector<Vector2d> &lines, uint startindex) const
{
  size_t count = vertices.size();
  if (count<2) return; // one point no line
  if (count<3) count--; // two points one line

  for(size_t i=0;i<count;i++)
    {
      lines.push_back(getVertexCircular(i+startindex));
      lines.push_back(getVertexCircular(i+startindex+1));
    }
}
示例#6
0
vector<InFillHit> Poly::lineIntersections(const Vector2d P1, const Vector2d P2,
					  double maxerr) const
{
  vector<InFillHit> HitsBuffer;
  Vector2d P3,P4;
  for(size_t i = 0; i < vertices.size(); i++)
    {  
      P3 = getVertexCircular(i);
      P4 = getVertexCircular(i+1);
      InFillHit hit;
      if (IntersectXY (P1,P2,P3,P4,hit,maxerr))
	HitsBuffer.push_back(hit);
    }
  return HitsBuffer;
}
示例#7
0
vector<Vector2d> Poly::getCenterline() const
{
  vector<Vector2d> line;
  for (uint i=0; i < vertices.size(); i++){
    Vector2d abp = angle_bipartition(vertices[i],
				     getVertexCircular(i-1), getVertexCircular(i+1));

    // int intersect2D_Segments( const Vector2d &p1, const Vector2d &p2,
    // 			      const Vector2d &p3, const Vector2d &p4,
    // 			      Vector2d &I0, Vector2d &I1,
    // 			      double &t0, double &t1,
    // 			      double maxerr)
  }
  return line;
}
示例#8
0
bool Poly::vertexInside2(const Vector2d &point, double maxoffset) const
{
  // Shoot a ray along +X and count the number of intersections.
  // If n_intersections is even, return false, else return true
  Vector2d EndP(point.x()+10000, point.y());
  int intersectcount = 1; // we want to test if uneven
  double maxoffsetSq = maxoffset*maxoffset;
  Vector2d dummy;
  for(size_t i=0; i<vertices.size();i++)
    {
      const Vector2d P1 = getVertexCircular(i-1);
      const Vector2d P2 = vertices[i];

      if (point_segment_distance_Sq(point, P1, P2, dummy) <= maxoffsetSq) return true;

      // Skip horizontal lines, we can't intersect with them,
      // because the test line is horizontal
      if(P1.y() == P2.y())
	continue;

      Intersection hit;
      if(IntersectXY(point,EndP,P1,P2,hit,maxoffset))
	intersectcount++;
    }
  return (intersectcount%2==0);
}
示例#9
0
// add to lines starting with given index
// closed lines sequence if number of vertices > 2 and poly is closed
void Poly::makeLines(vector<Vector2d> &lines, uint startindex) const
{
  size_t count = vertices.size();
  if (count<2) return; // one point no line
  bool closedlines = closed;
  if (count<3) closedlines = false; // two points one line
  vector<Vector2d> mylines;
  for(size_t i = startindex; i < count+startindex; i++)
    {
      if (!closedlines && i == count-1) continue;
      mylines.push_back(getVertexCircular(i));
      mylines.push_back(getVertexCircular(i+1));
    }
  if (!closedlines && startindex == count-1)
    lines.insert(lines.end(),mylines.rbegin(),mylines.rend());
  else
    lines.insert(lines.end(),mylines.begin(),mylines.end());
}
示例#10
0
// returns length and two points
double Poly::shortestConnectionSq(const Poly &p2, Vector2d &start, Vector2d &end) const
{
    double min1 = 100000000, min2 = 100000000;
    int minindex1=0, minindex2=0;
    Vector2d onpoint1, onpoint2;
    // test this vertices
    for (uint i = 0; i < vertices.size(); i++) {
        for (uint j = 0; j < p2.vertices.size(); j++) {
            Vector2d onpoint; // on p2
            // dist from point i to lines on p2
            const double mindist =
                point_segment_distance_Sq(p2.vertices[j], p2.getVertexCircular(j+1),
                                          vertices[i], onpoint);
            if (mindist < min1) {
                min1 = mindist;
                onpoint1 = onpoint;
                minindex1 = i;
            }
        }
    }
    // test p2 vertices
    for (uint i = 0; i < p2.vertices.size(); i++) {
        for (uint j = 0; j < vertices.size(); j++) {
            Vector2d onpoint; // on this
            // dist from p2 point i to lines on this
            const double mindist =
                point_segment_distance_Sq(vertices[j], getVertexCircular(j+1),
                                          p2.vertices[i], onpoint);
            if (mindist < min2) {
                min2 = mindist;
                onpoint2 = onpoint;
                minindex2 = i;
            }
        }
    }
    if (min1 < min2) { // this vertex, some point on p2 lines
        start = getVertexCircular(minindex1);
        end = onpoint1;
    } else { // p2 vertex, some point of this lines
        start = p2.getVertexCircular(minindex2);
        end = onpoint2;
    }
    return (end-start).squared_length();
}
示例#11
0
vector<Vector2d> Poly::getPathAround(const Vector2d &from, const Vector2d &to) const
{
  double dist;
  vector<Vector2d> path1, path2;
  // Poly off = Clipping::getOffset(*this, 0, jround).front();
  //cerr << size()<<  " Off " << off.size()<< endl;
  int nvert = size();
  if (nvert==0) return path1;
  int fromind = (int)nearestDistanceSqTo(from, dist);
  int toind = (int)nearestDistanceSqTo(to, dist);
  if (fromind==toind) {
    path1.push_back(vertices[fromind]);
    return path1;
  }
  //calc both direction paths
  if(fromind < toind) {
    for (int i=fromind; i<=toind; i++)
      path1.push_back(getVertexCircular(i));
    for (int i=fromind+nvert; i>=toind; i--)
      path2.push_back(getVertexCircular(i));
  } else {
    for (int i=fromind; i>=toind; i--)
      path1.push_back(getVertexCircular(i));
    for (int i=fromind; i<=toind+nvert; i++)
      path2.push_back(getVertexCircular(i));
  }
  // find shorter one
  double len1=0,len2=0;
  for (uint i=1; i<path1.size(); i++)
    len1+=(path1[i]-path1[i-1]).squared_length();
  for (uint i=1; i<path2.size(); i++)
    len2+=(path2[i]-path2[i-1]).squared_length();
  if (len1 < len2) {
     // path1.insert(path1.begin(),from);
     // path1.push_back(to);
    return path1;
  }
  else{
     // path2.insert(path2.begin(),from);
     // path2.push_back(to);
    return path2;
  }
}
示例#12
0
文件: poly.cpp 项目: atoun/repsnapper
vector<Intersection> Poly::lineIntersections(const Vector2d P1, const Vector2d P2,
					     double maxerr) const
{
  vector<Intersection> HitsBuffer;
  Vector2d P3,P4;
  for(size_t i = 0; i < vertices.size(); i++)
    {  
      P3 = getVertexCircular(i);
      P4 = getVertexCircular(i+1);
      Intersection hit;
      if (IntersectXY(P1,P2,P3,P4,hit,maxerr))
	HitsBuffer.push_back(hit);
    }
  // std::sort(HitsBuffer.begin(),HitsBuffer.end());
  // vector<Vector2d> v(HitsBuffer.size());
  // for(size_t i = 0; i < v.size(); i++)
  //   v[i] = HitsBuffer[i].p;
  return HitsBuffer;
}
示例#13
0
void Poly::draw(int gl_type, double z) const
{
  Vector2d v;
  uint count = vertices.size();
  glBegin(gl_type);	  
  for (uint i=0;i < count;i++){
    v = getVertexCircular(i);
    glVertex3f(v.x,v.y,z);
  }
  glEnd();
}
示例#14
0
文件: poly.cpp 项目: phord/repsnapper
void Poly::draw(int gl_type, double z, bool randomized) const
{
  Vector2d v;
  uint count = vertices.size();
  glBegin(gl_type);	  
  for (uint i=0;i < count;i++){
    v = getVertexCircular(i);
    if (randomized) v = random_displace(v);
    glVertex3f(v.x,v.y,z);
  }
  glEnd();
}
示例#15
0
文件: poly.cpp 项目: phord/repsnapper
// http://paulbourke.net/geometry/insidepoly/
// not really working
bool Poly::vertexInside2(const Vector2d p, double maxoffset) const
{
  uint c = false;
  //Poly off = Clipping::getOffset(*this,maxoffset).front();
  for (uint i = 0; i < vertices.size();  i++) {
    Vector2d Pi = vertices[i];
    Vector2d Pj = getVertexCircular(i+1);
    if ( ((Pi.y > p.y) != (Pj.y > p.y)) &&
	 (abs(p.x - (Pj.x-Pi.x) * (p.y-Pi.y) / (Pj.y-Pj.y) + Pi.x) > maxoffset) )
      c = !c;
  }
  if (!c) 
    for (uint i = 0; i < vertices.size();  i++) 
      if ((vertices[i]-p).length() < maxoffset) return true; // on a vertex    
  return c;
}
示例#16
0
// http://paulbourke.net/geometry/insidepoly/
bool Poly::vertexInside(const Vector2d &p, double maxoffset) const
{
#define POLYINSIDEVERSION 0
#if POLYINSIDEVERSION==0
  // this one works
  uint N = size();
  if (N < 2) return false;
  uint counter = 0;
  uint i;
  double xinters;
  const Vector2d *p1, *p2;
  p1 = &(vertices[0]);
  for (i=1;i<=N;i++) {
    p2 = &(vertices[i % N]);
    if (p.y() > min(p1->y(), p2->y())) {
      if (p.y() <= max(p1->y(), p2->y())) {
        if (p.x() <= max(p1->x(), p2->x())) {
          if (p1->y() != p2->y()) {
            xinters = (p.y()-p1->y())*(p2->x()-p1->x())/(p2->y()-p1->y())+p1->x();
            if (p1->x() == p2->x() || p.x() <= xinters)
              counter++;
          }
        }
      }
    }
    p1 = p2;
  }
  return (counter % 2 != 0);
#else
  // not really working?
  bool c = false;
  //Poly off = Clipping::getOffset(*this,maxoffset).front();
  for (uint i = 0; i < vertices.size();  i++) {
    const Vector2d Pi = vertices[i];
    const Vector2d Pj = getVertexCircular(i+1);
    if ( ((Pi.y() > p.y()) != (Pj.y() > p.y())) &&
	 (abs(p.x() - (Pj.x()-Pi.x())
	      * (p.y()-Pi.y()) / (Pj.y()-Pi.y()) + Pi.x()) > maxoffset) )
      c = !c;
  }
  if (!c)
    for (uint i = 0; i < vertices.size();  i++)
      if ((vertices[i]-p).length() < maxoffset) return true; // on a vertex
  return c;
#endif
}
示例#17
0
文件: poly.cpp 项目: phord/repsnapper
bool Poly::vertexInside(const Vector2d point, double maxoffset) const
{
  // Shoot a ray along +X and count the number of intersections.
  // If n_intersections is even, return false, else return true
  Vector2d EndP(point.x+10000, point.y);
  int intersectcount = 1; // we want to test if uneven

  for(size_t i=0; i<vertices.size();i++)
    {
      Vector2d P1 = getVertexCircular(i-1);
      Vector2d P2 = vertices[i];
                   
      // Skip horizontal lines, we can't intersect with them, 
      // because the test line is horizontal
      if(P1.y == P2.y)      
	continue;
      
      Intersection hit;
      if(IntersectXY(point,EndP,P1,P2,hit,maxoffset))
	intersectcount++;
    }
  return intersectcount%2;
}
示例#18
0
Vector3d Poly::getVertexCircular3(int pointindex) const
{
  Vector2d v = getVertexCircular(pointindex);
  return Vector3d(v.x(),v.y(),z);
}
示例#19
0
double Poly::angleAtVertex(uint i) const
{
  return angleBetween(getVertexCircular(i)-getVertexCircular(i-1),
		      getVertexCircular(i+1)-getVertexCircular(i));
}
示例#20
0
// length of the line starting at startindex
double Poly::getLinelengthSq(uint startindex) const
{
  const double length = (getVertexCircular(startindex+1) -
			 getVertexCircular(startindex)).squared_length();
  return length;
}