Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

203
Visualizações
How would I go about writing a program to rotate at point around a sphere based on an angle as if walking around it?

I am working on a project where I need to (as a 2d point) walk around a 3d sphere. I am having trouble figuring out how to achieve this without polar distortion. Basically I want to have Move Forward, Backward, Left, and Right, as well as Turn Left, and Turn Right. I've been trying to get this working with spherical coordinates, but my functions seem to be incorrect. What can I do to get this working? (I am making this in JavaScript, using the p5.js library)

Currently, I'm trying to map an x, and y variable to spherical space's phi, and theta respectively. It doesn't seem to be working, though, and I'm not sure whether, correctly implemented, the point would move in Great Circles.

I'm also using an angle variable, to move x, and y by (cos(A), sin(A)), but I'm not sure if this is working either.

I think what I need to do is related to Great Circle Navigation, but I don't understand the mathematics behind it.

Link to my current version: https://editor.p5js.org/hpestock/sketches/FXtn82-0k

Current code looks something like

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φ
}
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

I'm not sure about the math for doing this in polar coordinates but it can be done simply by tracking position and orientation as a pair of 3d cartesian vectors and using Rodrigues' rotation formula to move forward (by rotating the position) and turn (by rotating the axis).

// position vector
let pos;
// axis of rotation
let axis;

let scaler = 150;

function setup() {
  createCanvas(400, 400, WEBGL);
  background(220);
  pos = createVector(1, 0, 0);
  axis = createVector(0, 1, 0);
  fill('red');
  noStroke();
}

function draw() {
  if (keyIsDown(87) || keyIsDown(UP_ARROW)) {
    // move "forward"
    rotateVector(pos, axis, PI / 64);
  }
  if (keyIsDown(LEFT_ARROW)) {
    // turn left
    rotateVector(axis, pos, -PI / 64);
  }
  if (keyIsDown(RIGHT_ARROW)) {
    // turn right
    rotateVector(axis, pos, PI / 64);
  }

  ambientLight(100);
  directionalLight(200, 200, 200, 1, 1, -1);

  push();
  translate(pos.x * scaler, pos.y * scaler, pos.z * scaler);
  sphere(5);
  pop();
}

function rotateVector(v, axis, angle) {
  // v * cos(θ) + (axis ✕ v) * sin + axis * (axis · v) * (1 - cos)
  return v.mult(cos(angle))
    .add(axis.copy().cross(v).mult(sin(angle)))
    .add(axis.copy().mult(axis.dot(v) * (1 - cos(angle))));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

about 4 years ago · Juan Pablo Isaza Relatório

0

I do not know javascript, but you could implement the following functions (which I implemented in python and hopefully you can read off from them the mathematical/geometric logic behind them) that allow you to select a direction of motion on the sphere, to move along a great circle along a step of given angle ds, and to change directions of motion. I am assuming the motion is on the unit sphere (of radius 1). If not, you need to scale the code to the appropriate radius.

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_
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda