Exemple #1
0
// return how many lines are removed 
guint Printlines::makeIntoArc(guint fromind, guint toind)
{
  if (toind < fromind || toind+1 > lines.size()) return 0;
  Vector2d P = lines[fromind].from;
  Vector2d Q = lines[toind].to;
  // center perp of start -- endpoint:
  Vector2d connp1,connp2;
  center_perpendicular(P, Q, connp1, connp2);  
  // center perp of midpoint -- endpoint:
  guint midind = (toind+fromind)/2;
  Vector2d midp1,midp2;
  center_perpendicular(lines[midind].from, lines[toind].to, midp1, midp2);
  // intersection = center
  Vector2d center, ip;
  double t0, t1;
  int is = intersect2D_Segments(connp1, connp2, midp1, midp2, 
   				center, ip, t0,t1);
  if (is > 0) {
    double angle = angleBetween(P-center, Q-center);
    bool ccw = isleftof(center, lines[fromind].from, lines[fromind].to);
    if (!ccw) angle = -angle;
    if (angle<=0) angle+=2*M_PI;
    short arctype = ccw ? -1 : 1; 
    PLine newline(P, Q, lines[fromind].speed, lines[fromind].feedrate,
		  arctype, center, angle);
    lines[fromind] = newline;
    lines.erase(lines.begin()+fromind+1, lines.begin()+toind+1);
    return toind-fromind;
  } else cerr << "no Intersection of arc perpendiculars!" << endl;
  return 0;
}
Exemple #2
0
// calculates intersection and checks for parallel lines.
// also checks that the intersection point is actually on
// the line segment p1-p2
bool IntersectXY(const Vector2d &p1, const Vector2d &p2, 
		 const Vector2d &p3, const Vector2d &p4, InFillHit &hit,
		 double maxoffset)
{
	// BBOX test
	if(MIN(p1.x,p2.x) > MAX(p3.x,p4.x))
		return false;
	if(MAX(p1.x,p2.x) < MIN(p3.x,p4.x))
		return false;
	if(MIN(p1.y,p2.y) > MAX(p3.y,p4.y))
		return false;
	if(MAX(p1.y,p2.y) < MIN(p3.y,p4.y))
		return false;


	if(ABS(p1.x-p3.x) < maxoffset && ABS(p1.y - p3.y) < maxoffset)
	{
		hit.p = p1;
		hit.d = (p1-hit.p).length();
		hit.t = 0.0;
		return true;
	}
	if(ABS(p2.x-p3.x) < maxoffset && ABS(p2.y - p3.y) < maxoffset)
	{
		hit.p = p2;
		hit.d = (p1-hit.p).length();
		hit.t = 1.0;
		return true;
	}
	if(ABS(p1.x-p4.x) < maxoffset && ABS(p1.y - p4.y) < maxoffset)
	{
		hit.p = p1;
		hit.d = (p1-hit.p).length();
		hit.t = 0.0;
		return true;
	}
	if(ABS(p2.x-p4.x) < maxoffset && ABS(p2.y - p4.y) < maxoffset)
	{
		hit.p = p2;
		hit.d = (p1-hit.p).length();
		hit.t = 1.0;
		return true;
	}

	InFillHit hit2;
	double t0,t1;
	if(intersect2D_Segments(p1,p2,p3,p4,hit.p, hit2.p, t0,t1) == 1)
	{
	  hit.d = (p1-hit.p).length();
	  hit.t = t0;
	  return true;
	}
	return false;
}
Exemple #3
0
// Check the segments p1-p2 and p3-p4 for intersection,
// If the segments intersection, the intersection
// also checks that the intersection point is actually on
// the line segment p1-p2
bool IntersectXY(const Vector2d &p1, const Vector2d &p2,
		 const Vector2d &p3, const Vector2d &p4,
		 Intersection &hit, double maxoffset)
{
  Vector2d inter2;
  int is = intersect2D_Segments(p1,p2,p3,p4, hit.p, inter2);
  if (is > 0 && is < 3)
    {
      hit.d = (p1-hit.p).length();
      return true;
    }
  return false;
}
Exemple #4
0
// gets center of common arc of 2 lines if radii match inside maxSqerr range
Vector2d Printlines::arcCenter(const PLine l1, const PLine l2,
			       double maxSqerr) const
{
  Vector2d l1p1,l1p2;
  center_perpendicular(l1.from, l1.to, l1p1, l1p2);
  Vector2d l2p1,l2p2;
  center_perpendicular(l2.from, l2.to, l2p1, l2p2);
  Vector2d center, ip;
  double t0, t1;
  int is = intersect2D_Segments(l1p1, l1p2, l2p1, l2p2,
   				center, ip, t0,t1);
  if (is > 0) {
    // radii match?
    if (abs((l1p1-center).lengthSquared() -
	    (l2p1-center).lengthSquared()) < maxSqerr)
      return center;
  }
  return Vector2d(10000000,10000000);
}
Exemple #5
0
bool Shape::getPolygonsAtZ(const Matrix4d &T, double z,
			   vector<Poly> &polys,
			   double &max_gradient,
			   vector<Poly> &supportpolys,
			   double max_supportangle,
			   double thickness) const
{
  vector<Vector2d> vertices;
  vector<Triangle> support_triangles;
  vector<Segment> lines = getCutlines(T, z, vertices, max_gradient,
				      support_triangles, max_supportangle, thickness);
  //cerr << vertices.size() << " " << lines.size() << endl;
  if (!CleanupSharedSegments(lines)) return false;
  //cerr << vertices.size() << " " << lines.size() << endl;
  if (!CleanupConnectSegments(vertices,lines,true)) return false;
  //cerr << vertices.size() << " " << lines.size() << endl;
  vector< vector<uint> > connectedlines; // sequence of connected lines indices
  if (!getLineSequences(lines, connectedlines)) return false;
  for (uint i=0; i<connectedlines.size();i++){
    Poly poly(z);
    for (uint j = 0; j < connectedlines[i].size();j++){
      poly.addVertex(vertices[lines[connectedlines[i][j]].start]);
    }
    if (lines[connectedlines[i].back()].end !=
	lines[connectedlines[i].front()].start )
      poly.addVertex(vertices[lines[connectedlines[i].back()].end]);
    //cerr << "poly size " << poly.size() << endl;
    poly.calcHole();
    polys.push_back(poly);
  }

  for (uint i = 0; i < support_triangles.size(); i++) {
    Poly p(z);
    // keep only part of triangle above z
    Vector2d lineStart;
    Vector2d lineEnd;
    // support_triangles are already transformed
    int num_cutpoints = support_triangles[i].CutWithPlane(z, Matrix4d::IDENTITY,
							  lineStart, lineEnd);
    if (num_cutpoints == 0) {
      for (uint j = 0; j < 3; j++) {
	p.addVertex(Vector2d(support_triangles[i][j].x(),
			     support_triangles[i][j].y()));
      }
    }
    else if (num_cutpoints > 1) {
      // add points of triangle above z
      for (uint j = 0; j < 3; j++) {
	if (support_triangles[i][j].z() > z) {
	  p.addVertex(Vector2d(support_triangles[i][j].x(),
			       support_triangles[i][j].y()));
	}
      }
      bool reverse = false;
      // test for order if we get 4 points (2 until now)
      if (p.size() > 1) {
	Vector2d i0, i1;
	const int is = intersect2D_Segments(p[1], lineStart, lineEnd, p[0],
					    i0, i1);
	if (is > 0 && is < 3) {
	  reverse = true;
	}
      }
      // add cutline points
      if (reverse) {
	p.addVertex(lineEnd);
	p.addVertex(lineStart);
      } else {
	p.addVertex(lineStart);
	p.addVertex(lineEnd);
      }
    }
    if (p.isHole()) p.reverse();
    supportpolys.push_back(p);
  }

  // remove polygon areas from triangles
  // Clipping clipp;
  // clipp.clear();
  // clipp.addPolys(supportpolys, subject);
  // clipp.addPolys(polys, clip);
  // supportpolys = clipp.subtract(CL::pftPositive,CL::pftPositive);

  return true;
}
Exemple #6
0
// calculates intersection and checks for parallel lines.
// also checks that the intersection point is actually on
// the line segment p1-p2
bool IntersectXY(const Vector2f &p1, const Vector2f &p2, const Vector2f &p3, const Vector2f &p4, InFillHit &hit)
{
	// BBOX test
	if(MIN(p1.x,p2.x) > MAX(p3.x,p4.x))
		return false;
	if(MAX(p1.x,p2.x) < MIN(p3.x,p4.x))
		return false;
	if(MIN(p1.y,p2.y) > MAX(p3.y,p4.y))
		return false;
	if(MAX(p1.y,p2.y) < MIN(p3.y,p4.y))
		return false;


	if(ABS(p1.x-p3.x) < 0.01 && ABS(p1.y - p3.y) < 0.01)
	{
		hit.p = p1;
		hit.d = sqrtf( (p1.x-hit.p.x) * (p1.x-hit.p.x) + (p1.y-hit.p.y) * (p1.y-hit.p.y));
		hit.t = 0.0f;
		return true;
	}
	if(ABS(p2.x-p3.x) < 0.01 && ABS(p2.y - p3.y) < 0.01)
	{
		hit.p = p2;
		hit.d = sqrtf( (p1.x-hit.p.x) * (p1.x-hit.p.x) + (p1.y-hit.p.y) * (p1.y-hit.p.y));
		hit.t = 1.0f;
		return true;
	}
	if(ABS(p1.x-p4.x) < 0.01 && ABS(p1.y - p4.y) < 0.01)
	{
		hit.p = p1;
		hit.d = sqrtf( (p1.x-hit.p.x) * (p1.x-hit.p.x) + (p1.y-hit.p.y) * (p1.y-hit.p.y));
		hit.t = 0.0f;
		return true;
	}
	if(ABS(p2.x-p4.x) < 0.01 && ABS(p2.y - p4.y) < 0.01)
	{
		hit.p = p2;
		hit.d = sqrtf( (p1.x-hit.p.x) * (p1.x-hit.p.x) + (p1.y-hit.p.y) * (p1.y-hit.p.y));
		hit.t = 1.0f;
		return true;
	}

	InFillHit hit2;
	float t0,t1;
	if(intersect2D_Segments(p1,p2,p3,p4,hit.p, hit2.p, t0,t1) == 1)
	{
	hit.d = sqrtf( (p1.x-hit.p.x) * (p1.x-hit.p.x) + (p1.y-hit.p.y) * (p1.y-hit.p.y));
	hit.t = t0;
	return true;
	}
	return false;
/*

  float xD1,yD1,xD2,yD2,xD3,yD3;
  float dot,deg,len1,len2;
  float segmentLen1,segmentLen2;
  float ua,ub,div;

  // calculate differences
  xD1=p2.x-p1.x;
  xD2=p4.x-p3.x;
  yD1=p2.y-p1.y;
  yD2=p4.y-p3.y;
  xD3=p1.x-p3.x;
  yD3=p1.y-p3.y;

  // calculate the lengths of the two lines
  len1=sqrt(xD1*xD1+yD1*yD1);
  len2=sqrt(xD2*xD2+yD2*yD2);

  // calculate angle between the two lines.
  dot=(xD1*xD2+yD1*yD2); // dot product
  deg=dot/(len1*len2);

  // if ABS(angle)==1 then the lines are parallel,
  // so no intersection is possible
  if(ABS(deg)==1)
	  return false;

  // find intersection Pt between two lines
  hit.p=Vector2f (0,0);
  div=yD2*xD1-xD2*yD1;
  ua=(xD2*yD3-yD2*xD3)/div;
  ub=(xD1*yD3-yD1*xD3)/div;
  hit.p.x=p1.x+ua*xD1;
  hit.p.y=p1.y+ua*yD1;

  // calculate the combined length of the two segments
  // between Pt-p1 and Pt-p2
  xD1=hit.p.x-p1.x;
  xD2=hit.p.x-p2.x;
  yD1=hit.p.y-p1.y;
  yD2=hit.p.y-p2.y;
  segmentLen1=sqrt(xD1*xD1+yD1*yD1)+sqrt(xD2*xD2+yD2*yD2);

  // calculate the combined length of the two segments
  // between Pt-p3 and Pt-p4
  xD1=hit.p.x-p3.x;
  xD2=hit.p.x-p4.x;
  yD1=hit.p.y-p3.y;
  yD2=hit.p.y-p4.y;
  segmentLen2=sqrt(xD1*xD1+yD1*yD1)+sqrt(xD2*xD2+yD2*yD2);

  // if the lengths of both sets of segments are the same as
  // the lenghts of the two lines the point is actually
  // on the line segment.

  // if the point isn't on the line, return null
  if(ABS(len1-segmentLen1)>0.00 || ABS(len2-segmentLen2)>0.00)
    return false;

  hit.d = segmentLen1-segmentLen2;
  return true;*/
}
Exemple #7
0
	void Line2f::CleanOutLine(list<Line2f>& outline, float minDist2)
	{
		Line2f* last = &outline.back();
		bool done = false;
		int idx = 0;
		if (outline.begin() == outline.end())
		  return;
		for(list<Line2f>::iterator pIt = outline.begin(); !done; )
		{
			Vector2f Va = last->vertices.back();
			Vector2f Vb = pIt->vertices.front();

			Vector2f Na = last->src;
			Vector2f Nb = pIt->src;

			float Ao = atan2f(Na.y-Nb.y, Na.x-Nb.x);
			float Aa = atan2f(Va.y-Nb.y, Va.x-Nb.x);
			float Ab = atan2f(Vb.y-Nb.y, Vb.x-Nb.x);

			if( IsAngleInBetween(Aa, Ab, Ao) )
			{
				Vector2f ip0;
				Vector2f ip1;
				float t0;
				float t1;

				if( last->vertices.size() > 1 )
				{
					Vector2f Pa = pIt->src;
					list<Line2f>::iterator pIt2 = pIt;
					GoNext(outline, pIt2);
					Vector2f Pb = pIt2->src;

					while( last->vertices.size() > 1 )
					{
						Vb = *(--(--last->vertices.end()));
						if( linePointDist2D_Segments2(Pa, Pb, Vb) < minDist2 )
						{
							Va = Vb;
							last->vertices.pop_back();
						}
						else
						{
							break;
						}
					}
				}

				if( last->vertices.size() > 1 )
				{
					Vb = *(--(--last->vertices.end()));
					Nb = last->src;
				}
				else
				{
					list<Line2f>::iterator pIt2 = pIt;
					GoPrev(outline, pIt2);
					GoPrev(outline, pIt2);
					Vb = pIt2->vertices.back();
					Nb = pIt2->src;
				}
				// TODO flawed logic here, we wish to extend Va so that the segment Va-Vb is perpendicular to Va-Nb
				float OrigLength = (Nb-Na).length();
				float TransLength = (Vb-Va).length();
				if( OrigLength > TransLength )
				{
					Va = Vb+(Va-Vb)*(OrigLength/TransLength);
				}


				int intersectionPoints = 0;
				while( intersectionPoints == 0)
				{
					Vector2f Pa = pIt->src;
					Na = pIt->vertices.front();
					if( pIt->vertices.size() > 1 )
					{
						pIt->vertices.pop_front();
						Nb = pIt->vertices.front();
		
						list<Line2f>::iterator pIt2 = pIt;
						GoPrev(outline, pIt2);
						Pa = pIt2->src;
					}
					else
					{
						pIt = outline.erase(pIt);
						if( pIt == outline.end() )
						{
							if( outline.size() == 0) return; // this outline shrank to death
							done = true;
							pIt = outline.begin();
						}
						Nb = pIt->vertices.front();
					}
					Vector2f Pb = pIt->src;

					// TODO flawed logic here, we wish to extend Na so that the segment Na-Nb is perpendicular to Na-Pa
					OrigLength = (Pb-Pa).length();
					TransLength = (Nb-Na).length();
					if( OrigLength > TransLength )
					{
						Na = Nb+(Na-Nb)*(OrigLength/TransLength);
					}
					
					intersectionPoints = intersect2D_Segments(Vb, Va, Na, Nb, ip0, ip1, t0, t1);
					switch( intersectionPoints )
					{
					case 0:
						// just loop again.
						break;
					case 1:
						last->vertices.back() = ip0;
						break;
					case 2:
						// this should be impossible, but floating point precision will probably make us end up here.
						assert("If this assertion ever happen, go into the CleanOutLine and remove it. You can safely ignore it and continue!");
						break; 
					}
				}
			}
			last = &(*pIt);
			pIt++;
			done = done || pIt == outline.end();
			idx++;
		}
	}