Painting and rotating a polygon around a point in Java swing - java

just trying to paint multiple unfilled triangles rotating a central point in Java. Paint one triangle, rotate the points by a certain radius, and paint another one.
int rad = 10 //Radius between the triangles
int num = 20 //Number of triangles
for (int i = 0; i < num; i++){
// (250,250) would be the center
int[] xPoints = (250,175,325) //X points of the first triangle
int[] yPoints = (250,100,100) //Y points of the first triangle
g.drawPolygon(xPoints,yPoints,3); //Paint the shape
}
Of course my code only prints the first triangle, as I'm unsure how to rotate the points. I've searched around and found some trig, but I don't really understand it. Is there a simple way to rotate each point? Thanks.

Is there a simple way to rotate each point?
Use an AffineTranform that does the geometry for you.
Some examples can be seen in posts tagged affinetransform. Particularly those of mine, Trashgod, MadProgrammer & HovercraftFullOfEels (my apologies if I forgot someone who has done some nice examples).

The Graphics2d object contains an AffineTransform and has a call to set it directly to a rotation about given point.
When using this, you often (not always) want to save a copy of the transform first and then restore it so the next use of g has the original transform rather than a pre- or post-multiplied version:
AffineTransform savedTransform = g.getTransform();
g.rotate(theta, x_center_of_rotation, y_center_of_rotation);
g.setTransform(savedTransform);

Related

How to detect a colored rectangles in an image?

I'm trying to write an AI maze solver program. To do this, I will draw 2-color mazes in GIMP with red being walls and blue being background or floor. Then I will export from GIMP as a png and use ImageIO.read() to get a BufferedImage object of the maze. Finally, I will assign Rectangle hitboxes to walls and store them in an ArrayList so I can use .intersect() to check for sprite contact with walls. I can work with it from here.
However, there is one thing I want to be able to do for my program that I don't know how to do: Once I have stored my image as a BufferedImage, how can I detect the red parts (all the exact same RGB shade of red) and create matching Rectangles?
Notes:
Mazes will always be of fixed size (1000x1000 pixels).
There is a fixed starting point for each maze
The red areas will always form straight rectangles. The Rectangle objects which I create are just used as hitboxes so I can use .intersect(), never drawn or anything like that.
Rectangles that are created will be stored in an ArrayList.
Example Maze: (a simple one)
What I want to be able to do: (green areas being where the java.awt.Rectangles are created and stored into ArrayList)
I will provide a quite naive way of solving the problem (not fully implemented, just so you get the idea)..
Have a list of all rectangles List<Rectangle> mazeRectangles. All rectangles will be stored here.. And of course the image BufferedImage image;
Now we will iterate over all pictures until we find one with the right colour
Every time we found a rectangle, we will skip all x values for the width of the rectangle..
//iterate over every pixel..
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
//check if current pixel has maze colour
if(isMazeColour(image.getRGB(x, y))){
Rectangle rect = findRectangle(x, y);
x+=rect.width;
}
}
}
Your method for checking the colour:
public boolean isMazeColour(int colour){
// here you should actually check for a range of colours, since you can
// never expect to get a nicely encoded image..
return colour == Color.RED.getRGB();
}
The interesting part is the findRectangle method..
We see if there is already a Rectangle which contains our coordinates. If so return it, otherwise create a new Rectangle, add it to the list and return it.
If we have to create a new Rectangle, we will first check it's width. The annoying part about this is, that you'll still have to check every pixel for the rest of the rectangle, since you might have a configuration like that:
+++++++
+++++++
###
###
where # and + are separate boxes. So we first find the width:
public Rectangle findRectangle(int x, int y){
// this could be optimized. You could keep a separate collection where
// you remove rectangles from, once your cursor is below that rectangle
for(Rectangle rectangle : mazeRectangles){
if(!rectangle.contains(x, y)){
return rectangle;
}
}
//find the width of the `Rectangle`
int xD = 0;
while(x+xD < width && isMazeColour(image.getRGB(x+xD+1, y))){
xD++;
}
int yD = 0; //todo: find height of rect..
Rectangle toReturn = new Rectangle(x, y, xD, yD);
mazeRectangles.add(toReturn);
return toReturn;
}
I didn't implement the yD part, since it's a bit messy and I am a little lazy, but you'd need to iterate over y and check each row (so two nested loops)
Note that this algorithm might result in overlapping Rectangles. if you don't want that, when finding xD check for each pixel if it is already contained in a Rectangle. Only expand xD as long as you are not inside another Rectangle.
Another thing: You might end up with strange artefacts at the border of your rectangles, due to the interpolation of colours between red and blue. Maybe you want to check for Rectangles being to small (like only 1 pixel wide) and get rid of them..
Last year, someone asked about a more general case for solving a maze. They had one additional complexity in that there were multiple paths, but the "correct" path through an intersection was straight.
Python: solve "n-to-n" maze
The solution provided solves the maze by ray-casting. Starting at the beginning of a path, it projects lines down the path in all directions. Then it sorts the list and chooses the longest line and uses that to calculate the next starting point. Now, it repeats projecting lines in all directions except in the direction it came - the backtrack could be longer than the forward progress. That would just bounced the solution around in the longest leg of the maze.
If you are certain your angles are always 90 degrees, you could modify the code accordingly.

