android 2d arc collision detection - android

i have a rotated arc drawn using android 2d graphics
c.drawArc(new RectF(50, 50, 250, 250), 30, 270, true, paint);
the arc will rotate while the game is running ,
i wanna know how i can detect if any other game objects(rects ,circles) collide with it ??
this is the first time for me to write a game :)
i saw something like this in http://hakim.se/experiments/html5/core/01/
Thanks in advance

Arc collisions are slightly harder then normal collisions, but using boolean algebra you can easily check if a given point is inside your arc.
Take a look at the following picture.
There are 3 objects here. The black sphere, this visualizes your arc, if something collides with it, it might be inside your arc. The red sphere on top of the black sphere, this visualizes the 'inside' of the arc, if something is inside the red sphere, it's definately not 'inside' the arc. Now there is also the green triangle that Visualizes the 'cut-off' of your arc, anything inside the green triangle is also definately not in your arc.
Testing if something is inside the black sphere is easy. (object's distance to center of sphere <= radius of sphere). Same for the red sphere. The green triangle is a bit tricky, you first have to construct this. Find the start and end radians of your arc. and rotate a unit vector by start radians. Then rotate a unit vector by end radians. Lengthen both these vectors by 2 * the radius of the black sphere. Now use the center point of your arc and the positions of two vectors with added the center position as the 3 points of the triangle. You can then use one of the point-triangle collision solvers: http://www.bing.com/search?q=point+triangle+collision&go=&form=QBLH&scope=web
So remember: collision with arc = (collision with black sphere) && !(collision with red sphere) && !(collision with green triangle).

Related

Rotate item in a circle shape using phone accelerometer/gravity sensor vector

I'm trying to make a small circle move in another bigger circle as a ball moving in circle relative to Android phone tilting. I'm doing this in Godot but I think the principle is the same in all game engines probably. I make a scene in Godot and add two sprites as the two circles as the following picture. I get the accelerometer 3D vector, use x and y values and calculate the angle in x and y plate (relative to y axis i.e Vector2(0, 1) ) and rotate the mentioned scene to that degree using an animation, using this code
func _process(delta: float) -> void:
var vec3 = Input.get_accelerometer()
accelVec = Vector2(-stepify(vec3.x, 0.1), -stepify(vec3.y, 0.1))
var angle = accelVec.angle_to(Vector2(0, 1))
rotateTween.interpolate_property(self, "rotation", rotation, angle, 0.2,
Tween.TRANS_LINEAR)
rotateTween.start()
return
But the problem lies in here that when the x value of accelerometer 3D vector changes from a positive to negative value i.e when the ball is at top of the circle and is going to go to the other half of the circle, it actually moves from bottom of the circle to the desired point rather than from top of the circle.
I hope I explained the problem well, though I doubt it.
I added the Gif that shows actual test on an android phone here Testing in Android.
Any idea how to solve this problem?
Thanks in advance.
This is because Tween is interpolating linear values. It doesn't know it's working with angles, or that they should wrap around.
So when you're at -179 degrees and you tween to 179--a difference of 2 degrees--Tween just sees -179 -> 179 and goes through the whole circle.
You probably don't need a Tween here at all because _process() happens every frame.

How to create Path with rounded corners using rQuadTo that is equivalent to a specific dp?

As background, I am new to Android graphics. I'm trying to create a rectangle with rounded corners using Path specifically (I don't want to use method addRoundRect as I will make changes to my Path object later to not be rectangular). I want this to have the same curvature as a shape with corners with a radius of 12 dp. I'd like to use the methods rQuadTo or quadTo (based off of this question), but am a bit confused how to get the corners to match each other perfectly. Can someone explain the math behind how to to achieve this and what setting the radius exactly mean for drawable resource shape (is this a correct definition?)? Visuals would be help as well! Thanks.
Yes, link contains correct definition.
To build rounded corner with quadratic Bezier quadTo, you should start curve (end straight line) at distance r=12 before corner position, make control point exactly at corner position (to provide symmetry) and make end point at distance r after corner at perpendicular edge. Quadratic Bezier curve does not give perfect circle arc, but it is not significant for small sizes.
Example:
Horizontal edge in right direction to corner 100, 100.
End point of line is 88, 100. (and starting point of curve)
And quadto(100, 100, 100, 112)

How to detect shape collision - Android

