WPF 3 d.将3D坐标转换为2D坐标时的奇怪行为
本文关键字:坐标 2D 转换 3D WPF | 更新日期: 2023-09-27 18:14:28
由于某些原因,从3D到2D的对话在我的相机的某些旋转状态下失败了。
我写了一个小的示例应用程序来演示我的问题。当你按下示例应用左下角的小按钮"旋转相机"时,会发生错误的计算。在此旋转之后,它看起来就像其中一个线框(红线)以某种方式镜像。我的例子。
Xaml:<Window x:Class="Projection2D3D.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800">
<Grid>
<Viewport3D x:Name="Viewport">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="Cam" Position="-.9,-.9,-.5" LookDirection="0,0,1" UpDirection="0,-1,0"
FieldOfView="90" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D x:Name="ModelVisual3D">
<ModelVisual3D.Content>
<GeometryModel3D>
<GeometryModel3D.Geometry>
<MeshGeometry3D
Positions="-1,-1,0 1,-1,0 -1,1,0 1,1,0"
TriangleIndices="0 1 2 1 3 2" />
</GeometryModel3D.Geometry>
<GeometryModel3D.BackMaterial>
<DiffuseMaterial Brush="Blue"/>
</GeometryModel3D.BackMaterial>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
<Canvas x:Name="CnvOverlay"></Canvas>
<Button VerticalAlignment="Bottom" HorizontalAlignment="Left" Content="Rotate Camera" Margin="10" Click="BtnRotate_OnClick"/>
<TextBlock x:Name="TextBlock" Text="Wireframe correct!" FontWeight="Bold" FontSize="20" IsHitTestVisible="False"/>
</Grid>
c#: public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CompositionTarget.Rendering +=CompositionTarget_Rendering;
}
void CompositionTarget_Rendering(object sender, EventArgs e)
{
UpdateWireframe();
}
void UpdateWireframe()
{
GeometryModel3D model = ModelVisual3D.Content as GeometryModel3D;
CnvOverlay.Children.Clear();
if (model != null)
{
GeneralTransform3DTo2D transform = ModelVisual3D.TransformToAncestor(Viewport);
MeshGeometry3D geometry = model.Geometry as MeshGeometry3D;
for (int i = 0; i < geometry.TriangleIndices.Count; )
{
Polygon p = new Polygon();
p.Stroke = Brushes.Red;
p.StrokeThickness = 1;
p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
p.Points.Add(transform.Transform(geometry.Positions[geometry.TriangleIndices[i++]]));
CnvOverlay.Children.Add(p);
}
}
}
private void BtnRotate_OnClick(object sender, RoutedEventArgs e)
{
(sender as UIElement).IsEnabled = false;
this.TextBlock.Text = "Wireframe incorrect!";
var rotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 40), new Point3D(-1, -1, 0));
UpdateCamera(rotation);
}
private void UpdateCamera(Transform3D transform3D)
{
Cam.Position = transform3D.Transform(Cam.Position);
Cam.UpDirection = transform3D.Transform(Cam.UpDirection);
Cam.LookDirection = transform3D.Transform(Cam.LookDirection);
}
}
希望有人能帮助我这个。
http://www.neoaxis.com/forum/viewtopic.php?f=2&t=6692。