如果我理解正確的問題,你應該能夠實現通過創建一個球體的一部分,並使用圖像作爲紋理一樣的效果。不是移動圖片,而是旋轉球體。
代碼和主窗口的XAML:
namespace WpfBalls
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
Ball ball = new Ball();
ball.ImageSource = "YourPictureHere.jpg"; //path to the picture
visualModel.Children.Add(ball);
}
}
}
<Window x:Class="WpfBalls.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfBalls"
Title="3D WpfBalls" Height="400" Width="600">
<Grid>
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Grid.Background>
<Viewport3D x:Name="viewPort" Grid.Column="0" Grid.Row="0" ClipToBounds="False">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera" Position="0,0,-8"
UpDirection="0,1,0" LookDirection="0,0,1"
FieldOfView="25" NearPlaneDistance="0.125"/>
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D x:Name="visualModel">
<ModelVisual3D.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotationY"
Angle="{Binding ElementName=sliderY,Path=Value}" Axis="0,1,0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="rotationX"
Angle="{Binding ElementName=sliderX,Path=Value}" Axis="1,0,0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</ModelVisual3D.Transform>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
<Slider Height="23" HorizontalAlignment="Left" Margin="25,23,0,0" Name="sliderX" Minimum="-70" Maximum="70" Value="0" VerticalAlignment="Top" Width="100" />
<Slider Height="86" HorizontalAlignment="Left" Margin="25,52,0,0" Name="sliderY" Minimum="110" Maximum="250" Value="180" VerticalAlignment="Top" Width="27" Orientation="Vertical" />
</Grid>
</Window>
球類代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WpfBalls
{
public class Ball : ModelVisual3D
{
public Ball()
{
this.Content = new GeometryModel3D();
(this.Content as GeometryModel3D).Geometry = Tessellate();
}
static double DegToRad(double degrees)
{
return (degrees/180.0) * Math.PI;
}
internal Point3D GetPosition(double t, double y)
{
double r = Math.Sqrt(1 - y * y);
double x = r * Math.Cos(t);
double z = r * Math.Sin(t);
return new Point3D(x, y, z);
}
private Vector3D GetNormal(double t, double y)
{
return (Vector3D)GetPosition(t, y);
}
private Point GetTextureCoordinate(double t, double y)
{
Matrix TYtoUV = new Matrix();
TYtoUV.Scale(1/(2 * Math.PI), -0.5);
Point p = new Point(t, y);
p = p * TYtoUV;
return p;
}
public string ImageSource
{
set {
DiffuseMaterial dm = new DiffuseMaterial();
ImageSource imSrc = new
BitmapImage(new Uri(value, UriKind.RelativeOrAbsolute));
dm.Brush = new ImageBrush(imSrc);
(this.Content as GeometryModel3D).Material = dm;
}
}
public Point3D Offset
{
set {
this.Transform = new
TranslateTransform3D(value.X, value.Y, value.Z);
}
}
internal Geometry3D Tessellate()
{
int tDiv =750;
int yDiv = 750;
double maxTheta = DegToRad(360);
double minY = -1.0;
double maxY = 1.0;
double dt = maxTheta/tDiv;
double dy = (maxY - minY)/yDiv;
MeshGeometry3D mesh = new MeshGeometry3D();
for (int yi = 0; yi <= yDiv; yi++)
{
double y = minY + yi * dy;
for (int ti = 0; ti <= tDiv; ti++)
{
double t = ti * dt;
var p = GetPosition(t, y);
if (p.Z > 0 && p.X > -.5 && p.X < .5 && p.Y > -.5 && p.Y < .5)
{
mesh.Positions.Add(p);
mesh.Normals.Add(GetNormal(t, y));
mesh.TextureCoordinates.Add(GetTextureCoordinate(t, y));
}
}
}
for (int yi = 0; yi < yDiv; yi++)
{
for (int ti = 0; ti < tDiv; ti++)
{
int x0 = ti;
int x1 = (ti + 1);
int y0 = yi * (tDiv + 1);
int y1 = (yi + 1) * (tDiv + 1);
mesh.TriangleIndices.Add(x0 + y0);
mesh.TriangleIndices.Add(x0 + y1);
mesh.TriangleIndices.Add(x1 + y0);
mesh.TriangleIndices.Add(x1 + y0);
mesh.TriangleIndices.Add(x0 + y1);
mesh.TriangleIndices.Add(x1 + y1);
}
}
mesh.Freeze();
return mesh;
}
}
}
的代碼是基於這個例子: http://www.codegod.de/WebAppCodeGod/wpf-3d-animations-and-textures-AID439.aspx
您好,感謝您回答。這個例子很接近,但不是我想要達到的。我希望能夠在畫布周圍移動矩形圖像,但可以看到它在球體表面上的等距矩形投影。 (實際上畫布是解開的球體表面。)就像3D軟件包中的UVW貼圖一樣。請查看「HDR Light Studio」網站視頻,您將明白我需要實現哪種實時圖像失真。再次感謝。 – skokk 2010-11-17 14:34:35