Why are Polygons misshaped when using Vector coordinates in a Java Applet?

I have a completely graphed out blueprint of X, Y coordinates of 8 different multi-pointed shapes on paper. I put these coordinates into an array such as..
Polygon shape1;
int[] shapeOneX = {1,2,3,4,5,6,7,8,9};
int[] shapeOneY = {1,2,3,4,5,6,7,8,9};
shape1 = new Polygon {shapeOneX, shapeOneY, shapeOneX.length};
These coordinates are fake, and not my actual ones but on paper, these coordinates would follow the rules completely on how you would expect vector graphing to look like. When I load this into a Java Applet, the shape does not follow these exact coordinates. They're sometimes close, but not exact, and I need precision for my project.
Does anyone know why, or if there is a different formula you need to use on the coordinates to have it look the same in a java applet? If need more info, let me know.
I understand that starting coordinates for java applet start at the top left 0,0 then expand from there. I guess my questioning is,I have the understanding that "vector" cords start at 0,0 as a Mid point. I don't know much about graphing. So... my shapes are being created from a vector style, but being "placed" into an applet which has a 0,0 top left origin. Which is fine, I have the tools to adjust them where I need to put them. I just can't get them to create the shape I actually graph on paper. Do I need to graph on paper from a 0,0 top left origin and only create positive X, Y variables?
Another Edit-- I've noticed that when it draws onto the applet, it draws it almost mirrored as well. In other words, (x) goes right, (-x) goes left. That's normal. But (y) goes DOWN, and (-y) goes UP.. That doesn't seem normal HMM.. Confused.
Final Edit(probably) -- Well I was right about the Y axis being mirrored. Why? I don't know. But it has allowed for me to redesign some coordinates. I am currently under the impression that line borders were so thick that connected each vertex, that they reformed the shapes into a blob of junk. Because of the overlapping borders. It was hard to see where each vertex actually truly was. I also had to increase the values of my (x,y) coordinates in order to compensate for the size difference. Which I have probably near 100 or so different (x,y) combinations that I will need to re-do because of this... I really wish there was an easier answer. I am open to any and all suggestions, meanwhile I will plug away at remapping this. Thanks everyone who has, or continues to contribute.
For Example.. This first was the orignal coordinates:
int[] wallX = { -2,-2,-1,-1, 2, 2 };
int[] wallY = { -1, 3, 3, 0, 0,-1 };
And then the new WORKING coordinates I found to work are:
int[] wallOneX = { -2,-2, 1, 1, 10, 10 };
int[] wallOneY = { 4,-8,-8, 1, 1, 4 };
So thats the difference of numbers needed to create the same shape from paper, into the java applet. I don't really see a pattern or anything to recreate it for all my other ones. So I don't know.
You need to scale your coordinates based on the height and width of your jpanel or canvas object on which you are painting the polygon. use getHeight() and getWidth() to get the dimensions. Also, the origin is in the upper right corner of the jpanel or canvass, so you either need to use addition/subtraction to shift the scaled coordinates, or you need to use the affine transform to get the polygon where you want it to go.
Sometimes it helps to start with working examples. You might try this approach or this approach. Here is a third approach already in an applet.

Making a rectangle go around in a circle - Java/Swing

