ID:189954
 
This is more of a general math question than a BYOND-related one, so I felt that it belonged in the Off-Topic area.

Here is the situation:

There is a character at the coordinates (50,50), facing 0 degrees (due north). There is an object on the map at (60,40). How can I calculate if the object is within the character's line-of-sight (90 degrees). I've illustrated this problem at: www.geocities.com/serminacle/problem.bmp (Geocities doesn't seem to like direct links :-x).

My question is: what equation can get me the angle that the object is at in relation to the character?

If any clarification is needed, be sure to ask. I know that I'm not the best at explaining things. :)
The name of that problem.bmp file is rather ironic... hehehe. Convert to PNG or JPG! NOW! =P

I have a feeling this would have something to do with trig... but... my brain's gone to sleep. School holidays does that to me. =)
In response to Crispy
Crispy wrote:
The name of that problem.bmp file is rather ironic... hehehe. Convert to PNG or JPG! NOW! =P

Ech. I knew that someone would pester me about that. "Get faster internet! NOW! =P"

I have a feeling this would have something to do with trig... but... my brain's gone to sleep. School holidays does that to me. =)

Aye, I already know that trigonometry is involved, and I am capable of easily finding the angle between the origin and the object. However, this doesn't get me the degrees I need. :(
I have a proc that I adapted from something Lummox posted for that right here. I'll post a few others that you might find convenient if you're working with anything that involves 360-degree or less rotational movement.
(If I post them here, they'll be retreivable next time I spontaniously delete BYOND!)

Determines the direction from point A to point B.

<code>proc/GetExactDir(atom/Ref,atom/Target) if(!Ref || !Target) return 0 var/dx = ((Target.x*32) + Target.pixel_x - 16) - ((Ref.x*32) + Ref.pixel_x - 16) var/dy = ((Target.y*32) + Target.pixel_y - 16) - ((Ref.y*32) + Ref.pixel_y - 16) var/dev = sqrt(dx * dx + dy * dy) var/angle = 0 if(dev > 0) angle = arccos(dy / sqrt(dx * dx + dy * dy)) return (dx>=0) ? (angle) : (360-angle)</code>

Some others:

Determines the difference between the source object's angle and the desired direction From -180 to 180.

<code>proc/TurnAngle(current_dir, objective_dir) var/turn_angle = (objective_dir - current_dir) % 360 if(turn_angle < -180) turn_angle += 360 else if(turn_angle >= 180) turn_angle -= 360 return turn_angle</code>

Determines the distance between point A and point B.

<code>proc/ExactDist(atom/A, atom/B) var/dx = A.x - B.x var/dy = A.y - B.y return sqrt(dx*dx + dy*dy)</code>

Determines how many degrees off the ship is from facing the target.

<code>proc/GetAccuracy(ship/ship, atom/Target) var/dest = get_exact_dir(ship, Target) var/turn_angle = TurnAngle(ship.angle, dest) return turn_angle</code>

Version of the above that returns an absolute value.

<code>proc/GetAbsAccuracy(ship/ship, atom/Target) var/dest = get_exact_dir(ship, Target) var/turn_angle = TurnAngle(ship.angle, dest) return abs(turn_angle)</code>
</code>


Can't say whether they will be of any help to you or not, though, especially in anything that involves line-of-sight.
Malver wrote:
This is more of a general math question than a BYOND-related one, so I felt that it belonged in the Off-Topic area.

Here is the situation:

There is a character at the coordinates (50,50), facing 0 degrees (due north). There is an object on the map at (60,40). How can I calculate if the object is within the character's line-of-sight (90 degrees). I've illustrated this problem at: www.geocities.com/serminacle/problem.bmp (Geocities doesn't seem to like direct links :-x).

My question is: what equation can get me the angle that the object is at in relation to the character?

The character's vector would be <sin(dir),cos(dir)>, and the vector to the object is <obj.x-player.x,obj.y-player.y>. The angle between the two is what you want to find, and for that you need a dot product.

A dot product of two vectors is where you multiply their x's and y's (and z's, and so on), and add them together. The result is the length of the first vector, times the length of the second, times the cosine of the angle between them. So:

[sin(dir)*(obj.x-player.x) + cos(dir)*(obj.y-player.y)] = length(<obj.x-player.x,obj.y-player.y>) * cos(A)

That length is actually just the distance between the player and the object, so you can change the equation somewhat:

cos(A) = [sin(dir)*(obj.x-player.x) + cos(dir)*(obj.y-player.y)] / distance

Then if you use arccos(), you can find the angle A.

Lummox JR
In response to Foomer
Foomer wrote:
Can't say whether they will be of any help to you or not, though, especially in anything that involves line-of-sight.

Actually, that worked just fine (with a small amount of tweaking). Thanks! :)
In response to Malver
Malver wrote:
Crispy wrote:
The name of that problem.bmp file is rather ironic... hehehe. Convert to PNG or JPG! NOW! =P

Ech. I knew that someone would pester me about that. "Get faster internet! NOW! =P"

My internet's plenty fast enough. That doesn't change the fact that BMP is a terrible format for web images. =P