"Firing Arcs" for Hex Based Games

Started by
2 comments, last by chirstius 18 years, 1 month ago
I apoligize if this question seems obvious. I am trying to create a hex based game and would like to incorporate the concept of "firing arcs" for weapons. Meaning if a unit has a forward firing and rear firing weapon I need a way to dertermine if a given target is within the arc of those weapons. I am guessing there is a method to do this related to doing line-of-sight but I'm missing the "glue" for it to click for me. Say a forward firing weapon covers 180 degrees in front of the unit, and a rear firing covers 180 degrees behind the unit. How do I determine which arc a given enemy unit is in? If you took a line directly off the center of the unit's "forward" face and set that as 0 degrees, then the arcs themselves could be represented by just a starting and an ending angle and by determing the angle of the target from that line you should be able to determine which arc it falls in. This seems simple enough but does anyone have suggestions for an implementation of this?
Advertisement
I think you'll have to use a combination of coordinate and angle comparisons. I don't know anything about how your characters will be moving around in the world, so this might not be applicable at all, but here goes:

If you track your player's coordinates and your target's coordinates in world coordinates, you can use them to calculate the angle they form at any time. So say 0 degrees points down the positive Z axis and your player's position is (0,0,0) and your target's position is (1,0,1), then those points form an equilateral triangle with legs each length 1 unit, and a hypotenuse of length sqrt(2 units). I'm not positive, but cmath should have all the inverse trig funcs in it, and you can just use those to get the angle they form. At any rate, this would be -45 degrees (in a system that increases counterclockwise).

Then just subtract that angle from your player's angle relative to the world, and THAT will be the target's angle relative to the player.

I think we need an example..

Player starts out at (-1,0,0), facing directly left, which is positive 90 degrees.

Target starts out at (1,0,3).

TargetX_position - PlayerX_position = Leg 1 of the triangle = 2
TargetZ_position - PlayerZ_position = Leg 2 of the triangle = 3

Hypotenuse = sqrt( 2^2 + 3^2 ) = sqrt( 15 ).

The angle formed, then, is arcsin( 2 / sqrt(15) ), or arccos( 3 / sqrt(15) )
This is about 31 degrees. But remember, in a system that increases counterclockwise, this is negative 31 degrees.

PlayerAngle - FormedAngle = Target's Angle relative to player
90 degrees + 31 degrees = 121 degrees.

Since the direction the player always faces relative to itself is zero degrees, anything that is greater than 90 degrees or less than -90 degrees will be behind the player, so this target is behind the player.

It will probably take a LOT of playing with this idea to make it work in code. I'm positive there's a better way to do it. I highly suggest that if you're at least decent with mspaint or something similar, just draw yourself some scenarios on a little graph and that will help you make some progress.
Also, just as something to remember later on, make sure you don't exclude your boundaries in your checks. You don't want to make 90 and -90 degrees OUTSIDE of either the forward or the backward firing arcs, nor (I assume) would you want them to be included in BOTH firing arcs. You could probably just define your fowrard arc as less than 90 and greater than -90, and your backward as greater than or equal to 90 and less than or equal to -90.
Thank you SippyCup. One question first - Your exmaple uses x, y, and z coordinates. Is this an "endorsement" for the hex board as a "projection of 3d cubes" model? I am currently using only an x, y grid approach, but read about the other model today. Is that the way to go?

As for your example, I think that's what I am looking for. It also seems that different angle "ranges" could be used to determine "left" and "right" in addition to "in front of" and "behind". This just seems like one of those reinventing the wheel things where someone must have been through this already and a better/easier method exists. As I am barely grasping the methodology here I am sure any implementation I create will be less than optimal. but trial and error goes a long way. You have at least given me a direction. Thanks again.

This topic is closed to new replies.

Advertisement