Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Find coordinates of points on surface a sphere?

Scalar Tardis
SL Scientist/Engineer
Join date: 5 Nov 2005
Posts: 249
10-29-2006 20:42
Well, I am getting frustruated, and about to throw in the towel.. again.

Given a sphere with in-world coordinates <x,y,z> and Euler rotation of <a,b,c> and scale of <d,e,f> how do I find a in-world coordinates of a point on the surface of that sphere, as indicated by vector <g,h,i> which is local to the prim and rotates with it?

If it's easier to do this with a quat calculation vs using Eulers, that is fine since I'm trying to do this with an in-world primitive anyway.


Time for a break. My brain hurts.

Whoops, used same letters for <g,h,i> as scale. Fixed...
Thanto Usitnov
Lord Byron wannabe
Join date: 4 Aug 2006
Posts: 68
10-29-2006 21:18
for an unrotated sphere, assuming the vector is a unit vector (can be converted to one with llRot2Fwd() supplying any random value for s), it should be <x+a*d,y+b*e,z+c*f>. For a rototation though... umm... I'm too tired for this. I think it has something to do with measuring the vector from the same plane as the sphere, then rotating that or... I don't know.
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
10-29-2006 23:45
I know from recent experience that you can get the position of a child prim from the root prim (or an offset if you wish) by multiplying the offset by the Global Rotation..

Or basically, if the root prim is facing normal, zero_vector, and the offset is <10.0, 1.0, 0.0> then when the root prim is rotated some other way, multiply the offset by the rotation, to get the new offset. (or something to that effect. I excel in math, but this is greek to me)

So basically, if you have the scale, and can get the offset of the point in zero_rotation then simply apply the rotation to it.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
10-30-2006 01:50
Let me see if i understand, you want to know the position on the surface of a sphere that isn't uniform in relation to the sphere.

I think this will work. I've not done the proof but it holds true for the edges. It won't hold true if you cut or twist the sphere.
CODE

vector calc()
{
vector vSphereSize = <1.0,1.0,1.0>;
rotation rPointRot = <0.0,0.0,0.0,1.0>;//local to sphere, doesn't need to be normalized

vector vt = <1.0,0.0,0.0> * rPointRot;
vt = llVecNorm(<vt.x / vSphereSize.x, vt.y / vSphereSize.y, vt.z / vSphereSize.z>);
return <vt.x * vSphereSize.x, vt.y * vSphereSize.y, vt.z * vSphereSize.z>;
}

vector global_calc()
{
vector vSpherePos = <0.0,0.0,0.0>; //global pos
rotation rSphereRot = <0.0,0.0,0.0,1.0>;//global rot

return vSpherePos + calc() * rSphereRot;
}


My thinking:
I was thinking that if you smushed the rotation in regards to the sphere and then applied that to a unit vector and desmushed the vector, it would give you the local position of the location on the sphere. After writing it I realized it didn't have to be converted back to a rotation, as to generate the rotation you need the vector form of the rot as a unit vector, being that that was the smushed form we were going to then desmush... it got optimized out.

There is probably another way to do this but i don't know what it is. Isn't llRot2Fwd the same as multiplying a unit vector of that axis by the rot? If it is, then multiplying is the less expensive operation in (less bytecode, like 2 bytes).
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
10-30-2006 02:15
Oh then I expanded the math and then simplified...

Should use this version, it's going to be more accurate (and faster). Course accuracy is moot when you consider that SL doesn't render perfect spheres (just approximations).
CODE

vector calc()
{
vector vSphereSize = <1.0,1.0,1.0>;
rotation rPointRot = <0.0,0.0,0.0,1.0>;//local to sphere, doesn't need to be normalized

vector vt = <1.0,0.0,0.0> * rPointRot;
return vt / llVecMag(<vt.x / vSphereSize.x, vt.y / vSphereSize.y, vt.z / vSphereSize.z>);
}
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Scalar Tardis
SL Scientist/Engineer
Join date: 5 Nov 2005
Posts: 249
10-30-2006 19:03
*Bows to the Math God*

And so I've used that to make two general functions, one that uses the local vector to indicate the offset, and one that uses a local rotation..... though I have no idea why anyone would use the Local-Rotation method of finding a point on a sphere. :)

