#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# Spherical coordinates

edited April 2018

Hi there, please could somebody show me how to get the same x,y,z result but having the origin at c? I appreciate this is mainly a maths problem and sorry if has been answered before but I have been searching/trying to work this out for days now. Thank you

``````    PVector a;
PVector b;
PVector c;

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

a = new PVector(300, 154, 407);
b = new PVector(0, 0, 0);
c = new PVector(55, 233, 82);
}

void draw(){
background(255);

float theta = atan2(a.z, a.x);

float x =  rad * sin(phi) * cos(theta);
float y =  rad * cos(phi);
float z =  rad * sin(phi) * sin(theta);

println(x,y,z);
}
``````
Tagged:

• The solution is to subtract the origin coordinates from the vector `a` before calculating the spherical coordinates.

When transforming back to cartesian coordinates you need to add the origin coordinates after calculating the cartesian coordinates.

If you are going to be doing a lot of these calculations then I suggest you creates functions to do it for you.

• Out of curiosity I have created two functions to convert

cartesian --> spherical coordinates, and
spherical --> cartesian coordinates

If you want, I will post them here provided you assure me that it is not part of some academic assessment.

• Thanks very much quark,

I assure you my academic years are well behind me and use processing purely as a hobby.

• edited April 2018 Answer ✓

OK well here is the code. Hopefully the comments explain what is happening but if you have any questions please ask.

``````/**
Cartesian <--> Spherical conversion methods about any origin.

In the methods below :
The PVector xyz represents the cartsian coordinates [x, y, z]
The PVector rtp represents the spherical coordinates [radius, theta, phi]

The methods are designed to avoid unneccesasry PVector object creation
for efficiancy reasons.

These methods use the float datatype throughout so there will be some
rounding errors but will still be accurate to 7 significant digits. This
will have no visible effect in the vast majority of sketches so is no
cause for concern.

created by Quark 2018
*/

void setup() {
// Test using origin [0,0,0]
testConversion(new PVector(300, 154, 407), null);
// Test using origin [55, 233, 82]
PVector org = new PVector(55, 233, 82);
testConversion(new PVector(300, 154, 407), org);
}

void testConversion(PVector xyz, PVector origin) {
PVector v0 = cartesianToSpherical(xyz, null, origin);
PVector v1 = sphericalToCartesian(v0, null, origin);
println(xyz, "->", v0, "->", v1);
}

/**
Convert a set of cartesian coordinates to spherical coordinates.
The cartesian coordinates are about the origin [0,0,0] unless
another origin is specified.

@ param xyz cartesian coordinates to convert
@ param rtp PVector to hold caculated spherical coordinates (optional)
@ param origin the xyz coordinates origin in 3D space (optional)
@ return a PVector holding the spherical coordinates
*/
PVector cartesianToSpherical(PVector xyz, PVector rtp, PVector origin) {
// Create a new PVector only if the user has not provided one
if (rtp == null) {
rtp = new PVector();
}
// In most cases the origin will be [0,0,0] this avoids the need to create a
// PVector when an origin is not provided
float ox = xyz.x, oy = xyz.y, oz = xyz.z;
if (origin != null) {
ox -= origin.x;
oy -= origin.y;
oz -= origin.z;
}
float rad = sqrt(ox*ox + oy*oy + oz*oz);
rtp.y = atan2(oy, ox);
}
return rtp;
}

/**
Convert a set of spherical coordinates to cartesian coordinates.
The spherical coordinates are about the origin [0,0,0] unless
another origin is specified.

@ param rtp spherical coordinates to convert
@ param xyz PVector to hold caculated cartesian coordinates (optional)
@ param origin the xyz coordinates origin in 3D space (optional)
@ return a PVector holding the cartesian coordinates
*/
PVector sphericalToCartesian(PVector rtp, PVector xyz, PVector origin) {
// Create a new PVector only if the user has not provided one
if (xyz == null) {
xyz = new PVector();
}
// In most cases the origin will be [0,0,0] this avoids the need to create a
// PVector when an origin is not provided
float ox=0, oy=0, oz=0;
if (origin != null) {
ox = origin.x;
oy = origin.y;
oz = origin.z;
}
float sin_p = sin(rtp.z);
xyz.x = rtp.x * cos(rtp.y) * sin_p + ox;
xyz.y = rtp.x * sin(rtp.y) * sin_p + oy;
xyz.z = rtp.x * cos(rtp.z) + oz;
return xyz;
}
``````
• Thanks again quark :)