3d 到 2d 点转换 [英] 3d to 2d point conversion

查看:39
本文介绍了3d 到 2d 点转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 3D 点绘制到 2D 表面上(我目前正在使用 SDL.NET 作为我的游戏引擎").表面的大小为 800x400 像素,3d 坐标范围为 -4000 到 4000.我的视图将始终是自上而下的视图,并且不会有任何相机移动.有人可以提供一些本机 c#、伪代码或将 3-D 空间中的坐标转换为 2-D 表面的简单解释吗?

I'm trying to plot 3D points onto a 2D surface (I'm currently working with SDL.NET as my 'game engine'). The surface will be 800x400 pixels in size and the 3d coordinates will range from -4000 to 4000. My view will always be a top-down view and there will be no camera movement whatsoever. Could someone provide some native c#, pseudo code or an easy explanation for converting coordinates in the 3-D space to the 2-D surface?

同时我在订购这本书告诉我它会解决我的很多数学缺陷......希望:)

Meanwhile Im ordering this book which people tell me it will address a lot of my math shortcomings....hopefully :)

推荐答案

注意:这是一堵巨大的文字墙,我完全忽略了很多重要的东西——但我在这里的目的只是一个概述......希望这里的一些术语/概念能引导你更好地在网络上搜索适当的块.

NOTE: This is a big wall of text and I completely glaze over a lot of important stuff - but my intention here is just an overview...hopefully some of the terms/concepts here will lead you to better Googling for appropriate chunks on the web.

如果你走在人生为一个点"的道路上会有所帮助:

It helps if you walk your way through "Life as a point":

我们来了,一个漂亮的小 3 维点:

Here we are, a nice little 3-dimensional point:

var happyPoint = new Point(0, 0, 0);

这是它的好友,定义为与他的朋友相关:

And here is its buddy, defined in relation to his friend:

var friendlyPoint = new Point(1, 0, 0);

现在,让我们称这两个点为我们的模型"——我们将使用术语模型空间"来讨论单个三维结构(如房屋、怪物)的点等).

For now, let's call these two points our "model" - we'll use the term "model space" to talk about points within a single three-dimensional structure (like a house, monster, etc).

模型并不存在于真空中,但是……通常更容易将模型空间"和世界空间"分开,以便更轻松地进行模型调整(否则,您的所有模型都需要在相同的比例,相同的方向等等,再加上尝试在 3d 建模程序中对它们进行处理是不可能的)

Models don't live in a vacuum, however...it's usually easier to separate the "model space" and "world space" to make things easier for model tweaking (otherwise, all your models would need to be in the same scale, have the same orientation, etc, etc, plus trying to work on them in a 3d modelling program would be friggin impossible)

所以我们将为我们的模型"定义一个世界变换"(好吧,2 点是一个蹩脚的模型,但它仍然是一个模型).

So we'll define a "World Transform" for our "Model" (ok, 2 points is a lame model, but a model it remains).

什么是世界变换"?简单地说:

What is a "World Transform"? Simply put:

  • 世界变换W = T X R X S,其中
  • T = translation - 即沿 X、Y 或 Z 轴滑动
  • R = rotation - 相对于轴旋转模型
  • S = scaling - 沿轴调整模型大小(保留其中的所有相关点)
  • A world transform W = T X R X S, where
  • T = translation - that is, sliding it along the X, Y, or Z axes
  • R = rotation - turning the model with respect to an axis
  • S = scaling - resizing a model (maintaining all the relative points within) along an axis

我们在这里放轻松,将我们的世界变换定义为身份矩阵——基本上,这意味着我们不希望它平移、旋转或缩放:

We'll take the easy out here, and just define our world transform as the Identity matrix - basically, this means we don't want it to translate, rotate, or scale:

world = [
          1 0 0 0
          0 1 0 0
          0 0 1 0
          0 0 0 1
        ];

我强烈建议您复习一下矩阵数学,尤其是乘法和 Vector->Matrix 运算,它们在 3D 图形中ALL THE FREAKING TIME.

I highly recommend you brush up on your Matrix math, especially multiplication and Vector->Matrix operations its used ALL THE FREAKING TIME in 3D graphics.

如此巧妙地跳过了实际的矩阵乘法,我只是告诉你,将我们的世界变换"和我们的模型点相乘,结果又是我们的模型点(尽管在这个有趣的新 4 维向量表示中,我不会碰这里).

So cleverly skipping over the actual matrix multiplication, I'll just tell you that multiplying our "world transform" and our model points just ends up with our model points again (albeit in this fun new 4-dimensional vector representation, which I won't touch here).

所以我们得到了我们的点,并且我们绝对将它们定位在空间"中......现在怎么办?

So we've got our points, and we've absolutely located them in "space"...now what?

好吧,我们从哪里看?这引出了View TransformationsCamera Projection 的概念——基本上,它只是另一个矩阵乘法——观察:

Well, where are we looking at it from? This leads to the concept of View Transformations or Camera Projection - basically, it's just another matrix multiplication - observe:

