2011-08-24 10 views
0

WPF를 사용하여 3D로 점을 그려야합니다. ScreenSpaceLines3D 클래스를 사용하여 3D로 선을 그리지 만 3D로 점을 그릴 수 없습니다 (모델 확대/축소). 아무도 나를 도울 수 있습니까? 일부 예제 코드는 높이 평가 될 것입니다. 감사합니다WPF 3D 점 그림

답변

0

표면적이 없기 때문에 지점을 볼 수 없습니다. WPF 3d는 불행히도 광선 추적 엔진이 아닙니다.

그러나 누군가 멋진 레이 트레이싱 스타터 라이브러리를 만들었습니다. 이 프로젝트는 WPF로 광선 추적을 수행하려는 경우 좋은 출발점입니다 : http://raytracer.codeplex.com/.

0

너무 복잡한 작업이 아닙니다.

  1. 다운로드 Helix3D 도서관

  2. 은 실현 확대에 scphere의 반경을 연결 샘플에서 구 메쉬 코드

  3. 를 찾을 수 있습니다. 당신은 색상, 크기 viewport에 포인트를 추가 할 수 있습니다 함께 helixtoolkit에서

1

사용 PointsVisual3D 클래스. 변환을 적용 할 수도 있습니다.

0

나는 PointVisual3d 소유 클래스를 만들 수 있습니다. PointVisual3D의 코드는이 코드가 도움이된다고 생각합니다.

public class PointVisual3D:ModelVisual3D 
{ 
    private readonly GeometryModel3D _model; 
    private readonly MeshGeometry3D _mesh; 
    private Matrix3D _visualToScreen; 
    private Matrix3D _screenToVisual; 
    public PointVisual3D() 
    { 
     _mesh = new MeshGeometry3D(); 
     _model = new GeometryModel3D(); 
     _model.Geometry = _mesh; 
     SetColor(this.Color); 
     this.Content = _model; 
     this.Points = new Point3DCollection(); 
     CompositionTarget.Rendering += OnRender; 
    } 

    private void OnRender(object sender, EventArgs e) 
    { 
     if (Points.Count == 0 && _mesh.Positions.Count == 0) 
     { 
      return; 
     } 
     if (UpdateTransforms() && MainWindow.mousedown==false) 
     { 
      RebuildGeometry(); 
     } 
    } 

