private void SetupAnimationForGear(Canvas gearBox, double ratio, SweepDirection direction) { var duration = TimeSpan.FromMilliseconds(30000*ratio); var animationRotation = new DoubleAnimationUsingKeyFrames { Duration = new Duration(duration), RepeatBehavior = RepeatBehavior.Forever }; animationRotation.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromPercent(0))); animationRotation.KeyFrames.Add(new LinearDoubleKeyFrame( direction == SweepDirection.Clockwise ? 360 : -360, KeyTime.FromPercent(1))); var rotateTransform = new RotateTransform(); gearBox.RenderTransform = rotateTransform; gearBox.RenderTransformOrigin = new Point(0.5, 0.5); Storyboard.SetTarget(animationRotation, rotateTransform); Storyboard.SetTargetProperty(animationRotation, new PropertyPath(RotateTransform.AngleProperty)); animationRotation.Freeze(); _storyBoard.Children.Add(animationRotation); }
public ArcSegment (Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked) { Point = point; Size = size; IsLargeArc = isLargeArc; RotationAngle = rotationAngle; SweepDirection = sweepDirection; }
public static void DrawArc(this DrawingContext dc, Brush brush, Pen pen, Point position, double startAngle, double endAngle, SweepDirection direction, double radiusX, double radiusY) { double startRadians = startAngle / 180 * Math.PI; double endRadians = endAngle / 180 * Math.PI; var start = position + new Vector(Math.Cos(startRadians) * radiusX, -Math.Sin(startRadians) * radiusY); var end = position + new Vector(Math.Cos(endRadians) * radiusX, -Math.Sin(endRadians) * radiusY); dc.DrawArc(brush, pen, start, end, direction, radiusX, radiusY); }
public ArcData(double X, double Y, double SizeX, double SizeY, double RotationAngle, SweepDirection Sweep = SweepDirection.Clockwise, bool IsLarge = false) : base(X, Y) { this.SizeX = SizeX; this.SizeY = SizeY; Rotation = RotationAngle; this.IsLarge = IsLarge; SweepDirection = Sweep; }
public IPathBuilder CurveTo(double x, double y, SweepDirection direction) { var newPoint = new Point(x, y); var diff = Point.Subtract(_currentPoint, newPoint); var radius = new Size(Math.Abs(diff.X), Math.Abs(diff.Y)); _segments.Add(new ArcSegment(new Point(x, y), radius, 45, false, direction, _currentIsStroked)); return this; }
/// <summary> /// 使用指定的设置初始化 <see cref="ArcSegment"/> 类的新实例。 /// </summary> /// <param name="end">弧线路径段的终结点。</param> /// <param name="size">弧线路径段的尺寸。</param> /// <param name="rotationAngel">弧线路径段的旋转角度。</param> /// <param name="sweepDirection">弧线路径段的绘制方向。</param> /// <param name="arcSize">弧线路径段是否大于 180 度。</param> public ArcSegment(Vector2 end, Size2F size, float rotationAngel, SweepDirection sweepDirection, ArcSize arcSize) : base(PathType.Arc, end) { this.Size = size; this.RotationAngle = rotationAngel; this.SweepDirection = sweepDirection; this.ArcSize = arcSize; }
public static Point GetCenterPosition(RadialType type, Size finalSize, double minAngle, double maxAngle, SweepDirection sweepDir) { //get the quadrants of the limits int q1 = GetQuadrant(minAngle); int q2 = GetQuadrant(maxAngle); if (sweepDir == SweepDirection.Counterclockwise) { q1++; q2++; if (q1 > 4) q1 = 1; if (q2 > 4) q2 = 1; } else { //q2->q4 and q4->q2 if (q1 % 2 == 0) q1 = 6 - q1; if (q2 % 2 == 0) q2 = 6 - q2; } //calculate the difference int diff = q2 - q1; if (Math.Abs(diff) == 0) {//quarter possibility if (type == RadialType.Quadrant) { return GetCenterForQuadrant(q2, finalSize); } else if (type == RadialType.Semicircle) { if (q1 == 1 || q1 == 2) return new Point(finalSize.Width / 2, finalSize.Height); else return new Point(finalSize.Width / 2, 0); } else { //full circle return new Point(finalSize.Width / 2, finalSize.Height / 2); } } else if (Math.Abs(diff) == 1 || (Math.Abs(diff)==3 && (maxAngle-minAngle)<=180)) {//semicircle possibility if (type == RadialType.Quadrant || type == RadialType.Semicircle) { return GetCenterForSemicircle(q1, q2, finalSize); } else { //full circle return new Point(finalSize.Width / 2, finalSize.Height / 2); } } else { //full circle return new Point(finalSize.Width / 2, finalSize.Height / 2); } }
// http://blogs.vertigo.com/personal/ralph/Blog/archive/2007/02/09/wpf-drawing-arcs.aspx public static void DrawArc(this DrawingContext dc, Brush brush, Pen pen, Point start, Point end, SweepDirection direction, double radiusX, double radiusY) { // setup the geometry object var geometry = new PathGeometry(); var figure = new PathFigure(); geometry.Figures.Add(figure); figure.StartPoint = start; // add the arc to the geometry figure.Segments.Add(new ArcSegment(end, new Size(radiusX, radiusY), 0, false, direction, true)); // draw the arc dc.DrawGeometry(brush, pen, geometry); }
protected void DrawArc (DrawingContext dc, Point start, Point end, Size size, SweepDirection sweepDirection) { var figure = new PathFigure (); figure.StartPoint = start; figure.Segments.Add (new ArcSegment () { Point = end, Size = size, SweepDirection = sweepDirection } ); var geometry = new PathGeometry (); geometry.Figures.Add (figure); dc.DrawGeometry (null, new Pen (Colors.Black, 2), geometry); }
public ArcSegment CreateArcSegment(Point point, Size size, SweepDirection sweepDirection, bool isLargeArc = false) { const double rotationAngle = 0.0; const bool isStroked = true; var arcSegment = new ArcSegment(point, size, rotationAngle, isLargeArc, sweepDirection, isStroked); return arcSegment; }
public ArcSegmentGeometry(Point startPoint, Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection,bool isClosed,bool isStroked) { _startPoint = startPoint; _point = point; _size = size; _rotationAngle = rotationAngle; _isLargeArc = isLargeArc; _sweepDirection = sweepDirection; _isClosed = isClosed; _isStroked = isStroked; IPlatformRenderInterface factory = PerspexLocator.Current.GetService<IPlatformRenderInterface>(); IStreamGeometryImpl impl = factory.CreateStreamGeometry(); using (IStreamGeometryContextImpl context = impl.Open()) { context.BeginFigure(startPoint, isStroked); context.ArcTo(point, size, rotationAngle,isLargeArc, sweepDirection); context.EndFigure(isClosed); } PlatformImpl = impl; }
public static Geometry CreateArcGeometry(double minAngle, double maxAngle, double radius, int thickness, SweepDirection sweepDirection) { //the range will have 4 segments (arc, line, arc, line) //if the sweep angle is bigger than 180 use the large arc //first use the same sweep direction as the control. invert for the second arc. PathFigure figure = new PathFigure(); figure.IsClosed = true; figure.StartPoint = new Point((radius - thickness) * Math.Sin(minAngle * Math.PI / 180), -(radius - thickness) * Math.Cos(minAngle * Math.PI / 180)); //first arc segment ArcSegment arc = new ArcSegment(); arc.Point = new Point((radius - thickness) * Math.Sin(maxAngle * Math.PI / 180), -(radius - thickness) * Math.Cos(maxAngle * Math.PI / 180)); arc.Size = new Size(radius - thickness, radius - thickness); arc.SweepDirection = sweepDirection; if (Math.Abs(maxAngle - minAngle) > 180) arc.IsLargeArc = true; figure.Segments.Add(arc); //first line segment LineSegment line = new LineSegment(); line.Point = new Point(radius * Math.Sin(maxAngle * Math.PI / 180), -radius * Math.Cos(maxAngle * Math.PI / 180)); figure.Segments.Add(line); //second arc segment arc = new ArcSegment(); arc.Point = new Point(radius * Math.Sin(minAngle * Math.PI / 180), -radius * Math.Cos(minAngle * Math.PI / 180)); arc.Size = new Size(radius, radius); arc.SweepDirection = SweepDirection.Counterclockwise; if (sweepDirection == SweepDirection.Counterclockwise) arc.SweepDirection = SweepDirection.Clockwise; if (Math.Abs(maxAngle - minAngle) > 180) arc.IsLargeArc = true; figure.Segments.Add(arc); PathGeometry path = new PathGeometry(); path.Figures.Add(figure); return path; }
/// <summary> /// Draws the arc. /// </summary> /// <param name="dc">The dc.</param> /// <param name="brush">The brush.</param> /// <param name="pen">The pen.</param> /// <param name="start">The start.</param> /// <param name="end">The end.</param> /// <param name="direction">The direction.</param> /// <param name="radiusX">The radius X.</param> /// <param name="radiusY">The radius Y.</param> public static void DrawArc( this DrawingContext dc, Brush brush, Pen pen, Point start, Point end, SweepDirection direction, double radiusX, double radiusY) { // http://blogs.vertigo.com/personal/ralph/Blog/archive/2007/02/09/wpf-drawing-arcs.aspx // setup the geometry object var geometry = new PathGeometry(); var figure = new PathFigure(); geometry.Figures.Add(figure); figure.StartPoint = start; // add the arc to the geometry figure.Segments.Add(new ArcSegment(end, new Size(radiusX, radiusY), 0, false, direction, true)); // draw the arc dc.DrawGeometry(brush, pen, geometry); }
/// <summary> /// ArcTo - append an ArcTo to the current figure. /// </summary> // Special case this one. Bringing in sweep direction requires code-gen changes. // #if !PBTCOMPILER public abstract void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin);
/// <summary> /// ArcTo - append an ArcTo to the current figure. /// </summary> public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) { Debug.Assert(_figures != null); Debug.Assert(_currentFigure != null); FinishSegment(); // Is this the first segment? if (_segments == null) { // While we could always just retrieve _currentFigure.Segments (which would auto-promote) // it's more efficient to create the collection ourselves and set it explicitly. _segments = new PathSegmentCollection(); _currentFigure.Segments = _segments; } ArcSegment segment = new ArcSegment(); segment.Point = point; segment.Size = size; if (isLargeArc != s_defaultValueForArcSegmentIsLargeArc) { segment.IsLargeArc = isLargeArc; } if (sweepDirection != s_defaultValueForArcSegmentSweepDirection) { segment.SweepDirection = sweepDirection; } if (rotationAngle != s_defaultValueForArcSegmentRotationAngle) { segment.RotationAngle = rotationAngle; } // Handle common PathSegment properties. if (isStroked != s_defaultValueForPathSegmentIsStroked) { segment.IsStroked = isStroked; } if (isSmoothJoin != s_defaultValueForPathSegmentIsSmoothJoin) { segment.IsSmoothJoin = isSmoothJoin; } _segments.Add(segment); _currentSegmentType = MIL_SEGMENT_TYPE.MilSegmentArc; }
public static ESRI.ArcGIS.Client.Geometry.MapPoint ConstructCenterPoint(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, double bearing, double distance, double radius, bool isMinor, SweepDirection direction, out double bearing1, out double bearing2) { bearing1 = bearing2 = 0.0; if (distance == 0) return null; ESRI.ArcGIS.Client.Geometry.MapPoint endPoint = ConstructPoint(startPoint, bearing, distance); if (endPoint == null) return null; return ConstructCenterPoint(startPoint, endPoint, radius, isMinor, direction, out bearing1, out bearing2); }
private static bool SweepToBool(SweepDirection sweep) { if (sweep == SweepDirection.Counterclockwise) return false; else return true; }
public void ArcTo(PointShapeViewModel point, PathSizeViewModel size, double rotationAngle = 0.0, bool isLargeArc = false, SweepDirection sweepDirection = SweepDirection.Clockwise) { if (_currentFigure is not null) { var segment = _viewModelFactory.CreateArcSegment( point, size, rotationAngle, isLargeArc, sweepDirection); _currentFigure.Segments = _currentFigure.Segments.Add(segment); } }
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { throw new NotImplementedException(); }
/// <summary> /// Creates the arc segment from parameters of the GDI+ DrawArc function. /// </summary> public static ArcSegment CreateArcSegment(double x, double y, double width, double height, double startAngle, double sweepAngle, out SysPoint startPoint) { // Normalize the angles. double α = startAngle; if (α < 0) { α = α + (1 + Math.Floor((Math.Abs(α) / 360))) * 360; } else if (α > 360) { α = α - Math.Floor(α / 360) * 360; } Debug.Assert(α >= 0 && α <= 360); if (Math.Abs(sweepAngle) >= 360) { sweepAngle = Math.Sign(sweepAngle) * 360; } double β = startAngle + sweepAngle; if (β < 0) { β = β + (1 + Math.Floor((Math.Abs(β) / 360))) * 360; } else if (β > 360) { β = β - Math.Floor(β / 360) * 360; } if (α == 0 && β < 0) { α = 360; } else if (α == 360 && β > 0) { α = 0; } // Scanling factor. double δx = width / 2; double δy = height / 2; // Center of ellipse. double x0 = x + δx; double y0 = y + δy; double cosα, cosβ, sinα, sinβ; if (width == height) { // Circular arc needs no correction. α = α * Calc.Deg2Rad; β = β * Calc.Deg2Rad; } else { // Elliptic arc needs the angles to be adjusted such that the scaling transformation is compensated. α = α * Calc.Deg2Rad; sinα = Math.Sin(α); if (Math.Abs(sinα) > 1E-10) { if (α < Math.PI) { α = Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα)); } else { α = 3 * Math.PI / 2 - Math.Atan(δy * Math.Cos(α) / (δx * sinα)); } } //α = Calc.πHalf - Math.Atan(δy * Math.Cos(α) / (δx * sinα)); β = β * Calc.Deg2Rad; sinβ = Math.Sin(β); if (Math.Abs(sinβ) > 1E-10) { if (β < Math.PI) { β = Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ)); } else { β = 3 * Math.PI / 2 - Math.Atan(δy * Math.Cos(β) / (δx * sinβ)); } } //β = Calc.πHalf - Math.Atan(δy * Math.Cos(β) / (δx * sinβ)); } sinα = Math.Sin(α); cosα = Math.Cos(α); sinβ = Math.Sin(β); cosβ = Math.Cos(β); startPoint = new SysPoint(x0 + δx * cosα, y0 + δy * sinα); SysPoint destPoint = new SysPoint(x0 + δx * cosβ, y0 + δy * sinβ); SysSize size = new SysSize(δx, δy); bool isLargeArc = Math.Abs(sweepAngle) >= 180; SweepDirection sweepDirection = sweepAngle > 0 ? SweepDirection.Clockwise : SweepDirection.Counterclockwise; #if !SILVERLIGHT && !NETFX_CORE bool isStroked = true; ArcSegment seg = new ArcSegment(destPoint, size, 0, isLargeArc, sweepDirection, isStroked); #else ArcSegment seg = new ArcSegment(); seg.Point = destPoint; seg.Size = size; seg.RotationAngle = 0; seg.IsLargeArc = isLargeArc; seg.SweepDirection = sweepDirection; // isStroked does not exist in Silverlight 3 #endif return(seg); }
public static double GetRadius(RadialType type, Size finalSize, double minAngle, double maxAngle, SweepDirection sweepDir) { //get the quadrants of the limits int q1 = GetQuadrant(minAngle); int q2 = GetQuadrant(maxAngle); if (sweepDir == SweepDirection.Counterclockwise) { q1++; q2++; if (q1 > 4) { q1 = 1; } if (q2 > 4) { q2 = 1; } } else { //q2->q4 and q4->q2 if (q1 % 2 == 0) { q1 = 6 - q1; } if (q2 % 2 == 0) { q2 = 6 - q2; } } //calculate the difference int diff = q2 - q1; if (Math.Abs(diff) == 0) {//quarter possibility if (type == RadialType.Quadrant) { return(Math.Min(finalSize.Width, finalSize.Height)); } else if (type == RadialType.Semicircle) { return(finalSize.Height); } else {//full circle return(Math.Min(finalSize.Width / 2, finalSize.Height / 2)); } } else if (Math.Abs(diff) == 1 || (Math.Abs(diff) == 3 && (maxAngle - minAngle) <= 180)) {//semicircle possibility if (type == RadialType.Quadrant || type == RadialType.Semicircle) { return(GetRadiusForSemicircle(q1, q2, finalSize)); } else {//full circle return(Math.Min(finalSize.Width / 2, finalSize.Height / 2)); } } else {//full circle return(Math.Min(finalSize.Width / 2, finalSize.Height / 2)); } }
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) { CheckState(); ArcSegment seg = new ArcSegment(); seg.Point = point; seg.Size = size; seg.RotationAngle = rotationAngle; seg.IsLargeArc = isLargeArc; seg.SweepDirection = sweepDirection; _Fig.Segments.Add(seg); }
public static Point GetRoundCenter(Point startPoint, Point endPoint, double radius, SweepDirection sweepDirection, bool isLargeArc) { if (startPoint == endPoint) throw new Exception("Zero lenght line."); var width = Math.Sqrt((startPoint.Y - endPoint.Y)*(startPoint.Y - endPoint.Y) + (startPoint.X - endPoint.X)*(startPoint.X - endPoint.X)); if (width > radius) throw new RadiusException("Line width cannot be greater whan arc radius."); var crossingPoint = new Point((startPoint.X + endPoint.X)/2, (startPoint.Y + endPoint.Y)/2); var k1 = (startPoint.Y - endPoint.Y)/(startPoint.X - endPoint.X); var distance = Math.Sqrt(radius*radius - (width*width)/4); Point roundCenterLeft; Point roundCenterRight; if (double.IsInfinity(k1)) { roundCenterLeft = new Point(crossingPoint.X + distance, crossingPoint.Y); roundCenterRight = new Point(crossingPoint.X - distance, crossingPoint.Y); } else if (k1 == 0) { roundCenterLeft = new Point(crossingPoint.X, crossingPoint.Y + distance); roundCenterRight = new Point(crossingPoint.X, crossingPoint.Y - distance); } else { var k2 = (-1)/k1; var xOffset = distance/(Math.Sqrt(1 + k2*k2)); var xTemp = crossingPoint.X + xOffset; var yTemp = k2*(xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterLeft = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); xTemp = crossingPoint.X - xOffset; yTemp = k2*(xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterRight = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); } if (-1 == GetPointLeftOrRight(startPoint, endPoint, roundCenterLeft)) { var pointTemp = roundCenterLeft; roundCenterLeft = roundCenterRight; roundCenterRight = pointTemp; } if (isLargeArc) { if (sweepDirection == SweepDirection.Clockwise) { return roundCenterRight; } return roundCenterLeft; } if (sweepDirection == SweepDirection.Clockwise) { return roundCenterLeft; } return roundCenterRight; }
public string MeasurementConditionsSummary() { using (StringWriter result = new StringWriter()) { result.WriteLine("Input DUT=> Scope Channel: " + InputDUTChannel.ToString() + " Coupling: " + InputDUTCoupling.ToString() + " Attenuation: " + InputDUTAttenuation.ToString() + " DC Offset: " + InputDUTDCOffset.ToString() + "V"); result.WriteLine("Output DUT=> Scope Channel: " + OutputDUTChannel.ToString() + " Coupling: " + OutputDUTCoupling.ToString() + " Attenuation: " + OutputDUTAttenuation.ToString() + " DC Offset: " + OutputDUTDCOffset.ToString() + "V"); result.WriteLine("Stimulus DUT=> Amplitude: " + InitialStimulus.ToString() + "V" + " DC Offset: " + StimulusOffset.ToString() + "V"); result.WriteLine("Frequency Sweep => Start Freqeuncy: " + StartFrequencyHz.ToString() + " Hz " + " Stop Freqeuncy: " + StopFrequencyHz.ToString() + " Hz " + " Steps/Decade: " + StepsPerDecade.ToString() + " Sweepdirection: " + SweepDirection.ToString()); return(result.ToString()); } }
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { ArcToHelper.ArcTo(this, _currentPoint, point, size, rotationAngle, isLargeArc, sweepDirection); _currentPoint = point; }
void AppendPartialArc(SysPoint point1, SysPoint point2, double rotationAngle, SysSize size, bool isLargeArc, SweepDirection sweepDirection, PathStart pathStart) { const string format = Config.SignificantFigures4; Debug.Assert(pathStart == PathStart.Ignore1st); int pieces; PointCollection points = GeometryHelper.ArcToBezier(point1.X, point1.Y, size.Width, size.Height, rotationAngle, isLargeArc, sweepDirection == SweepDirection.Clockwise, point2.X, point2.Y, out pieces); int count = points.Count; int start = count % 3 == 1 ? 1 : 0; if (start == 1) AppendFormatPoint("{0:" + format + "} {1:" + format + "} m\n", points[0].X, points[0].Y); for (int idx = start; idx < count; idx += 3) AppendFormat3Points("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} c\n", points[idx].X, points[idx].Y, points[idx + 1].X, points[idx + 1].Y, points[idx + 2].X, points[idx + 2].Y); }
private Path CreateArc(double width, double height, double boxWidth, Brush color, int lineThickness, SweepDirection direction) { var streamGeometry = new StreamGeometry(); using (var gc = streamGeometry.Open()) { gc.BeginFigure(new Point(_width / 2 - width / 2, height), false, false); gc.ArcTo(new Point(_width / 2 - width / 2 + boxWidth, height), new Size(100, 100), 0, false, direction, true, false); } return(new Path() { Stroke = color, StrokeThickness = lineThickness, Data = streamGeometry }); }
/// <summary> /// Draws an arc to the specified point using polylines, quadratic or cubic Bezier curves /// Significantly more precise when drawing elliptic arcs with extreme width:height ratios. /// </summary> /// <param name="point">The destination point.</param> /// <param name="size">The radii of an oval whose perimeter is used to draw the angle.</param> /// <param name="rotationAngle">The rotation angle of the oval that specifies the curve.</param> /// <param name="isLargeArc">true to draw the arc greater than 180 degrees; otherwise, false.</param> /// <param name="sweepDirection"> /// A value that indicates whether the arc is drawn in the Clockwise or Counterclockwise direction. /// </param> public void PreciseArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { PreciseEllipticArcHelper.ArcTo(this, _currentPoint, point, size, rotationAngle, isLargeArc, sweepDirection); }
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { var arcSegment = new ArcSegment { Size = size, RotationAngle = rotationAngle, IsLargeArc = isLargeArc, SweepDirection = sweepDirection, Point = point }; _currentFigure.Segments.Add(arcSegment); }
/// <summary> /// ドーナツ形、アーチ形のPathGeometry作成 /// </summary> /// <param name="center">中心座標</param> /// <param name="width">幅</param> /// <param name="distance">中心からの距離</param> /// <param name="startDeg">開始角度、0以上360未満</param> /// <param name="stopDeg">終了角度、0以上360未満</param> /// <param name="direction">回転方向、clockwiseが時計回り</param> /// <returns></returns> private PathGeometry DonutGeometry(Point center, double width, double distance, double startDeg, double stopDeg, SweepDirection direction) { //外側の円弧終始点 Point outSideStart = MakePoint(startDeg, center, distance); Point outSideStop = MakePoint(stopDeg, center, distance); //内側の円弧終始点は角度と回転方向が外側とは逆になる Point inSideStart = MakePoint(stopDeg, center, distance - width); Point inSideStop = MakePoint(startDeg, center, distance - width); //開始角度から終了角度までが180度を超えているかの判定 //超えていたらArcSegmentのIsLargeArcをtrue、なければfalseで作成 double diffDegrees = (direction == SweepDirection.Clockwise) ? stopDeg - startDeg : startDeg - stopDeg; if (diffDegrees < 0) { diffDegrees += 360.0; } bool isLarge = (diffDegrees > 180) ? true : false; //arcSegment作成 var outSideArc = new ArcSegment(outSideStop, new Size(distance, distance), 0, isLarge, direction, true); //内側のarcSegmentは回転方向を逆で作成 var inDirection = (direction == SweepDirection.Clockwise) ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; var inSideArc = new ArcSegment(inSideStop, new Size(distance - width, distance - width), 0, isLarge, inDirection, true); //PathFigure作成、外側から内側で作成している //2つのarcSegmentは、2本の直線(LineSegment)で繋げる var fig = new PathFigure(); fig.StartPoint = outSideStart; fig.Segments.Add(outSideArc); fig.Segments.Add(new LineSegment(inSideStart, true)); //外側終点から内側始点への直線 fig.Segments.Add(inSideArc); fig.Segments.Add(new LineSegment(outSideStart, true)); //内側終点から外側始点への直線 fig.IsClosed = true; //Pathを閉じる必須 var pg = new PathGeometry(); pg.Figures.Add(fig); return(pg); }
/// <inheritdoc /> public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { _path.ArcTo( (float)size.Width, (float)size.Height, (float)rotationAngle, isLargeArc ? SKPathArcSize.Large : SKPathArcSize.Small, sweepDirection == SweepDirection.Clockwise ? SKPathDirection.Clockwise : SKPathDirection.CounterClockwise, (float)point.X, (float)point.Y); }
/// <summary> /// 円弧のPathGeometryを作成 /// </summary> /// <param name="center">中心座標</param> /// <param name="distance">中心点からの距離</param> /// <param name="startDegrees">開始角度、0以上360未満で指定</param> /// <param name="stopDegrees">終了角度、0以上360未満で指定</param> /// <param name="direction">回転方向、Clockwiseが時計回り</param> /// <returns></returns> private PathGeometry ArcGeometry(Point center, double distance, double startDegrees, double stopDegrees, SweepDirection direction) { Point stop = MakePoint(stopDegrees, center, distance);//終点座標 //IsLargeの判定、 //開始角度から終了角度までが180度を超えていたらtrue、なければfalse double diffDegrees = (direction == SweepDirection.Clockwise) ? stopDegrees - startDegrees : startDegrees - stopDegrees; if (diffDegrees < 0) { diffDegrees += 360.0; } bool isLarge = (diffDegrees > 180) ? true : false; //ArcSegment作成 var arc = new ArcSegment(stop, new Size(distance, distance), 0, isLarge, direction, true); //PathFigure作成 var fig = new PathFigure(); Point start = MakePoint(startDegrees, center, distance); //始点座標 fig.StartPoint = start; //始点座標をスタート地点に fig.Segments.Add(arc); //ArcSegment追加 //PathGeometry作成、PathFigure追加 var pg = new PathGeometry(); pg.Figures.Add(fig); return(pg); }
/// <summary> /// 根据弧的起点,终点,半径,绘制方向,返回圆心点 /// </summary> /// <param name="startPoint">点1</param> /// <param name="endPoint">点2</param> /// <param name="radius">半径</param> /// <param name="sweepDirection">绘制方向</param> /// <returns>坐标</returns> /// <!--作者: 韦腾 时间:2008.12.16--> public static Point GetRoundCenter(Point startPoint, Point endPoint, double radius, SweepDirection sweepDirection, bool isLargeArc) { if (startPoint == endPoint) { throw new Exception("起点与终点不能重合."); } //弧连线的长 double width = Math.Sqrt((startPoint.Y - endPoint.Y) * (startPoint.Y - endPoint.Y) + (startPoint.X - endPoint.X) * (startPoint.X - endPoint.X)); if (width / 2 > radius) { throw new RadiusException("半径不能小于起点与终点的距离."); } //中点,即交点 Point crossingPoint = new Point((startPoint.X + endPoint.X) / 2, (startPoint.Y + endPoint.Y) / 2); //弧连线斜率 double k1 = (startPoint.Y - endPoint.Y) / (startPoint.X - endPoint.X); //圆心连线斜率 double k2; //弧于圆心的距离 double distance; distance = Math.Sqrt(radius * radius - (width * width) / 4); //圆心点 Point roundCenterLeft = new Point(); Point roundCenterRight = new Point(); if (double.IsInfinity(k1)) { roundCenterLeft = new Point(crossingPoint.X + distance, crossingPoint.Y); roundCenterRight = new Point(crossingPoint.X - distance, crossingPoint.Y); } else if (k1 == 0) { roundCenterLeft = new Point(crossingPoint.X, crossingPoint.Y + distance); roundCenterRight = new Point(crossingPoint.X, crossingPoint.Y - distance); } else { k2 = (-1) / k1; double xOffset = distance / (Math.Sqrt(1 + k2 * k2)); double xTemp, yTemp; #region 第一个圆心点 xTemp = crossingPoint.X + xOffset; yTemp = k2 * (xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterLeft = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); #endregion #region 第二个圆心点 xTemp = crossingPoint.X - xOffset; yTemp = k2 * (xTemp - crossingPoint.X) + crossingPoint.Y; roundCenterRight = new Point(Math.Round(xTemp, 4), Math.Round(yTemp, 4)); #endregion } if (-1 == MathExtension.GetPointLeftOrRight(startPoint, endPoint, roundCenterLeft)) { Point pointTemp = roundCenterLeft; roundCenterLeft = roundCenterRight; roundCenterRight = pointTemp; } //大弧(注意坐标已经发先水平翻转) if (isLargeArc) { //顺时针 取左边圆心 if (sweepDirection == SweepDirection.Clockwise) { return(roundCenterRight); } else//逆时针 取右边圆心 { return(roundCenterLeft); } } else //小弧 { //顺时针 取右边圆心 if (sweepDirection == SweepDirection.Clockwise) { return(roundCenterLeft); } else//逆时针 取左边圆心 { return(roundCenterRight); } } }
//完成形、回転方向を指定できるように /// <summary> /// 扇(pie)型のPathGeometryを作成 /// </summary> /// <param name="center">中心座標</param> /// <param name="distance">中心点からの距離</param> /// <param name="startDegrees">開始角度、0以上360未満で指定</param> /// <param name="stopDegrees">終了角度、0以上360未満で指定</param> /// <param name="direction">回転方向、Clockwiseが時計回り</param> /// <returns></returns> private PathGeometry PieGeometry(Point center, double distance, double startDegrees, double stopDegrees, SweepDirection direction) { Point start = MakePoint(startDegrees, center, distance); //始点座標 Point stop = MakePoint(stopDegrees, center, distance); //終点座標 //開始角度から終了角度までが180度を超えているかの判定 //超えていたらArcSegmentのIsLargeArcをtrue、なければfalseで作成 double diffDegrees = (direction == SweepDirection.Clockwise) ? stopDegrees - startDegrees : startDegrees - stopDegrees; if (diffDegrees < 0) { diffDegrees += 360.0; } bool isLarge = (diffDegrees > 180) ? true : false; var arc = new ArcSegment(stop, new Size(distance, distance), 0, isLarge, direction, true); //PathFigure作成 //ArcSegmentとその両端と中心点をつなぐ直線LineSegment var fig = new PathFigure(); fig.StartPoint = start; //始点座標 fig.Segments.Add(arc); //ArcSegment追加 fig.Segments.Add(new LineSegment(center, true)); //円弧の終点から中心への直線 fig.Segments.Add(new LineSegment(start, true)); //中心から円弧の始点への直線 fig.IsClosed = true; //Pathを閉じる、必須 //PathGeometryを作成してPathFigureを追加して完成 var pg = new PathGeometry(); pg.Figures.Add(fig); return(pg); }
public void EllipseArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked) { ArcSegment segment = new ArcSegment(point, size, rotationAngle, isLargeArc, sweepDirection, isStroked); Figure.Segments.Add(segment); }
private void DrawArcSegment (double xm1, double ym1, double xm2, double ym2, double xr, double yr, double alpha, bool isLargeArc, SweepDirection direction) { if (xr <= 0.000000001 || yr <= 0.000000001) return; var x1 = xm1 * Math.Cos (-alpha) - ym1 * Math.Sin (-alpha); var y1 = xm1 * Math.Sin (-alpha) + ym1 * Math.Cos (-alpha); var x2 = xm2 * Math.Cos (-alpha) - ym2 * Math.Sin (-alpha); var y2 = xm2 * Math.Sin (-alpha) + ym2 * Math.Cos (-alpha); var r = 0.0; if (xr > yr) { y1 = y1 * xr / yr; y2 = y2 * xr / yr; r = xr; } else { x1 = x1 * yr / xr; x2 = x2 * yr / xr; r = yr; } if (4 * r * r < (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) return; var xc1 = 0.0; var xc2 = 0.0; var yc1 = 0.0; var yc2 = 0.0; if (Math.Abs (y1 - y2) > 0.000000001) { var A = (x1 - x2) / (y2 - y1); var B = (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1) / (2 * (y2 - y1)); var a = A * A + 1; var b = -2 * x1 + 2 * A * B - 2 * A * y1; var c = x1 * x1 + B * B - 2 * B * y1 + y1 * y1 - r * r; xc1 = (-b + Math.Sqrt (b * b - 4 * a * c)) / (2 * a); yc1 = A * xc1 + B; xc2 = (-b - Math.Sqrt (b * b - 4 * a * c)) / (2 * a); yc2 = A * xc2 + B; } else { xc1 = (x1 + x2) / 2; yc1 = y1 + Math.Sqrt (r * r - (xc1 - x1) * (xc1 - x1)); xc2 = (x1 + x2) / 2; yc2 = y1 - Math.Sqrt (r * r - (xc2 - x1) * (xc2 - x1)); } var angle1 = Math.Abs (y1 - yc1) / r > 1 ? Math.PI / 2 : Math.Asin (Math.Abs (y1 - yc1) / r); if ((x1 < xc1) && (y1 >= yc1)) angle1 = Math.PI - angle1; if (y1 < yc1) if (x1 < xc1) angle1 = Math.PI + angle1; else angle1 = - angle1; var angle2 = Math.Abs (y2 - yc1) / r > 1 ? Math.PI / 2 : Math.Asin (Math.Abs (y2 - yc1) / r); if ((x2 < xc1) && (y2 >= yc1)) angle2 = Math.PI - angle2; if (y2 < yc1) { if (x2 < xc1) angle2 = Math.PI + angle2; else angle2 = - angle2; } var alfa1 = Math.Abs (y1 - yc2) / r > 1 ? Math.PI / 2 : Math.Asin (Math.Abs (y1 - yc2) / r); if ((x1 < xc2) && (y1 >= yc2)) alfa1 = Math.PI - alfa1; if (y1 < yc2) { if (x1 < xc2) alfa1 = Math.PI + alfa1; else alfa1 = - alfa1; } var alfa2 = Math.Abs (y2 - yc2) / r > 1 ? Math.PI / 2 : Math.Asin (Math.Abs (y2 - yc2) / r); if ((x2 < xc2) && (y2 >= yc2)) alfa2 = Math.PI - alfa2; if (y2 < yc2) { if (x2 < xc2) alfa2 = Math.PI + alfa2; else alfa2 = - alfa2; } cr.Save (); cr.Rotate (alpha); if (xr > yr) cr.Scale (1, yr / xr); else cr.Scale (xr / yr, 1); if (direction == SweepDirection.Clockwise) { if (isLargeArc) { if ((y1 < y2) || ((Math.Abs (y1 - y2) < 0.00000001) && (x1 > x2))) cr.Arc (xc1, yc1, r, angle1, angle2); else cr.Arc (xc2, yc2, r, alfa1, alfa2); } else { if ((y1 > y2) || ((Math.Abs (y1 - y2) < 0.00000001) && (x1 < x2))) cr.Arc (xc1, yc1, r, angle1, angle2); else cr.Arc (xc2, yc2, r, alfa1, alfa2); } } else { if (isLargeArc) { if ((y1 > y2) || ((Math.Abs (y1 - y2) < 0.00000001) && (x1 < x2))) cr.ArcNegative (xc1, yc1, r, angle1, angle2); else cr.ArcNegative (xc2, yc2, r, alfa1, alfa2); } else { if ((y1 < y2) || ((Math.Abs (y1 - y2) < 0.00000001) && (x1 > x2))) cr.ArcNegative (xc1, yc1, r, angle1, angle2); else cr.ArcNegative (xc2, yc2, r, alfa1, alfa2); } } cr.Restore (); }
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { }
public static Telerik.Windows.Documents.Fixed.Model.Graphics.SweepDirection ConvertSweepDirection(SweepDirection sweepDirection) { return(sweepDirection == SweepDirection.Clockwise ? Telerik.Windows.Documents.Fixed.Model.Graphics.SweepDirection.Clockwise : Telerik.Windows.Documents.Fixed.Model.Graphics.SweepDirection.Counterclockwise); }
/// <summary> /// Parses the specified markup string. /// </summary> /// <param name="s">The markup string.</param> public void Parse(string s) { bool openFigure = false; using (StringReader reader = new StringReader(s)) { Command lastCommand = Command.None; Command command; Point point = new Point(); while ((command = ReadCommand(reader, lastCommand)) != Command.Eof) { switch (command) { case Command.FillRule: // TODO: Implement. reader.Read(); break; case Command.Move: case Command.MoveRelative: if (openFigure) { _context.EndFigure(false); } point = command == Command.Move ? ReadPoint(reader) : ReadRelativePoint(reader, point); _context.BeginFigure(point, true); openFigure = true; break; case Command.Line: point = ReadPoint(reader); _context.LineTo(point); break; case Command.LineRelative: point = ReadRelativePoint(reader, point); _context.LineTo(point); break; case Command.HorizontalLine: point = point.WithX(ReadDouble(reader)); _context.LineTo(point); break; case Command.HorizontalLineRelative: point = new Point(point.X + ReadDouble(reader), point.Y); _context.LineTo(point); break; case Command.VerticalLine: point = point.WithY(ReadDouble(reader)); _context.LineTo(point); break; case Command.VerticalLineRelative: point = new Point(point.X, point.Y + ReadDouble(reader)); _context.LineTo(point); break; case Command.CubicBezierCurve: { Point point1 = ReadPoint(reader); Point point2 = ReadPoint(reader); point = ReadPoint(reader); _context.CubicBezierTo(point1, point2, point); break; } case Command.Arc: { //example: A10,10 0 0,0 10,20 //format - size rotationAngle isLargeArcFlag sweepDirectionFlag endPoint Size size = ReadSize(reader); ReadSeparator(reader); double rotationAngle = ReadDouble(reader); ReadSeparator(reader); bool isLargeArc = ReadBool(reader); ReadSeparator(reader); SweepDirection sweepDirection = ReadBool(reader) ? SweepDirection.Clockwise : SweepDirection.CounterClockwise; point = ReadPoint(reader); _context.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection); break; } case Command.Close: _context.EndFigure(true); openFigure = false; break; default: throw new NotSupportedException("Unsupported command"); } lastCommand = command; } if (openFigure) { _context.EndFigure(false); } } }
private void DrawWedge(DrawingContext drawingContext, int centerX, int centerY, SweepDirection sweepDirection, double percentage) { GeometryDrawing geometryDrawing = new GeometryDrawing(); StreamGeometry streamGeo = new StreamGeometry(); double sweepRadians = (Math.PI / 2.0) * percentage; // Determine start point double startX = centerX; double startY = centerY; // Determine end point double endX = Math.Cos(sweepRadians) * 50.0; double endY = Math.Sin(sweepRadians) * 50.0; if (sweepDirection == SweepDirection.Clockwise) { endX = centerX - endX; } using (StreamGeometryContext sgc = streamGeo.Open()) { sgc.BeginFigure(new System.Windows.Point(startX, startY), true, true); sgc.ArcTo(new System.Windows.Point(endX, endY), new Size(50.0, 50.0), sweepRadians, false, sweepDirection, false, true); } geometryDrawing.Geometry = streamGeo; drawingContext.DrawGeometry(Brushes.Red, null, geometryDrawing.Geometry); }
/// <summary> /// Draws an arc to the specified point. /// </summary> /// <param name="point">The destination point.</param> /// <param name="size">The radii of an oval whose perimeter is used to draw the angle.</param> /// <param name="rotationAngle">The rotation angle of the oval that specifies the curve.</param> /// <param name="isLargeArc">true to draw the arc greater than 180 degrees; otherwise, false.</param> /// <param name="sweepDirection"> /// A value that indicates whether the arc is drawn in the Clockwise or Counterclockwise direction. /// </param> public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) { _impl.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection); }
/// <summary> /// 向当前路径中添加一条弧线段。 /// </summary> /// <param name="end">弧线路径段的终结点。</param> /// <param name="size">弧线路径段的尺寸。</param> /// <param name="rotationAngel">弧线路径段的旋转角度。</param> /// <param name="sweepDirection">弧线路径段的绘制方向。</param> /// <param name="arcSize">弧线路径段是否大于 180 度。</param> public void AddArc(Vector2 end, Size2F size, float rotationAngel, SweepDirection sweepDirection, ArcSize arcSize) { this.Add(new ArcSegment(end, size, rotationAngel, sweepDirection, arcSize)); }
public override void ArcTo(Point Point, Size Size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) { _builder.AppendFormat("c.ArcTo({0}, {1}, {2}, {3}, {4}, true, false);\n", Point.ToCode(), Size.ToCode(), rotationAngle.ToCode(), isLargeArc.ToCode(), sweepDirection.ToCode()); }
public PathGeometry GetCircleSegment(Point centerPoint, double radius, double angle, SweepDirection direction) { var path = new Path(); var pathGeometry = new PathGeometry(); var circleStart = new Point(3, 50); var arcSegment = new ArcSegment { IsLargeArc = false, Point = ScaleUnitCirclePoint(centerPoint, angle, radius + 2), Size = new Size(radius, radius), SweepDirection = direction }; var pathFigure = new PathFigure { StartPoint = circleStart, IsClosed = false }; pathFigure.Segments.Add(arcSegment); pathGeometry.Figures.Add(pathFigure); return(pathGeometry); }
/// <summary> /// Initializes a new instance of the Visfiire.Charts.PieChart.PathGeometryParams class /// </summary> /// <param name="size">Pie/Doughnut size</param> /// <param name="rotation">Rotation angle</param> /// <param name="isLargeArc">Whether IsLargeArc</param> /// <param name="sweepDirection">SweepDirection</param> /// <param name="endPoint">EndPoint as Point</param> public ArcSegmentParams(Size size, Double rotation, Boolean isLargeArc, SweepDirection sweepDirection, Point endPoint) : base(endPoint) { Size = size; RotationAngle = rotation; IsLargeArc = isLargeArc; SweepDirection = sweepDirection; }
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) #endif { SerializePointAndTwoBools(ParserGeometryContextOpCodes.ArcTo, point, isStroked, isSmoothJoin); // // Pack isLargeArc & sweepDirection into a single byte. // byte packMe = 0; if (isLargeArc) { packMe = LowNibble; } #if PBTCOMPILER if (sweepDirection) #else if (SweepToBool(sweepDirection)) #endif { packMe |= HighNibble; } _bw.Write(packMe); // // Write out Size & Rotation Angle. // XamlSerializationHelper.WriteDouble(_bw, size.Width); XamlSerializationHelper.WriteDouble(_bw, size.Height); XamlSerializationHelper.WriteDouble(_bw, rotationAngle); }
/// <inheritdoc/> public void ArcTo(IPointShape point, IPathSize size, double rotationAngle = 0.0, bool isLargeArc = false, SweepDirection sweepDirection = SweepDirection.Clockwise, bool isStroked = true, bool isSmoothJoin = true) { var segment = _factory.CreateArcSegment( point, size, rotationAngle, isLargeArc, sweepDirection, isStroked, isSmoothJoin); _currentFigure.Segments = _currentFigure.Segments.Add(segment); }
public static ESRI.ArcGIS.Client.Geometry.MapPoint ConstructCenterPoint(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, ESRI.ArcGIS.Client.Geometry.MapPoint endPoint, double radius, bool isMinor, SweepDirection direction, out double bearing1, out double bearing2) { bearing1 = bearing2 = 0.0; // We need to switch the curve direction, b/c we are starting with the end point if (radius > 0) direction = direction == SweepDirection.Clockwise ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; bool isLargeArc = !isMinor; // Used logic from http://www.charlespetzold.com/blog/2008/01/Mathematics-of-ArcSegment.html Point pt1 = new Point(startPoint.X, startPoint.Y); Point pt2 = new Point(endPoint.X, endPoint.Y); bool isCounterclockwise = direction == SweepDirection.Counterclockwise; // Get info about chord that connects both points Point midPoint = new Point((pt1.X + pt2.X) / 2, (pt1.Y + pt2.Y) / 2); Vector vect = pt2 - pt1; double halfChord = vect.Length / 2; // Get vector from chord to center Vector vectRotated; // (comparing two Booleans here!) if (isLargeArc == isCounterclockwise) vectRotated = new Vector(-vect.Y, vect.X); else vectRotated = new Vector(vect.Y, -vect.X); vectRotated.Normalize(); // maintains its direction but its Length becomes 1. // Distance from chord to center double centerDistance = Math.Sqrt(Math.Abs(radius * radius - halfChord * halfChord)); // Calculate center point Point center = midPoint + centerDistance * vectRotated; if ((center.X == double.NaN) || (center.Y == double.NaN)) return null; // Get angles from center to the two points double angle1 = Math.Atan2(pt1.Y - center.Y, pt1.X - center.X); double angle2 = Math.Atan2(pt2.Y - center.Y, pt2.X - center.X); if ((angle1 == double.NaN) || (angle2 == double.NaN)) return null; // (another comparison of two Booleans!) if (isLargeArc == (Math.Abs(angle2 - angle1) < Math.PI)) { if (angle1 < angle2) angle1 += 2 * Math.PI; else angle2 += 2 * Math.PI; } // Convert to bearing and reverse line bearing1 = (Math.PI / 2 - angle1) - Math.PI; if (bearing1 < 0) bearing1 += Math.PI * 2; // Convert to bearing and reverse line bearing2 = (Math.PI / 2 - angle2) - Math.PI; if (bearing2 < 0) bearing2 += Math.PI * 2; return new ESRI.ArcGIS.Client.Geometry.MapPoint(center.X, center.Y); }
/// <summary> /// 设置百分百,输入小数,自动乘100 /// </summary> /// <param name="percentValue"></param> private void SetValue(double percentValue) { /***************************************** * 方形矩阵边长为34,半长为17 * 环形半径为14,所以距离边框3个像素 * 环形描边3个像素 ******************************************/ double angel = percentValue * 360; //角度 double radius = 20; //环形半径 //起始点 double leftStart = 25; double topStart = 5; //结束点 double endLeft = 0; double endTop = 0; //数字显示 //lbValue.Content = (percentValue * 100).ToString("0") + "%"; /*********************************************** * 整个环形进度条使用Path来绘制,采用三角函数来计算 * 环形根据角度来分别绘制,以90度划分,方便计算比例 ***********************************************/ bool isLagreCircle = false; //是否优势弧,即大于180度的弧形 //小于90度 if (angel <= 90) { /***************** * * * * * ra * * * * * * * * * * * * ******************/ double ra = (90 - angel) * Math.PI / 180; //弧度 endLeft = leftStart + Math.Cos(ra) * radius; //余弦横坐标 endTop = topStart + radius - Math.Sin(ra) * radius; //正弦纵坐标 } else if (angel <= 180) { /***************** * * * * * * * * * * * * * * ra * * * * ******************/ double ra = (angel - 90) * Math.PI / 180; //弧度 endLeft = leftStart + Math.Cos(ra) * radius; //余弦横坐标 endTop = topStart + radius + Math.Sin(ra) * radius; //正弦纵坐标 } else if (angel <= 270) { /***************** * * * * * * * * * * * * * * * ra* * * ******************/ isLagreCircle = true; //优势弧 double ra = (angel - 180) * Math.PI / 180; endLeft = leftStart - Math.Sin(ra) * radius; endTop = topStart + radius + Math.Cos(ra) * radius; } else if (angel < 360) { /***************** * * * * * ra * * * * * * * * * * * * * * ******************/ isLagreCircle = true; //优势弧 double ra = (angel - 270) * Math.PI / 180; endLeft = leftStart - Math.Cos(ra) * radius; endTop = topStart + radius - Math.Sin(ra) * radius; } else { isLagreCircle = true; //优势弧 endLeft = leftStart - 0.001; //不与起点在同一点,避免重叠绘制出非环形 endTop = topStart; } Point arcEndPt = new Point(endLeft, endTop); //结束点 Size arcSize = new Size(radius, radius); SweepDirection direction = SweepDirection.Clockwise; //顺时针弧形 //弧形 ArcSegment arcsegment = new ArcSegment(arcEndPt, arcSize, 0, isLagreCircle, direction, true); //形状集合 PathSegmentCollection pathsegmentCollection = new PathSegmentCollection(); pathsegmentCollection.Add(arcsegment); //路径描述 PathFigure pathFigure = new PathFigure(); pathFigure.StartPoint = new Point(leftStart, topStart); //起始地址 pathFigure.Segments = pathsegmentCollection; //路径描述集合 PathFigureCollection pathFigureCollection = new PathFigureCollection(); pathFigureCollection.Add(pathFigure); //复杂形状 PathGeometry pathGeometry = new PathGeometry(); pathGeometry.Figures = pathFigureCollection; //Data赋值 var path = Template.FindName("MyCycleProcessBar", this) as Path; if (path == null) { return; } double thickness = Thickness / (Height / 50); path.Data = pathGeometry; path.StrokeThickness = double.IsNaN(thickness) ? Thickness : thickness; //达到100%则闭合整个 CircleProgressBar s = this as CircleProgressBar; if (angel == 360) { path.Data = Geometry.Parse(path.Data.ToString() + " z"); } }
/// <summary> /// Create a circular arc from current point to (x,y) with specified parameters. /// </summary> /// <remarks> /// Note `CanvasRenderingContext2D.arcTo` is implemented in a different approach compared with WPF's ArcSegment. /// WPF's approach is used here. See <see cref="ArcSegmentExtension.Flatten"/>. /// </remarks> public void ArcTo(double x, double y, double radius, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked) { ArcTo(new Point(x, y), radius, rotationAngle, isLargeArc, sweepDirection, isStroked); }
public void ArcTo(Point point, double radius, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked) { ArcSegment segment = new ArcSegment(point, new Size(radius, radius), rotationAngle, isLargeArc, sweepDirection, isStroked); Figure.Segments.Add(segment); }
public override void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked, bool isSmoothJoin) { _lastPoint = point; _fill = false; }
/// <summary> /// Create an elliptical arc from current point to (x,y) with specified parameters. /// </summary> public void EllipseArcTo(double x, double y, double radiusX, double radiusY, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection, bool isStroked) { EllipseArcTo(new Point(x, y), new Size(radiusX, radiusY), rotationAngle, isLargeArc, sweepDirection, isStroked); }
/// <summary> /// Parses the specified markup string. /// </summary> /// <param name="s">The markup string.</param> public void Parse(string s) { bool openFigure = false; using (StringReader reader = new StringReader(s)) { Command command = Command.None; Point point = new Point(); bool relative = false; Point? previousControlPoint = null; while (ReadCommand(reader, ref command, ref relative)) { switch (command) { case Command.FillRule: _context.SetFillRule(ReadFillRule(reader)); previousControlPoint = null; break; case Command.Move: if (openFigure) { _context.EndFigure(false); } point = ReadPoint(reader, point, relative); _context.BeginFigure(point, true); openFigure = true; previousControlPoint = null; break; case Command.Line: point = ReadPoint(reader, point, relative); _context.LineTo(point); previousControlPoint = null; break; case Command.HorizontalLine: if (!relative) { point = point.WithX(ReadDouble(reader)); } else { point = new Point(point.X + ReadDouble(reader), point.Y); } _context.LineTo(point); previousControlPoint = null; break; case Command.VerticalLine: if (!relative) { point = point.WithY(ReadDouble(reader)); } else { point = new Point(point.X, point.Y + ReadDouble(reader)); } _context.LineTo(point); previousControlPoint = null; break; case Command.QuadraticBezierCurve: { Point handle = ReadPoint(reader, point, relative); previousControlPoint = handle; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.QuadraticBezierTo(handle, point); break; } case Command.SmoothQuadraticBezierCurve: { Point end = ReadPoint(reader, point, relative); if (previousControlPoint != null) { previousControlPoint = MirrorControlPoint((Point)previousControlPoint, point); } _context.QuadraticBezierTo(previousControlPoint ?? point, end); point = end; break; } case Command.CubicBezierCurve: { Point point1 = ReadPoint(reader, point, relative); ReadSeparator(reader); Point point2 = ReadPoint(reader, point, relative); previousControlPoint = point2; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.CubicBezierTo(point1, point2, point); break; } case Command.SmoothCubicBezierCurve: { Point point2 = ReadPoint(reader, point, relative); ReadSeparator(reader); Point end = ReadPoint(reader, point, relative); if (previousControlPoint != null) { previousControlPoint = MirrorControlPoint((Point)previousControlPoint, point); } _context.CubicBezierTo(previousControlPoint ?? point, point2, end); previousControlPoint = point2; point = end; break; } case Command.Arc: { Size size = ReadSize(reader); ReadSeparator(reader); double rotationAngle = ReadDouble(reader); ReadSeparator(reader); bool isLargeArc = ReadBool(reader); ReadSeparator(reader); SweepDirection sweepDirection = ReadBool(reader) ? SweepDirection.Clockwise : SweepDirection.CounterClockwise; ReadSeparator(reader); point = ReadPoint(reader, point, relative); _context.ArcTo(point, size, rotationAngle, isLargeArc, sweepDirection); previousControlPoint = null; break; } case Command.Close: _context.EndFigure(true); openFigure = false; previousControlPoint = null; break; default: throw new NotSupportedException("Unsupported command"); } } if (openFigure) { _context.EndFigure(false); } } }
ArcSegment MakeArc(double x, double y, SweepDirection dir) { ArcSegment arc = new ArcSegment( new Point(x, y), new Size(cornerRadius, cornerRadius), 0, false, dir, true); arc.Freeze(); return arc; }