如何画圆弧半径和启停角 [英] How to draw arc with radius and start and stop angle

查看:106
本文介绍了如何画圆弧半径和启停角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在我的画布元素的DataContext以下四个属性。

If I have the following four properties in my DataContext of my Canvas element

Point  Center
double Radius
double StartAngle
double EndAngle

我可以没有任何额外的code身后划出一道弧线?

can I draw an arc without any extra code behind?

推荐答案

提供了一个自定义组件被证明是最好的解决方案。我用它像这样在我的code

Providing a custom component turned out to be the best solution. I use it like this in my code

<Controls:Arc Center="{Binding Path=PreviousMousePositionPixels}" 
         Stroke="White" 
         StrokeDashArray="4 4"
         SnapsToDevicePixels="True"
         StartAngle="0" 
         EndAngle="{Binding Path=DeltaAngle}" 
         SmallAngle="True"
         Radius="40"/>

小角度为真时,将呈现点之间的小角度,不论顺序
由startAngle EndAngle 。当小角度是假的弧线呈现反
顺时针方向旋转。

SmallAngle when true will render the small angle between the points irrespective of order of StartAngle and EndAngle. When SmallAngle is false the arc is rendered counter clockwise.

的实现。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;

public sealed class Arc : Shape
{
    public Point Center
    {
        get { return (Point)GetValue(CenterProperty); }
        set { SetValue(CenterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Center.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CenterProperty =
        DependencyProperty.Register("Center", typeof(Point), typeof(Arc)
        , new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsRender));


    public double StartAngle
    {
        get { return (double)GetValue(StartAngleProperty); }
        set { SetValue(StartAngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for StartAngle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty StartAngleProperty =
        DependencyProperty.Register("StartAngle", typeof(double), typeof(Arc)
        , new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender));

    public double EndAngle
    {
        get { return (double)GetValue(EndAngleProperty); }
        set { SetValue(EndAngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for EndAngle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EndAngleProperty =
        DependencyProperty.Register("EndAngle", typeof(double), typeof(Arc)
        , new FrameworkPropertyMetadata(Math.PI/2.0, FrameworkPropertyMetadataOptions.AffectsRender));

    public double Radius
    {
        get { return (double)GetValue(RadiusProperty); }
        set { SetValue(RadiusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Radius.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty RadiusProperty =
        DependencyProperty.Register("Radius", typeof(double), typeof(Arc)
        , new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender));



    public bool SmallAngle
    {
        get { return (bool)GetValue(SmallAngleProperty); }
        set { SetValue(SmallAngleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SmallAngle.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SmallAngleProperty =
        DependencyProperty.Register("SmallAngle", typeof(bool), typeof(Arc)
        , new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));


    static Arc()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Arc), new FrameworkPropertyMetadata(typeof(Arc)));
    }

    protected override Geometry DefiningGeometry
    {
        get
        {

            var a0 = StartAngle < 0 ? StartAngle + 2 * Math.PI : StartAngle;
            var a1 = EndAngle < 0 ? EndAngle + 2 * Math.PI : EndAngle;

            if (a1<a0)
            {
                a1 += Math.PI * 2;
            }

            SweepDirection d = SweepDirection.Counterclockwise;
            bool large;

            if (SmallAngle)
            {
                large = false;
                double t = a1;
                if ((a1-a0)>Math.PI)
                {
                    d = SweepDirection.Counterclockwise;
                }
                else
                {
                    d = SweepDirection.Clockwise;
                }


            }else{
                large = (Math.Abs(a1 - a0) < Math.PI);
            }

            Point p0 = Center + new Vector(Math.Cos(a0), Math.Sin(a0)) * Radius;
            Point p1 = Center + new Vector(Math.Cos(a1), Math.Sin(a1)) * Radius;


            List<PathSegment> segments = new List<PathSegment>(1);
            segments.Add(new ArcSegment(p1, new Size(Radius, Radius), 0.0, large, d, true));

            List<PathFigure> figures = new List<PathFigure>(1);
            PathFigure pf = new PathFigure(p0, segments, true);
            pf.IsClosed = false;
            figures.Add(pf);

            Geometry g = new PathGeometry(figures, FillRule.EvenOdd, null);
            return g;
        }
    }
}

这篇关于如何画圆弧半径和启停角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