void CheckOffset(double x0, double y0, double x1, double y1, double segFrac, double offset, double expectedX, double expectedY) { LineSegment seg = new LineSegment(x0, y0, x1, y1); Coordinate p = seg.PointAlongOffset(segFrac, offset); Assert.IsTrue(EqualsTolerance(new Coordinate(expectedX, expectedY), p, 0.000001)); }
/// <summary> /// Adds a limited mitre join connecting the two reflex offset segments. /// A limited mitre is a mitre which is beveled at the distance /// determined by the mitre ratio limit. /// </summary> /// <param name="offset0">The first offset segment</param> /// <param name="offset1">The second offset segment</param> /// <param name="distance">The offset distance</param> /// <param name="mitreLimit">The mitre limit ratio</param> private void AddLimitedMitreJoin( LineSegment offset0, LineSegment offset1, double distance, double mitreLimit) { var basePt = _seg0.P1; var ang0 = AngleUtility.Angle(basePt, _seg0.P0); //var ang1 = AngleUtility.Angle(basePt, _seg1.P1); // oriented angle between segments var angDiff = AngleUtility.AngleBetweenOriented(_seg0.P0, basePt, _seg1.P1); // half of the interior angle var angDiffHalf = angDiff / 2; // angle for bisector of the interior angle between the segments var midAng = AngleUtility.Normalize(ang0 + angDiffHalf); // rotating this by PI gives the bisector of the reflex angle var mitreMidAng = AngleUtility.Normalize(midAng + Math.PI); // the miterLimit determines the distance to the mitre bevel var mitreDist = mitreLimit * distance; // the bevel delta is the difference between the buffer distance // and half of the length of the bevel segment var bevelDelta = mitreDist * Math.Abs(Math.Sin(angDiffHalf)); var bevelHalfLen = distance - bevelDelta; // compute the midpoint of the bevel segment var bevelMidX = basePt.X + mitreDist * Math.Cos(mitreMidAng); var bevelMidY = basePt.Y + mitreDist * Math.Sin(mitreMidAng); var bevelMidPt = new Coordinate(bevelMidX, bevelMidY); // compute the mitre midline segment from the corner point to the bevel segment midpoint var mitreMidLine = new LineSegment(basePt, bevelMidPt); // finally the bevel segment endpoints are computed as offsets from // the mitre midline var bevelEndLeft = mitreMidLine.PointAlongOffset(1.0, bevelHalfLen); var bevelEndRight = mitreMidLine.PointAlongOffset(1.0, -bevelHalfLen); if (_side == Positions.Left) { _segList.AddPt(bevelEndLeft); _segList.AddPt(bevelEndRight); } else { _segList.AddPt(bevelEndRight); _segList.AddPt(bevelEndLeft); } }
private static Coordinate[] GenerateSegmentCurve(Coordinate p0, Coordinate p1, double width0, double width1) { var seg = new LineSegment(p0, p1); var dist0 = width0 / 2; var dist1 = width1 / 2; var s0 = seg.PointAlongOffset(0, dist0); var s1 = seg.PointAlongOffset(1, dist1); var s2 = seg.PointAlongOffset(1, -dist1); var s3 = seg.PointAlongOffset(0, -dist0); Coordinate[] pts = { s0, s1, s2, s3, s0 }; return pts; }