Sign in to follow this  
Cruis.In

help with firing arcs

Recommended Posts

hey guys I am fiddling with learning by making asteroids type space game and such. It is 2d.

 

In this I have the 'view' fixed on the playership at the centre of the screen.

 

I want to calculate constantly the arc seen in the image below which is directly ahead of the ship. This would be a frontal firing arc. http://imageshack.us/photo/my-images/593/arcx.png/

 

This is where I am stumped. Having gone through so many maths lessons the past few days on py theorem etc...

 

Your ship rotates based on an angle based on your left/right input via kieyboard. So I know what direction the ship is facing in terms of a bearing. That value is held in the variable 'angle'.

 

Of course I know where my ship XY is, and I know where enemy ships XY are. I've used atan2 and I have calculated the bearing or angle of the enemy ship from my ship. But this won't help to create a fixed firing 'arc' in front of my player ship.

 

Basically I need a formula or calculation to calculate that tangent as seen in the picture, no matter what direction I am facing or where I am. So the value of that 'area' in front of the ship always remains constant which means it is my frontal firing arc. Let's say a value of about 60 degrees. So quite a narrow firing arc.

 

I know how to check if a potential target is within said firing arc before being allowed to fire, but determining that arc in front my ship is giving me measles.


Can anyone shed some light?

 

thanks

Share this post


Link to post
Share on other sites

not quite sure how an equation would help you out on this due to the rotation... the only thing i can think of is calculating the arc of the circle as arcLength = ThetaAngle * Radius.   And constantly update your max radius of the ship by 1 coordinate, so it would scan based on the cented of the ship, but to fix that use MaxRadius - InitialRadius(ship). after each update you scan the arch coordinates to see if they collide with the enemy ship.

That could work... if I understand correctly what you are trying to do. If the arc rotates with the ship im not sure how the equation will work with the different signs.

Edited by JinixVomitorium

Share this post


Link to post
Share on other sites

hey there thanks for the reply.

 

here is an actual view, forgive the placeholder art and debug stuff.

 

http://imageshack.us/photo/my-images/39/arcsss.png/

 

So the grey ship is mine. Always centered in the middle of the screen and it can move about the world. Rotate accel etc, but the camera is always fixed top down on it wherever it goes.

 

now if I fly around the green ship, I can get the angle of it from me using atan2.

 

But if I rotate that doesn't get taken into account by atan2. So the enemy ship could be at 60 degree value, and I could rotate my ship (let say I am now stationary) and my aft section will be facing the enemy, yet I would be able to fire, although the enemy isn't in my 'front arc'

 

So checking on the angle of the enemy from your ship using atan2 or anything else i've used and using the value returned it to see if it is inside your front firing arc isn't working out.

 

the firing arc is for my projectiles, not really related to collision

Edited by Cruis.In

Share this post


Link to post
Share on other sites
If you have the angle of bearing can't you just add and subtract 30 degrees from that to get the bounds of your arc and then check to see if the angle to the target is within those bounds? I guess I don't understand what you're asking. Maybe if you describe what you're trying to do from a slightly higher level? Edited by Khatharr

Share this post


Link to post
Share on other sites

Yeah, your question is confusing. I guess you're trying to figure out if the enemy ship is within your own ships "view", which would be a triangle. And if the enemy is in that triangle, you'll enable the ship to fire. Is that the case? I guess it'd be similar to using a bounding box. Decide the perimeter of the triangle, and check if the ship is within that perimeter. If so, you can fire.

 

I guess you'd do that by deciding how far out you can see. Say it's 10 pixels. Then the two long sides are 10 pixels, and the short side opposite the ship is a little weird to get. You could use arc length. We're talking 60 degrees right? That's 1/3 a radian, I believe. Multiply that by 10. That's the length of the other side.

 

Now I dunno how you'd check if something is within a triangle. I'm sure someone has that figured out. Maybe it takes some basic calculus. Regardless, it might just be better to make a bounding box instead and pretend it's some viewing arc. But I dunno. You'd have to explain what you're looking for better if you need more help. It's hard to understand what you're asking completely.

