如何设置这种视角的变换中的Matrix3D?视角、如何设置、Matrix3D

2023-09-03 06:39:11 作者:尸血腥色

我有一个形象,有一些价值,使其在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°
  



英雄联盟3D视角全景体验来袭

任何帮助将是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.