ko444evnik (ko444evnik) wrote,
ko444evnik
ko444evnik

Петцольдовкий сэмпл с динамичной перерисовкой кривой Безье

картинка:



в хамле описываются 4 именованные точки (EllipseGeometry)
x:Name="ptStart"
x:Name="ptCtrl1"
x:Name="ptCtrl2"
x:Name="ptEnd"

к которые далее привязываются точки для фигуры, изображающей кривую Безье:
<PathFigure
StartPoint="{Binding ElementName=ptStart,Path=Center}">
<BezierSegment
Point1="{Binding ElementName=ptCtrl1,Path=Center}"
Point2="{Binding ElementName=ptCtrl2,Path=Center}"
Point3="{Binding ElementName=ptEnd,Path=Center}" />
</PathFigure>

соответственно в коде - обработчики щелчков мыши на Канвасе. щелчок одной кнопки мыши меняет позицию ptCtrl1, другой - ptCtrl2. зависящая от них кривая Безье - автоматически перерисовывается.


хамл:

p://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="Petzold.BezierExperimenter.BezierExperimenter"
    Title="Bezier Experimenter">
  <Canvas Name="canvas">

    <!-- Draw the four points defining the curve. -->
    
    <Path Fill="{DynamicResource
                {x:Static SystemColors.WindowTextBrushKey}}"
>
      <Path.Data>
        <GeometryGroup>
          <EllipseGeometry x:Name="ptStart" RadiusX="2" RadiusY="2" />
          <EllipseGeometry x:Name="ptCtrl1" RadiusX="2" RadiusY="2" />
          <EllipseGeometry x:Name="ptCtrl2" RadiusX="2" RadiusY="2" />
          <EllipseGeometry x:Name="ptEnd" RadiusX="2" RadiusY="2" />
        </GeometryGroup>
      </Path.Data>
    </Path>

    <!-- Draw the curve itself -->
    
    <Path Stroke="{DynamicResource
                {x:Static SystemColors.WindowTextBrushKey}}"
>
      <Path.Data>
        <PathGeometry>
          <PathGeometry.Figures>
            <PathFigure StartPoint="{Binding ElementName=ptStart,
                             Path=Center}"
>
              <BezierSegment Point1="{Binding ElementName=ptCtrl1,
                              Path=Center}"

                      Point2="{Binding ElementName=ptCtrl2,
                              Path=Center}"

                      Point3="{Binding ElementName=ptEnd,
                              Path=Center}"
/>
            </PathFigure>            
          </PathGeometry.Figures>          
        </PathGeometry>        
      </Path.Data>
    </Path>

    <!-- Draw gray lines connecting end points and control points. -->
    
    <Path Stroke="{DynamicResource
              {x:Static SystemColors.GrayTextBrushKey}}"
>
      <Path.Data>
        <GeometryGroup>
          <LineGeometry StartPoint="{Binding ElementName=ptStart,
                            Path=Center}"

                 EndPoint="{Binding ElementName=ptCtrl1,
                           Path=Center}"
/>
          <LineGeometry StartPoint="{Binding ElementName=ptEnd,
                            Path=Center}"

                 EndPoint="{Binding ElementName=ptCtrl2,
                           Path=Center}"
/>
        </GeometryGroup>        
      </Path.Data>
    </Path>

    <!-- Display some labels with the actual points. -->

    <Label Canvas.Left="{Binding ElementName=ptStart, Path=Center.X}"
        Canvas.Top="{Binding ElementName=ptStart, Path=Center.Y}"
        Content="{Binding ElementName=ptStart, Path=Center}" />

    <Label Canvas.Left="{Binding ElementName=ptCtrl1, Path=Center.X}"
        Canvas.Top="{Binding ElementName=ptCtrl1, Path=Center.Y}"
        Content="{Binding ElementName=ptCtrl1, Path=Center}" />

    <Label Canvas.Left="{Binding ElementName=ptCtrl2, Path=Center.X}"
        Canvas.Top="{Binding ElementName=ptCtrl2, Path=Center.Y}"
        Content="{Binding ElementName=ptCtrl2, Path=Center}" />

    <Label Canvas.Left="{Binding ElementName=ptEnd, Path=Center.X}"
        Canvas.Top="{Binding ElementName=ptEnd, Path=Center.Y}"
        Content="{Binding ElementName=ptEnd, Path=Center}" />
  </Canvas>
</Window>





.СS

//---------------------------------------------------
// BezierExperimenter.cs (c) 2006 by Charles Petzold
//---------------------------------------------------
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace Petzold.BezierExperimenter
{
  public partial class BezierExperimenter : Window
  {
    [STAThread]
    public static void Main()
    {
      Application app = new Application();
      app.Run(new BezierExperimenter());
    }
    public BezierExperimenter()
    {
      InitializeComponent();
      canvas.SizeChanged += CanvasOnSizeChanged;
    }
    // When the Canvas size changes, reset the four points.
    protected virtual void CanvasOnSizeChanged(object sender,
                    SizeChangedEventArgs args)
    {
      ptStart.Center = new Point(args.NewSize.Width / 4,
                    args.NewSize.Height / 2);
      ptCtrl1.Center = new Point(args.NewSize.Width / 2,
                    args.NewSize.Height / 4);
      ptCtrl2.Center = new Point(args.NewSize.Width / 2,
                    3 * args.NewSize.Height / 4);
      ptEnd.Center = new Point(3 * args.NewSize.Width / 4,
                   args.NewSize.Height / 2);
    }
    // Change the control points based on mouse clicks and moves.
    protected override void OnMouseDown(MouseButtonEventArgs args)
    {
      base.OnMouseDown(args);
      Point pt = args.GetPosition(canvas);

      if (args.ChangedButton == MouseButton.Left)
        ptCtrl1.Center = pt;

      if (args.ChangedButton == MouseButton.Right)
        ptCtrl2.Center = pt;
    }
    protected override void OnMouseMove(MouseEventArgs args)
    {
      base.OnMouseMove(args);
      Point pt = args.GetPosition(canvas);

      if (args.LeftButton == MouseButtonState.Pressed)
        ptCtrl1.Center = pt;

      if (args.RightButton == MouseButtonState.Pressed)
        ptCtrl2.Center = pt;
    }
  }
}




P.S. кусок кода с [STAThread] public static void Main(){..} - является старорежимной формой запуска и более не используется. если создавать новый проект в VS2010 и переносить в него код - его следует удалить.

Tags: .net, .wpf, графика, пример-кода
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 2 comments