This equation works great except for a very minor problem. The size reported by llGetScale() is the diameter of the sphere, but your original equation assumes the scale is the radius. I fixed that bit in these functions. (Whoohoo, I'm not a total math moron.)


CODE
// Rotation equations by: Strife Onizuka
// Generalized functions: Scalar Tardis
//
// See thread in SL Forum: Scripting Tips:
// http://forums.secondlife.com/showthread.php?t=146231

vector PointOnSphereLocVec(vector vSphereSize, vector vSpherePos,
rotation rSphereRot, vector vLocalVector)
{
// llGetScale() returns prim diameter, but this equation
// assumes it's a radius, so divide size in half
vSphereSize.x /= 2; vSphereSize.y /= 2; vSphereSize.z /= 2;
vector vt = vLocalVector * <0.0,0.0,0.0,1.0>;
return vSpherePos + (vt / llVecMag(<vt.x / vSphereSize.x, vt.y
/ vSphereSize.y, vt.z / vSphereSize.z>)) * rSphereRot;
}

vector PointOnSphereLocRot(vector vSphereSize, vector vSpherePos,
rotation rSphereRot, rotation rLocalRot)
{
// llGetScale() returns prim diameter, but this equation
// assumes it's a radius, so divide size in half
vSphereSize.x /= 2; vSphereSize.y /= 2; vSphereSize.z /= 2;
vector vt = <0.0,0.0,-1.0> * rLocalRot;
return vSpherePos + (vt / llVecMag(<vt.x / vSphereSize.x, vt.y
/ vSphereSize.y, vt.z / vSphereSize.z>)) * rSphereRot;
}


default
{ state_entry()
{ llSay(0, "Ready."); }

touch_start(integer total_number)
{
vector MyScale = llGetScale();
vector MyPos = llGetPos();
rotation MyRot = llGetRot();
llSay(0, "My Position:" + (string)MyPos );

// Here's a short table of Local-Vector offsets
// for a sphere with Euler-format rotation of 0°, 0°, 0°
//
// <-1.0, 0.0, 0.0>; = -x
// < 1.0, 0.0, 0.0>; = +x
// < 0.0,-1.0, 0.0>; = -y
// < 0.0, 1.0, 0.0>; = +y
// < 0.0, 0.0,-1.0>; = -z
// < 0.0, 0.0,-1.0>; = +z

vector LocalVec = <0.0,0.0,-1.0>;
llSay(0, "Local Vector offset is: " + (string)
PointOnSphereLocVec(MyScale, MyPos, MyRot, LocalVec));

// Here's a short table of Local-Rotation offsets
// for a sphere with a Euler-format rotation of 0°, 0°, 0°
//
// < 0.000,-0.707, 0.000, 0.707> = -x
// < 0.000, 0.707, 0.000, 0.707> = +x
// < 0.707, 0.000, 0.000, 0.707> = -y
// <-0.707, 0.000, 0.000, 0.707> = +y
// < 0.000, 0.000, 0.000, 1.000> = -z
// < 0.000,-1.000, 0.000, 0.000> = +z

rotation LocalRot = < 0.000, 0.000, 0.000, 1.000>;
llSay(0, "Local Rotation offset is: " + (string)
PointOnSphereLocRot(MyScale, MyPos, MyRot, LocalRot));
}
}


Would this be worthy of adding to the Scripting Library? :)
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
10-30-2006 19:23
From: Scalar Tardis
*Bows to the Math God*

(Whoohoo, I'm not a total math moron.)



After looking at that... I think I am.. sheesh. Math used to be my favorite subject.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
10-31-2006 16:52
*blush*

From: Aakanaar LaSalle
After looking at that... I think I am.. sheesh. Math used to be my favorite subject.


Was mine too, though I sucked at trig (i could never remember it; the trig really hurt when i did calc).

Script library would be a really good idea. I suppose you would choose your method depending upon what you were trying to do.

CODE

//You can replace
vSphereSize.x /= 2; vSphereSize.y /= 2; vSphereSize.z /= 2;
//with
vSphereSize /= 2;

//or you can just bake it into the equations (which is what i would do; i don't like to waste on a store operation, saves 10 bytes and runs a bit faster).

vector PointOnSphereLocVec(vector vSphereSize, vector vSpherePos,
rotation rSphereRot, vector vLocalVector)
{
// llGetScale() returns prim diameter, but this equation
// assumes it's a radius, so divide size in half
vector vt = vLocalVector * <0.0,0.0,0.0,1.0>;
return vSpherePos + (vt / llVecMag(<vt.x / vSphereSize.x, vt.y
/ vSphereSize.y, vt.z / vSphereSize.z> * 2)) * rSphereRot;
}

vector PointOnSphereLocRot(vector vSphereSize, vector vSpherePos,
rotation rSphereRot, rotation rLocalRot)
{
// llGetScale() returns prim diameter, but this equation
// assumes it's a radius, so divide size in half
vector vt = <0.0,0.0,-1.0> * rLocalRot;
return vSpherePos + (vt / llVecMag(<vt.x / vSphereSize.x, vt.y
/ vSphereSize.y, vt.z / vSphereSize.z> * 2)) * rSphereRot;
}


(i think it's really cool the math all worked out)
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey