Difference between revisions of "Category talk:LSL Vector"

From Second Life Wiki
Jump to navigation Jump to search
Line 77: Line 77:
With this function, the above tests work. It tests for number of elements and then lets the compiler decide what it accepts as vector. Only for ZERO_VECTOR, special treatment is necessary. Therefore, it checks that only zeros and decimal points are in the remaining string. The compiler itself accepts missing ">" and it would also accept more than 3 elements - that's why the function checks the number of elements before.
With this function, the above tests work. It tests for number of elements and then lets the compiler decide what it accepts as vector. Only for ZERO_VECTOR, special treatment is necessary. Therefore, it checks that only zeros and decimal points are in the remaining string. The compiler itself accepts missing ">" and it would also accept more than 3 elements - that's why the function checks the number of elements before.


It's probably not the most efficient way to do it and also accepts more than is actually valid (esp. for ZERO_VECTOR), but it does accept all valid vactors (I hope ^^). Discussion and improvements are welcome. For IsRotation, the implementation would be almost the same, except checking for 4 elements instead of 3.
It's probably not the most efficient way to do it and also accepts more than is actually valid (esp. for ZERO_VECTOR), but it does accept all valid vectors (I hope ^^). Discussion and improvements are welcome. For IsRotation, the implementation would be almost the same, except checking for 4 elements instead of 3.


[[User:Shuichi Shinji|Shuichi Shinji]] 01:13, 31 March 2014 (PDT)
[[User:Shuichi Shinji|Shuichi Shinji]] 01:13, 31 March 2014 (PDT)

Revision as of 02:02, 31 March 2014

<lsl> //******************************* //IMPOSSIBLE TO GET A ZERO_VECTOR //*******************************

vector c = <0.0, 0.0, 0.1>;

default {

   touch_start(integer total_number)
   {
       c -= <0.0, 0.0, 0.025>;
       llSay(0, (string)c);
       if (c == ZERO_VECTOR) llSay(0, "ZERO_VECTOR"); // never c is a ZERO_VECTOR
   }

} </lsl> <lsl> //********************** //IN THIS WAY IT RUNS... //**********************

vector c = <0.0, 0.0, 0.1>;

default {

   touch_start(integer total_number)
   {
       c -= <0.0, 0.0, 0.025>;
       llSay(0, (string)c);
       if ((string)c == "<0.00000, 0.00000, 0.00000>") llSay(0, "ZERO_VECTOR");
   }

} </lsl> —The preceding unsigned comment was added on 06:29, 29 April 2012 by Zohan Galewind


The above is caused by how floating point math works. 0.1 does not fall on an exact boundary as a float, nor does 0.025. Furthermore the rounding on the two values do not exactly line up, so (4 * 0.025) != 0.1. This is not a bug but a caveat of using floating point math. -- Strife (talk|contribs) 11:00, 29 April 2012 (PDT)

Useful Snippets

The IsVector function fails for vectors whose z element is negative, at least under Mono. (It also does not work on other grids because the cast to vector and back to string eliminates negative zero there.)

I tried the following:

<lsl> // After the "->" is the expected result (for the proposed new function), after the ":" the actual one llOwnerSay( "IsVector(<0.47,0.149, 1.001>) -> 1: " + (string)IsVector( "<0.47,0.149, 1.001>" ) ); llOwnerSay( "IsVector(<0.47,0.149, 1.001,3>) -> 0: " + (string)IsVector( "<0.47,0.149, 1.001,3>" ) ); llOwnerSay( "IsVector(<0.47,0.149,-1.001>) -> 1: " + (string)IsVector( "<0.47,0.149,-1.001>" ) ); llOwnerSay( "IsVector(<0.47,0.149,+1.001>) -> 1: " + (string)IsVector( "<0.47,0.149,+1.001>" ) ); llOwnerSay( "IsVector( < 0.47, 0.149, -1.001 > ) -> 0: " + (string)IsVector( " < 0.47, 0.149, -1.001 > " ) ); llOwnerSay( "IsVector(<0.47,0.1A9,-1.001>) -> 0: " + (string)IsVector( "<0.47,0.1A9,-1.001>" ) ); llOwnerSay( "IsVector(<0.47,;0.149,-1.001>) -> 0: " + (string)IsVector( "<0.47,;0.149,-1.001>" ) ); llOwnerSay( "IsVector(<0.47,0.149,-1.001) -> 1: " + (string)IsVector( "<0.47,0.149,-1.001" ) ); llOwnerSay( "IsVector(<0,0.000,0>) -> 1: " + (string)IsVector( "<0,0.000,0>" ) ); llOwnerSay( "IsVector(<0,0.000,0,0>) -> 0: " + (string)IsVector( "<0,0.000,0,0>" ) ); llOwnerSay( "IsVector(<+0,-0.000,-0>) -> 1: " + (string)IsVector( "<+0,-0.000,-0>" ) ); </lsl>

I propose the following change:

<lsl> // Returns whether the given string contains a vector. // Accepts what the compiler accepts and checks ZERO_VECTOR separately. integer IsVector ( string s ) {

   list split = llParseString2List( s, ["<", ">", ",", " ", "-", "+"], [] );  // not allowed to be inside numbers
   if ( llGetListLength( split ) != 3 ) return FALSE;  // must be 3 elements
   if ( (vector)s != ZERO_VECTOR ) return TRUE;  // parsing error or real ZERO_VECTOR lead to ZERO_VECTOR
   split = llParseString2List( (string)split, ["0", "."], [] );
   return (split == []);

} </lsl>

With this function, the above tests work. It tests for number of elements and then lets the compiler decide what it accepts as vector. Only for ZERO_VECTOR, special treatment is necessary. Therefore, it checks that only zeros and decimal points are in the remaining string. The compiler itself accepts missing ">" and it would also accept more than 3 elements - that's why the function checks the number of elements before.

It's probably not the most efficient way to do it and also accepts more than is actually valid (esp. for ZERO_VECTOR), but it does accept all valid vectors (I hope ^^). Discussion and improvements are welcome. For IsRotation, the implementation would be almost the same, except checking for 4 elements instead of 3.

Shuichi Shinji 01:13, 31 March 2014 (PDT)