using System.Windows; using System.Windows.Media.Media3D; namespace HelixToolkit { /// /// A plane defined by origin and normal, length and width /// public class PlaneVisual3D : MeshElement3D { public static readonly DependencyProperty DivLengthProperty = DependencyProperty.Register("DivLength", typeof(int), typeof(PlaneVisual3D), new UIPropertyMetadata(10)); public static readonly DependencyProperty DivWidthProperty = DependencyProperty.Register("DivWidth", typeof(int), typeof(PlaneVisual3D), new UIPropertyMetadata(10)); public static readonly DependencyProperty LengthDirectionProperty = DependencyProperty.Register("LengthDirection", typeof(Vector3D), typeof(PlaneVisual3D), new PropertyMetadata(new Vector3D(1, 0, 0), GeometryChanged)); public static readonly DependencyProperty LengthProperty = DependencyProperty.Register("Length", typeof(double), typeof(PlaneVisual3D), new PropertyMetadata(10.0, GeometryChanged)); public static readonly DependencyProperty NormalProperty = DependencyProperty.Register("Normal", typeof(Vector3D), typeof(PlaneVisual3D), new PropertyMetadata(new Vector3D(0, 0, 1), GeometryChanged)); public static readonly DependencyProperty OriginProperty = DependencyProperty.Register("Origin", typeof(Point3D), typeof(PlaneVisual3D), new PropertyMetadata(new Point3D(0, 0, 0), GeometryChanged)); public static readonly DependencyProperty WidthProperty = DependencyProperty.Register("Width", typeof(double), typeof(PlaneVisual3D), new PropertyMetadata(10.0, GeometryChanged)); /// /// Gets or sets the center point of the plane. /// /// The origin. public Point3D Origin { get { return (Point3D)GetValue(OriginProperty); } set { SetValue(OriginProperty, value); } } /// /// Gets or sets the normal vector of the plane. /// /// The normal. public Vector3D Normal { get { return (Vector3D)GetValue(NormalProperty); } set { SetValue(NormalProperty, value); } } /// /// Gets or sets the length direction. /// /// The length direction. public Vector3D LengthDirection { get { return (Vector3D)GetValue(LengthDirectionProperty); } set { SetValue(LengthDirectionProperty, value); } } /// /// Gets or sets the length. /// /// The length. public double Length { get { return (double)GetValue(LengthProperty); } set { SetValue(LengthProperty, value); } } /// /// Gets or sets the width. /// /// The width. public double Width { get { return (double)GetValue(WidthProperty); } set { SetValue(WidthProperty, value); } } /// /// Gets or sets the number of divisions in the 'length' direction. /// /// The number of divisions. public int DivLength { get { return (int)GetValue(DivLengthProperty); } set { SetValue(DivLengthProperty, value); } } /// /// Gets or sets the number of divisions in the 'width' direction. /// /// The number of divisions. public int DivWidth { get { return (int)GetValue(DivWidthProperty); } set { SetValue(DivWidthProperty, value); } } protected override MeshGeometry3D Tessellate() { Vector3D u = LengthDirection; Vector3D w = Normal; Vector3D v = Vector3D.CrossProduct(w, u); u = Vector3D.CrossProduct(v, w); u.Normalize(); v.Normalize(); w.Normalize(); double le = Length; double wi = Width; var pts = new Point3DCollection(); for (int i = 0; i < DivLength; i++) { double fi = -0.5 + (double)i / (DivLength - 1); for (int j = 0; j < DivWidth; j++) { double fj = -0.5 + (double)j / (DivWidth - 1); pts.Add(Origin + u * le * fi + v * wi * fj); } } var builder = new MeshBuilder(); builder.AddRectangularMesh(pts, DivWidth); return builder.ToMesh(); } } }