Paddle collision side detection using Graphics - java

I've implemented a kind of Pong where the paddles (Rectangle2D) can rotate.
To obtain more accuracy, many things are managed by Graphics2D.
The rotation too is managed by the methods rotate(...) of the previous told class.
To reach a realistic bounce, I need to know where the ball hits the paddle (only the side, not the particular point).
I've tried to define (and rotate) two Rectangle2D that represent the back and the front side of the paddle and then recognize the bounce in one of these two by the method hit(Rectangle2D r, Shape s, boolean onStroke), but it doesn't work properly.
Here is the java class Graphics2D:
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html
Have you any idea?

Assuming you have one rectangle for your paddle and know the center of rectangle and circle and the rotation of your rectangle.
Assuming a rotation of zero means, your rectangle is aligned horizontally (width > height).
Calculate the difference vector (center of circle) - (center of rectangle)
Get the angle of that vector and subtract the rotation of your rectangle (angle of vector is Math.atan2(y, x))
The resulting value a tells you the relative direction of your circle
Make sure a lies between 0 and 2*pi
q = Math.atan2(height of rectangle, width of rectangle)
If a is between q and pi-q, your circle has hit on the front long (upper) side.
If a is lower than q or bigger than 2*pi-q it's on the right side.
If a is between pi-q and pi+q it's on the left side.
If a is between pi+q and 2pi-q it's hit the bottom of your rectangle

Related

3D rotation ratios via mouse placement on screen - Java

I am making a 3D game in which the player can rotate their view point via the mouse to look around the environment. I firstly just did x and y rotation via vertical and horizontal movement of the mouse and z via another control. But after playing the game I realised it did not rotate correctly. NOTE: I have a global variable matrix which represents the player's angle (3x1), at 0,0,0 it seems to work correctly as up or down is a direct x axis rotation and right or left is a direct y axis rotation, but if I move my camera diagonally for example then left doesn't directly correlate to a y axis rotation anymore.
Visually on a unit circle the players viewpoint wouldn't travel the full circumference anymore and would travel in a circle that is smaller that the circumference. This is the current code (x and yRateOfRot is the ratio of how far away from the centre the cursor is in each direction between -1 and 1):
private static void changeRotation(){
angle.set(Matrix.add(angle.matrix,new double[][]{
{ROTATION_SPEED * camera.xRateOfRot()},
{ROTATION_SPEED * camera.yRateOfRot()},
{ROTATION_SPEED * camera.zRateOfRot()}}));
}
I have looked at this source http://paulbourke.net/geometry/rotate/ and understand how to rotate via an arbitrary axis which I could do but I am not sure how to correlate this into getting a ratio to find out what the x,y and z change would be for looking in a specific direction i.e. at 0,0,0 the ratio of looking up would be x:1, y:0, z:0 but then at another angle the ratios would be different as looking up no longer means only an x rotation. Any information would be appreciated, thanks!

How do I create a hitbox for a semi-circle?

I want to collide a rectangle with a semi-circle that comes rotating. A rectangular hitbox for the semi-circle, of course, is not appropriate as the side of the rectangular hitbox on the round side of the semi-circle will touch other targets before the semi-circle touches the targets. I am not inclined to use pixel collision detection as the two images are large.
I am thinking of using stripes of narrow hitbox rectangles of varying heights that approximately cover the contours of the semi-circle. How well would this work?
Not sure how you are doing collision detection, so I will just assume parametric equations and you can easily test for collisions between basic shapes.
If you think of a semi-circle as a circle missing a triangular element, then this is easy.
if (collide(rect, circle) && !collide(rect, triangle)) {
// then collision semi-circle
}
Use an isosceles triangle. The tip of the triangle is the center of the circle. The height of the triangle is the radius of the circle. The angle is based on what is missing from the circle.

Position Vector relative to origin

I have a little tech game I am messing around with and I can't figure out the formula to position 1 object given another objects origin.
So I have a Spaceship and a Cannon. I have the game setup to use units, so 1 unit = 16 pixels (pixel art).
Basically my cannon should be placed 0.5625 units on the X and 0 on the Y relative to the origin of the Spaceship, which is located at 0, 0 (bottom left corner).
The cannon should is independent on the angle of the spaceship, it can aim in different directions rather than being fixed to aim the way of the spaceship.
I have it constantly following the cursor, which works fine. Now when I rotate the Spaceship, obviously the origin of the Spaceship is changing in world coordinates, so my formula to place the cannon is all messed up, like so:
protected Vector2 weaponMount = new Vector2();
weaponMount.set(getBody().getPosition().x + 0.5625f, getBody()
.getPosition().y);
Obviously if I position the ship at a 90° angle, X is going to be different and the cannon would be waaaayyy off the ship. Here is a screenshot example of what I mean:
What would be the formula for this? I have tried using cos/sin but that does not work.
Any ideas?
weaponMount.set(0.5625f,0).setAngle(SpaceshipAngle).add(getBody().getPosition());
Where SpaceshipAngle is the angle of your Spaceship.
The origin of the spaceship is the point, arround which the spaceship will rotate and scale (the Texture of it). The position instead is always the lower left corner of the Texture and does not depend on the rotation.
Your problem is, that your offset does not depent on the rotation of your spaceship.
To take care about this rotation you should store a Vector2 offset, which describes your weapons offset (in your case it is a Vector2(0.5625f, 0)).
Next store a float angle describing your spaceships rotation.
Then you can rotate the offset by using: offset.setAngle(rotation).
The last thing is to set the weapons position. The code for this did not change so much:
weaponMount.set(getBody().getPosition().x + offset.x, getBody()
.getPosition().y + offset.y);

