- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个 3D 引擎,我正在开发所有图形的软件渲染,主要是为了更深入地了解事物的工作原理。
现在我拥有我需要的一切(基于 map 的坐标系、3D 坐标系、多线程纹理引擎、多相机透视功能、 block 级碰撞/命中检测、射弹和简单的粒子引擎)、蹩脚的物理等)
我构建了所有内容并将旋转数学保持在最低限度,因为我一直在尝试同时学习三角函数(我知道你要说什么,但请你自己保密,我是一个很棒的程序员,不是数学家;大声笑)...
但是...我就是做不对,几天后它让我抓狂。我一直在研究、阅读和编码,但我就是想不通。
这是我当前的旋转函数,它使节点在 Y 轴上顺时针旋转。
Public Function RotatePoints(nodeCollection() As Point3d, centerPoint As Point, angleInDegrees As Double) As Point3d()
For l = 0 To nodeCollection.Count - 1
Dim angleInRadians As Double = angleInDegrees * (Math.PI / 180)
Dim cosTheta As Double = Math.Cos(angleInRadians)
Dim sinTheta As Double = Math.Sin(angleInRadians)
Dim pointToRotate As New Point
pointToRotate.X = nodeCollection(l).X
pointToRotate.Y = nodeCollection(l).Y
Dim key As New Point
key.X = CInt(cosTheta * (pointToRotate.X - centerPoint.X) - sinTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.X)
key.Y = CInt(sinTheta * (pointToRotate.X - centerPoint.X) + cosTheta * (pointToRotate.Y - centerPoint.Y) + centerPoint.Y)
With nodeCollection(l)
.X = key.X
.Y = key.Y
End With
Next
Return nodeCollection
End Function
我的目标是让对象围绕 View 透视轴水平旋转。类似于您在游戏中环顾四周,世界围绕您左右移动。
我不在乎是什么编程语言响应,我能流利地使用很多语言,但我不擅长触发 :(
我一直在尝试在没有帮助的情况下做到这一点,但我被卡住了,并且编程语法中通常不提供滚动、俯仰和偏航的计算,而且理解起来令人窒息,这就是我这样做的全部原因这 --- 学习。
最佳答案
如果您想要完整的 3D 旋转,则必须查看旋转矩阵。
如果您正在使用 3D 引擎,则必须学习如何使用它。一开始可能有点令人印象深刻,但并不难。
https://en.wikipedia.org/wiki/Rotation_matrix https://en.wikipedia.org/wiki/Transformation_matrix
使用矩阵,您可以以各种可能的方式操作对象:规模回转翻译
您首先需要学习如何将矩阵(通常是 4x4,您可以搜索为什么会找到答案)与其他矩阵和 vector 相乘。
这样对于你世界中的每个对象,你将存储每个顶点的位置(一个绝对位置,基于对象原点),然后你将存储一个转换矩阵(缩放,旋转和平移(=位置)世界上的物体)。最后,您将拥有一个相机矩阵,这将使您能够在相机的相反方向和位置上移动世界,使相机看起来像是在移动。
所以:
假设我们的对象只是一个点。
对象:
• 顶点[1, 2, -1, 1]
(x、y、z 和w 通常等于1)
• 缩放矩阵(假设在 y 上缩放 x2.0)
[1, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 1]
• 旋转矩阵(假设在 z 轴上旋转 90°,我们查看 wiki 然后开始)
c = cos(90°) and s = sin(90°)
[ c, s, 0, 0] [ 0, 1, 0, 0]
[-s, c, 0, 0] [-1, 0, 0, 0]
[ 0, 0, 1, 0] = [ 0, 0, 1, 0]
[ 0, 0, 0, 1] [ 0, 0, 0, 1]
• 平移矩阵(假设为 -2、1、4)
[1, 0, 0, -2]
[0, 1, 0, 1]
[0, 0, 1, 4]
[0, 0, 0, 1]
现在我们只需要将所有这些结合起来,我们就得到了一个新的点:
T * R * S
[1, 0, 0, -2] [ 0, 1, 0, 0] [1, 0, 0, 0]
[0, 1, 0, 1] [-1, 0, 0, 0] [0, 2, 0, 0]
[0, 0, 1, 4] * [ 0, 0, 1, 0] * [0, 0, 1, 0]
[0, 0, 0, 1] [ 0, 0, 0, 1] [0, 0, 0, 1]
=
[ 0, 1, 0,-2] [1, 0, 0, 0] [ 0, 2, 0,-2]
[-1, 0, 0, 1] [0, 2, 0, 0] [-1, 0, 0, 1]
[ 0, 0, 1, 4] * [0, 0, 1, 0] = [ 0, 0, 1, 4]
[ 0, 0, 0, 1] [0, 0, 0, 1] [ 0, 0, 0, 1]
这是我们的对象矩阵。
现在我们只需要将我们的顶点乘以它就可以得到它在世界中的位置:
[ 0, 2, 0,-2] [ 1] [2]
[-1, 0, 0, 1] [ 2] [0]
[ 0, 0, 1, 4] * [-1] = [3]
[ 0, 0, 0, 1] [ 1] [1]
在 (2, 0, 3, 1) 处给出一个点。
现在我们将计算相机矩阵,将它的变换应用于世界。
你需要 vector 计算(如叉积或点积)
https://en.wikipedia.org/wiki/Cross_product
https://en.wikipedia.org/wiki/Dot_product
https://en.wikipedia.org/wiki/Norm_(mathematics)#Euclidean_norm
你的相机有 2 个点,第一个是它的位置,另一个是“注视”点。
有了它,您可以计算这些值:
zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)
[ xaxis.x , yaxis.x , zaxis.x , 0]
[ xaxis.y , yaxis.y , zaxis.y , 0]
[ xaxis.z , yaxis.z , zaxis.z , 0]
[-dot(xaxis, eye), -dot(yaxis, eye), -dot(zaxis, eye), 1]
这里你有你的相机矩阵,你只需要将它应用到你的世界的每个顶点,你就完成了。
我不记得那个公式是否适用透视。
如果你自己做所有事情,你还需要处理裁剪(当一个点在相机后面时,在处理透视时数学就被打破了)。
还要记住矩阵相乘的顺序,看一下:
Cam * Translation * Rotation * Scale * Point
点总是最后一个(矩阵数学,sry),最接近它的矩阵最先应用到它,所以这里我们首先对点应用缩放,然后是旋转,然后是平移,最后是相机定位。
祝你好运。
关于c# - 在水平任意轴上旋转 3D 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42918744/
我想要以下内容: void foo( /* something representing a function f */, /* arguments a1, a2, etc. in s
简而言之,我想声明一个这样的特征: trait Test { def test(amount: Int): A[Int] // where A must be a Monad } 这样我就可以
在 GWT 中,如何在 onModuleLoad 方法中插入框架集以及相对嵌套的框架集和框架,以合并许多小程序和其他小部件和 HTML?代码片段是: 公共(public)类 MainEntryPoin
这个问题在这里已经有了答案: How do I best simulate an arbitrary univariate random variate using its probability
我对java相当陌生,并且习惯于枚举本质上只不过是一个命名的整数列表。 现在我正在编写一个实现,其中父类有几个采用枚举值作为参数的方法。枚举将在子类中定义,并且会略有不同。由于枚举基本上看起来像类,所
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
想象一下 6-7 台服务器的设置都完全相同Java 版本“1.6.0_18”OpenJDK 运行时环境 (IcedTea6 1.8) (fedora-36.b18.fc11-i386)OpenJDK
这个问题在这里已经有了答案: What are some uses of template template parameters? (10 个答案) 关闭 4 年前。 我有一个根据策略舍入值的函数
我正在寻找如何在 Java 中给定一个 Async CompletableFutures 列表,以便前 N 个中的任何一个成功完成或失败。除非没有 N 次成功,否则忽略任何失败。 有这方面的例子吗?
我面临的问题是项目已经使用集群编程来分配任务。 if (cluster.isMaster) { // Fork workers. for (var i = 0; i { }); } el
我正在为 Luxology modo(3D 和 VFX 应用程序)编写脚本,该脚本使用 python 作为脚本语言。在我的脚本中的某个位置,我正在读取从其他应用程序输出的文本文件,并从该文本文件的行创
这个问题在这里已经有了答案: Fast arbitrary distribution random sampling (inverse transform sampling) (5 个答案) 关闭
我只是遇到了一个问题,我有一个结构数组,例如 package main import "log" type Planet struct { Name string `json:"
我正在尝试将 class ResponseResult 编码为 json case class ResponseResult (var Code : Int, var
我想将一个矩阵中的一个 block 复制到另一个矩阵的一部分中。要将其与任何类型的 n 维数组一起使用,我需要通过 [] 运算符应用带有偏移量的列表。有办法做到这一点吗? mat_bigger[0:5
我有一个匹配一组数字和字母的正则表达式。但是我希望能够排除任何三个连续的字母。这是为了防止意外形成单词或缩写。 我的表达如下。它还排除了一些类似的字符,如 0、o、O 和 1、i、I、l): ^[2-
根据documentation . 应匹配任何字符,但不匹配重音字符。 mysql> select 'test' regexp 't.st'; +----------------------+ | '
我该如何用 JavaScript 编写这个 if 语句? if(url == "http://www.google.com/" && "*") { ... } * 需要灵活并接受添加到第一个变量上
我知道 cPython 有一个 GIL,因此如果不使用多处理模块,您的脚本就无法在多个内核上运行。但是有什么可以阻止内置功能,例如使用多核进行排序吗?我不了解 cPython 结构,但我想我要问的问题
寻找命令行 gdb 的替代方法来检查 OSX 上的核心转储 - 有没有办法让 Xcode 打开带有调试符号的任意核心转储? 最佳答案 您是否尝试过使用 MachOView 1? 听起来它可能适用于查看
我是一名优秀的程序员,十分优秀!