    public static readonly DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(PointVisual3D), new PropertyMetadata(Colors.White, OnColorChanged)); 
    private static void OnColorChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     ((PointVisual3D)sender).SetColor((Color)args.NewValue); 
    } 

    private void SetColor(Color color) 
    { 
     MaterialGroup unlitMaterial = new MaterialGroup(); 
     unlitMaterial.Children.Add(new DiffuseMaterial(new SolidColorBrush(Colors.Black))); 
     unlitMaterial.Children.Add(new EmissiveMaterial(new SolidColorBrush(color))); 
     unlitMaterial.Freeze(); 
     _model.Material = unlitMaterial; 
     _model.BackMaterial = unlitMaterial; 
    } 

    public Color Color 
    { 
     get { return (Color)GetValue(ColorProperty); } 
     set { SetValue(ColorProperty, value); } 
    } 

    //public static readonly DependencyProperty ThicknessProperty = DependencyProperty.Register("Thickness", typeof(double), typeof(PointVisual3D), new PropertyMetadata(1.0, OnThicknessChanged)); 
    //private static void OnThicknessChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    //{ 
    // ((PointVisual3D)sender).GeometryDirty(); 
    //} 

    //public double Thickness 
    //{ 
    // get { return (double)GetValue(ThicknessProperty); } 
    // set { SetValue(ThicknessProperty, value); } 
    //} 

    public static readonly DependencyProperty PointsProperty = DependencyProperty.Register("Points", typeof(Point3DCollection), typeof(PointVisual3D), new PropertyMetadata(null, OnPointsChanged)); 
    private static void OnPointsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     ((PointVisual3D)sender).GeometryDirty(); 
    } 

    public Point3DCollection Points 
    { 
     get { return (Point3DCollection)GetValue(PointsProperty); } 
     set { SetValue(PointsProperty, value); } 
    } 

    private void GeometryDirty() 
    { 
     _visualToScreen = MathUtils.ZeroMatrix; 
    } 

    private void RebuildGeometry() 
    { 
     //double halfThickness = Thickness/2.0; 
     //int numLines = Points.Count/2; 
     //Point3DCollection positions = new Point3DCollection(numLines * 4); 
     //for (int i = 0; i < numLines; i++) 
     //{ 
     // int startIndex = i * 2; 
     // Point3D startPoint = Points[startIndex]; 
     // Point3D endPoint = Points[startIndex + 1]; 
     // AddSegment(positions, startPoint, endPoint, halfThickness); 
     //} 
     //positions.Freeze(); 
     //_mesh.Positions = positions; 
     Int32Collection indices = new Int32Collection(Points.Count * 6); 
     for (int i = 0; i < Points.Count; i++) 
     { 
      indices.Add(i * 4 + 2); 
      indices.Add(i * 4 + 1); 
      indices.Add(i * 4 + 0); 
      indices.Add(i * 4 + 2); 
      indices.Add(i * 4 + 3); 
      indices.Add(i * 4 + 1); 
     } 

     indices.Freeze(); 
     _mesh.TriangleIndices = indices; 
     _mesh.Positions = CreatePositions(this.Points, this.Size, 0.0); 
    } 

    public Point3DCollection CreatePositions(IList<Point3D> points, double size = 1.0, double depthOffset = 0.0) 
    { 
     double halfSize = size/2.0; 
     int numPoints = points.Count; 

     var outline = new[] 
      { 
       new Vector(-halfSize, halfSize), new Vector(-halfSize, -halfSize), new Vector(halfSize, halfSize), 
       new Vector(halfSize, -halfSize) 
      }; 

     var positions = new Point3DCollection(numPoints * 4); 

     for (int i = 0; i < numPoints; i++) 
     { 
      var screenPoint = (Point4D)points[i] * this._visualToScreen; 

      double spx = screenPoint.X; 
      double spy = screenPoint.Y; 
      double spz = screenPoint.Z; 
      double spw = screenPoint.W; 

      if (!depthOffset.Equals(0)) 
      { 
       spz -= depthOffset * spw; 
      } 

      var p0 = new Point4D(spx, spy, spz, spw) * this._screenToVisual; 
      double pwinverse = 1/p0.W; 

      foreach (var v in outline) 
      { 
       var p = new Point4D(spx + v.X * spw, spy + v.Y * spw, spz, spw) * this._screenToVisual; 
       positions.Add(new Point3D(p.X * pwinverse, p.Y * pwinverse, p.Z * pwinverse)); 
      } 
     } 

     positions.Freeze(); 
     return positions; 
    } 

    /// <summary> 
    /// Identifies the <see cref="Size"/> dependency property. 
    /// </summary> 
    public static readonly DependencyProperty SizeProperty = DependencyProperty.Register(
     "Size", typeof(double), typeof(PointVisual3D), new UIPropertyMetadata(1.0, GeometryChanged)); 

    protected static void GeometryChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     ((PointVisual3D)sender).GeometryDirty(); 
    } 

    public double Size 
    { 
     get 
     { 
      return (double)this.GetValue(SizeProperty); 
     } 

     set 
     { 
      this.SetValue(SizeProperty, value); 
     } 
    } 


    //private void AddSegment(Point3DCollection positions, Point3D startPoint, Point3D endPoint, double halfThickness) 
    //{ 
    // Vector3D lineDirection = endPoint * _visualToScreen - startPoint * _visualToScreen; 
    // lineDirection.Z = 0; 
    // lineDirection.Normalize(); 
    // Vector delta = new Vector(-lineDirection.Y, lineDirection.X); 
    // delta *= halfThickness; 
    // Point3D pOut1, pOut2; 
    // Widen(startPoint, delta, out pOut1, out pOut2); 
    // positions.Add(pOut1); 
    // positions.Add(pOut2); 
    // Widen(endPoint, delta, out pOut1, out pOut2); 
    // positions.Add(pOut1); 
    // positions.Add(pOut2); 
    //} 
    //private void Widen(Point3D pIn, Vector delta, out Point3D pOut1, out Point3D pOut2) 
    //{ 
    // Point4D pIn4 = (Point4D)pIn; 
    // Point4D pOut41 = pIn4 * _visualToScreen; 
    // Point4D pOut42 = pOut41; 
    // pOut41.X += delta.X * pOut41.W; 
    // pOut41.Y += delta.Y * pOut41.W; 
    // pOut42.X -= delta.X * pOut42.W; 
    // pOut42.Y -= delta.Y * pOut42.W; 
    // pOut41 *= _screenToVisual; 
    // pOut42 *= _screenToVisual; 
    // pOut1 = new Point3D(pOut41.X/pOut41.W, pOut41.Y/pOut41.W, pOut41.Z/pOut41.W); 
    // pOut2 = new Point3D(pOut42.X/pOut42.W, pOut42.Y/pOut42.W, pOut42.Z/pOut42.W); 
    //} 
    private bool UpdateTransforms() 
    { 
     Viewport3DVisual viewport; 
     bool success; 
     Matrix3D visualToScreen = MathUtils.TryTransformTo2DAncestor(this, out viewport, out success); 
     if (!success || !visualToScreen.HasInverse) 
     { 
      _mesh.Positions = null; 
      return false; 
     } 
     if (visualToScreen == _visualToScreen) 
     { 
      return false; 
     } 
     _visualToScreen = _screenToVisual = visualToScreen; 
     _screenToVisual.Invert(); 
     return true; 
    } 
}