# How do I detect if a sensor placed at vPos would see someone standing at vTargetPos?

## Recommended Posts

Am I right in thinking that I subtract vPos from vTargetPos and then examine llAxisAngle2Rot(<0.0, 0.0, 1.0>, llAtan2(vResult.y, vResult.x)) to see if the result is within a certain range?    Or does that just tell me if it's within my field of vision in the x,y plane but not the cone that llSensor draws?

Or, if I'm completely wrong, which is generally the case when I'm unsure about matters geometrical, how do I do it, please?

##### Share on other sites

The sensor detects in a cone that is sliced out of a spherical volume. Your test is examining a horizontal wedge that has its apex and the center of that volume.  It's not defining a volume, per se, but any point that has x,y values within that wedge (regardless of its z value) will pass the test.  The intersection of the spherical volume and the wedge is the volume of space that satisfies both conditions.   So .... points in the horizontal plane ( where z = z at the center of the detection sphere ) will be detectable all the way to the full range of the sensor.  Points closer to the center of the sphere but at higher or lower relative values of z might not be detected.  In fact, points directly overhead but beyond the sensor range definitely will not be.

So...

17 minutes ago, Innula Zenovka said:

that just tell[s] me if it's within my field of vision in the x,y plane but not the cone that llSensor draws

Edited by Rolig Loon
Cleaner wording
##### Share on other sites

59 minutes ago, Rolig Loon said:

The sensor detects in a cone that is sliced out of a spherical volume. Your test is examining a horizontal wedge that has its apex and the center of that volume.  It's not defining a volume, per se, but any point that has x,y values within that wedge (regardless of its z value) will pass the test.  The intersection of the spherical volume and the wedge is the volume of space that satisfies both conditions.   So .... points in the horizontal plane ( where z = z at the center of the detection sphere ) will be detectable all the way to the full range of the sensor.  Points closer to the center of the sphere but at higher or lower relative values of z might not be detected.  In fact, points directly overhead but beyond the sensor range definitely will not be.

So...

How, then, do I calculate whether the target's z value, minus that of the test point, is in range?   I can see it's a similar calculation, but I'm not sure how to perform it.

Or is there an easier way to do it?

##### Share on other sites

You know that the target is within range if it is within the detection cone of llSensor.  If you want to get the vertical component of a point on the detection sphere at any distance x straight ahead of the sensor, you''ll want

z = x sin(alpha)

where alpha is half the cone angle.  Sadly, my mind isn't quick enough to pump out the spherical trigonometric function that will tell you the values of z for points that are not straight ahead of you, but I suspect that it's something like

z = x sin(alpha) * y cos (alpha)

At least that will give you values that increase the closer the target is to you and decrease the farther the target is off to the left or right of your line of sight.

EDIT:  No, that can't be right.  To work, alpha can't be the angle of the detection cone. It has to be the angle between the cone axis and the vector to the point, along the lines that Tessa has suggested.

Edited by Rolig Loon
• 1
##### Share on other sites

```integer isInCone(vector X, vector s, float angle, float range, vector t)
{	// s = position of sensor;
// X = a vector representing the center /Axis/ of the cone in global coordinates.
//   if the sensor is facing due east, X could be n*<1,0,0> for any positive float value of n.
//   if the sensor is looking at some object at point p, let X= p-s;
//   if you know the rotation of the sensor, then let X = llRot2Fwd(rSensor); or equivalently: <1,0,0>*rSensor;
// range = distance of sensor.
// angle = angle of sensor cone, 0 to PI (whole sphere)
// t = target position
vector diff = t-s;
if(diff*diff > range*range)
return FALSE; // target is out of range
if(llRot2Angle(llRotBetween(diff,X))> angle)
return FALSE; // the angle between target and the local x vector of the sensor is too big.
return TRUE;
}```

Hmm, could simplify parameters by using the length of X as the range. in that case use

`if(diff*diff > X*X)`

for the first test.

Edited by Quistess Alpha
Clarification on X
• 2
##### Share on other sites

3 hours ago, Quistess Alpha said:
`   // X = the vector representing the center of the cone in global coordinates.`

Is that the cone's centre of mass (25% of the distance from the base -- the flat bit at the big end) and the vertex (the sensor)?

I know the sensor's position would be, if I were using a sensor, and I know what its rotation would have been, and I know the range, so I can calculate X from that, I think, can't I?

Edited by Innula Zenovka
##### Share on other sites

11 minutes ago, Innula Zenovka said:

I know what its rotation would have been

if you have the rotation then X = llRot2Fwd(rot); I had that in an earlier edit of the script example, but I figured giving the function a rot just to convert it to a vector was a bit silly. The magnitude of the vector is also unused. multiply it by 100 or whatever and you'll get the same result.

