我在3D空间中有一个单位向量,其方向我希望在0到θ的范围内以某个角度扰动,向量的位置保持不变。我能做到这一点的方法是什么?
感谢。
编辑:在考虑了我提出问题的方式后,似乎有点过于笼统。我将尝试使其更具体:假设矢量来自物体的表面(即球体,圆形,盒形,线形,圆柱形,锥形)。如果有不同的方法为每个对象找到新的方向,那么为球体提供帮助就可以了。编辑2:我打算在评论中输入这个,但是太多了。
所以我有orig_vector
,我想在0和theta
之间的某个方向上扰动。 theta
可以被认为是在我的向量周围形成一个圆锥(theta
是圆锥的中心和一边之间的角度)并且我希望在该圆锥内生成一个新的向量。我可以在平面上生成一个与矢量相切的点,从而在点的方向上创建一个单位矢量,称之为rand_vector
。目前,我orig_vector
和t rand_vector
是两个彼此垂直的单位向量。
我生成第一个角度,angle1
介于0和2pi之间,我rand_vector
围绕orig_vector
angle1
旋转rand_vector2
,形成angle2
。我在线查找了一个资源,它说第二个角度sin(theta)
应该介于0和theta
之间(其中rand_vector2
是原始的“圆锥”角度)。然后,我围绕acos(angle2)
和rand_vector2
之间的叉积定义的向量,按orig_vector
轮换theta=0
。
当我这样做时,我没有获得所需的结果。也就是说,当orig_vector
时,我仍然会受到扰动的向量,我希望得到angle2 = sin(theta)*rand()
。如果有人能够解释角度的原因以及它们的原因,我将非常感激。
编辑3:这是最后的编辑,我保证=)。所以我修复了我的错误,我上面描述的所有内容都有效(这是一个实现错误,而不是理论错误)。但是,我关于角度的问题(即为什么是perturbed_vector = rand_vector2.Rotate(rand_vector2.Cross(orig_vector), acos(angle2))
以及为什么是{{1}}。非常感谢!
答案 0 :(得分:7)
以下是我之前用于此类问题的算法。它在Ray Tracing News中有描述。
1)使第三个向量垂直于另外两个构建正交基础:
cross_vector = unit( cross( orig_vector, rand_vector ) )
2)在[0,1]中选择两个均匀的随机数:
s = rand( 0, 1 )
r = rand( 0, 1 )
3)设h是锥角的余弦:
h = cos( theta )
4)修改球体上的均匀采样,以在+ Z:
周围的锥体中拾取随机向量phi = 2 * pi * s
z = h + ( 1 - h ) * r
sinT = sqrt( 1 - z * z )
x = cos( phi ) * sinT
y = sin( phi ) * sinT
5)改变基础以围绕原始角度重新定位:
perturbed = rand_vector * x + cross_vector * y + orig_vector * z
答案 1 :(得分:1)
如果你有另一个矢量来表示旋转轴,那么有一些库将采用轴和角度并给你一个旋转矩阵,然后可以乘以起始矢量来得到你想要的结果。 / p>
但是,旋转轴应与起始矢量成直角,以获得您期望的旋转量。如果旋转轴不在垂直于矢量的平面内,则结果将与theta略有不同。
话虽这么说,如果你已经一个与你想要扰动的矢量成直角的矢量,并且你不会对扰动的方向挑剔,你可以轻松地采取您的起始矢量与垂直矢量的线性组合,根据需要调整幅度。
即,如果P和Q是具有相同幅度并且垂直的矢量,并且您想要在Q方向上旋转P,那么由R = [P cos(θ)+ Q给出的矢量R sin(theta)]将满足你给出的限制。如果P和Q具有不同的幅度,那么将涉及一些缩放。
答案 2 :(得分:0)
您可能对3D坐标变换感兴趣,以改变矢量角度。
我不知道您想要改变角度的方向,但是将笛卡尔坐标转换为spherical coordinates可以让您根据自己的意愿改变角度。
答案 3 :(得分:0)
实际上,这很容易做到。您所要做的就是将矢量乘以正确的旋转矩阵。生成的矢量将是您的旋转矢量。现在,你如何获得这样的旋转矩阵?这取决于您使用的3d框架/引擎。任何3d框架都必须提供获取旋转矩阵的函数,通常作为Matrix类的静态方法。
祝你好运。答案 4 :(得分:0)
与其他评论中说的一样,您可以使用旋转矩阵旋转矢量。
旋转矩阵有两个角度可以旋转矢量。您可以使用随机数生成器来选择它们,但是从平面生成器中选择两个是不正确的。为了确保您的旋转矢量是平坦的,您必须从平面发生器中选择一个随机角度φ,并从cosθ中的发生器平面中选择另一个角度;这可以确保正确定义您的立体角元素dcos(θ)dφ(φ θ和球面坐标通常定义。
示例:选择一个没有范围限制的随机方向,random()
在[0,1]中生成平面
angle1 = acos(random())
angle2 = 2*pi*random()
答案 5 :(得分:0)
我的团结代码 - 经过测试和工作:
private Block frames[] = new Block[4];