Talk:LSL Addition

From Second Life Wiki
Jump to navigation Jump to search

footnotes

I tried using the footnote template, but it only leaves a tiny link, and in some cases (rotation especially on this page) a larger more noticeable link is appropriate... thoughts?
-- Void (talk|contribs) 18:04, 16 January 2010 (UTC)

Adding quaternions

Yes that is a valid thing to do! If you add rotations, the result is like an "average" from ZERO_ROTATION. For a visualization you can make 2 or 3 "lever" prims, then a 4th prim can rotate itself to the added lever rotations in a timer. --Cerise Sorbet 01:32, 17 January 2010 (UTC)

It's not like an "average", it's not valid for working with quaternions. A quaternion represents a point on a four-dimensional sphere but quaternions only use half of the sphere. Points that lie in the other half give the same results. As such <0,0,0,1> is equivalent to <0,0,0,-1>. Now if you want the reciprocal of a quaternion, instead of inverting all the floats in the structure like you would with a vector, you only negating the first three of the four values (or by negating only the forth if it is non-zero). Now if you were to negate all four values, you would get the equivalent. Now if you were to "add" quaternions 'a' and 'b' in this manner you describe you would get a value 'c' and likewise if you were to add 'a' and the equivalent of 'b' you would get 'd'; 'c' and 'd' would not be equivalent. Using addition on a quaternion is just not of mathematical interest; I wish it were but it tends to be a newbie trap instead.

Lets also not forget that, in doing this you are more likely than not changing the magnitude of the quaternion; that is to say it will not be a unit quaternion. Now if you are using the value in a built in LSL function like llSetRot this isn't going to be a problem but if you are using it to transform a vector, it's going to change the magnitude of the vector as well.

Out of curiosity I worked out the relationship between the magnitudes and addition.

definitions:
  q = <q.x, q.y, q.z, q.s>
  p + q = <p.x + q.x, p.y + q.y, p.z + q.z, p.s + q.s>
  p • q = (p.x * q.x) + (p.y * q.y) + (p.z * q.z) + (p.s * q.s)
  q.magnitude = (q.x^2 + q.y^2 + q.z^2 + q.s^2) ^ (1 / 2)
              = (q • q) ^ (1 / 2)

 A Unit Quaternion is any quaternion which has a magnitude of 1.
  IsUnitQuanternion(q) = (q.magnitude == 1)

//it should be noted that LSL does not have a quaternion dot product, though for the sake of brevity I have used one here.


math:
  a + b = c
  a.magnitude = (a.x^2 + a.y^2 + a.z^2 + a.s^2)
  b.magnitude = (b.x^2 + b.y^2 + b.z^2 + b.s^2)

  c.magnitude = ((a.x + b.x)^2 + (a.y + b.y)^2 + (a.z + b.z)^2 + (a.s + b.s)^2) ^ (1 / 2)
  c.magnitude^2 = ((a.x + b.x)^2 + (a.y + b.y)^2 + (a.z + b.z)^2 + (a.s + b.s)^2)
                = (a.x^2 + (2*a.x*b.x) + b.x^2) + (a.y^2 + (2*a.y*b.y) + b.y^2) + (a.z^2 + (2*a.z*b.z) + b.z^2) + (a.s^2 + (2*a.s*b.s) + b.s^2)
                = a.x^2 + a.y^2 + a.z^2 + a.s^2 + (2*a.x*b.x) + (2*a.y*b.y) + (2*a.z*b.z) + (2*a.s*b.s) + b.x^2 + b.y^2 + b.z^2 + b.s^2
                = a.magnitude^2 + (2*a.x*b.x) + (2*a.y*b.y) + (2*a.z*b.z) + (2*a.s*b.s) + b.magnitude^2
                = a.magnitude^2 + (2*(a.x*b.x + a.y*b.y + a.z*b.z + a.s*b.s)) + b.magnitude^2
                = a.magnitude^2 + (2*(a • b)) + b.magnitude^2

  c.magnitude^2 - a.magnitude^2 - b.magnitude^2 = 2 * (a • b);
  (c.magnitude^2 - a.magnitude^2 - b.magnitude^2) / 2 = a • b;


conclusion:
 If you want 'c' to be a unit quaternion when adding the two unit quaternions 'a' and 'b', the following must be true:
  -1 / 2 = a • b;
 That is to say, the dot product of the inputs must equal negative 1/2.
 I did find a pair that satisfies the equation, from which you can find countless others.
 a = < 0,   0,   0,  -1 >
 b = <1/2, 1/2, 1/2, 1/2>

For those curious, given a vector 'v' and a quaternion 'q', using 'q' to transform 'v' in the direction of 'q' will result in a vector 'r'. Here is the relationship of the magnitude of 'r' to those of 'v' and 'q'. r.magnitude = v.magnitude * q.magnitude * q.magnitude

It should also be noted that transforming 'v' in the opposite direction of 'q' (giving a result vector 'R') in LSL will also yield the same equation relationship of the magnitudes. R.magnitude = v.magnitude * q.magnitude * q.magnitude I think this is a bug and it should yield the relationship: R.magnitude = v.magnitude / (q.magnitude * q.magnitude)

-- Strife (talk|contribs) 05:22, 19 January 2010 (UTC)

Is there a misunderstanding that quaternions must be normalized? That is not so. SL rotations have no use for sizes but they are valid. If you performa the mormalization yourself you may better see what happens. --Cerise Sorbet 07:32, 19 January 2010 (UTC)
I'll bite:
  1. <0.5, 0.5, 0.5, 0.5> + <0, 0, 0, 1> = <0.5,0.5,0.5,1.5> => <0.288675134, 0.288675134, 0.288675134, 0.866025403>
  2. <0.5, 0.5, 0.5, 0.5> + <0, 0, 0, -1> = <0.5,0.5,0.5,-0.5> => <0.5, 0.5, 0.5, -0.5>
*prods at it in LSLEditor*
I take it back, it is of mathematical interest.
*prods it some more*
Aww sh*t. So that is how this manifests in quaternions? Oh it breaks the symmetry of quaternions. It still is something the average user should be ignoring as it is pretty useless unless you have the math background to take advantage of it (which most scripters do not).
P.S. LSL does not make it easy to normalize quaternions. -- Strife (talk|contribs) 08:30, 19 January 2010 (UTC)
I wanted to add to my previous post, that I do not consider it a bug. -- Strife (talk|contribs) 08:33, 19 January 2010 (UTC)