C#:如何将3D X Y和Z位置转换为2D X和Y位置?
我想要的是将3D位置转换为2D位置的某种功能,C#:如何将3D X Y和Z位置转换为2D X和Y位置?
Private Function Get2DPoint(ByRef x As Short, ByRef y As Short, ByRef z As Short)
Dim newX = x + z '< Some fancy math
Dim newY = y + z '< Some fancy math
Dim temp = {newX, newY}
Return temp
End Function
在线资源,我已签,但我无法理解(我没有复制从页面的信息,因为他们已经启动并运行了很长一段时间,并有在上述页面的大量的信息。):
请不要告诉我,我应该使用预先存在的库。我已经阅读了很多关于这个问题的问题,并且使用了像OpenGL这样的东西。或者其他图书馆不是我想要做的。
我一直在寻找相当长的一段时间,我真的没有更接近理解如何做到这一点,任何和所有的帮助将不胜感激。
如果我忘记提供任何信息,请让我知道,在此先感谢。
注:
我使用Visual Studio 2015年的Visual Basic编程,但是如果给予的任何代码的例子是在它的罚款:C++,C#,Python和Lua的。或其他类似的编程语言。
我本来想发布更多的链接,但我没有所需的10+声望。
一切顺利,约瑟夫·富特
随着你linked example所示,您需要定义一个class
你的立方体,在空间中的点class
,你照相机的class
和矩形中的class
它已经存在了System.Drawing.Rectangle
:
我不会从C#代码翻译成VB.net SI这可以很容易地完成,这是你的工作:)但我会解释它是如何工作的
首先你需要初始化你想绘制的立方体,然后,你需要定义你想要的起源在您的案例中,3D空间位于您的PictureBox
中,可以说您要将(0,0,0)点的立方体中间位于PictureBox
中间的中间位置:
//Point is also a System.Drawing type.
Point origin = new Point(picCube.Width/2, picCube.Height/2);
现在您只需要随时渲染图片即可。在这个例子中,渲染本身在接收我们刚刚计算的原点的Cube
class
内完成,在示例中,向量始终是Y轴。
所有的方法的第一被定义具有以下签名:
//Gets the origin on the PictureBox to be displayed (middle of the PictureBox).
//Returns the rendered picture.
public Bitmap drawCube(Point drawOrigin)
接着,3个变量的声明:
- 临时三维原点。
- 临时的2D起源。
- 24个2D点的数组要绘制(立方体将被绘制为4个四边形 - 每边将绘制两次 - 一次为每一个四边形,这是在本例中一种不好的做法)
这是代码:
PointF[] point3D = new PointF[24]; //Will be actual 2D drawing points
Point tmpOrigin = new Point(0, 0);
Math3D.Point3D point0 = new Math3D.Point3D(0, 0, 0); //Used for reference
然后,摄像机的Z位置相对于被定义为屏幕分辨率,以保持立方体不弄乱:
//Screen is another System.Drawing class.
//Called "zoom" in the example.
double baseCameraZ = Screen.PrimaryScreen.Bounds.Width/1.5;
接下来,根据空间中的立方体的宽度,高度和深度计算立方体的点数(同样,由于它们是按每个面绘制的,所以它们有24个而不是8个),并且相应地调整cameraZ
的位置,立方将适合:
//Just filling a 24 length array of Point3D, you can see in the example their exact order.
//note that the order matters mostly so each face's vertexes will be together in the array - one after another.
Math3D.Point3D[] cubePoints = fillCubeVertices(width, height, depth);
//Calculate the camera Z position to stay constant despite rotation
Math3D.Point3D anchorPoint = (Math3D.Point3D)cubePoints[4]; //anchor point
double cameraZ = -(((anchorPoint.X - cubeOrigin.X) * baseCameraZ)/cubeOrigin.X) + anchorPoint.Z;
//That's the actual camera of the cube - read the example itself for more info.
camera1.Position = new Math3D.Point3D(cubeOrigin.X, cubeOrigin.Y, cameraZ);
下一个功能做transformations over the points using matrices - 你不必了解它是如何工作,但你应该想读一点关于它,它的作用是基本应用旋转立方体并将其定位在相对于原点的3D空间中的固定位置:
//Apply Rotations, moving the cube to a corner then back to middle
cubePoints = Math3D.Translate(cubePoints, cubeOrigin, point0);
cubePoints = Math3D.RotateX(cubePoints, xRotation); //The order of these
cubePoints = Math3D.RotateY(cubePoints, yRotation); //rotations is the source
cubePoints = Math3D.RotateZ(cubePoints, zRotation); //of Gimbal Lock
cubePoints = Math3D.Translate(cubePoints, point0, cubeOrigin);
下一条代码转换空间立方体,他们的结果2D图像中属于的3D点,也存在的情况下的特殊检查点落在相机(这是if
句话背后)。再次,如果你想忠实地理解它,你需要了解一些基本Linear Algebra:
的最后一件事将是绘制使用Graphics
的整体形象:
Rectangle bounds = getBounds(point3D);
bounds.Width += drawOrigin.X;
bounds.Height += drawOrigin.Y;
Bitmap tmpBmp = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(tmpBmp))
{
//Back Face
g.DrawLine(Pens.Black, point3D[0], point3D[1]);
g.DrawLine(Pens.Black, point3D[1], point3D[2]);
g.DrawLine(Pens.Black, point3D[2], point3D[3]);
g.DrawLine(Pens.Black, point3D[3], point3D[0]);
//Front Face
g.DrawLine(Pens.Black, point3D[4], point3D[5]);
g.DrawLine(Pens.Black, point3D[5], point3D[6]);
g.DrawLine(Pens.Black, point3D[6], point3D[7]);
g.DrawLine(Pens.Black, point3D[7], point3D[4]);
//... Four more faces ...
}
现在,所有你需要做的是返回呈现的位图。
注意,在这个例子中,设计不一定是最好的,因为每个对象绘制本身,并不知道ZBuffer和场景中的其他对象,也,本示例使用int
!而非float
S IN的所有的坐标变量,这会使您失去很多准确性 - 在使用3D渲染器时不应该这样做。
Here is a good source学习在C#和C++最佳实践3D渲染的基础。
什么是您的3D位置?你想要2D位置代表什么,投影在视图矩阵上的相同3D位置? –
好吧,让我们说我的立方体在0,0,0,每个角落距离0,0,0为10个单位。至于视图矩阵,我不太确定那是什么,也许你可以解释一下吗? –
当从一个certine位置观察一个3D物体时,有很少的东西会被计数,物体的位置(您的立方体),相机位置,相机的外观矢量,相机“上”矢量以及相机视角和比率。当你告诉我你在哪里以及物体在哪里时,想想它,但是如果你直视它,并且如果你站立颠倒或者你的眼睛视野有多大,你就不会告诉我。 –