# Spherical Coordinates and Angle back to Origin?

**URL:** <https://discourse.processing.org/t/spherical-coordinates-and-angle-back-to-origin/39770>\
**Category:** Coding Questions\
**Created:** [November 18, 2022, 5:39am UTC](https://discourse.processing.org/t/spherical-coordinates-and-angle-back-to-origin/39770 "2022-11-18T05:39:39Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ASHER](https://avatars.discourse-cdn.com/v4/letter/a/dc4da7/32.png) [@ASHER](https://discourse.processing.org/u/ASHER)\
**Post date:** [November 18, 2022, 5:39am UTC](https://discourse.processing.org/t/spherical-coordinates-and-angle-back-to-origin/39770/1 "2022-11-18T05:39:40Z")

</div>

Alright, so I’ve been Googling for several days and cannot figure how to solve what I think is rather simple…? I’ve also searched the forum here and will list at the end some of the links I’ve explored.

Context: In 2D I can find the angle from one point to another using atan2 and create a line from one point in the direction of the other point with any desired length. I have some sample code below that has an origin at the center of the window and a secondary point that is essentially the mouseX and mouseY values. A line points from mouseX and mouseY towards the origin.x and origin.y.

Problem: My question is what is the equivalent to the above 2D solution in 3D? Create a line from one point with a given radius towards another in 3D space. From my searching I can place a point with x, y, and z values on the surface of a sphere given an origin, radius, theta, and phi. I believe this is called spherical to Cartesian coordinates. However, I cannot seem to be able to draw a line from a 3D point on the sphere surface back to the origin. I can seem to get theta and phi from a point on a sphere surface that when converted to Cartesian coordinates returns the origin point.

2D example:

```auto
PVector origin; // center of window
PVector target; // mouse position

void setup() {
  size(500, 500, P3D);
  origin = new PVector(width/2, height/2);
  target = new PVector();
}

void draw() {
  background(255);
  
  // set target to mouse position
  target.x = mouseX;
  target.y = mouseY;
  target.z = 100;
  
  // calculate angle from target/mouse to origin point
  float angle = atan2(origin.y - target.y, origin.x - target.x);
  float radius = 50;
  
  // caluclate new point form target towards origin with length radius
  float x = target.x + cos(angle) * radius;
  float y = target.y + sin(angle) * radius;
  
  // display origin and angle 
  fill(0);
  stroke(0);
  strokeWeight(10);
  point(origin.x, origin.y, origin.z); 
  strokeWeight(5);
  line(target.x, target.y, x, y);
  
  // what is the equivalent in 3D?
  // how can i draw a line with radius 50 from target pointing towards origin?
}

```

From my searching I’ve found the following:

```auto
float dx = origin.x - target.x;
float dy = origin.y - target.y;
float dz = origin.z - target.z;

float theta = atan2(dz, dx);
float phi = atan2(sqrt(sq(dz) + sq(dx)), dy)
// or:
float phi = atan2(sqrt(sq(dz) + sq(dx)), dy) * PI

// this can be converted to new points
// however this does not point back to origin
float x = target.x + radius * sin(phi) * cos(theta);
float y = target.y + radius * sin(phi) * sin(theta);
float z = target.z + radius * cos(phi);

```

I tried exploring the code from this question as well to no success:

> [@Cartesian to Spherical coordinates conversion issue](https://discourse.processing.org/t/cartesian-to-spherical-coordinates-conversion-issue/8174):
>
> Hi everyone, I am trying to convert the cartesian coordinates a PVector in 3D space, with coordinates (x, y, z) in spherical coordinates (so obtaining radius, theta and phi). Below is the code I am testing, rarely it “works”, I guess there is something wrong so something is just inverted. import peasy.\*; PeasyCam cam; PVector p; void setup() { size(600, 600, P3D); cam = new PeasyCam(this, 500); // the vector with cartesian coordinates p = PVector.random3D(); p.mult(100); } …

Any tips or suggestions would be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [November 18, 2022, 9:16am UTC](https://discourse.processing.org/t/spherical-coordinates-and-angle-back-to-origin/39770/2 "2022-11-18T09:16:58Z")

</div>

Hi @ASHER,

Welcome to the forum! 😉

Thanks for the well written post!

First thing I would like to point out is that the 2D example can be simplified with vector math (without using atan2). In fact you can do the following:

(pseudocode below)

```auto
PVector mouseToCenter = center - mouse
PVector directionNormalized = mouseToCenter.normalize()
PVector lineEnd = center + directionNormalized * lineLength

```

```processing
float lineLength = 50;

void setup() {
  size(500, 500);
}

void draw() {
  background(255);
  
  PVector mouse = new PVector(mouseX, mouseY);
  PVector center = new PVector(width / 2, height / 2);
  
  PVector direction = PVector.sub(center, mouse).normalize();
  PVector lineEnd = PVector.add(mouse, PVector.mult(direction, lineLength));
  
  strokeWeight(5);
  line(mouse.x, mouse.y, lineEnd.x, lineEnd.y);
}

```

And in 3D this is the same computation but with one more dimension. Here with an animation around a sphere with a radius:

```processing
float lineLength = 50;
float time = 0;
float radius = 100;

void setup() {
  size(500, 500, P3D);
}

void draw() {
  background(255);
  
  translate(width / 2, height / 2);
  
  PVector lineOrigin = new PVector(cos(time) * radius, sin(time) * radius, cos(time / 2) * radius);
  PVector center = new PVector(0, 0, 0);
  
  PVector direction = PVector.sub(center, lineOrigin).normalize();
  PVector lineEnd = PVector.add(lineOrigin, PVector.mult(direction, lineLength));
  
  strokeWeight(5);
  line(lineOrigin.x, lineOrigin.y, lineOrigin.z, lineEnd.x, lineEnd.y, lineEnd.z);
  
  time += 0.1;
}

```

Of course you can still use spherical coordinates and convert it to cartesian but I find the above solution simpler 😉 (if it suits your needs)

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [November 19, 2022, 12:53pm UTC](https://discourse.processing.org/t/spherical-coordinates-and-angle-back-to-origin/39770/3 "2022-11-19T12:53:58Z")

</div>

Hello @ASHER ,

> [@ASHER](#):
>
> I can place a point with x, y, and z values on the surface of a sphere given an origin, radius, theta, and phi. I believe this is called spherical to Cartesian coordinates. However, I cannot seem to be able to draw a line from a 3D point on the sphere surface back to the origin. I can seem to get theta and phi from a point on a sphere surface that when converted to Cartesian coordinates returns the origin point.

Some code I wrote to convert:

- spherical to Cartesian
- Cartesian to spherical \< To compare to above!

```auto
// Spherical Coordinate System
// v1.0.0
// GLV 2022-11-19

// Reference:
// https://en.wikipedia.org/wiki/Spherical_coordinate_system

void setup()
  {
  size(500, 500, P3D);
  background(255);
  frameRate(60); //Default
  }

  float theta;
  float phi;
  
  
void draw()
  {
  //background(255);
  
  translate(width/2, height/2);
  
  //phi = random(0, TAU);
  phi = random(-TAU/2, TAU/2);
  theta = random(0, TAU/2);
  println( nf(degrees(phi), 3, 1), nf(degrees(theta), 3, 1) );
  //println(nf((degrees((phi + TAU)%TAU)), 3, 1), nf(degrees(theta), 3, 1)); // Converts to 0 to TAU
    
  float radius = 200;

  float x = radius * sin(theta) * cos(phi);
  float y = radius * sin(theta) * sin(phi);
  float z = radius * cos(theta);
  
  theta = acos(z/200);
  phi = atan2(y, x);
  
  // See atan2() reference
  // Values returned are PI to -PI
  println( nf(degrees(phi), 3, 1), nf(degrees(theta), 3, 1) );
  //println(nf((degrees((phi + TAU)%TAU)), 3, 1), nf(degrees(theta), 3, 1)); // Converts to 0 to TAU
  println();
  
  strokeWeight(1);
  stroke(128);
  line(0, 0, 0, x, y, z);
  
  strokeWeight(4);
  stroke(0, 255, 0);
  line(x, y, z, x-x/4, y-y/4, z-z/4);
  
  strokeWeight(10);
  stroke(255, 0, 0);
  point(x, y, z);
  
  strokeWeight(10);
  stroke(255, 0, 0);
  point(0, 0, 0);
  }

```

Also added some frills.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/9/6961a59778e3de498f8e9de62a9d81ab766c55fd.png)

Base code above with some embellishments (not included here):

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/2/c2d3c4dd5552d89db408c285fb6e2ffc47208644.png)

Reference:  
[https://en.wikipedia.org/wiki/Spherical\_coordinate\_system](https://en.wikipedia.org/wiki/Spherical_coordinate_system)

`:)`
