//-------------------------------------------------------------------------------------------------- public bool ComputeParameters(out Parameters parameters) { if (FirstPoint.IsEqual(SecondPoint, 0.01)) { parameters = new(); return(false); } var arrowSize = DrawingRenderHelper.GetArrowSize(); double scale = 1.0; // Dimension line var radius = _CenterPoint.Distance(Position); // Extension line var extDir1 = new Vec2d(_CenterPoint, _FirstPoint).ToDir(); var angle1 = -extDir1.Angle(Dir2d.DX); var extVector1 = extDir1.ToVec(radius - _CenterPoint.Distance(_FirstPoint) + _ExtensionOverlength); var extDir2 = new Vec2d(_CenterPoint, _SecondPoint).ToDir(); var angle2 = -extDir2.Angle(Dir2d.DX); var extVector2 = extDir2.ToVec(radius - _CenterPoint.Distance(_SecondPoint) + _ExtensionOverlength); var angle = (angle1 - angle2).Abs(); if (_AutoText) { Text = (angle1 - angle2).Abs().ToDeg().ToInvariantString("F0") + "°"; } Geom2d_Circle circle = new(new Ax2d(_CenterPoint, Dir2d.DX), radius); var dimWidth = circle.Circ2d().Length() / circle.Period() * angle; scale = Math.Min(scale, dimWidth / (arrowSize.Length * 3)); // Text Pnt2d textOrigin = new(); Vec2d textTangent = new(); circle.D1(angle1.Lerp(angle2, 0.5), ref textOrigin, ref textTangent); if (textTangent.X < 0.0) { textTangent.Reverse(); } var textDirection = textTangent.ToDir(); var textNormal = new Vec2d(_CenterPoint, textOrigin).ToDir(); var textWidth = 1.0; var textHeight = 1.0; var textRotation = textDirection.Angle(Dir2d.DX); var textScale = scale; if (!Text.IsNullOrWhiteSpace()) { var fontStyle = DrawingRenderHelper.GetDefaultFontStyle(); var textSize = DrawingRenderHelper.MeasureText(Text, fontStyle); textScale = Math.Min(1.0, dimWidth * 0.90 / textSize.X); scale = Math.Min(scale, textScale); var textOffset = textNormal.Y < 0 ? -1.0 : 1.0; // Exact positioning on above dim line textOrigin.Translate(textNormal.ToVec(textOffset)); textOrigin.Translate(textDirection.ToVec(-textSize.X / 2 * textScale)); textWidth = textSize.X * textScale; textHeight = textSize.Y * textScale; } // Arrows bool reverse = angle1 < angle2; double arrowAngle = circle.Period() / circle.Circ2d().Length() * arrowSize.Length * scale * (reverse ? 0.5 : -0.5); angle1 += arrowAngle; angle2 -= arrowAngle; Pnt2d arrowP1 = new(), arrowP2 = new(); Vec2d arrowT1 = new(), arrowT2 = new(); circle.D1(angle1, ref arrowP1, ref arrowT1); circle.D1(angle2, ref arrowP2, ref arrowT2); if (reverse) { arrowT1.Reverse(); } else { arrowT2.Reverse(); } arrowP1.Translate(arrowT1.ToDir().ToVec(arrowSize.Length * scale * 0.5)); arrowP2.Translate(arrowT2.ToDir().ToVec(arrowSize.Length * scale * 0.5)); // Move arrows slightly towards center, to compensate that the tangent is taken from the middle of the arrow double arrowOffset = _CenterPoint.Distance(circle.Value(angle1)) - _CenterPoint.Distance(arrowP1); arrowP1.Translate(extDir1.ToVec(arrowOffset)); arrowP2.Translate(extDir2.ToVec(arrowOffset)); parameters = new () { FirstExtensionVector = extVector1, FirstArrowPoint = arrowP1, FirstArrowTangent = arrowT1.ToDir(), SecondExtensionVector = extVector2, SecondArrowPoint = arrowP2, SecondArrowTangent = arrowT2.ToDir(), Radius = radius, StartAngle = angle1 + arrowAngle, EndAngle = angle2 - arrowAngle, TextOrigin = textOrigin, TextRotation = textRotation, TextWidth = textWidth, TextHeight = textHeight, Scale = scale, TextScale = textScale }; return(true); } //-------------------------------------------------------------------------------------------------- #endregion }
/// <summary> /// Returns the angle between this halfedge and the previous at its start vertex. /// Result is between 0 and Pi. /// </summary> /// <returns></returns> public static double GetAngle <V, E>(this IHalfedge <V, E> hedge, Func <V, Vec2d> getPosition) where V : IHeVertex <V, E> where E : IHalfedge <V, E> { return(Vec2d.Angle(hedge.GetDelta(getPosition), hedge.PrevAtStart.GetDelta(getPosition))); }
//-------------------------------------------------------------------------------------------------- public bool ComputeParameters(out Parameters parameters) { if (FirstPoint.IsEqual(SecondPoint, 0.01)) { parameters = new(); return(false); } double scale = 1.0; // Dimension line direction var dimDir = new Vec2d(_FirstPoint, _SecondPoint).ToDir(); var dimMid = _FirstPoint.Lerped(_SecondPoint, 0.5); var dimWidth = _FirstPoint.Distance(_SecondPoint); scale = Math.Min(scale, dimWidth / (DrawingRenderHelper.GetArrowSize().Length * 3)); if (_AutoText) { Text = dimWidth.ToInvariantString("F1"); } var rotation = dimDir.Angle(Dir2d.DX); bool dimRightToLeft = false; if (rotation < -Maths.HalfPI) { rotation += Maths.PI; dimRightToLeft = true; } else if (rotation > Maths.HalfPI) { rotation -= Maths.PI; dimRightToLeft = true; } // Extension line var extDir = new Dir2d(dimDir.Y, -dimDir.X); if (dimDir.Angle(new Vec2d(dimMid, Position).ToDir()) > 0) { extDir.Reverse(); } var dimToPos = new gp_Lin2d(_FirstPoint, dimDir).Distance(Position); var extVector = extDir.ToVec(dimToPos + _ExtensionOverlength); var dimOffset = extDir.ToVec(dimToPos); // Text var textOrigin = _FirstPoint.Lerped(_SecondPoint, 0.5) .Translated(dimOffset); var textWidth = 1.0; var textHeight = 1.0; var textScale = scale; if (!Text.IsNullOrWhiteSpace()) { var fontStyle = DrawingRenderHelper.GetDefaultFontStyle(); var textSize = DrawingRenderHelper.MeasureText(Text, fontStyle); textScale = Math.Min(1.0, dimWidth * 0.90 / textSize.X); scale = Math.Min(scale, textScale); // Exact positioning on above dim line var textOffset = dimDir.Angle(extDir) > 0 ? 1.0 : -1.0; if (dimRightToLeft) { textOffset *= -1; } textOrigin.Translate(extDir.ToVec(textOffset)); // Center textOrigin.Translate(dimDir.ToVec((dimRightToLeft ? 1.0 : -1.0) * textSize.X / 2 * textScale)); textWidth = textSize.X * textScale; textHeight = textSize.Y * textScale; } parameters = new Parameters() { ExtensionVector = extVector, DimensionDirection = dimDir, DimensionOffset = dimOffset, DimensionRotation = rotation, TextOrigin = textOrigin, TextWidth = textWidth, TextHeight = textHeight, Scale = scale, TextScale = textScale }; return(true); }