//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 15JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Strokes the outline of a IShape using the settings of the current * Graphics2D context. * @param brush the brush used to fill the shape. * @param shape the IShape to be rendered. */ public void Fill(Brush brush, IShape shape) { if (brush != null) { _graphicsFP.SetBrush(brush._wrappedBrushFP); _defaultBrush = brush; } PathIterator pathIterator = shape.GetPathIterator(null); int[] coords = new int[6]; GraphicsPathFP graphicsPathFP = new GraphicsPathFP(); PointFP pointFP1 = new PointFP(); PointFP pointFPCtl1 = new PointFP(); PointFP pointFPCtl2 = new PointFP(); while (!pathIterator.IsDone()) { int type = pathIterator.CurrentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddMoveTo(pointFP1); break; case PathIterator.SEG_CLOSE: graphicsPathFP.AddClose(); break; case PathIterator.SEG_LINETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddLineTo(pointFP1); break; case PathIterator.SEG_QUADTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddQuadTo(pointFPCtl1, pointFP1); break; case PathIterator.SEG_CUBICTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFPCtl2.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[4] << SingleFP.DECIMAL_BITS, coords[5] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddCurveTo(pointFPCtl1, pointFPCtl2, pointFP1); break; } pathIterator.Next(); } _graphicsFP.FillPath(graphicsPathFP); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Get the head outline. * @param ff_rad * @return */ public LineFP GetHeadOutline(int ffRad) { var p = new PointFP(Pt1.X - Pt2.X, Pt1.Y - Pt2.Y); var len = GetLength(); p.Reset(MathFP.Div(-p.Y, len), MathFP.Div(p.X, len)); p.Reset(MathFP.Mul(p.X, ffRad), MathFP.Mul(p.Y, ffRad)); return(new LineFP(Pt1.X - p.X, Pt1.Y - p.Y, Pt1.X + p.X, Pt1.Y + p.Y)); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 15JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Strokes the outline of a IShape using the settings of the current * Graphics2D context. * @param pen the pen used to stroke the shape. * @param shape the IShape to be rendered. */ public void Draw(Pen pen, IShape shape) { SetGraphicsFPPenAttribute(pen); PathIterator pathIterator = shape.GetPathIterator(null); int[] coords = new int[6]; GraphicsPathFP graphicsPathFP = new GraphicsPathFP(); PointFP pointFP1 = new PointFP(); PointFP pointFPCtl1 = new PointFP(); PointFP pointFPCtl2 = new PointFP(); while (!pathIterator.IsDone()) { int type = pathIterator.CurrentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddMoveTo(pointFP1); break; case PathIterator.SEG_CLOSE: graphicsPathFP.AddClose(); break; case PathIterator.SEG_LINETO: pointFP1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddLineTo(pointFP1); break; case PathIterator.SEG_QUADTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddQuadTo(pointFPCtl1, pointFP1); break; case PathIterator.SEG_CUBICTO: pointFPCtl1.Reset(coords[0] << SingleFP.DECIMAL_BITS, coords[1] << SingleFP.DECIMAL_BITS); pointFPCtl2.Reset(coords[2] << SingleFP.DECIMAL_BITS, coords[3] << SingleFP.DECIMAL_BITS); pointFP1.Reset(coords[4] << SingleFP.DECIMAL_BITS, coords[5] << SingleFP.DECIMAL_BITS); graphicsPathFP.AddCurveTo(pointFPCtl1, pointFPCtl2, pointFP1); break; } pathIterator.Next(); } _graphicsFP.DrawPath(graphicsPathFP); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * get the tail outline. * @param ff_rad * @return */ public LineFP GetTailOutline(int ffRad) { var c = GetCenter(); var p = new PointFP(Pt2.X - c.X, Pt2.Y - c.Y); p.Reset(p.Y, -p.X); var dis = PointFP.Distance(PointFP.Origin, p); if (dis == 0) { dis = 1; } p.Reset(MathFP.Div(MathFP.Mul(p.X, ffRad), dis), MathFP.Div(MathFP.Mul(p.Y, ffRad), dis)); return(new LineFP(Pt2.X - p.X, Pt2.Y - p.Y, Pt2.X + p.X, Pt2.Y + p.Y)); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param distance * @return */ internal PointFP GetPointAtDistance(int distance) { var lineLength = GetLength(); if (distance > lineLength) { return(null); } if (distance == lineLength) { return(new PointFP(Pt2)); } var scale = MathFP.Div(distance, lineLength); var pointFP = new PointFP(); pointFP.Reset(Pt1.X + MathFP.Mul(Pt2.X - Pt1.X, scale), Pt1.Y + MathFP.Mul(Pt2.Y - Pt1.Y, scale)); return(pointFP); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param distance * @return */ internal PointFP GetPointAtDistance(int distance) { var lineLength = GetLength(); if (distance > lineLength) { return null; } if (distance == lineLength) { return new PointFP(Pt2); } var scale = MathFP.Div(distance, lineLength); var pointFP = new PointFP(); pointFP.Reset(Pt1.X + MathFP.Mul(Pt2.X - Pt1.X, scale), Pt1.Y + MathFP.Mul(Pt2.Y - Pt1.Y, scale)); return pointFP; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * get the tail outline. * @param ff_rad * @return */ public LineFP GetTailOutline(int ffRad) { var c = GetCenter(); var p = new PointFP(Pt2.X - c.X, Pt2.Y - c.Y); p.Reset(p.Y, -p.X); var dis = PointFP.Distance(PointFP.Origin, p); if (dis == 0) { dis = 1; } p.Reset(MathFP.Div(MathFP.Mul(p.X, ffRad), dis), MathFP.Div(MathFP.Mul(p.Y, ffRad), dis)); return new LineFP(Pt2.X - p.X, Pt2.Y - p.Y, Pt2.X + p.X, Pt2.Y + p.Y); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Get the head outline. * @param ff_rad * @return */ public LineFP GetHeadOutline(int ffRad) { var p = new PointFP(Pt1.X - Pt2.X, Pt1.Y - Pt2.Y); var len = GetLength(); p.Reset(MathFP.Div(-p.Y, len), MathFP.Div(p.X, len)); p.Reset(MathFP.Mul(p.X, ffRad), MathFP.Mul(p.Y, ffRad)); return new LineFP(Pt1.X - p.X, Pt1.Y - p.Y, Pt1.X + p.X, Pt1.Y + p.Y); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * check to see if two line intects and return the the intersction point. * @param l1 * @param l2 * @param intersection * @return */ public static bool Intersects(LineFP l1, LineFP l2, PointFP intersection) { var x = SingleFP.NOT_A_NUMBER; var y = SingleFP.NOT_A_NUMBER; if (intersection != null) { intersection.Reset(x, y); } var ax0 = l1.Pt1.X; var ax1 = l1.Pt2.X; var ay0 = l1.Pt1.Y; var ay1 = l1.Pt2.Y; var bx0 = l2.Pt1.X; var bx1 = l2.Pt2.X; var by0 = l2.Pt1.Y; var by1 = l2.Pt2.Y; var adx = (ax1 - ax0); var ady = (ay1 - ay0); var bdx = (bx1 - bx0); var bdy = (by1 - by0); if (IsZero(adx) && IsZero(bdx)) { return IsEqual(ax0, bx0); } if (IsZero(ady) && IsZero(bdy)) { return IsEqual(ay0, by0); } if (IsZero(adx)) { // A vertical x = ax0; y = IsZero(bdy) ? by0 : MathFP.Mul(MathFP.Div(bdy, bdx), x - bx0) + by0; } else if (IsZero(bdx)) { // B vertical x = bx0; y = IsZero(ady) ? ay0 : MathFP.Mul(MathFP.Div(ady, adx), x - ax0) + ay0; } else if (IsZero(ady)) { y = ay0; x = MathFP.Mul(MathFP.Div(bdx, bdy), y - by0) + bx0; } else if (IsZero(bdy)) { y = by0; x = MathFP.Mul(MathFP.Div(adx, ady), y - ay0) + ax0; } else { var xma = MathFP.Div(ady, adx); // slope segment A var xba = ay0 - (MathFP.Mul(ax0, xma)); // y intercept of segment A var xmb = MathFP.Div(bdy, bdx); // slope segment B var xbb = by0 - (MathFP.Mul(bx0, xmb)); // y intercept of segment B // parallel lines? if (xma == xmb) { // Need trig functions return xba == xbb; } // Calculate points of intersection // At the intersection of line segment A and B, //XA=XB=XINT and YA=YB=YINT x = MathFP.Div((xbb - xba), (xma - xmb)); y = (MathFP.Mul(xma, x)) + xba; } // After the point or points of intersection are calculated, each // solution must be checked to ensure that the point of intersection lies // on line segment A and B. var minxa = MathFP.Min(ax0, ax1); var maxxa = MathFP.Max(ax0, ax1); var minya = MathFP.Min(ay0, ay1); var maxya = MathFP.Max(ay0, ay1); var minxb = MathFP.Min(bx0, bx1); var maxxb = MathFP.Max(bx0, bx1); var minyb = MathFP.Min(by0, by1); var maxyb = MathFP.Max(by0, by1); if (intersection != null) { intersection.Reset(x, y); } return ((x >= minxa) && (x <= maxxa) && (y >= minya) && (y <= maxya) && (x >= minxb) && (x <= maxxb) && (y >= minyb) && (y <= maxyb)); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * check to see if two line intects and return the the intersction point. * @param l1 * @param l2 * @param intersection * @return */ public static bool Intersects(LineFP l1, LineFP l2, PointFP intersection) { var x = SingleFP.NOT_A_NUMBER; var y = SingleFP.NOT_A_NUMBER; if (intersection != null) { intersection.Reset(x, y); } var ax0 = l1.Pt1.X; var ax1 = l1.Pt2.X; var ay0 = l1.Pt1.Y; var ay1 = l1.Pt2.Y; var bx0 = l2.Pt1.X; var bx1 = l2.Pt2.X; var by0 = l2.Pt1.Y; var by1 = l2.Pt2.Y; var adx = (ax1 - ax0); var ady = (ay1 - ay0); var bdx = (bx1 - bx0); var bdy = (by1 - by0); if (IsZero(adx) && IsZero(bdx)) { return(IsEqual(ax0, bx0)); } if (IsZero(ady) && IsZero(bdy)) { return(IsEqual(ay0, by0)); } if (IsZero(adx)) { // A vertical x = ax0; y = IsZero(bdy) ? by0 : MathFP.Mul(MathFP.Div(bdy, bdx), x - bx0) + by0; } else if (IsZero(bdx)) { // B vertical x = bx0; y = IsZero(ady) ? ay0 : MathFP.Mul(MathFP.Div(ady, adx), x - ax0) + ay0; } else if (IsZero(ady)) { y = ay0; x = MathFP.Mul(MathFP.Div(bdx, bdy), y - by0) + bx0; } else if (IsZero(bdy)) { y = by0; x = MathFP.Mul(MathFP.Div(adx, ady), y - ay0) + ax0; } else { var xma = MathFP.Div(ady, adx); // slope segment A var xba = ay0 - (MathFP.Mul(ax0, xma)); // y intercept of segment A var xmb = MathFP.Div(bdy, bdx); // slope segment B var xbb = by0 - (MathFP.Mul(bx0, xmb)); // y intercept of segment B // parallel lines? if (xma == xmb) { // Need trig functions return(xba == xbb); } // Calculate points of intersection // At the intersection of line segment A and B, //XA=XB=XINT and YA=YB=YINT x = MathFP.Div((xbb - xba), (xma - xmb)); y = (MathFP.Mul(xma, x)) + xba; } // After the point or points of intersection are calculated, each // solution must be checked to ensure that the point of intersection lies // on line segment A and B. var minxa = MathFP.Min(ax0, ax1); var maxxa = MathFP.Max(ax0, ax1); var minya = MathFP.Min(ay0, ay1); var maxya = MathFP.Max(ay0, ay1); var minxb = MathFP.Min(bx0, bx1); var maxxb = MathFP.Max(bx0, bx1); var minyb = MathFP.Min(by0, by1); var maxyb = MathFP.Max(by0, by1); if (intersection != null) { intersection.Reset(x, y); } return((x >= minxa) && (x <= maxxa) && (y >= minya) && (y <= maxya) && (x >= minxb) && (x <= maxxb) && (y >= minyb) && (y <= maxyb)); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * reset the line the to given points. * @param p1 * @param p2 */ public void Reset(PointFP p1, PointFP p2) { Pt1.Reset(p1); Pt2.Reset(p2); }