透視相機的updirection,是具有三個參數的的屬性(X,Y,Z),不過Z屬性是沒有作用的。
那麼X,Y是什麼呢?
是用來确定角度的。
注意H邊,
我們知道機關圓上的一點都是可以用XY表示,用Y/X,即tan函數就可以求出圓心角的弧度,然後轉角度就可以了。
比如說UpDirection我們設定為 1 1 0,Y/X=1,tan等于1弧度,等于57.29度。
但是這麼做隻能先設定計算好XY的比值才能确定角度,不友善。
********************************************************************************************
是以我們使用極坐标,這樣我們就可以先設定角度又程式計算XY的值。
所謂極坐标即直角坐标系内使用角度和長度作為表示方式,比如 直角坐标系内的某點是(x,y)在極坐标内就是(p,θ)注意這裡面的θ是弧度。p是長度。
程式的UpDirection是用直角坐标系,是以我們給定好角度和長度後需要從極坐标轉到直角坐标系,使得我們的角度換算成直角坐标系内的表達方式,好在是,我們使用機關圓的預設長度即可也就是1;
極坐标換算直角坐标系方式為
x=p*cosθ
y=p*sinθ;
直角坐标系換算極坐标
p=根号下X的平凡+Y的平方
θ=Arctan(Y/X);
假設,XY坐标系内畫一個直徑為1的圓(圓心[0,0])
确定好圓上的點連接配接圓心之後和Y軸之間的夾角之後再用反三角函數求出角度即可
比如說我用tan函數
當确定X,Y值後,點連接配接圓心,長度為1,圓心角的對邊長度為X坐标,斜邊長度為1(不知道為什麼直接寫1不好使,必須用勾股定理求一下斜邊),之後再Arctan函數轉角度就好了。
上代碼:
<Window.Resources>
<local:AngleConverter x:Key="Angle"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera LookDirection="0 0 -1"
FieldOfView="90"
UpDirection="{Binding ElementName=AngleSlider, Path=Value, Converter={StaticResource Angle}, Mode=TwoWay}"
Position="0 0 400"/>
</Viewport3D.Camera>
<Viewport2DVisual3D>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True"/>
</Viewport2DVisual3D.Material>
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D>
<MeshGeometry3D.Positions>
-100 100 0,
-100 -100 0,
100 -100 0,
100 100 0
</MeshGeometry3D.Positions>
<MeshGeometry3D.TextureCoordinates>
0 0,
0 1,
1 1,
1 0
</MeshGeometry3D.TextureCoordinates>
<MeshGeometry3D.TriangleIndices>
0 ,1 ,2 ,0 ,2 ,3
</MeshGeometry3D.TriangleIndices>
</MeshGeometry3D>
</Viewport2DVisual3D.Geometry>
<Viewport2DVisual3D.Visual>
<Button Content="旋轉" Height="150" Width="150"/>
</Viewport2DVisual3D.Visual>
</Viewport2DVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="White"/>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
<StackPanel Grid.Row="1">
<Slider Minimum="-360" Maximum="360" Value="0" x:Name="AngleSlider"/>
<TextBlock Text="{Binding ElementName=AngleSlider, Path=Value, Mode=OneWay}" />
</StackPanel>
</Grid>
背景
namespace 向上鏡頭
{
class AngleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double angle , x,y;
//轉換為弧度
angle = Math.PI / 180*System.Convert.ToDouble(value);
//極坐标轉為直角坐标系
x = Math.Cos(angle);
y = Math.Sin(angle);
return new Vector3D(x, y, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var point = (Vector3D)value;
return Math.Atan2(point.X, point.Y) / Math.PI * 180;
}
}
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
看看效果