Jump to content

A Little Advice on llDetectedTouchUV


MG Canonmill
 Share

You are about to reply to a thread that has been inactive for 3464 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hello - I've been going to the College of Scripting trying to learn lsl. I'm learning a lot but I've got a long way to go.

I'm creating a HUD for sailing, that will chat the wind direction I want to change to, to the BWind engine in the sailboat. I'm using llDetectedTouchUV and I have all the vector coordinates for the HUD face. The HUD has the face of a compass on it and clicking on the N, NE, E etc will chat the command to the boat. It is working as is but I'm certain there must be a more efficient way of coding it than what I'm doing. I would be very grateful for any advice on how to do it more efficiently. I've pasted the code below. This snippet only checks for three compass points as the code is a bit long for all of them.

 

default
{
    touch_start(integer x)
    {
        vector Coords = llDetectedTouchUV(0);
        
        if(Coords.x > 0.43873 && Coords.x < 0.55831)
        {
            if(Coords.y > 0.81020 && Coords.y < 0.93204)
            {
                llOwnerSay("n");
            }
        }
        if(Coords.x > 0.70976 && Coords.x < 0.82900)
        {
            if(Coords.y > 0.71769 && Coords.y < 0.83696)
            {
                llOwnerSay("ne");
            }
        }
        if(Coords.x > 0.82074 && Coords.x < 0.94111)
        {
            if(Coords.y > 0.44054 && Coords.y < 0.56099)
            {
                llOwnerSay("e");
            }
        }
        
    }
}

 

Link to comment
Share on other sites

You can cut down on things a little by nesting your conditional tests so that, for example, you ask first whether the user has touched anywhere in the upper half of the target face (actually, anywhere that y > 0.44054) and then whether s/he has touched in the right side (x > 0.43873) or the left side ( x < 0.55831).  Those two tests, one right after the other, narrow down the possible choices to the three that you posted. If the very first test indicates FALSE, you have eliminated half of the compass and you can move on to doing the same tests in the bottom half of the face.  An so on....  It beats having to test every single possibility every single time.

Other than that, sooner or later you have to code each of the eight possible final choices.

===========

EDIT:  Of course, the other option is to forget using cartesian (x,y) coordinates and convert everything to polar coordinates.  That way you cn just use your compass texure as the background for your llDetectedTouchUV.  You don't really care how far someone's touch is from the center of the compass.  All you really need to know is the angular measurement around the compass.  So the angle you want is

Theta = arctan (y/x)

The only trick is that the zero for UV space is the lower left corner of the face and you want to measure the angles around the center of the face, at <0.5,0.5,0.0>, so you need to offset your detected X and Y values. So

vector Spot = llDetectedTouchUV(0) - <0.5,0.5,0.0>;

float Theta = llAtan2(Spot.y,Spot.x);

The LSL function llAtan2 gives you results in radians that are positive for anti-clockwise angles less than PI and negative for angles between PI and TWO_PI from your zero point.

So now you have the angle (in radians) from East (the center of the right edge of the face).  Only two more steps:

1. You want the angle in degrees (so multiply Theta * RAD_TO_DEG) from North, not East, (so subtract 90.0 degrees from Theta).

2. You want angles measured clockwise from North, not anti-clockwise (so make all angles 360 -Theta).

The final result is

default{    touch_start(integer num)    {         vector spot = llDetectedTouchUV(0);         spot = spot -<0.5,0.5,0.0>; //offset to center         llSay(0, (string)spot);         float angle = llAtan2(spot.y,spot.x);         float Dangle = angle * RAD_TO_DEG - 90.0; //Convert to Deg, rotate to North         if (Dangle < 0) // Make all angles positive ...         {             Dangle = 360 + Dangle;         }         Dangle = 360.0 - Dangle;  // ... and clockwise         llSay (0, "Angle = "+ (string)angle + " radians ( " + (string)Dangle + " degrees)");             }}

 So now you can write your if tests in terms of Theta (one number) instead of X and Y.  That's a little more elegant and (from the user's perspective) simpler to use.  :smileywink:

 

Link to comment
Share on other sites

It looks so much better in degree's since it correlates much better to the compass rose. I never would've thought of doing it that way. Well maybe not NEVER but it would've been a long time down the road. *grins*

Thank you very much Rolig! You've taught me something new today.

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3464 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...