我正在开发Java游戏引擎,而且我遇到了问题。
我试图将我的世界空间物体投射到视野中。我对它的假想顶点有一个视锥体(让我们把它称为平截头体的眼睛"它只是截头锥体的边缘会遇到的地方,如果顶部不是"切断"。我的对象的所有顶点都通过线段连接到眼睛。这条线与平截头体的小端相交的位置是x和y屏幕上显示的对象的坐标。
我的问题是确定它们与截锥体的小端相交的位置。我已经考虑过这个问题并对其进行了相当多的研究,但我找不到任何有关我应该如何做的资源。
我现在拥有的课程如下:
class Point
- 一个基本上包含x-y-z变量的简单类。我还使用Point类来表示向量。
class Frustum
,这基本上是八个点,使形状像一个压扁的方块。
class Triangle
,基本上是三点。它有几种方法可以解决这些问题。
我还有几个经过彻底测试的功能:
double Distance_Between(Point p1, Point p2)
- 计算两个3d点之间的距离
Point GetNormalVector(Point p1, Point p2, Point p3)
- 获取三个共面点的法线向量。
void NormalizeVector(Point p)
- 规范化矢量
double GetDotProduct(Point p1, Point p2)
- 获取两点的点积。
int[] GetSharedSide(Triangle t1, Triangle t2)
- 获取两个三角形的共享面。
void MovePointAlongVector(Point point, Point direction, float distance)
- 沿给定向量移动给定数量的给定点。
如果您能找到已经存在的功能的答案,那将会很棒,但我能够添加更多的实用功能。
这对游戏引擎非常重要 - 可以说这个功能是最重要的功能。我想这将需要一些几何以及三角学。这是完美的,因为我最近在高中时都参加了这项活动!
答案 0 :(得分:0)
你真的在看一个投射变换。
考虑眼睛位于原点并且截头体的方形末端位于x=1
平面的情况。如果我们取点(x, y, z)
,则从眼睛到该点的线上的点将具有(a x, a y, a z)
形式。现在,如果a = 1/x
给出了点(1, y/x, z/x)
。
解决问题的最简单方法是设置转换库。因此,您可以应用旋转和其他变换,表示为矩阵。最简单的方法是使用4乘4矩阵,因为这样可以将翻译表示为矩阵。使用此库,您可以转换场景,使眼睛位于原点,而截头柱末端的法线位于其中一个基本轴上。
更复杂的方法是一般的分段 - 平面交叉。为此,计算平面的法线n,并找到平面到原点的距离,使用点积取d = P . n
。使用从A点到B点的细分,计算两个点积d1 = A . n
和d2= B . n
。对于段相交,d1和d2中的一个应大于d,另一个小于d。您现在可以使用线性插值来找到两者之间的点。
m A + (1 - m) B
我们希望这与正常的点积为d
。
(m A + (1 - m) B) . n = d
m A . n + (1 - m) B . n = d
m d1 + (1 - m) d2 = d
m (d1 - d2) + d2 = d
m = (d - d2) / (d1 - d2)
这给出了参数,然后可以使用该参数找到段上的交叉点。
许多库都有lerp函数,可以进行线性插值。