I'm trying to draw a hexagon shaped asteroid on a clone of Asteroids I'm making for a class.
sprite = new Polygon();
sprite.addPoint(0,0);
sprite.addPoint(0,-40);
sprite.addPoint(30,-40);
sprite.addPoint(60,-10);
sprite.addPoint(60,20);
sprite.addPoint(40,50);
sprite.addPoint(-20,50);
sprite.addPoint(-50,20);
sprite.addPoint(50,-10);
sprite.addPoint(20,-40);
Yet when I do it, I end up with this
So what is going wrong? I drew it out on a coordinate plane, and copied the points over. It was my understanding that Java would draw it out in the order I listed the points, and I had the (0,0) in there in the interest of rotating the asteroid for the game.
Zane is close, he forgot to include i in his formula:
for(i=0; i<6; i++) {
sprite.addpoint(x + r*cos(i*2*pi/6), y + r*sin(i*2*pi/6))
}
First, if it is supposed to be a hexagon, then it should have 6 points, not 10. Second, just drawing this on paper from your coordinates gives me quite a similar polygon as they one in your picture. So I guess your coordinates are wrong. Check them again.
If you want to draw a symmetric hexagon, then all you need is its center, say (x,y) and its radius r. Then the points of the hexagon are
for(i=0; i<6; i++) {
sprite.addpoint(x + r*cos(i*2*pi/6), y + r*sin(i*2*pi/6))
}
It's not really a hexagon, the last two points look strange
sprite.addPoint(50,-10);
sprite.addPoint(20,-40);
Think those final two should be:
sprite.addPoint(-50,-10);
sprite.addPoint(-20,-40);
but even with that, its going to look a lop-sided pacman - back to the drawing board I think.
I would check your coordinates. The last few transitions do not look right to me, especially (-50, 20) to (50, -10). It has a jump of 100 units in the x direction, bigger than any other change in coordinates. (-50, -10) seems more plausible.
Related
I am writing a program that allows a user to left-click the panel and add a bouncing ball, and right-click to remove a ball. The balls bounce off of all walls with a constant velocity. I have all of this finished. The last part that I cannot figure out is handling the collisions with other bouncing balls. The same results as bouncing off of the walls should occur. Any help will be greatly appreciated. Here is the code for the movement of the ball so far...
#SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
private void processMovement(long interval)
{
/* Compute the distance moved in the interval. Decompose the distance
moved into x and y components, and determine the next position of the Ball
by those amounts. */
float x = position.x + velocity.getDistanceX(interval);
float y = position.y + velocity.getDistanceY(interval);
position.setLocation(x, y);
/* Collisions with the walls. If so, adjust the speed and direction for
the next period. */
/* Collision with the east or west (vertical) wall. */
float wall;
if( x <= (wall = 0.0F) ||
x >= (wall = model.getDimension().width - SIZE) )
{
x = wall;
velocity.reverseX();
}
/* Collision with the north or south (horizontal) wall. */
if( y <= (wall = 0.0F) ||
y >= (wall = model.getDimension().height - SIZE) )
{
y = wall;
velocity.reverseY();
}
position.setLocation(x, y);
}
When I wrote a program like this, I ended up creating a wall object, which had a start x/y and an end x/y. Geometry was needed in order to determine the correct ricochet/bounce angle since walls could be at any orientation. Essentially the direction of the ball changes by two times the difference in orientation between the wall and the ball's direction. For example, if the ball is moving at 45* above the X-axis, and the wall is oriented at 90* above the X-axis (i.e. it's straight up and down), then the ball's new heading is its original heading plus two times the difference between its heading and the wall's direction, or in other words 45* + 2*(90*-45*), or in other words, 135*. The problem is that it doesn't work if you consider the wall's orientation to be -90* (i.e. 90* below the X-axis, which is still straight up and down). In that case you'd calculate the ball's new heading as -45* which is wrong. It also matters if you hit the wall from the left or from the right. Fun, right? Lots of things to think about.
Balls collide when their centers are within (R1 + R2) distance of each other, where R1 is the radius of the first ball, and R2 is the radius of the second ball.
Essentially, what I did was I created a temporary (invisible) wall that was perpendicular with the vector from the center of one ball to the center of the other, and then I ordered the two balls to bounce off of this wall. This gave the correct ricochet behavior.
I know you probably don't care about my "wall collision" stuff, but I think what I have described could give you something of an idea of the kind of geometry you're going to need to perform in order to solve this problem.
In short, bouncing balls off of each other correctly is difficult. Consider removing/abandoning this functionality if it's not required and/or you're not willing to spend the effort.
You could also put together something less correct, but easier. You could simply have balls move away from each other when they collide, but then you'd get "unnatural" looking ricochets.
I know it certainly doesn't solve your problem, but hopefully this helps.
In Java (at least when using Bluej as the environment), the top left corner pixel is (0,0) and bottom left is (600,600)(depending on window size). Your logic is unfamiliar to me, but assuming your math is correct to have the balls reverse direction when hitting a wall you should have 4 if statements per ball. I know there are ways of getting away with 1 or 2 and my way is ugly and not very effecient, but a least it will isolate if the problem is your math of logic.
if (X<=0 || X>=600)
{
velocity.reverseX();
}
if (Y<=0 || Y>=600)
{
velocity.reverseY();
}
I hope this helps :)
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.
Can someone guide me how I can implement the following in java: I need to reference two rectangles after splitting from any rectilinear polygon into two or more pieces.
Polygon http://img853.imageshack.us/img853/2475/picture1eu.jpg
My Algorithm:
ArrayList coordinates;
for (int a = 0; a < coordinates.size(); a++)
{
if (coordinates[a] at point of concave)
{
Draw intersecting line North Or South from coordinates[a] depending on
which direction remains inside the polygon.
}
}
On this particular diagram both concave edges lie on the same x-axis, however this is not always the case.
I'm guessing I need to use the Shape and Area class? I guess what I'm struggling with the most is what do I use to make the split (regular .drawLine?) and then be able to reference the two rectangles afterwards.
Thank you.
You can get list of possible rectangles finding all possible combinations of 4 vertexes. Then leave only rectangles (check x and y of neighbour vertexes). Then check whether they intersect each other.
Also they should be inside main Shape (use contains()) method of Area created from the Polygon.
Does it work?
I'm creating a 2d game. There are a lot of objects(oval, triangle etc) created by Bitmap. I'm going to detect collisions. Now I can do it only with rectange like this:
int x, y;
...
if(x>=bmp.getX() && x<=bmp.getX()+bmp.getWidth()
&& y>=bmp.getY() && y<=bmp.getY()+bmp.getHeight()) {
//Collision.
}
But there is one problem: I don't know how to do it with another figure (oval, triangle, etc). Any ideas will be appreciated. Thank you.
A simple solution is to use sub rectangles to calculate collisions. The sub rectangles wont be able to cover the entire object but they can cover most of it.
This image should illustrate what I mean, it uses several rectangles for collision detection of a aeroplane
Another option (though NOT recommended) is to use per pixel color collision, if a colored pixel in the triangle intercepts a colored of an oval then there is a collision. Be warned this is computationally expensive.
1) for most figures try formula for intersection of edges
to find more try ie: How do you detect where two line segments intersect?
2) for intersection of circle and not circle, try distance from centre of circle to edgeHow to tell if a line segment intersects with a circle?
3) intersection of two circles is easiest, just check is distance between both centres are lower than sum of their radius
I faced the same problem as you, however with irregular Shapes. How I fixes the problem:
Create a Shape class that contains a list of Rectangles.
When first creating your game object, you should add Rectangles to the list so that a Shape is formed.
Now for collision detection; instead of just checking the one rect, iterate over all the rects in the list.
I hope this helps.
For oval you can use: -
if((Math.pow(x, 2) / Math.pow(a, 2)) + (Math.pow(y, 2) / Math.pow(b, 2)) < 1) {
/** Point (x, y) is inside Oval **/
}
For Triangle, it is a little trivial task: -
Visit this link
I need ideas about how to move an object (a circle which represents a robot in my application).
The surface the object will be moving on consists of Tiles of BufferedImage of 3 rows and 3 columns ( represented in arrays). All the Tiles are equal in sizes (160 X 160).The 3rd row and the 3rd column are the track rails on which the object must be moving on.
It means that the object(robot) can move horizontal (forward and backward) and vertical (upwards and downwards).
The Tile at the position [2][2] (please am counting from top. so the top row will be 0 the next afterward is 1 etc.. ) is a crossing which the robot will use to change to the vertical track rails or to the horizontal track rails.
My problem now is how to move the object to a specific Tile after the crossing has turned. For instance the robot will be in the Tile at position [2][1] and want to move to the tile at position [1][2] after the crossing is turned and then move further upwards. Or it can be at [1][2] and want to move to [2][1] after the crossing is turned and then move further backwards .
How can i move the robot from one Tile to another Tile? Which way can i refer to a specific Tile in the BufferedImage that i can place the object. All what i want is give me the ideas how i can do it.
Please this is my first time of doing such project so forgive me if my question is too elementary. With your explanation and help i will learn more from it.
Thank you very much.
In order to display your image you need to figure out the bounds of the grid you want to put your image into. I usually create two helper methods, one to translate grid coordinates into display coordinates and the other one to go the other direction.
private Point convertGridToDisplay(int x, int y) {
return new Point(x * 160, y * 160);
}
private Point convertDisplayToGrid(int x, int y) {
return new Point(x / 160, y / 160);
}
convertGridToDisplay() will give you the upper left hand coordinate where you should draw your image to.
For example:
Point point = convertGridToDisplay(2, 1);
graphics.drawImage(img, null, point.x, point.y)
will draw your image at grid (2, 1).
convertDisplayToGrid() will come in handy when you want to figure out which grid a mouse click was made in.