By "center" I meant a vector representing the line from the tip to the center of the base, or "center-line" not the actual point of the center. if the "center of mass" of the cone was a thing you happened to have, then X= COM-posSensor; would also work.

Edited by Quistess Alpha
##### Share on other sites

35 minutes ago, Quistess Alpha said:

if you have the rotation then X = llRot2Fwd(rot); I had that in an earlier edit of the script example, but I figured giving the function a rot just to convert it to a vector was a bit silly.

No, I meant I think I can calculate X on the fly, can't I?:

```		vector vTargetPos;
vector vSensorPos;
rotation rSensorRot;
float fRange = 20.0;
float fAngle = 0.5* PI_BY_TWO;//45 degree cone
vector vX = vSensorPos+<(fRange * 0.75),0.0,0.0> * rSensorRot;
vector vDiff = vTargetPos - vSensorPos;

if((vDiff*vDiff)>(fRange*fRange)){
//out of range
}

if(llRot2Angle(llRotBetween(vDiff,vX))> fAngle){
// the angle between target and the local x vector of the sensor is too big
}
else{//the opposite of the previous two tests, and the calculation I think I need
if( ((vDiff*vDiff)<(fRange*fRange)) &&
(llRot2Angle(llRotBetween(vDiff,vX))< fAngle)){
llOwnerSay("the sensor can see the target");
}

}```

##### Share on other sites

am not sure what you want exactly, but if this is about animals that can stalk other animals then Dora Gustafson's dotproduct method works quite well for this

a example of using Dora's method on doors is here. Only open the door when an avatar is looking at the door even if they are within range of the sensor

there are two perspective calculations in the code example. One from the sensor position.  And the other from the target position

• 1
##### Share on other sites

1 hour ago, Innula Zenovka said:
`vector vX = vSensorPos+<(fRange * 0.75),0.0,0.0> * rSensorRot;`

and what I said was you should instead have that as vector vX = <1,0,0> * rSensorRot;

• 1
##### Share on other sites

4 minutes ago, Quistess Alpha said:

and what I said was you should instead have that as vector vX = <1,0,0> * rSensorRot;

As an alternative to using the centre of the cone for vX, you mean, rather than as an equivalent to?

##### Share on other sites

28 minutes ago, Innula Zenovka said:

As an alternative to using the centre of the cone for vX, you mean, rather than as an equivalent to?

I mean that vX does not represent the center /point/ of the cone, it represents the center /vector/ (edit: axis) of the cone (the center point would suffice if the tip is at <0,0,0>) I.e. if your sensor is facing east, vX = <1,0,0>; your code will not do what you intend it to do.

inline-test without returns:

```if( (vDiff*vDiff)<(fRange*fRange) )
{  if( llRot2Angle(llRotBetween(vDiff,llRot2Fwd(rSensor)))< fAngle )
{ // sensor with rotation rSensor can see the target.
}
}```

It's important to distinguish between vectors that represent positions and vectors that represent /changes/ in position, or abstract directions.  in my code I usually name my positional variables something like posX, for the position of X, although I haven't come up with a good nomenclature for abstract vectors.

Edited by Quistess Alpha
• 1
##### Share on other sites

On 9/22/2021 at 12:43 AM, Quistess Alpha said:

I mean that vX does not represent the center /point/ of the cone, it represents the center /vector/ (edit: axis) of the cone (the center point would suffice if the tip is at <0,0,0>) I.e. if your sensor is facing east, vX = <1,0,0>; your code will not do what you intend it to do.

inline-test without returns:

```if( (vDiff*vDiff)<(fRange*fRange) )
{  if( llRot2Angle(llRotBetween(vDiff,llRot2Fwd(rSensor)))< fAngle )
{ // sensor with rotation rSensor can see the target.
}
}```

It's important to distinguish between vectors that represent positions and vectors that represent /changes/ in position, or abstract directions.  in my code I usually name my positional variables something like posX, for the position of X, although I haven't come up with a good nomenclature for abstract vectors.

Thank you!   I've not really appreciated the distinction between the two different types of vector before, and how they can represent both position and direction (I mean, I knew they could, but hadn't really thought about what that actually means in practice).

So when I calculate a dot product, would I be correct in understanding that  it's an expression of the relationship between two directional vectors (the cosine  of the angle between them) anywhere they happen to intersect?

##### Share on other sites

2 hours ago, Innula Zenovka said:

So when I calculate a dot product, would I be correct in understanding that  it's an expression of the relationship between two directional vectors (the cosine  of the angle between them) anywhere they happen to intersect?

well, maybe? not entirely understanding you.

generally when I use the dot product, I multiply a directional vector by itself, which results in the squared distance of that vector. Squared distance (quadrance) is in many cases a more computationally efficient value to work with than the actual distance of a vector.