Charles Petzold's 3D Library, which can be downloaded here under "The Petzold.Media3D library", contains a class ViewportInfo
with these two static methods:
public static Point Point3DToPoint2D(Viewport3D viewport, Point3d point)
public static bool Point2DToPoint3D(Viewport3D viewport, Point, ptIn, out LineRange range)
Point2DToPoint3D
isn't an exact match for PointAndZToPoint3D()
because it returns (via an out
parameter) a LineRange
rather than a specific point, but it just so happens that LineRange
has a method PointFromZ(double zValue)
, which provides the point where the ray intersects the plane defined by z = zValue
.
Code Sample:
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 Code
<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>