Category talk:LSL Vector
<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)