public static Geometry CreateGeometry(GunPitchLimitsComponent traverse, TurretYawLimits yawLimits, double size, Point center, double geometryRotation = 0, double margin = 0, double padding = 0, Func <double, double> verticalTraverseTransform = null) { if (verticalTraverseTransform == null) { verticalTraverseTransform = GunTraverseHelper.DefaultVerticalTraverseTransform; } if (traverse.HasSingularValue && yawLimits.Range == 360) { var radius = size / 2 - margin; return(new EllipseGeometry(center, radius, radius)); } else { var maxRadiusInDegrees = traverse.GetMaxValue(); var scale = (size / 2 - margin - padding) / maxRadiusInDegrees; Func <double, double> radiusConverter = r => padding + Math.Max(verticalTraverseTransform(r) * scale, 0); return(GunTraverseHelper.CreateGeometry(traverse, yawLimits, center, radiusConverter, geometryRotation)); } }
public void SetTraverse(GunPitchLimitsComponent gunPitch, TurretYawLimits turretYaw) { this.CurveCanvas.Children.Clear(); if (gunPitch == null) { return; } var traverseFigureStrokeStyle = this.FindResource("TraverseFigure") as Style; var maxRadius = gunPitch.GetMaxValue(); //maxRadius = Math.Ceiling(maxRadius / 5) * 5; const double margin = 1; var scale = 80 / (maxRadius + margin); var size = scale * maxRadius * 2; var center = new Point(100, 100); var figurePath = new Path { Data = GunTraverseHelper.CreateGeometry(gunPitch, turretYaw, size, center, 90, scale * margin, verticalTraverseTransform: v => v + 1), Style = traverseFigureStrokeStyle }; this.CurveCanvas.Children.Add(figurePath); // draw references var thinReferenceGeometry = new GeometryGroup(); var thickReferenceGeometry = new GeometryGroup(); const double referenceCircleGap = 20; const double halfReferenceCircleGap = referenceCircleGap / 2; var sign = Math.Sign(maxRadius); var absMaxRadius = Math.Abs(maxRadius); var thickDivisor = absMaxRadius > 45 ? 20 : absMaxRadius > 25 ? 10 : 5; var thinDivisor = absMaxRadius > 25 ? 5 : 1; for (var i = thinDivisor; i <= absMaxRadius; i += thinDivisor) { var radius = scale * i * sign; Geometry geometry; var isThickRing = i % thickDivisor == 0; if (absMaxRadius < 10 || isThickRing) { var gapHalfAngle = Math.Asin(halfReferenceCircleGap / radius) * 180 / Math.PI; if (double.IsNaN(gapHalfAngle)) { gapHalfAngle = 180; } var startPoint = GunTraverseHelper.PolarToCartesian(center, radius, gapHalfAngle); var endPoint = GunTraverseHelper.PolarToCartesian(center, radius, 360 - gapHalfAngle); var arc = new ArcSegment(endPoint, new Size(radius, radius), 360 - gapHalfAngle * 2, true, SweepDirection.Counterclockwise, true); var figure = new PathFigure(startPoint, new[] { arc }, false); geometry = new PathGeometry(new[] { figure }); var referenceTextContainer = new Grid { Width = 20, Height = referenceCircleGap }; var referenceTextContainerPosition = GunTraverseHelper.PolarToCartesian(center, radius, 0); Canvas.SetLeft(referenceTextContainer, referenceTextContainerPosition.X - 10); Canvas.SetTop(referenceTextContainer, referenceTextContainerPosition.Y - halfReferenceCircleGap); var referenceText = new TextBlock { Text = (i * sign).ToString(), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, FontSize = isThickRing ? 10 : 8, Foreground = isThickRing ? Brushes.White : new SolidColorBrush(Color.FromArgb(0x80, 0xff, 0xff, 0xff)) }; referenceTextContainer.Children.Add(referenceText); this.CurveCanvas.Children.Add(referenceTextContainer); } else { geometry = new EllipseGeometry(center, radius, radius); } if (isThickRing) { thickReferenceGeometry.Children.Add(geometry); } else { thinReferenceGeometry.Children.Add(geometry); } } var thinReferencePath = new Path { Data = thinReferenceGeometry, Style = this.FindResource("ThinReferenceStroke") as Style }; this.CurveCanvas.Children.Add(thinReferencePath); var thickReferencePath = new Path { Data = thickReferenceGeometry, Style = this.FindResource("ThickReferenceStroke") as Style }; this.CurveCanvas.Children.Add(thickReferencePath); }
private void UpdateTraverseBoundary() { if (this.ElevationLimits == null) { this.BoundaryCanvas.Children.Clear(); return; } double size; double radius; Point center; this.GetDimentions(out size, out radius, out center); if (size == 0) { return; } var oneThirdsRadius = radius / 3; var maxElevation = this.ElevationLimits.GetMaxValue(); var maxDepression = this.DepressionLimits.GetMaxValue(); var maxTraverse = -maxElevation + maxDepression; // elevation/outer figure _elevationRadiusConverter = r => (-r + maxDepression) / maxTraverse * oneThirdsRadius * 2 + oneThirdsRadius; _depressionRadiusConverter = r => (maxDepression - r) / maxTraverse * oneThirdsRadius * 2 + oneThirdsRadius; _inverseVerticalTraverseConverter = r => - ((r - oneThirdsRadius) / (oneThirdsRadius * 2) * maxTraverse - maxDepression); var elevationGeometry = GunTraverseHelper.CreateGeometry(this.ElevationLimits, this.TurretYawLimits, center, _elevationRadiusConverter); var depressionGeometry = GunTraverseHelper.CreateGeometry(this.DepressionLimits, this.TurretYawLimits, center, _depressionRadiusConverter); var combinedGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, elevationGeometry, depressionGeometry); var figure = new Path { Data = combinedGeometry }; var borderStyle = this.FindResource("Border") as Style; var delimiterStyle = this.FindResource("Delimiter") as Style; figure.Style = borderStyle; var delimiterCircle = new Ellipse(); var delimiterCircleSize = _depressionRadiusConverter(0) * 2; delimiterCircle.Width = delimiterCircleSize; delimiterCircle.Height = delimiterCircleSize; delimiterCircle.Style = delimiterStyle; Canvas.SetLeft(delimiterCircle, (size - delimiterCircleSize) / 2); Canvas.SetTop(delimiterCircle, (size - delimiterCircleSize) / 2); this.BoundaryCanvas.Children.Clear(); this.BoundaryCanvas.Children.Add(delimiterCircle); this.BoundaryCanvas.Children.Add(figure); Canvas.SetLeft(this.YawDirectionLine, center.X); Canvas.SetTop(this.YawDirectionLine, center.Y); }