我有一个形象,有一些价值,使其在Silverlight中的透视,但不能完全弄清楚什么,我需要做的mathmatically做到这一点。最重要的是我的角度称为视场( FOV )。
这是正常的图片:
例如:
X = 30° X = 30° X = 30° FOV = 30° FOV = 60° FOV = 120° X = 60° X = 60° X = 60° FOV = 30° FOV = 60° FOV = 120°
任何帮助将是pciated走我通过数学在Silverlight中重现这些AP $ P $。
解决方案我觉得这个问题大家遇到的是,需要有随着角度变换视口的转变。
尝试了这一点:
私人无效ApplyProjection()
{
双fovY = FOV * Math.PI / 180 / 2.0;
双translationZ = -image1.ActualHeight / Math.Tan(fovY / 2.0);
双THETA = YourAngleX * Math.PI / 180.0;
的Matrix3D centerImageAtOrigin = TranslationTransform(
-image1.ActualWidth / 2.0,
-image1.ActualHeight / 2.0,0);
的Matrix3D invertYAxis = CreateScaleTransform(1.0,-1.0,1.0);
的Matrix3D rotateAboutY = RotateYTransform(THETA);
的Matrix3D translateAwayFromCamera = TranslationTransform(0,0,translationZ);
的Matrix3D角度= PerspectiveTransformFovRH(fovY,
image1.ActualWidth / image1.ActualHeight,//长宽比
1.0,//近平面
1000.0); //远平面
的Matrix3D视= ViewportTransform(image1.ActualWidth,image1.ActualHeight);
的Matrix3D M = centerImageAtOrigin * invertYAxis;
M = M * rotateAboutY;
M = M * translateAwayFromCamera;
M = M *的观点;
M = M *视;
Matrix3DProjection m3dProjection =新Matrix3DProjection();
m3dProjection.ProjectionMatrix =米;
image1.Projection = m3dProjection;
}
私人的Matrix3D TranslationTransform(双TX,双TY,双TZ)
{
的Matrix3D M =新Matrix3D();
m.M11 = 1.0; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = 1.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX = TX; m.OffsetY = TY; m.OffsetZ = TZ; m.M44 = 1.0;
返回米;
}
私人的Matrix3D CreateScaleTransform(双SX,SY双,双SZ)
{
的Matrix3D M =新Matrix3D();
m.M11 = SX; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = SY; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = SZ; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
返回米;
}
私人的Matrix3D RotateYTransform(双THETA)
{
双罪= Math.Sin(THETA);
双COS = Math.Cos(THETA);
的Matrix3D M =新Matrix3D();
m.M11 = COS; m.M12 = 0.0; m.M13 = -sin; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = 1.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 =罪。 m.M32 = 0.0; m.M33 = COS; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
返回米;
}
私人的Matrix3D RotateZTransform(双THETA)
{
双COS = Math.Cos(THETA);
双罪= Math.Sin(THETA);
的Matrix3D M =新Matrix3D();
m.M11 = COS; m.M12 =罪。 m.M13 = 0.0; m.M14 = 0.0;
m.M21 = -sin; m.M22 = COS; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
返回米;
}
私人的Matrix3D PerspectiveTransformFovRH(双fieldOfViewY,双重的aspectRatio,双zNearPlane,双zFarPlane)
{
双高= 1.0 / Math.Tan(fieldOfViewY / 2.0);
双宽度=高度/的aspectRatio;
双D = zNearPlane - zFarPlane;
的Matrix3D M =新Matrix3D();
m.M11 =宽度; m.M12 = 0; m.M13 = 0; m.M14 = 0;
m.M21 = 0; m.M22 =高度; m.M23 = 0; m.M24 = 0;
m.M31 = 0; m.M32 = 0; m.M33 = zFarPlane /天; m.M34 = -1;
m.OffsetX = 0; m.OffsetY = 0; m.OffsetZ = zNearPlane * zFarPlane /天; m.M44 = 0;
返回米;
}
私人的Matrix3D ViewportTransform(双宽,双高)
{
的Matrix3D M =新Matrix3D();
m.M11 =宽度/ 2.0; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = -height / 2.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX =宽度/ 2.0; m.OffsetY =身高/ 2.0; m.OffsetZ = 0.0; m.M44 = 1.0;
返回米;
}
这将创建适当的角度转变和相匹配的PowerPoint正在生产。
这code是改编自的 MSDN 。
I have an image with and have a few values to make it a perspective in Silverlight, but can't quite figure out what I need to do mathmatically to make it happen. The most important thing is I have an angle called a "Field of View" (FOV).
This is the normal picture:
For example:
X = 30° X = 30° X = 30° FOV = 30° FOV = 60° FOV = 120° X = 60° X = 60° X = 60° FOV = 30° FOV = 60° FOV = 120°
Any help would be appreciated to walk me through the math to reproduce these in Silverlight.
解决方案I think the problem everyone is encountering is that there needs to be a viewport shift along with the perspective transformation.
Try this out:
private void ApplyProjection()
{
double fovY = FOV * Math.PI / 180 / 2.0;
double translationZ = -image1.ActualHeight / Math.Tan(fovY / 2.0);
double theta = YourAngleX * Math.PI / 180.0;
Matrix3D centerImageAtOrigin = TranslationTransform(
-image1.ActualWidth / 2.0,
-image1.ActualHeight / 2.0, 0);
Matrix3D invertYAxis = CreateScaleTransform(1.0, -1.0, 1.0);
Matrix3D rotateAboutY = RotateYTransform(theta);
Matrix3D translateAwayFromCamera = TranslationTransform(0, 0, translationZ);
Matrix3D perspective = PerspectiveTransformFovRH(fovY,
image1.ActualWidth / image1.ActualHeight, // aspect ratio
1.0, // near plane
1000.0); // far plane
Matrix3D viewport = ViewportTransform(image1.ActualWidth, image1.ActualHeight);
Matrix3D m = centerImageAtOrigin * invertYAxis;
m = m * rotateAboutY;
m = m * translateAwayFromCamera;
m = m * perspective;
m = m * viewport;
Matrix3DProjection m3dProjection = new Matrix3DProjection();
m3dProjection.ProjectionMatrix = m;
image1.Projection = m3dProjection;
}
private Matrix3D TranslationTransform(double tx, double ty, double tz)
{
Matrix3D m = new Matrix3D();
m.M11 = 1.0; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = 1.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX = tx; m.OffsetY = ty; m.OffsetZ = tz; m.M44 = 1.0;
return m;
}
private Matrix3D CreateScaleTransform(double sx, double sy, double sz)
{
Matrix3D m = new Matrix3D();
m.M11 = sx; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = sy; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = sz; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
return m;
}
private Matrix3D RotateYTransform(double theta)
{
double sin = Math.Sin(theta);
double cos = Math.Cos(theta);
Matrix3D m = new Matrix3D();
m.M11 = cos; m.M12 = 0.0; m.M13 = -sin; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = 1.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = sin; m.M32 = 0.0; m.M33 = cos; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
return m;
}
private Matrix3D RotateZTransform(double theta)
{
double cos = Math.Cos(theta);
double sin = Math.Sin(theta);
Matrix3D m = new Matrix3D();
m.M11 = cos; m.M12 = sin; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = -sin; m.M22 = cos; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX = 0.0; m.OffsetY = 0.0; m.OffsetZ = 0.0; m.M44 = 1.0;
return m;
}
private Matrix3D PerspectiveTransformFovRH(double fieldOfViewY, double aspectRatio, double zNearPlane, double zFarPlane)
{
double height = 1.0 / Math.Tan(fieldOfViewY / 2.0);
double width = height / aspectRatio;
double d = zNearPlane - zFarPlane;
Matrix3D m = new Matrix3D();
m.M11 = width; m.M12 = 0; m.M13 = 0; m.M14 = 0;
m.M21 = 0; m.M22 = height; m.M23 = 0; m.M24 = 0;
m.M31 = 0; m.M32 = 0; m.M33 = zFarPlane / d; m.M34 = -1;
m.OffsetX = 0; m.OffsetY = 0; m.OffsetZ = zNearPlane * zFarPlane / d; m.M44 = 0;
return m;
}
private Matrix3D ViewportTransform(double width, double height)
{
Matrix3D m = new Matrix3D();
m.M11 = width / 2.0; m.M12 = 0.0; m.M13 = 0.0; m.M14 = 0.0;
m.M21 = 0.0; m.M22 = -height / 2.0; m.M23 = 0.0; m.M24 = 0.0;
m.M31 = 0.0; m.M32 = 0.0; m.M33 = 1.0; m.M34 = 0.0;
m.OffsetX = width / 2.0; m.OffsetY = height / 2.0; m.OffsetZ = 0.0; m.M44 = 1.0;
return m;
}
This will create the appropriate perspective shift and match what PowerPoint is producing.
This code was adapted from MSDN.