Geometric Center
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 01:09
Hi all. Got a quick question. I was looking over the Wikki (or the alternate one) and couldn't find anything to help explain how to do this.
I have four objects, cubes, all sized 10 by 10 by 0.01, set to form a 20 x 20 square. One of these objects is the root prim of the link set.
I know I can get the position of the root prim with llGetPos or llGetRootPosition (depending if i have the script in the root prim or another prim) and I can apply an offset by adding it to the root position. This would allow me to get the geometric center of the four prims.
This is of course, depending on the link set having Zero Rotation. If however, the object is rotated, my offset is no longer suffecient.
So given the llGetRot (or llGetRootRotation), how do I find the geometric center?
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 01:58
Hi, hmm. I am the lazy type and would place a small invisible prim in the exact center and make it the root - no calculation needed but one prim more used.  Not wanting to waste the prim .... the origin is - if you use squares, halfway up the diagonal, right? So first attempt I'd do is to get the origins of two opposing centers and do the vector math. But this requires more scripts .... Doing it with a single script just by using on evector and the rotation .... hmmm .... you must project the rotation on the vector and this will reflect the change in x,y and z coordinates. So - step 1 - get your origins, step two get your rotation, step 3 .... multiply them? I'd have to test this inworld but I have no access to SL now. I would add a fifth prim and place it in the center. Install a listener that will tell you its position for cross check purposes - just make sure it is *not* the root. then try for your root llGetPos() * llGetRot() and compare the result to the center piece alternatively try llGetPos() / llGetRot() Not sure if this will do the desired projection ....
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 02:22
nope. tried using that.. and some variations of the code shown in teh SetPos or SetRot or something.. none of it is working. The object is already 23 prims, i'm hoping to not add any more if possible.. since it will be for sale eventually.
What I'm attempting to do, is have it give a script to the owner on request, which when dropped into a newly built prim will center that prim and then delete itself (the script that is).
So I need a script listening on the object which will, when requested, figgure out the position of that center, and Say it back to the requesting prim.
::Edit:: Ah well, it's late. got a Doctors appointment tomorrow, I'll check back on this thread after then.
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 05:55
I must try this online when I am back home. From my point of view it *should* work. The diagonal method *will* work - I do not need SL for this to verify.  The other method means you must get the vector from your root's origin to the origin of your composed object. If we have a cube at zero rotation (in relation to the world axis) with 2m in every aspect then the vector to your proposed origin would be probably be (<-1,-1,0>  unless I am very mistaken or the root prim is not the upper right square in a 4 block construct. This vector must now be subjected to the rotational transformation. After the transformation is done you must add it to your root's center again and then you should have your compound origin again .... I did some quick calc and got my brain seriously twisted but unless LS works different to my manual calulation this should get you there. Let us see when I can get online and get my "Oh No!" experience 
|
|
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
|
09-11-2006 06:27
From: Aakanaar LaSalle So given the llGetRot (or llGetRootRotation), how do I find the geometric center? Using llGetGeometricCenter()..? ^^; although i dunno if it still has problems reported on that page...
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 10:00
Before I look at the llGetGeometricCenter() i'm sure it's not what i need. These four prims described above arn't the only prims in the object. there are 23 prims currently. The Center that it sounds like llGetGeometricCenter() would return, would be off by a bit. HtF.. What I tried was: (I'm guessing at what I did last night..) *Note* I created a set of cubes, 1m by 1m by 0.01 positioned and rotated same as the main object, to test the code on. at zero rotation, they look like the following. (C = Child, R = Root) [C][C] [R][C] With X acess running North (or UP) and Y axis running West (or to the left) rotation myRot = llGetRot(); vector myPos = llGetPos(); vector offset = <0.5, -0.5, 0>; vector newPos = myPos + offset; vector center = newPos + (myPos - offset) * myRot // Some Math I don't even begin to understand
Basically i tried adding, multiplying, various things and just llSay() the positions and rotatoins etc as i went. I kept getting negative positions. it completely lost me
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 10:00
OK - works as I thought it would - if you want to see with your own eyes I have a demonstration model in my garden.
I put four squares together and put a ball in the middle. I then have the ball report its position and I have my calculated position reported. Both are off but only after the 3rd or 4th decimal - may be a positioning error when building the model may be a calculus error by SL.
Here is what I do:
1. I take the vector from the geometric center of my rootprim to the intended origin. Working with 2m vubes this made a vector of <-1,-1,0>.
2. I take the current rotation of the root prim
3. I multiply the vector with the roatation
4. I add my origin of my root prim and the rotated vector
The results match with the reports by the sphere inside by 10th of centimeters.
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 10:04
thanks.. i havn't time this morning, but when i get back from the doctors, i'll give that a shot.. and see how it works..
so (offset * rotation) + root_position
I'll check that out.
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 10:08
From: Aakanaar LaSalle HtF.. What I tried was: (I'm guessing at what I did last night..) rotation myRot = llGetRot(); vector myPos = llGetPos(); vector offset = <0.5, -0.5, 0>; vector newPos = myPos + offset; vector center = newPos + (myPos - offset) * myRot // Some Math I don't even begin to understand
Basically i tried adding, multiplying, various things and just llSay() the positions and rotatoins etc as i went. I kept getting negative positions. it completely lost me You did it almost right  Your first mistake was to rotate the combined vector. By calling llGetPos() in the root you already have the x,y and z coordinates. No need to project them. All you need to project is your offset vector and *then* add this projection to your root's origin. Here's my code snippet: vector mypos; vector calcpos; rotation myrot; mypos = llGetPos(); myrot = llGetRot(); calcpos = <-1,-1,0> * myrot; calcpos = calcpos + mypos; llSay(0,"Calculated rotational Center: " + (string) calcpos);
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 10:11
From: Aakanaar LaSalle thanks.. i havn't time this morning, but when i get back from the doctors, i'll give that a shot.. and see how it works..
so (offset * rotation) + root_position
I'll check that out. In case of doubt I sent you a landmark to my place. It's in the garden and kinda hard to miss. Play around with it  And good luck with the doc!!!
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 13:33
Ok.. doctor's visit was nothing.. walked in.. he looked at x-rays.. can still see the fracture but it's healed up nice.. dismissed me saying he doesn't need to see me anymore.. in and out in 5 minutes. heh.
That forumla works.. now working on the two scripts needed to make it work.. the one that gives the geometric center when requested, and the other that will set the object to those coords and delete itself.
For the center, i'm only going to set to the X and Y coords, but the Z coords, I have to add .005 + half of the height of the object itself. I think llGetScale will return what i'm looking for..
Thanks.
|
|
Aakanaar LaSalle
Registered User
Join date: 1 Sep 2006
Posts: 132
|
09-11-2006 15:14
ok.. in the root prim of the object, i Put this script. vector vctOffset = <5.0, -5.0, 0.0>; integer intComChan = -1530;
default { state_entry() { llListen(intComChan, "", NULL_KEY, ""); } on_rez(integer intParam) { llResetScript(); } listen(integer intChan, string strName, key keyID, string strMsg) { if (strMsg == "Request: Grid Center") { vector vctCentPos = (vctOffset * llGetRootRotation()) + llGetRootPosition(); llSay(intComChan, "Center: " + (string)vctCentPos); } } }
Then I add this to the objects I want to center integer intComChan = -1530; vector vctOffSet = <0.0, 0.0, 0.0>;
integer intAttemptCount = 0; integer intAttempts = 4;
default { state_entry() { vector vctScale = llGetScale(); vctOffSet.z += (vctScale.z / 2) + 0.005; llListen(intComChan, "", NULL_KEY, ""); llSleep(0.1); llSay(intComChan, "Request: Grid Center"); // llSay(0, "Attempting to retrieve coordinates."); intAttemptCount = 1; llSetTimerEvent(5.0); } listen(integer intChan, string strName, key keyID, string strMsg) { if (llGetSubString(strMsg, 0, 7) == "Center: ") { vector vctMyPos = (vector)llGetSubString(strMsg, 8, -1); vctMyPos = vctMyPos + vctOffSet; llSetPos(vctMyPos); llRemoveInventory(llGetScriptName()); } } timer() { if (++intAttemptCount > intAttempts) { llSay(0, "Error: Failed to receive coordinates!"); llSleep(0.1); llRemoveInventory(llGetScriptName()); } else { llSay(intComChan, "Request: Grid Center"); // llSay(0, "Attempting to receive coordinates"); } } }
It works for the most part. I find if i get too far out to one corner it doesn't pick up the llListen's.. so there's an obvious range issue. I don't think there's much I can do about that.. No way I know of to make the script shout on a channel. But it does work. Thanks again.
|
|
HtF Visconti
Registered User
Join date: 21 Jul 2006
Posts: 123
|
09-11-2006 21:17
As for range issue .... just use llShout() instead of llSay() .... 
|