silverlight:贝塞尔曲线

简介: Silverlight并没有象flash那样直接提供画线、画圆、画曲线的方法,只能用Path来生成贝塞尔曲线。 下面是示例代码: XAML部分: ...

Silverlight并没有象flash那样直接提供画线、画圆、画曲线的方法,只能用Path来生成贝塞尔曲线。

下面是示例代码:

XAML部分:

<UserControl x:Class="SLCurveSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="400">

    <Canvas x:Name="LayoutRoot" Background="White">
        <Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="Red" x:Name="point1"></Ellipse>
        <TextBlock Text="Left Point" Name="tbLeftPoint" Visibility="Collapsed"></TextBlock>
        <Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="Red" x:Name="point2"></Ellipse>
        <TextBlock Text="Right Point" Name="tbRightPoint" Visibility="Collapsed"></TextBlock>
        <Path Stroke="Red" StrokeThickness="1" x:Name="p" >
            <Path.Data>
                <PathGeometry>
                    <PathGeometry.Figures>
                        <PathFigure>
                            <PathFigure.Segments>
                                <BezierSegment />                              
                            </PathFigure.Segments>
                        </PathFigure>
                    </PathGeometry.Figures>
                </PathGeometry>
            </Path.Data>
        </Path>
    </Canvas>
</UserControl>

 Xaml.cs部分:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace SLCurveSample
{
    public partial class MainPage : UserControl
    {
        Point _leftPoint = new Point();
        Point _rightPoint = new Point();
        BezierSegment seg = null;

        public MainPage()
        {
            InitializeComponent();
            this.Loaded += PageLoaded;


        }



        void PageLoaded(object sender, RoutedEventArgs e)
        {
            this.SizeChanged += PageSizeChanged;
            this.MouseMove += PageMouseMove;

            this.Loaded -= PageLoaded;
        }

        void PageMouseMove(object sender, MouseEventArgs e)
        {
            Point mousePos = e.GetPosition(this);

            //根据鼠标的位置对线条粗细、左右圈圈大小做一些交互
            double scale = Math.Abs(_leftPoint.Y - mousePos.Y) / _leftPoint.Y;
            point1.Width = point1.Height = 10 + 40 * scale;
            point2.Width = point2.Height = point1.Width;
            p.StrokeThickness = 3 - 2 * scale;

            //重绘
            Draw();

            //计算二个控制点的位置
            Point ctlPoint1 = new Point() { X = (mousePos.X + _leftPoint.X) * 0.5, Y = (mousePos.Y + _leftPoint.Y) * 0.5 };
            Point ctlPoint2 = new Point() { X = (mousePos.X + _rightPoint.X) * 0.5, Y = (mousePos.Y + _rightPoint.Y) * 0.5 };
            if (seg != null)
            {
                seg.Point1 = ctlPoint1;//贝兹曲线的第一个控制点
                seg.Point2 = ctlPoint2;//贝兹曲线的第二个控制点
            }





        }

        void PageSizeChanged(object sender, SizeChangedEventArgs e)
        {

            Draw();

        }

        void Draw()
        {

            double _stageWidth = this.ActualWidth;
            double _stageHeight = this.ActualHeight;

            double _margin = 80;
            //将二个小圈定位于左右二侧
            point1.SetValue(Canvas.TopProperty, _stageHeight * 0.5);
            point1.SetValue(Canvas.LeftProperty, _margin);

            point2.SetValue(Canvas.TopProperty, _stageHeight * 0.5);
            point2.SetValue(Canvas.LeftProperty, _stageWidth - _margin);



            //计算左侧小圈的中心
            _leftPoint.X = (double)point1.GetValue(Canvas.LeftProperty) + point1.Width * 0.5;
            _leftPoint.Y = (double)point1.GetValue(Canvas.TopProperty) + point1.Height * 0.5;

            tbLeftPoint.SetValue(Canvas.LeftProperty, _leftPoint.X - 20);
            tbLeftPoint.SetValue(Canvas.TopProperty, _leftPoint.Y + 10);


            //计算右侧小圈的中心
            _rightPoint.X = (double)point2.GetValue(Canvas.LeftProperty) + point2.Width * 0.5;
            _rightPoint.Y = (double)point2.GetValue(Canvas.TopProperty) + point2.Height * 0.5;

            tbRightPoint.SetValue(Canvas.LeftProperty, _rightPoint.X - 20);
            tbRightPoint.SetValue(Canvas.TopProperty, _rightPoint.Y + 10);

            PathFigure figure = (p.Data as PathGeometry).Figures[0];
            figure.StartPoint = _leftPoint;//设置(贝兹曲线的)起点

            seg = figure.Segments[0] as BezierSegment;
            seg.Point3 = _rightPoint;//贝兹曲线的终点


        }
    }
}

 以上的代码,先在Canvas中放置了一段Path,然后在后台去动态修改贝塞尔曲线的控制点,并加入了与鼠标的一些简单交互。更详细的原理也可参见我之前记录的Flash/Flex学习笔记(20):贝塞尔曲线

运行截图:

目录
相关文章
|
图形学
浅谈Unity之贝塞尔曲线
贝塞尔曲线的创建
|
数据可视化 图形学
Unity 之 贝塞尔曲线介绍和实际使用
Unity 中对贝塞尔曲线的实战应用,制作可视化操作曲线工具,文末附工具源码链接~
862 0
Unity 之 贝塞尔曲线介绍和实际使用
|
C#
WPF中的3D变换PlaneProjection
原文:WPF中的3D变换PlaneProjection 在UWP中有一个比较好用的伪3D变换PlaneProjection,可以以一种轻量级和非常简单的方式实现3D的效果。这种效果在Silverlight中也有这种变换,但在WPF中确一直没有提供。
905 0
|
C# vr&ar
WPF 碰撞检测
原文:WPF 碰撞检测 have tested this, it worked, at least for me var x1 = Canvas.GetLeft(e1); var y1 = Canvas.
1236 0
|
容器
Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)
原文:Silverlight & Blend动画设计系列二:旋转动画(RotateTransform)   Silverlight的基础动画包括偏移、旋转、缩放、倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的。
1013 0
|
C# 前端开发
wpf实现两头渐窄的线条效果
原文:wpf实现两头渐窄的线条效果 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangli321456/article/details/80064509 ...
779 0
|
C# 小程序
WPF 3D变换应用
原文:WPF 3D变换应用  WPF可以提供的3D模型使我们可以轻松地创建3D实体,虽然目前来看还很有一些性能上的问题,不过对于一些简单的3D应用应该是可取的,毕竟其开发效率高,而且也容易上手。         下面给大家演示的是使用在WPF 3D上实现视角变换,通过鼠标拖动来变换观察视角,通过滚轮来放缩视距。
737 0
|
C#
WPF 2D 碰撞检测
原文:WPF 2D 碰撞检测     var intersectionDetail = path1.Data.FillContainsWithDetail(path2.Data); if (intersectionDetail != IntersectionDetail.
903 0
|
C# 前端开发
[原译]WPF绘制圆角多边形
原文:[原译]WPF绘制圆角多边形 介绍 最近,我发现我需要个圆角多边形。而且是需要在运行时从用户界面来绘制。WPF有多边形。但是不支持圆角。我搜索了一下。也没找到可行的现成例子。于是就自己做吧。本文描述了圆角多边形的实现,也包括如何用在你的项目里。
1581 0