public override void Line0(LineParameters lp) { if (doClipping) { int x1 = lp.x1; int y1 = lp.y1; int x2 = lp.x2; int y2 = lp.y2; int flags = ClipLiangBarsky.ClipLineSegment(ref x1, ref y1, ref x2, ref y2, clippingRectangle); if ((flags & 4) == 0) { if (flags != 0) { LineParameters lp2 = new LineParameters(x1, y1, x2, y2, AggBasics.uround(AggMath.calc_distance(x1, y1, x2, y2))); Line0NoClip(lp2); } else { Line0NoClip(lp); } } } else { Line0NoClip(lp); } }
public bool IsEqual(VertexDistance val) { bool ret = (dist = AggMath.calc_distance(x, y, val.x, val.y)) > AggMath.VERTEX_DISTANCE_EPSILON; if (!ret) { dist = 1.0 / AggMath.VERTEX_DISTANCE_EPSILON; } return(ret); }
public override void Line3(LineParameters lp, int sx, int sy, int ex, int ey) { if (doClipping) { int x1 = lp.x1; int y1 = lp.y1; int x2 = lp.x2; int y2 = lp.y2; int flags = ClipLiangBarsky.ClipLineSegment(ref x1, ref y1, ref x2, ref y2, clippingRectangle); if ((flags & 4) == 0) { if (flags != 0) { LineParameters lp2 = new LineParameters(x1, y1, x2, y2, AggBasics.uround(AggMath.calc_distance(x1, y1, x2, y2))); if ((flags & 1) != 0) { sx = x1 + (y2 - y1); sy = y1 - (x2 - x1); } else { while (Math.Abs(sx - lp.x1) + Math.Abs(sy - lp.y1) > lp2.len) { sx = (lp.x1 + sx) >> 1; sy = (lp.y1 + sy) >> 1; } } if ((flags & 2) != 0) { ex = x2 + (y2 - y1); ey = y2 - (x2 - x1); } else { while (Math.Abs(ex - lp.x2) + Math.Abs(ey - lp.y2) > lp2.len) { ex = (lp.x2 + ex) >> 1; ey = (lp.y2 + ey) >> 1; } } Line3NoClip(lp2, sx, sy, ex, ey); } else { Line3NoClip(lp, sx, sy, ex, ey); } } } else { Line3NoClip(lp, sx, sy, ex, ey); } }
//-------------------------------------------------------------------- // Join path. The path is joined with the existing one, that is, // it behaves as if the pen of a plotter was always down (drawing) //template<class VertexSource> public void JoinPath(VertexStoreSnap s) { double x, y; var snapIter = s.GetVertexSnapIter(); VertexCmd cmd = snapIter.GetNextVertex(out x, out y); if (cmd == VertexCmd.Stop) { return; } if (VertexHelper.IsVertextCommand(cmd)) { double x0, y0; VertexCmd flags0 = GetLastVertex(out x0, out y0); if (VertexHelper.IsVertextCommand(flags0)) { if (AggMath.calc_distance(x, y, x0, y0) > AggMath.VERTEX_DISTANCE_EPSILON) { if (VertexHelper.IsMoveTo(cmd)) { cmd = VertexCmd.LineTo; } myvxs.AddVertex(x, y, cmd); } } else { if (VertexHelper.IsEmpty(flags0)) { cmd = VertexCmd.MoveTo; } else { if (VertexHelper.IsMoveTo(cmd)) { cmd = VertexCmd.LineTo; } } myvxs.AddVertex(x, y, cmd); } } while ((cmd = snapIter.GetNextVertex(out x, out y)) != VertexCmd.Stop) { myvxs.AddVertex(x, y, VertexHelper.IsMoveTo(cmd) ? VertexCmd.LineTo : cmd); } }
public bool IsEqual(Vertex2d val) { return(AggMath.calc_distance(x, y, val.x, val.y) <= AggMath.VERTEX_DISTANCE_EPSILON); //if ((dist = AggMath.calc_distance(x, y, val.x, val.y)) > AggMath.VERTEX_DISTANCE_EPSILON) //{ // //diff enough=> this is NOT equal with val // return false; //} //else //{ // //not diff enough => this is equal (with val) // dist = 1.0 / AggMath.VERTEX_DISTANCE_EPSILON; // return true; //} }
void ClearCollectedTmpPoints(out double tmp_expectedLen) { //clear all previous collected points int j = _tempPoints.Count; tmp_expectedLen = 0; if (j > 0) { tmp_expectedLen = _expectedSegmentLen; for (int i = 0; i < j;) { //p0-p1 TmpPoint p0 = _tempPoints[i]; TmpPoint p1 = _tempPoints[i + 1]; //------------------------------- //a series of connected line //if ((_nextMarkNo % 2) == 1) //{ // if (i == 0) // { // //move to // _output.AddMoveTo(p0.x, p0.y); // } // _output.AddLineTo(p1.x, p1.y); //} if (i == 0) { //1st move to _currentMarker.lineSegDel(_output, VertexCmd.MoveTo, p0.x, p0.y); } _currentMarker.lineSegDel(_output, VertexCmd.LineTo, p1.x, p1.y); //------------------------------- double len = AggMath.calc_distance(p0.x, p0.y, p1.x, p1.y); tmp_expectedLen -= len; i += 2; _latest_X = p1.x; _latest_Y = p1.y; } //------------ _tempPoints.Clear(); } //----------------- }
public void LineTo(double x1, double y1) { switch (_state) { default: throw new NotSupportedException(); case WalkState.Init: _state = WalkState.PolyLine; goto case WalkState.PolyLine; case WalkState.PolyLine: { //clear prev segment len //find line segment length double new_remaining_len = AggMath.calc_distance(_latest_X, _latest_Y, x1, y1); //check current gen state //find angle double angle = Math.Atan2(y1 - _latest_Y, x1 - _latest_X); double sin = Math.Sin(angle); double cos = Math.Cos(angle); double new_x, new_y; OnBeginLineSegment(sin, cos, ref new_remaining_len); while (new_remaining_len >= _expectedSegmentLen) { //we can create a new segment new_x = _latest_X + (_expectedSegmentLen * cos); new_y = _latest_Y + (_expectedSegmentLen * sin); new_remaining_len -= _expectedSegmentLen; //each segment has its own line production procedure //eg. OnSegment(new_x, new_y); //-------------------- _latest_Y = new_y; _latest_X = new_x; } //set on corner OnEndLineSegment(x1, y1, new_remaining_len); } break; } }
void ClearCollectedTmpPoints(out double tmp_expectedLen) { //clear all previous collected points int j = _tempPoints.Count; tmp_expectedLen = 0; if (j > 0) { tmp_expectedLen = _expectedSegmentLen; for (int i = 0; i < j;) { //p0-p1 VectorMath.Vector2 p0 = _tempPoints[i]; VectorMath.Vector2 p1 = _tempPoints[i + 1]; //------------------------------- //a series of connected line if (i == 0) { //1st move to _currentMark.InvokeMoveTo(_output, p0.x, p0.y); } _currentMark.InvokeLineTo(_output, p1.x, p1.y); //------------------------------- double len = AggMath.calc_distance(p0.x, p0.y, p1.x, p1.y); tmp_expectedLen -= len; i += 2; _latest_X = p1.x; _latest_Y = p1.y; } _tempPoints.Clear(); } //----------------- }
public double CalLen(Vertex2d another) { return(AggMath.calc_distance(x, y, another.x, another.y)); }
void CreateMiter(VertexStore output, Vertex2d v0, Vertex2d v1, Vertex2d v2, double dx1, double dy1, double dx2, double dy2, LineJoin lj, double mlimit, double dbevel) { double xi = v1.x; double yi = v1.y; double di = 1; double lim = m_width_abs * mlimit; bool miter_limit_exceeded = true; // Assume the worst bool intersection_failed = true; // Assume the worst if (AggMath.CalcIntersect(v0.x + dx1, v0.y - dy1, v1.x + dx1, v1.y - dy1, v1.x + dx2, v1.y - dy2, v2.x + dx2, v2.y - dy2, out xi, out yi)) { // Calculation of the intersection succeeded //--------------------- di = AggMath.calc_distance(v1.x, v1.y, xi, yi); if (di <= lim) { // Inside the miter limit //--------------------- AddVertex(output, xi, yi); miter_limit_exceeded = false; } intersection_failed = false; } else { // Calculation of the intersection failed, most probably // the three points lie one straight line. // First check if v0 and v2 lie on the opposite sides of vector: // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular // to the line determined by vertices v0 and v1. // This condition determines whether the next line segments continues // the previous one or goes back. //---------------- double x2 = v1.x + dx1; double y2 = v1.y - dy1; if ((AggMath.Cross(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) == (AggMath.Cross(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0)) { // This case means that the next segment continues // the previous one (straight line) //----------------- AddVertex(output, v1.x + dx1, v1.y - dy1); miter_limit_exceeded = false; } } if (miter_limit_exceeded) { // Miter limit exceeded //------------------------ switch (lj) { case LineJoin.MiterRevert: // For the compatibility with SVG, PDF, etc, // we use a simple bevel join instead of // "smart" bevel //------------------- AddVertex(output, v1.x + dx1, v1.y - dy1); AddVertex(output, v1.x + dx2, v1.y - dy2); break; case LineJoin.MiterRound: CreateArc(output, v1.x, v1.y, dx1, -dy1, dx2, -dy2); break; default: // If no miter-revert, calculate new dx1, dy1, dx2, dy2 //---------------- if (intersection_failed) { mlimit *= m_width_sign; AddVertex(output, v1.x + dx1 + dy1 * mlimit, v1.y - dy1 + dx1 * mlimit); AddVertex(output, v1.x + dx2 - dy2 * mlimit, v1.y - dy2 - dx2 * mlimit); } else { double x1 = v1.x + dx1; double y1 = v1.y - dy1; double x2 = v1.x + dx2; double y2 = v1.y - dy2; di = (lim - dbevel) / (di - dbevel); AddVertex(output, x1 + (xi - x1) * di, y1 + (yi - y1) * di); AddVertex(output, x2 + (xi - x2) * di, y2 + (yi - y2) * di); } break; } } }