private Point GetPosition(double value, EllipseGeometry geometry) { var pathGeometry = geometry.GetOutlinedPathGeometry(); if (pathGeometry.Figures.Count == 0) { return(geometry.Center); } var outherGeometry = new PathGeometry(new[] { pathGeometry.Figures[0] }); Point outherPoint, outherTangent; outherGeometry.GetPointAtFractionLength(value, out outherPoint, out outherTangent); return(outherPoint); }
public void ArcUpdate() { // 線の太さ double thick = this.ViewModel.StrokeThickness; // 入力値切捨て double inputValue = Math.Floor(this.ViewModel.Percentage * 100.0); // 角度の計算 double angle = (inputValue * 3.6); if (angle < 0) { angle += 360; } if (angle > 360) { angle %= 360.0; } // 0-360を許容 if (0 < angle && angle < 360) { // 角度によってフラグを変える this.ViewModel.IsLargeArcFlg = false; if (angle >= 180) { // 180°を超える(180を含む)場合はフラグをtrue this.ViewModel.IsLargeArcFlg = true; } } // 角度と半径から座標を計算 double radius = (this.pathArc.Width / 2) - thick; pathArc.StrokeThickness = thick; pathCircleBackground.StrokeThickness = thick; if (angle != 0 && angle != 360) { angle -= 90; double radian = Math.PI * angle / 180.0; double x = radius * Math.Cos(radian); double y = radius * Math.Sin(radian); x = ToRoundDown(x, 3); y = ToRoundDown(y, 3); // 終点計算 double endPointX = radius + x + thick; double endPointY = radius + y + thick; // 図形生成 PathFigure pfArc = new PathFigure(); pfArc.StartPoint = new Point(100, thick); // 開始点 // セグメント生成 ArcSegment arc = new ArcSegment(); arc.Point = new Point(endPointX, endPointY); // 終点(計算値) arc.Size = new Size(radius, radius); // 半径 arc.IsLargeArc = this.ViewModel.IsLargeArcFlg; arc.SweepDirection = SweepDirection.Clockwise; //arc.RotationAngle = Math.PI * -90.0 / 180.0; // 図形入れ替え pfArc.Segments.Clear(); pfArc.Segments.Add(arc); this.pathGeometryArc.Figures.Clear(); this.pathGeometryArc.Figures.Add(pfArc); // 図形生成(背景) PathFigure pfCircle = new PathFigure(); pfCircle.StartPoint = new Point(100, thick); // 開始点 // セグメント生成 ArcSegment circle = new ArcSegment(); circle.Point = new Point(endPointX, endPointY); // 終点(計算値) circle.Size = new Size(radius, radius); // 半径 circle.IsLargeArc = !this.ViewModel.IsLargeArcFlg; circle.SweepDirection = SweepDirection.Counterclockwise; // 図形入れ替え pfCircle.Segments.Clear(); pfCircle.Segments.Add(circle); this.pathGeometryCircle.Figures.Clear(); this.pathGeometryCircle.Figures.Add(pfCircle); } else { var center = new Point(this.pathArc.Width / 2, this.pathArc.Height / 2); var circle = new EllipseGeometry(center, radius, radius); var pathgeo = circle.GetOutlinedPathGeometry(); this.pathGeometryArc.Clear(); this.pathGeometryCircle.Clear(); if (angle == 0) { this.pathGeometryCircle.Figures = pathgeo.Figures; } else { this.pathGeometryArc.Figures = pathgeo.Figures; } } }
/// <summary> /// Positionates each child in an ellipse form depending on the amount of child controls. /// </summary> /// <param name="finalSize">The maximum possible space given by the parent control.</param> /// <returns>The calculated needed space in sum of all available child controls.</returns> protected override Size ArrangeOverride(Size finalSize) { if (finalSize.Height <= 0 || finalSize.Width <= 0) { return(finalSize); } if (InternalChildren.Count <= 0) { return(base.ArrangeOverride(finalSize)); } ResetEllipse(finalSize); var figure = _ellipse.GetOutlinedPathGeometry().Figures[0]; var pathGeometry = new PathGeometry(new[] { figure }); var points = new List <Point>(); var tangents = new List <Point>(); var distance = (double)1 / (double)InternalChildren.Count; var position = GetElementStartPositionValue(); foreach (var child in InternalChildren) { Point point, tangent; pathGeometry.GetPointAtFractionLength(position, out point, out tangent); points.Add(point); tangents.Add(tangent); position += distance; if (position > 1) { position -= 1; } } if (EllipseRotateDirection == SweepDirection.Counterclockwise) { points.Reverse(); tangents.Reverse(); var point = points.Last(); points.Remove(point); points.Insert(0, point); var tangent = tangents.Last(); tangents.Remove(tangent); tangents.Insert(0, tangent); } int pos = 0; foreach (UIElement child in InternalChildren) { var childSize = child.DesiredSize; var elementPos = points[pos]; elementPos.X -= childSize.Width / 2; elementPos.Y -= childSize.Height / 2; child.SnapsToDevicePixels = true; child.Arrange(new Rect(elementPos, childSize)); if (RotateElements) { var elementCenter = new Size(childSize.Width / 2, childSize.Height / 2); var transforms = new TransformGroup(); var centerPoint = new Point(finalSize.Width / 2, finalSize.Height / 2); var angle = CalculatePileToPlayerAngle(elementPos, centerPoint); transforms.Children.Add(new RotateTransform(angle, elementCenter.Width, elementCenter.Height)); //transforms.Children.Add(new RotateTransform((Math.Atan2(tangents[pos].Y, tangents[pos].X) // * 180 // / Math.PI) // + GetElementsRotateDirectionValue(), // elementCenter.Width, // elementCenter.Height)); child.RenderTransform = transforms; } else { child.RenderTransform = null; } ++pos; } return(base.ArrangeOverride(finalSize)); }