假设我们有一个点 X,在...哦,(4 2) 左右:

Say we've got a point X, at...oh, (4 2) or so:

 |
 |
 |
 |    
 |    X
 |
 ------------------------

从原点 (0 0) 的角度来看,X 在 (4 2) - 但是假设我们把相机放在右边?

From the perspective of the origin (0 0), X is at (4 2) - but say we put our camera off to the right?

 |
 |
 |
 |    
 |    X         >-camera
 |
 ------------------------

X 相对于相机的位置"是什么?可能更接近 (0 9) 或 (9 0),具体取决于您的相机的向上"和向右"方向.这就是视图转换 - 将一组 3D 点映射到另一组 3D 点,以便从观察者的角度来看它们是正确的".在您使用自上而下的固定相机的情况下,您的观察者将位于天空中的某个固定位置,所有模型都会相应地进行转换.

What is the "position" of X, relative to the camera? Probably something closer to either (0 9) or (9 0), depending on what your camera's "up" and "right" directions are. This is what View transformations are - mapping one set of 3D points to another set of 3D points such that they are "correct" from the perspective of an observer. In your case of a top-down fixed camera, your observer would be some fixed position in the sky, and all the models would be transformed accordingly.

让我们画画吧!

不幸的是,我们的屏幕还不是 3D 的,所以首先我们需要将此点投影"到 2D 表面上.投影是...嗯,它基本上是一个映射,看起来像:

Unfortunately, our screen isn't 3D (yet), so first we need to "project" this point onto a 2D surface. Projection is...well, its basically a mapping that looks like:

(x, y, z) => (x, y)

可能的投影数量几乎是无限的:例如,我们可以将 XY 坐标移动 Z:

The number of possible projections is nigh-infinite: for example, we could just shift over the X and Y coordinates by Z:

func(x, y, z) => new point2d(x + z, y + z);

通常,您希望此投影模拟人类视网膜在观看 3D 场景时所做的投影,因此我们引入了视图投影的概念.有几种不同的视图投影,例如 OrthographicYawPitchRoll-definedPerspective/FOV-defined;每一个都有几个关键的数据位,你需要正确地构建投影.

Usually, you want this projection to mimic the projection the human retina does when looking at 3D scenes, however, so we bring in the concepts of a View Projection. There are a few different view projections, like Orthographic, YawPitchRoll-defined, and Perspective/FOV-defined; each of these has a couple of key bits of data you need to properly build the projection.

例如,基于透视/FOV 的投影需要:

A Perspective/FOV based projection, for example, needs:

  • 眼球"(即屏幕)的位置
  • 您的眼球"能够聚焦多远(远剪裁平面")
  • 您的视角范围(即,伸出双臂,刚好在周边视野的边缘)
  • 您正在查看的镜头"的宽高比(通常是您的屏幕分辨率)

一旦你有了这些数字,你就可以创建一个叫做边界截头体"的东西,它看起来有点像一个顶部被砍掉的金字塔:

Once you've got these numbers, you create something called a "bounding frustum", which looks a bit like a pyramid with the top lopped off:

-----------------/
                /
               /
              /
             /
     -------/

或者从前面:

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|  |             |  |
|  |             |  |
|  |             |  |
|  |_____________|  |
|___________________|

我不会在这里进行矩阵计算,因为这在其他地方都有很好的定义——事实上,大多数库都有帮助方法来为你生成相应的矩阵——但它的工作原理大致如下:

I won't do the matrix calculations here, since that's all well defined elsewhere - in fact, most libraries have helper methods that'll generate the corresponding matrices for you - but here's roughly how it works:

让我们说你的快乐小点在于这个平截头体:

Let's say your happy little point lies in this frustum:

-----------------/
                /
   o<-pt       /
              /
             /
     -------/

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|o |             |  |
|^---- pt        |  |
|  |             |  |
|  |_____________|  |
|___________________|

请注意,它离一侧很远,到目前为止它在近剪裁平面"矩形之外 - 如果您看向"金字塔较小的一端,它会是什么样子?

Notice it's way off to the side, so far that it's out of the "near clip plane" rectangle - What would it look like if you "looked into" the smaller end of the pyramid?

很像看棱镜(或镜头),点会弯曲"到视野中:

Much like looking into a Prism (or a lens), the point would be "bent" into view:

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|>>>o <- pt is   |  |
|  |    shifted  |  |
|  |             |  |
|  |_____________|  |
|___________________|

换句话说,如果您在视锥体后面有一盏明亮的光,那么您的点的阴影会投射"到近剪裁场的哪里?(较小的矩形)投影就是这样 - 一个点到另一个点的映射,在这种情况下,移除 Z 分量并相应地以对我们的眼睛有意义"的方式改变 X 和 Y.

Put another way, if you had a bright light behind the frustum, where would the shadows from your points be "cast" upon the near clipping field? (the smaller rectangle) That's all projection is - a mapping of one point to another, in this case, removing the Z component and altering the X and Y accordingly in a way that "makes sense" to our eyes.

这篇关于3d 到 2d 点转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