Need help writing writing conversion methods between 2D and 3D (Point3DToPoint and PointAndZToPoint3D)

I'm new to WPF 3D, so I can just skip something obvious, but how do I convert from 3D to 2D and (for a given z location) from 2D to 3D?

In particular, I need two conversion methods:

  • Point3DToPoint . If I have the coordinate (x, y, z) in the 3D world, how to determine the coordinate (x, y) on the projected 2D surface. Method Signature:public Point Point3DToPoint(Point3D point3D)

  • PointAndZToPoint3D . If I have the coordinate (x, y) on the projection of the 2D surface and az in the 3D world, how can I determine the (x, y, z) coordinates in the 3D world? Method Signature:public Point3D PointAndZToPoint3D(Point point, double z)

I would like the 2D coordinate to be located in the upper left corner Viewport3Dand the 3D coordinate to be a place relative to the origin (0, 0, 0) of the 3D world.

Note 1: I found this question, but it only deals with converting from 3D to 2D (not vice versa), and I'm not sure if the answers are relevant.

Note 2: I am currently using .NET 3.5, but if there are improvements in .NET 4.0 that will help me, let me know.

+3
source share
1 answer

The Charles Petzold 3D library, which can be downloaded here in the Petzold.Media3D Library section, contains a class ViewportInfowith these two static methods:

  • public static Point Point3DToPoint2D(Viewport3D viewport, Point3d point)

  • public static bool Point2DToPoint3D(Viewport3D viewport, Point, ptIn, out LineRange range)

Point2DToPoint3D PointAndZToPoint3D(), ( out) a LineRange, , , LineRange PointFromZ(double zValue), , , z = zValue.

:

using System.Windows;
using System.Windows.Input;
using Petzold.Media3D;

namespace _3DTester
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        /* This MouseDown event handler prints:
          (1) the current position of the mouse
          (2) the 3D mouse location on the ground plane (z = 0)
          (3) the 2D mouse location converted from the 3D location */

        private void Window_MouseDown(object sender, MouseEventArgs e)
        {
            var range = new LineRange();
            var isValid = ViewportInfo.Point2DtoPoint3D(Viewport, e.GetPosition(Viewport), out range);
            if (!isValid)
                MouseLabel.Content = "(no data)";
            else
            {
                var point3D = range.PointFromZ(0);
                var point = ViewportInfo.Point3DtoPoint2D(Viewport, point3D);
                MouseLabel.Content = e.GetPosition(Viewport) + "\n" + point3D + "\n" + point;
            }
        }
    }
}

XAML

<Window
    x:Class="_3DTester.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1"
    Height="300"
    Width="300"
    MouseDown="Window_MouseDown">
    <Grid>
        <Viewport3D Name="Viewport">
            <Viewport3D.Camera>
                <PerspectiveCamera
                    Position="0,0,30"
                    LookDirection="0,0,-1" 
                    UpDirection="0,1,0" />
            </Viewport3D.Camera>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup>
                        <DirectionalLight Color="White" Direction="1,-1,-1" />
                        <GeometryModel3D>
                            <GeometryModel3D.Geometry>
                                <MeshGeometry3D
                                    Positions="0,0,10 -5,-5,0 -5,5,0 5,5,0 5,-5,0"
                                    TriangleIndices="2 1 0  2 0 3  4 3 0  1 4 0" />
                            </GeometryModel3D.Geometry>
                            <GeometryModel3D.Material>
                                <DiffuseMaterial Brush="Red" />
                            </GeometryModel3D.Material>
                        </GeometryModel3D>
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D>
        <Label Name="MouseLabel" Content="(no data)" />
    </Grid>
</Window>
+4

Source: https://habr.com/ru/post/1743405/


All Articles