Collision Response of ball at Corners of rectangle

i have a fixed rectangle. When ball hits a vertex of a triangle, i calculate tangent at point of contact(rectangle vertex). Then i rotate Velocity vector to coincide with the tangent, flip the y value of velocity and rotate it back. Here is my code for top-left corner:
double c1x=rec.x-ball.getX();
double c1y=rec.y-ball.getY();
if(c1*c1+c2*c2<ball.getRadius()*ball.getRadius())
{
double angle=Math.atan2(-c1x,c1y); //angle made by tangent
Vector2D v=ball.velocity.rotate(angle); //rotate velocity vector by 'angle'
if(v.y<0.0f) //ball is already moving away from corner
return;
v.setY(-v.y); //flip y
ball.velocity=v.rotate(-angle); //rotate back
return;
}
But this code doesnot works. When ball strikes the corner it gets stuck, moves along the top edge and then falls off, not bouncing back. Am i doing it correct?
Making some guesses about your conventions, I suggest this:
double angle=Math.atan2(-c1x,-c1y);
If that doesn't work, we can do some experiments to figure out what's actually going on.
EDIT:
All right, we must build up from simpler solutions. Try these experiments:
1) Set velocity to (0,1) and verify that the ball moves straight up after the collision.
2) Set velocity to (-1,1) and verify that the ball moves up and leftward.
If those work as expected, then pick a trajectory that you would expect to behave in a normal way, such as approaching from above and to the left, then rebounding almost straight up but slightly leftward, then run it through your code but print out all the values in the collision and tell us what they are. That's at least c1x, c1y, angle, and the values of velocity initially and after each rotation.You'll probably notice where things go screwy, and if you don't we will.

Drawing a square by dragging the mouse

I am writing a Java program that closely mimics Microsoft Paint. It can draw four different shapes: Lines, Ovals, Rectangles, and Squares. I am very close to finishing this but I am stuck on the logic for drawing squares.
There are two Points involved while drawing these shapes. The first Point(point1) is when the user presses the mouse button and the second Point(point2) is while the user drags the mouse across the canvas. I believe drawing Rectangles and Squares should be quite similar but the part that has confused me is when drawing a square the sides are equal length so point2 isn't exactly where the mouse is.
Here is the fillRect() method header for reference:
fillRect(x, y, width, height)
My functioning code for drawing rectangles is as follows:
g.fillRect((((point1.x < point2.x) ? point1.x : point2.x)),
((point1.y < point2.y) ? point1.y : point2.y),
Math.abs(point2.x - point1.x),
Math.abs(point2.y - point1.y));
I tried using the same code for drawing squares except changing the height parameter to be equal to the width parameter because squares have equal length sides:
g.fillRect((((point1.x < point2.x) ? point1.x : point2.x)),
((point1.y < point2.y) ? point1.y : point2.y),
Math.abs(point2.x - point1.x),
Math.abs(point2.x - point1.x)); //same as width
I don't know what the problem is with making both width and height equal. It works when drawing downwards to the left or right but of course the shape does not expand if you pull straight down. Clicking and dragging up does not work; the square simply moves up with the mouse along the Y axis instead of expanding.
Could anyone point me in the right direction regarding the logic for drawing square from two points?
I can explain my code a bit better if need be.
If I were using a tool to draw a square, I would expect that my mouse cursor would remain on one of the sides of the square while drawing. If you always use the x distance as the side, then if I've drawn farther down than across, the cursor will be outside the square.
I think, while the dragging is going on, the code would need to calculate whether the x distance or the y distance to the origin is the longer, and use that as the side of the square-in-progress. Then the cursor will be on one of the sides, and that side will extend out beyond the cursor to the corner of the square-in-progress.
I don't know why the drawing is going awry -- it is difficult to be sure I understand what you say is going wrong.
You should do two calculations in your MouseDragged method -- first you should calculate the two corner Points of the rectangle, p1, and p2, and only then should you calculate the width. Point p1 is easy -- it's always the first Point pressed, but p2 will require a simple calculation. Once these are clarified, your calculations should fall out correctly.
i.e., something like:
int width = Math.abs(pointA.x - pointB.x);
int height = Math.abs(pointA.y - pointB.y);
width = Math.max(width, height);
height = width;
int x = pointA.x > pointB.x ? pointA.x - width : pointA.x;
int y = pointA.y > pointB.y ? pointA.y - width : pointA.y;
g.fillRect(x, y, width, height);

Categories