Share this post


Link to post
Share on other sites

I figured out a little bit of it for you. the posative/negative part.  since a circle is 360degrees and has 4 quadrants,   + +, + -, - -, - +.  you need to set up some if constructs to handle those. so you will need variables to hold the values of true north, south, east, west. then compare them to the fixed values of north south east west on your ships .

 

By (y) i mean the y coordinate of that object. You may need to include an x to defer from quadrants 2,3 and 1,4.

the -arcs are inverss of the of the atan2 if your map coordinates are 0,0 on the center of the ship. otherwise you should have to either add rotation of 180degrees or add/subtract the diameter of the circle.

 

//quadrant 2

if shipNorth(Y) > trueNorth(Y) && shipNorth(Y) < trueWest(y)

{ arcX = -arcX  //ArcY stays same}

 

//quadrant 3

if shipNorth(Y) > trueWest(Y) && shipNorth(Y) < trueSouth(Y)

{ arcX = -arcX 

  arcY = -arcY}

 

//quadrant 4

if shipNorth(Y) < trueSouth(Y) && shipNorth(Y) > trueEast(Y)

{ arcX = -arcX 

  arcY = -arcY}

 

 

hopefully that all makes sense... i didnt apply it to code, but it is sound logic.

Share this post


Link to post
Share on other sites
might I ask what language you are programming in?

 

sure its blitzmax!

 

If you have the angle of bearing can't you just add and subtract 30 degrees from that to get the bounds of your arc and then check to see if the angle to the target is within those bounds? I guess I don't understand what you're asking. Maybe if you describe what you're trying to do from a slightly higher level?

 

the problem is that although I know the angle of the target from my ship, that is just the angle of the target from my ENTIRE ship.  In this case, the firing arc is going to be a *frontal arc* so only if the player ship its target can it fire. Since the arc is a forward arc and its going to be narrow.

 

Since the ship can rotate on one spot while stationary, its possible for the angle of the target to be = to the firing arc, even though your ship isn't facing. Which would mean you could still fire.

Share this post


Link to post
Share on other sites

try using inverse tan of the detector length to get the coordinates of the tip of the detector pointing north, then use an x,y ratio to get the new detector coordinates. wish i could draw this out on here....

 

length of the radius + extended part to the tip of the detector.  use the x coordinates of the center of the circle as the x on the north detector, and use center circle y coordinates + length of detector(including radius of circle).  then use the rotation degree of the ship, say :ex: 35degree.... devide it by 100 which would be a .35 to .65 ratio. go left .35 * length of detector, go right .65 * length of detector, add or subtract both by the radius of the circle based on the quadrent they are located, and you should have the x and x for the new detector direction(center of the arc). be sure to take into account of the posative and necative rotation of degrees.

Share this post


Link to post
Share on other sites

I don't get it. That's a firing cone. Or do you mean you need to also have an arc at the end which indicates the maximum range of the player? And do you have problem drawing it or calculating it?

Share this post


Link to post
Share on other sites
I dunno why you are using trig for this, use vectors. Dot product of your normalised facing direction and the normalised vector to a target gives you the cosine in radians of the angle between your facing direction and the target direction.

Share this post


Link to post
Share on other sites

Paradigm: I understand somewhat that you have said, but not being much of a mathmetician I need it more layman.

 

How do I calculate the dot product of my normalised facing (which I believe is my ships angle) and how do I calculate the dot product of the vector to my target (which I believe is the angle of the target from me?)

 

Once done I am assuming from what you said, this gives the angle from the enemy vector to my facing vector. Once I have that angle, I can then allow "fire" once that angle falls within a certain value. And am I correct in saying that this would mean that once I am facing the enemy, the value of the angle between my facing direction and the target direction will be = to 0

 

 

 

Others

no the cone isn't for range, it merely looks like a cone because of the lines etc.

 

the lines are just imaginary they do are drawn, it's just showing the vectors of the limits of your firing arc, merely to show the width of the arc I was seeking.

 

So basically its a front arc. If the target is in front of you, only then can you fire. Its top down 2d view. the 'camera' is focused on your ship which remains at the centre of the screen. You can fly about the game world, and rotate, similar to asteroids, but your ship remains drawn at the centre of your screen even tho u are moving, so unline asteroids in that aspect.

 

So imagine asteroids, imagine that you could only fire if the enemy was in front of you.

 

But I realise I think I have over complicated it and kind of fooled myself. Since it doesn't make sense to only be ABLE to fire if an enemy is in front of you. You should be able to fire all the time from the front guns on your ship.

 

What really complicated this is that at first I am using the mouse pointer as the aimer. So I can getting the angle of the mouse pointer relative to your ship, and offsetting it with your current direction of facing.  So if the mouse pointer falls within your frontal firing arc, you can fire in that direction, which is the front. So the front of the ship has a 60 degree arc. -30 to the left and 30 to the right. So the angle of the mouse cursor to my ship + the offset of my current ship angle was being calculated and held in a variable. I then stipulated that if that value is = within a certain range you can fire. These range is = to a small 60 degree arc.

 

So now I changed it to be independent of the mouse pointer, but instead to calculate where the enemy ship angle is relative to your ship, and if the enemy ship falls within those specified arcs to the front, then you can fire. Which really is a work around, because this means you cannot fire AT ALL unless an enemy ship is in front.

 

What I could do is allow you to fire all the time if the enemy is out of arc, but set the projectile to go straight ahead.

 

THen if the enemy is within the arc, the projectile is aimed at the vector of the enemy from your ship. So your allowed to fire all the time, whether a target is directly in front of you or not, just that the projectile will go straight. Now once an enemy peeps his little nose in front of your ship, the projectile will go for him.

 

Thank you guys all for your help, regardless of whether I rap my head around it I do understand more. Sorry to waste your times.

Share this post


Link to post
Share on other sites
If you are facing northeast, your direction vector would be in the direction of (+1, +1), normalised this gives (1/sqrt(2), 1/sqrt(2)).

The vector from you to an enemy is posEnemy - posYou so if you are at (10, 0) and an enemy is at (5, 5) then the vector towards them is (5-10, 5-0) = (-5, 5), normalised (-1/sqrt(2), 1/sqrt(2)).

Dot product between those vectors is -1/2 + 1/2 = 0.

This is the cosine of the angle between you, and cos(90degrees) = 0, so they are perpendicular to your facing.

If the dot product is 1, they are directly ahead of you (cos(0) = 1). If it is 0, they are perpendicular to your facing.

All you need to check is that the dot product is greater than the cosine of the desired half-angle of your cone.

Hope that helps.

EDIT: Maths fail, oops ;) Fixed now Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites

ok to normalize a vector

 

divide its x,y by its length

 

the vector in our example is -5,5 (vector towards target from player)

 

length = sqr( (-5 * 5) + (5 * 5))

 

length = sqr ( 25 + 25)

 

length = sqr (50)

 

length = 7.07

 

didn't you make a mistake in your magnitude calculation? since the brackets must be added before you find the square root?

 

normalized = -5/7.07 = -0.7

5/7.07 = 0.7

 

 

This is the cosine of the angle between you, and cos(90degrees) = 0, so they are perpendicular to your facing.

 

 

now that part I do not get. Could you word that better?

Edited by Cruis.In

Share this post


Link to post
Share on other sites
The dot product of the two (normalized) vectors is the cosine of the angle you want.
So after you have taken the dot product, you feed the result to acos()/arccos()/whatever, and you have the angle.
It will be in radians instead of degrees; if you are more comfortable thinking in degrees, you can convert between the two.
Full circle is 2*pi radians or 360 degrees, so if angle X is "Xdeg" in degrees and "Xrad" in radians, Xdeg = 360 / (2 * pi) * Xrad, and Xrad = 2*pi / 360 * Xdeg. Edited by Stroppy Katamari

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this