我该如何编写一个程序,让它以一个角度为基础,在球体周围的点上旋转,就像绕着它走一样?
我正在做一个项目,我需要(作为2D点)绕着3D球体漫步。我很难弄清楚如何在不扭曲极地的情况下实现这一点。基本上我想要向前,向后,向左,向右,以及左转,右转。我一直试图让它在球面坐标下工作,但我的函数似乎不正确。我能做些什么才能让它正常工作呢?(我使用的是p5.js库,使用的是JavaScript)
目前,我正在尝试将x和y变量分别映射到球面空间的phi和theta。然而,它似乎不起作用,我不确定,如果正确实施,这一点是否会绕着大圈移动。我还使用了一个角度变量来移动x和y(cos(A),sin(A)),但我也不确定这是否有效。
我想我需要做的是与大圆圈导航相关的,但我不懂背后的数学原理。
指向我的当前版本的链接:https://editor.p5js.org/hpestock/sketches/FXtn82-0k
当前代码类似
var X,Y,Z;
X=0;
Y=0;
Z=0;
var A=0;
var scaler = 100;
var MOVE_FORWARD = true;
var MOVE_BACKWARD= false;
var MOVE_LEFT = false;
var MOVE_RIGHT = false;
var TURN_LEFT = false;
var TURN_RIGHT = false;
//var i=0;
var x = 0;
var y = 0;
function setup() {
createCanvas(400, 400, WEBGL);
x= 0;
y= 0;
A= 0;
background(220);
}
function keyPressed(){
if(key == "w"){
MOVE_FORWARD = true;
}else if(key == "ArrowLeft"){
TURN_LEFT = true;
}else if(key == "ArrowRight"){
TURN_RIGHT = true;
}
}
function keyReleased(){
if(key == "w"){
MOVE_FORWARD = false;
}else if(key == "ArrowLeft"){
TURN_LEFT = false;
}else if(key == "ArrowRight"){
TURN_RIGHT = false;
}
}
function draw() {
if(MOVE_FORWARD){
x+=0.005*cos(A);
y+=0.005*sin(A);
}
if(TURN_LEFT){
A+=PI/64;
}
if(TURN_RIGHT){
A-=PI/64;
}
var xyz = Sph(1,y,x);
X=xyz[0];
Y=xyz[1];
Z=xyz[2];
background(220);
sphere(scaler);
push();
translate(X*scaler,Y*scaler,Z*scaler);
sphere(5);
pop();
/*i+=PI/32;
if(i>2*PI){
i=0;
}*/
}
function Move(a,d){
//
}
function Sph(p,t,h){
//p = radius
//t (theta) = 2d rotation
//h (phi) = 3d roation
return ([p*cos(h)*cos(t),p*cos(h)*sin(t),p*sin(h)]);
//x=ρsinφcosθ,y=ρsinφsinθ, and z=ρcosφ
}
解决方案
我不知道Java脚本,但您可以实现以下函数(我是用Python语言实现的,希望您可以从它们中读出它们背后的数学/几何逻辑),这些函数允许您选择球体上的运动方向,沿着给定角度DS的步长沿大圆移动,以及更改运动方向。我假设运动是在单位球面上(半径为1)。如果不是,您需要将代码缩放到适当的半径。
import numpy as np
import math
def direct(r, a):
'''
given position-vector r on the unit sphere and initial angle a,
measured from the meridian, i.e. direction north being a = 0,
the result is the unit vector t pointing in that direction
'''
e_z = np.array([0,0,1])
u = np.cross(e_z, r)
u = u / math.sqrt(u.dot(u))
v = np.cross(r, u)
t = math.cos(a) * v + math.sin(a) * u
return r, t
def move(r, t, ds):
'''
given unit position-vector r and unit direction vector t on the unit sphere,
make a step of arclength ds radians from point r in the direction of t along
the great circle that passes through r and tangent to t. The result is the
new position r_ and the new direction vector t_ still tangent to the same
great circle.
'''
co = math.cos(ds)
cs = math.sin(ds)
r_ = co * r + si * t
t_ = -si * r + cs * t
return t_, t_
def redirect(r, t, da):
'''
given unit position-vector r and unit direction vector t on the unit sphere,
rotate the vector t at an angle da.
The result is the new direction vector t_
when da > 0 redirect right
when da < 0 redirect left
'''
rot_axis = np.cross(r, t)
t_ = math.cos(da) * t - math.sin(da) * rot_axis
return r, t_
相关文章