My maths isn't that good so I'm having a bit of trouble in one of my applications that I'm trying to do where I want a rectangle to represent a vehicle and I want that vehicle/rectangle to "drive" around in a circle. Imagine a roundabout with only 1 vehicle in it, just circling around forever.
If I can get some help how to do that then I'll be able to build on the example and most importantly learn.
If someone could write up a simple example for me I'd be grateful. No background no images, just a rectangle "driving" around in a circle. I'm using java and Swing.
Sorry, I am not sure if could understand clear you exactly need. If you need to draw rectangle which is moving around inside of circle, you can use sin/cos functions.
Something like that:
double r = 50.0; // radius (it might radius of your circle, but consider dimensions of rectangle to make sure you are drawing inside of circle, e.g. circleRadius - rectangeDimesion / 2.0)
for (int f = 0; f < 360; f++) {
double x = Math.sin(Math.toRadians((double)f)) * r;
double y = Math.cos(Math.toRadians((double)f)) * r;
// draw rectangle on [x, y] coordinates
}
If you know the radius of the round about, all the you would need would be a trigonometric function and the angle which the vehicle makes to the round about. You could take a look at this simple introduction which should get you started in the right direction.
On another hand, another approach would be to use a Transformation Matrix where you start with a matrix containing two points (your X and Y co-ordinates) and you transform them to become the new co-ordinates.
You can then rotate the rectangle to mimic a vehicle turning.
If you have a limited background in Mathematics, the first option might be easier for you to grasp.
This is more an extended comment than an answer.
I would divide the problem up into several easier problems, and work on each of them separately:
Draw your rectangle with a specified center location and long axis orientation.
Determine the center point and long axis orientation for an object orbiting around the origin. Note that to get make the long axis a tangent it needs to be perpendicular to the radius through the center.
Translate the whole system so that it orbits the desired point, rather than the origin.

own implementation of phong illumination with ray casting

I am trying to write a program in java from scratch that renders a sphere with ray casting technique and phong illumination, but I am a bit lost.
I understand the concept behind the phong equation coefficients, but I don't understand how to get to the vector values, and what is the relation of all this with ray casting
so let's say I want to renders the sphere in the middle of my screen, and I have it's position and radius, so (cx,cy,r). Where exactly do I start now? how exactly do I get to the vector values? my idea is as follows (pseudocode)
int cx = window width/2
int cy = window height/2
int r = 30;
for(i = 0 -> window height) {
for(j = 0 -> window width) {
if( (j-cx)^2 + (i-cy)^2 < r^2) {
//point inside
Color c = phong(arguments..)
draw pixel j,i with color c
}
}
}
but I have no idea if this is correct or not, and if it is, how do I get the vector values, for starters, the Normal?
could you point me in the right way? I have tried googling a lot with no success, thank you in advance
The vectors for calculating the normal usually come from a tessellation (approximation) of the real geometrical object. So you break the sphere up into, say, triangles. Then each triangle (p1,p2,p3) has its own normal vector ((p2-p1)×(p3-p1).
The phong shading method is an interpolation which then (ideally) blurs over the lines that give away the fact that you're drawing triangles instead of a true sphere. It's doesn't help with corners around the sides, though. :(
For the tessellation, one way is to approximate the sphere with Bezier surface patches which can then be subdivided to a suitably small sizes and simplified to triangles. My question over here explores doing this work to draw a teapot (mostly surfaces of revolution, not unlike spheres).

Hide Rubik's Cube Internal Wirings

In the context of a Java/OpenGL application I am drawing a black wired only (without filling) big cube composed of 27 smaller cubes. To do that I wrote the following code:
for (int x = 1; x <= 3; x++) {
for (int y = 1; y <= 3; y++) {
for (int z = 1; z <= 3; z++) {
wireCube(x - 2, 2 - y, 2 - z);
}
}
}
The wireCube method is implemented using GL11.glBegin(GL11.GL_LINE_LOOP);
Using the right call to gluPerspective to define the projection and the correct call to gluLookAt to position the "camera" I am able to display my big cube as needed and ....I am very happy with that !!!
My new problem is now, how to modify this code in order to "hide" all the wirings that are inside the big cube ? To help visualize the scene, these wirings are the ones that are usually drawn has dashed lines when learning 3D geometry at school.
Thanks in advance for help
Manu
Enable depth testing (glEnable(GL_DEPTH_TEST)) and put quads on the surfaces of the cubes.
To draw a quad, use glBegin(GL_QUADS) followed by the four vertices and the glEnd() call.
Draw all your cubes with black polygons (or disable color output : glColorMask(false,false,false,false); ): this will fill the depth buffer.
Then draw your lines. The ones hidden by the polygons will not appear. There will be z-fighting though, so glDepthTest(GL_LEQUAL);
If you want to draw "unvisible" lines dashed, this won't be enough. You can draw again with glDepthTest(GL_GREATER);
Another solution is to draw polygons that face the camera with a solid line, and other with a dashed line. This is a simple dot product (camDir.faceNorm).
Use glPolygonOffset() to drown or to emerge your wireframe above (or below) the polygons with the same coordinates.

Categories

Resources