I would like to detect collisions between shapes dynamically drawn on a canvas (SurfaceView) for an Android game.
I can easily use intersect method of Rect or RectF objects but the result is not very good (see picture below where I have a "false" detection).
I don't want to use Bitmap so it's impossible to use the "pixel perfect" method.
Do you know a way to do this for circle, rect, triangle and other basic shapes intersection ?
Thx for help ;)
For a good collision detection you have to create your own models behind. In those models you specify the conditions that two objects colide.
For example, a circle is described by the center position and by the radius. A square is described by the left down corner and by the edge length.
You don' t have to describe all possible poligons, you can use the so called bounding boxes, meaning that, for a complex random poligon you can use a square or whathever shape fits it best(also you can use multiple shapes for a single object).
After you have the objects in mind you compute the condition that each one of them will colide with all other shapes including itself.
In your example The sphere and the square colides if the distance between any corner of the square is greater than the circle's radius.
Here you can read more http://devmag.org.za/2009/04/13/basic-collision-detection-in-2d-part-1/
This problem can get very complex, keep it simple if you want something simple.
Here is a directly applicable method I use in my own game to detect circle and rectangle intersection. It takes the ball (which is a view in this case) and the rectangle (also a view) to be checked for collision with the ball as parameters. You can put the method in a Timer and set the interval you want the circle and rectangle to be checked for collision.
Here is the method:
public boolean intersects(BallView ball, Rectangle rect) {
boolean intersects = false;
if (ball.getX() + ball.getR() >= rect.getTheLeft() &&
ball.getX() - ball.getR() <= rect.getTheRight() &&
ball.getY() + ball.getR() <= rect.getTheBottom() &&
ball.getY() - ball.getR() >= rect.getTheTop())
{
intersects = true;
}
return intersects;
}
getR() gets the circle's radius
getX() gets the center of the circle's X position value
getTheLeft() gets the rectangle's left X value
getTheRight() gets the rectangle's right X value
getTheTop() gets the rectangle's top Y value
getTheBottom() gets the rectangle's bottom Y value
If you can't directly use this method in your code you can still conjecture the logic it entails to implement it where it would work for you. It detects all collisions without using pseudo-collision detection like a collision box for the circle.
Good luck! And if you have any questions feel free to ask, I'm here to help!
To know if a polygon in 2d is colliding with a circle, you can test, for each of its lines, where is the point on the line that is closest to the center of the circle (this might help).
Then, check if the point you found is between to two corners that make the line - that is, that the point is actually on the line, and not just on its continuation - and if the distance of that point to the center of the circle is smaller or equal to the radius of the circle. If both are true for any of the lines of the polygon, you have a collusion. You also have to check for the edge cases where the corners of the polygon might be in, or touching the circle.
For two circles, this is easier. Check the distance between the centers, and compare it to the sum of their radiuses. If the distance is smaller or equal to the sum, you have a collusion.

Drawing an 2d cone in android like a pie chart.

I am trying to draw a dynamic radar, but I can't get the cone shape to draw properly. I can get the two lines to work fine, but I can't get the shading between them to work.
My Goal:
What I am getting:
And this is my code:
paint.setColor(Color.WHITE);
RectF oval = new RectF(0,0,200,200);
canvas.drawArc(oval,(float)globalAzimuth+26, (float)globalAzimuth-26,false,paint);
globalAzimuth is the direction the phone is facing. The radar spins as the phone does. The lines spin fine and synchorinized, but the arc just gets bigger and is obviously terribly off.
Does anyone know how to do this?
It looks like you're treating the parameter sweepAngle as a stop angle. It should be the number of degrees to sweep, clockwise from startAngle.
From the docs:
sweepAngle : Sweep angle (in degrees) measured clockwise
Edit : It looks like you could use a constant 52 as the sweep angle, since you're just going 26 degrees in either direction from globalAzimuth(although your lines appear closer together than 52 degrees, so I'm not sure). If you do, you'll need to keep in mind that it goes clockwise, so your startAngle should be globalAzimuth - 26, rather than plus.

Android Canvas Paint Arc Border

I am drawing an arc with a border by painting two arcs, one over the other the first being slightly larger.
The issue is with "slightly larger" this can end up with the border not always being even all the way round.
Both the arcs I am drawing have the same radius, I simply make it larger by adding a degree to the start and two degrees to the end (necessary to ensure the borders on either end of the arc are equal) and increasing the stroke width.
In the supplied picture the thicker border edge is the smallest I can possibly make it while it is still visible. (-1 degree off the inner arc)
I have considered drawing the arc outline with four separate calls two straight lines for either end and two arcs. This seems quite inefficient for what I want to achieve.
I am wondering if anyone has any suggestions about how else I could draw a border thats even, minimizing the number of draw/canvas rotation calls if possible.
Relevant code sample for current solution:
Paint mOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mFillPaint.setStyle(Style.STROKE);
mFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
mFillPaint.setColor(Color.TRANSPARENT);
mFillPaint.setStrokeWidth(mValueWidth);
mOutlinePaint.setStyle(Style.STROKE);
mOutlinePaint.setStrokeWidth(mBorderWidth);
mOutlinePaint.setColor(Color.WHITE);
mRect.set(mHalfXSubRadius, mHalfYSubRadius, mHalfXAddRadius, mHalfYAddRadius);
canvas.drawArc(mRect, ARC_START-1, MAX_ARC+2, false, mOutlinePaint);
canvas.drawArc(mRect, ARC_START, MAX_ARC, false, mFillPaint);
U shouldnt make your arc bigger, instead try to draw the same sized arc (in white), X pixel right,down,up,left,corners as well (total of 8 drawings).
where X is the border size u want.
after that draw the main arc (in gray) in the middle.
psuedo code:
paint=white;
drawArc(x,y+2);
drawArc(x,y-2);
drawArc(x+2,y+2);
drawArc(x+2,y-2);
drawArc(x-2,y+2);
drawArc(x-2,y+2);
drawArc(x+2,y);
drawArc(x-2,y);
paint=gray;
drawArc(x,y);

Categories

Resources