出于某种不敬虔的原因,我试图通过龟库制作一个程序来显示纯Python 3.6.3中的线框图形。我已经到了要跳过为优化目的而绘制不必要的Tris的地步。不必要的Tris表示应由模型的其他部分(即法线背对3D摄像机)遮盖的Tris。
程序使用的模型数据只是一个巨大的3d数组,每个tri的格式如下。
[[Vert],[Vert],[Vert],[Normal]]
我当前的代码版本只有一个模型(立方体),看起来像这样:
from turtle import *
Cube = [[[-50,50,-50],[-50,50,50,],[50,50,50],[0,1,0]],
[[-50,50,-50],[50,50,50,],[50,50,-50],[0,1,0]],
[[-50,50,-50],[-50,50,50],[-50,-50,50],[1,0,0]],
[[-50,50,-50],[-50,-50,-50],[-50,-50,50],[1,0,0]],
[[-50,50,50],[50,50,50],[50,-50,50],[0,0,1]],
[[-50,50,50],[50,-50,50],[-50,50,50],[0,0,1]],
[[-50,-50,-50],[-50,-50,50,],[50,-50,50],[0,-1,0]],
[[-50,-50,-50],[50,-50,50,],[50,-50,-50],[0,-1,0]],
[[50,50,-50],[50,50,50],[50,-50,50],[-1,0,0]],
[[50,50,-50],[50,-50,-50],[50,-50,50],[-1,0,0]],
[[-50,50,-50],[50,50,-50],[50,-50,-50],[0,0,-1]],
[[-50,50,-50],[50,-50,-50],[-50,50,-50],[0,0,-1]]]
CamVector = [0,1,0]
def DrawModel(Model):
for i in range(0,len(Model)):
goto(Model[i][0][0],Model[i][0][1])
pd()
goto(Model[i][1][0],Model[i][1][1])
goto(Model[i][2][0],Model[i][2][1])
goto(Model[i][0][0],Model[i][0][1])
pu()
Model = Cube
DrawModel(Model)
但是我想将每个tri的法线与CamVector进行比较,因此代码最终看起来像这样:
def DrawModel(Model):
for i in range(0,len(Model)):
AngleAwayFromCamera = *Math voodoo*
if AngleAwayFromCamera <= 90:
*draw tri*
如果有人对如何提供帮助有任何想法,可以向像我这样的胡桃木般大脑的人解释,那将是很棒的。我看了很多文档,但是大多数文档飞得比我高-可能是因为我没有通过GCSE数学。
答案 0 :(得分:0)
在数学上没有过多介绍的细节,在数学中有一种叫做点积的东西。
基本上,这是一种将两个向量(分别称为 a 和 b )组合在一起的方法。此数字等于 a 的大小,再乘以 b 的大小,再乘以它们之间的夹角余弦(可以称为θ)。>
借助此等式,通过四处移动,我们最终可以得到所需的θ。
假设我们有 a :[1, 2, 3]
和 b :[4, 5, 6]
。我们可以通过对元素进行平方并取和的平方根来计算其大小。因此, a 的大小为(1 ** 2 + 2 ** 2 + 3 ** 2) ** 0.5 = 14 ** 0.5
,而 b 的大小为(4 ** 2 + 5 ** 2 + 6 ** 2) ** 0.5 = 77 ** 0.5
。
将它们相乘得到1078 ** 0.5
。因此,点积等于(1078 ** 0.5) * cos θ
。
事实证明,可以通过将两个向量的相应元素相乘并将结果相加来计算点积。因此,对于上面的 a 和 b ,点积为1 * 4 + 2 * 5 + 3 * 6 = 32
。
鉴于点积的这两个不同(但相等)的表达式,我们可以将它们等效为求解θ,如下所示(arccos是将cosθ变成θ的函数):
(1078 ** 0.5) * cos θ = 32
cos θ = 32 / (1078 ** 0.5)
θ = arccos(32 / (1078 ** 0.5))
θ ≈ 12.93 (in degrees)
现在,剩下的就是用代码实现这一点了:
from numpy import arccos
def angle_between_vectors(v1, v2):
def magnitude(v):
return sum(e ** 2 for e in v) ** 0.5
dot_product = sum(e1 * e2 for e1, e2 in zip(v1, v2))
magnitudes = magnitude(v1) * magnitude(v2)
angle = arccos(dot_product / magnitudes)
return angle
将此函数应用于上方的 a 和 b 并将弧度转换为度(除以π并乘以180)可以得到12.93,如预期的那样。