///<summary> /// Adds a limited mitre join connecting the two reflex offset segments. ///</summary> /// <remarks> /// A limited mitre is a mitre which is beveled at the distance /// determined by the mitre ratio limit. /// </remarks> /// <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) { Coordinate basePt = _seg0.P1; double ang0 = AngleUtility.Angle(basePt, _seg0.P0); double ang1 = AngleUtility.Angle(basePt, _seg1.P1); // oriented angle between segments double angDiff = AngleUtility.AngleBetweenOriented(_seg0.P0, basePt, _seg1.P1); // half of the interior angle double angDiffHalf = angDiff / 2; // angle for bisector of the interior angle between the segments double midAng = AngleUtility.Normalize(ang0 + angDiffHalf); // rotating this by PI gives the bisector of the reflex angle double mitreMidAng = AngleUtility.Normalize(midAng + Math.PI); // the miterLimit determines the distance to the mitre bevel double mitreDist = mitreLimit * distance; // the bevel delta is the difference between the buffer distance // and half of the length of the bevel segment double bevelDelta = mitreDist * Math.Abs(Math.Sin(angDiffHalf)); double bevelHalfLen = distance - bevelDelta; // compute the midpoint of the bevel segment double bevelMidX = basePt.X + mitreDist * Math.Cos(mitreMidAng); double bevelMidY = basePt.Y + mitreDist * Math.Sin(mitreMidAng); Coordinate bevelMidPt = new Coordinate(bevelMidX, bevelMidY); // compute the mitre midline segment from the corner point to the bevel segment midpoint LineSegment mitreMidLine = new LineSegment(basePt, bevelMidPt); // finally the bevel segment endpoints are computed as offsets from // the mitre midline Coordinate bevelEndLeft = mitreMidLine.PointAlongOffset(1.0, bevelHalfLen); Coordinate bevelEndRight = mitreMidLine.PointAlongOffset(1.0, -bevelHalfLen); if (_side == Positions.Left) { _vertexList.AddPt(bevelEndLeft); _vertexList.AddPt(bevelEndRight); } else { _vertexList.AddPt(bevelEndRight); _vertexList.AddPt(bevelEndLeft); } }
public void TestNormalize() { Assert.AreEqual(AngleUtility.Normalize(0.0), 0.0, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-0.5 * Math.PI), -0.5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-Math.PI), Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-1.5 * Math.PI), .5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-2 * Math.PI), 0.0, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-2.5 * Math.PI), -0.5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-3 * Math.PI), Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(-4 * Math.PI), 0.0, Tolerance); Assert.AreEqual(AngleUtility.Normalize(0.5 * Math.PI), 0.5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(Math.PI), Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(1.5 * Math.PI), -0.5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(2 * Math.PI), 0.0, Tolerance); Assert.AreEqual(AngleUtility.Normalize(2.5 * Math.PI), 0.5 * Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(3 * Math.PI), Math.PI, Tolerance); Assert.AreEqual(AngleUtility.Normalize(4 * Math.PI), 0.0, Tolerance); }