Draw a circle using a plotter - java

I have a class called Circle that extends from a class called Shape. I am trying to figure out how to get a circle to draw on a plotter using the given description of the draw() method.
Here's what I have so far for the class:
public class Circle extends Shape{
private double radius;
public Circle(double x_origin, double y_origin, double r, Color c){
super(x_origin, y_origin, c);
this.radius = r;
}
public void draw(WinPlotter plotter){
setPenColor(plotter);
}
}
The setPenColor just provides a color for the circle to be drawn, feel free to ignore it.
The javadoc description for the circle's draw method is as follows:
Draws the Circle. Uses sine and cosine functions from the
java.lang.Math class to compute a finite set of points that lie on the
circumference of a circle, and then uses the drawTo method of
WinPlotter to draw a sequence of small connected straight-line
segments. When enough segments are drawn (about 25 segments are
sufficient), a smooth circle is approximated.
If you need to see the entire Circle javadoc for it, here it is
Here is the WinPlotter javadoc to use as a reference. I have only been using the moveTo() and drawTo() methods for every other shape I have had to draw.
I just want to know the best way to draw a circle on the plotter.

Simple way I can think of is to use Math.sin and Math.cos to loop to 360 degress(2*PI) over a set interval, drawing lines between the current value and the previous one.
Look at http://en.wikipedia.org/wiki/Trigonometric_functions and check out the pictures on the right. Then think about it as a loop with your loop variable being thea
GL on your homework.
Edit: Heres the link you should really look at http://iopixels.com/cos-sin-explain

Related

Java calculating points of Angles in a non-right triangle

I am currently working on a project in which i need to draw a non-right triangle in the center of a JFrame using either, java.awt.Graphics's drawLine() or drawPolygon() methods. Both of these methods require the coordinates of all of the points to function. My problem is that instead of points, all i have are all of the angles and side lengths of the triangle. I've drawn up a nifty diagram of what I hope helps you visualize my problem:
(EDIT the position of C in this Senario is not fixed betwen a and b and may be anywhere below the axis on which AB rests)
as you can see from my picture, I need the coordantes of C based off the coordanes of A, is there any way to calculate this given the lengths of all sides and angles of the non-right triangle?
Bonus: How would i find an (x, y) value for A that would effectivly center the triangle in the middle of the JFrame?
If you know angle CAB, the coordinate of point C should be:
(x+b·sin(θ), y-b·cos(θ))
In Java, there is:
double Math.sin(double radians);
double Math.cos(double radians);
Keep in mind that the angle needs to be in radians. If your angles are in degrees, try:
double Math.sin(Math.toRadians(double degrees));
double Math.cos(Math.toRadians(double degrees));
Hope this helps.

Java AWT bounds

I have an assignment to draw a certain number of circles using java.awt.Graphics.
Drawing the circles is fairly simple, but I am only supposed to draw the circle if it appears within the visible area. I know I can call method getClipBounds() to determine the drawing area, but I'm having trouble finding a java implementation of a way to determine if a circle intersects a Rectangle.
Is that the right way to go about determining if the circle I want to draw will be completely visible or is there a simpler way?
Don't use the Graphics.fillOval(...) method to do the painting.
Instead you can use the Graphics2D.fill(Shape) method. You can create oval Shape objects using the Ellipse2D class.
but I'm having trouble finding a java implementation of a way to determine if a circle intersects a Rectangle.
The Shape object has a method that will allow you to get the rectangular bounds of the Shape. Then you can use the Rectangle.contains(...) method of the your Graphics area to determine if the Shape is fully contained within your panel.
Check out Playing With Shapes for more information and ideas.
use Ellipse2D.Float to instanciate an object for example:
Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
basically the parameters,from left to right, are: Height, Width, X of the Top left and Y of the top left, and by keeping the X and Y both greater or equal to zero, your circle will always be visible.
the parameters of the Float(...) are documented for the Ellipse2D.Float in Java SE 7 in
http://docs.oracle.com/javase/7/docs/api/java/awt/geom/Ellipse2D.Float.html

Finding nearest free position for a circle for any point [x,y] in a 2D space with circles

I am making a game in which the user player places circles on the screen. It is important that the circles never overlap, so I need to figure out the nearest possible free spot from the cursor. I have found circle packing algorithms, but they do not seem a fit for my problem. I have also solved a similar problem in the past for boxes (here), but with circles, I cannot seem to figure it out.
I figured out how I can find the nearest free position when it intersects with one circle, or even when two are involved. However, I cannot find a robust algorithm that can deal with complex cases that have any number of circles in any arrangement.
Precise description of problem:
I have a 2D space with any number of non-intersecting circles, all with identical radii (though that may not matter). I want to find a position for the next circle that will make it not intersect with any other circle, and which center [x,y] is nearest to a specified location [x,y].
Suggestions of any kind appreciated (references, approaches, or (Java) libraries).
p.s. Bonus points if the solution includes making sure the circle stays within a specific bounding box (i.e. display).
My final solution: (based on David Wallace's suggestions)
Calculate the minimal distance between the centers of two circles (in my case, all circles are the same size, so always 2*radius)
Make a list of all circles that are closer to the mouse position than the minimum distance
If 0 overlaps: all good!
If 1 overlap: move the new circle's center to the minimum distance from the compared circle's center, along the vector that runs from compared circle's center to mouse position
If 2 overlap: find out where the two overlapping circles intersect. Place the new circle on the intersection closest to the mouse position. If this position still overlaps with any circle, move to the other intersection. If that one doesn't work, leave the new circle were it is.
If 3 overlap: same as in 2 overlap, just take the two circles closest to the new circle.
Note that this does not work perfectly, but good enough in my case, where a user is dragging the new circle on the screen. It works in most cases and in those it doesn't, usually when there are many circles very close together, the new circle simply stays in the last position (which was valid). The user can then decide to drag it a fit further and be more precise in where he wants the new circle to go.
This isn't a complete answer, but you may be able to make it into one.
Suppose you've already placed circles of radii r1, r2, r3 ... rn with centres C1, C2, C3 ... Cn, and you're looking to place a new circle of radius rz, the new circle's centre will have to be outside all of a set of "enlarged" circles, centred at C1, C2, C3 ... Cn; with radii (r1+rz), (r2+rz), (r3+rz) ... (rn+rz). So if the cursor is at point P, then there are some cases to consider.
(1) If P is not in any of the enlarged circles, then the problem is solved.
(2) If P is in just one of the enlarged circles, then move outwards along a radius of that circle, until you either reach a point that's outside all of the enlarged circles, or until you reach another enlarged circle. The former case reduces to scenario (1); the latter reduces to scenario (2). Pick an arbitrary direction if P happens to be the centre of the circle.
(3) If P is in several of the circles, then find the directions from P to each centre of a circle that it's in. Find the pair of directions that have the widest interval between them, and bisect that angle, to work out which direction to head along. For example, if the directions to the centres of the circles are 30deg, 120deg and 330deg, then bisect the angle between 120deg and 330deg - then head in a direction of 225deg. Head in that direction until you reach the edge of a circle, then recalculate. Keep doing this until you get back to scenario (2).
The thing that I can't work out is what to do if you get stuck in scenario (3). Maybe only allow a certain number of steps, then exit. After all, it's possible that there's no suitable place to put the circle.
To calculate the distance between a point and a circle is with the center, considering your Circle class is like this one:
public class Circle{
int x;
int y;
int radius;
}
public interface CircleHelper{
public int distanceBetweenCircleAndPoint(Circle c, Point p);
public int distanceBetweenTwoCircles(Circle c1, Circle c2);
}
First of all, I would think about using Quadtrees and check if there is any quad without surrounding circles
The quadtree deep can be selected considering the radius of the circles.
so if you have a point in one of the quads, you would look to its surrounding quads to check if there is any circle there and move from the point in the direction of empty quads.
I hope you understand my approach
Here is a solution that will work for varying radiuses, and can be simplified if all radiuses are equal, as in your case. We first transform the problem slightly. Instead of fitting a circle among other circles, we extend the radiuses of all other circles by the radius of our circle to place, and instead try to place a point outside of these extended circles. This is equivalent to the original problem. We proceed as follows:
First a special case. If the point is outside of all circles, we have a trivial solution.
Find all the circles the point is inside. Calculate the closest point on their circumference (just move out from the original point along the radius).
Find all the intersection points between pairs of circles.
Combine the sets of points from steps 2 and 3, and filter these by finding the ones that are not covered by any other circle.
Pick the closest point from the remaining set. Done!
This seems to be O(n^3), so not terribly fast, but should be doable if your set is not too huge.

Constraint of XY coordinate

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

Triangle Draw Method

I have trouble drawing a triangle with the draw(Graphics g) method in Java.
I can draw a rectangle like so:
public void draw(Graphics g) {
g.setColor(colorFill);
g.fillRect(p.x, p.y, width, height);
g.setColor(colorBorder);
g.drawRect(p.x, p.y, width, height);
drawHandles(g);
Where p represents "the top left corner of the shapes". How would I draw the triangle in the same manner?
Could someone give me an example for a standard triangle?
There is not a drawTriangle method neither in Graphics nor Graphics2D. You need to do it by yourself. You can draw three lines using the drawLine method or use one these methods:
drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
drawPolygon(Polygon p)
drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
These methods work with polygons. You may change the prefix draw to fill when you want to fill the polygon defined by the point set. I inserted the documentation links. Take a look to learn how to use them.
There is the GeneralPath class too. It can be used with Graphics2D, which is capable to draw Shapes. Take a look:
http://docs.oracle.com/javase/tutorial/2d/geometry/arbitrary.html
You should try using the Shapes API.
Take a look at JPanel repaint from another class which is all about drawing triangles, look to the getPath method for some ideas
You should also read up on GeneralPath & Drawing Arbitrary Shapes.
This method is much easy to apply AffineTransformations to
Use a line algorithm to connect point A with point C, and in an outer loop, let point A wander towards point B with the same line algorithm and with the wandering coordinates, repeat drawing that line. You can probably also include a z delta with which is also incremented iteratively. For the line algorithm, just calculate two or three slopes for the delta change of each coordinate and set one slope to 1 after changing the two others proportionally so they are below 1. This is very important for drawing closed geometrical areas between connected mesh particles. Take a look at the Qt Elastic Nodes example and now imagine drawing triangles between the nodes after stretching this over a skeleton.
As long as it will remain online
there is no command directly to draw Triangle. For Drawing of triangle we have to use the concept of lines here.
i.e, g.drawLines(Coordinates of points)
There is no direct method to draw a triangle.
You can use drawPolygon() method for this.
It takes three parameters in the following form:
drawPolygon(int x[],int y[], int number_of_points);
To draw a triangle:
(Specify the x coordinates in array x and y coordinates in array y and number of points which will be equal to the elements of both the arrays.Like in triangle you will have 3 x coordinates and 3 y coordinates which means you have 3 points in total.)
Suppose you want to draw the triangle using the following points:(100,50),(70,100),(130,100)
Do the following inside public void paint(Graphics g):
int x[]={100,70,130};
int y[]={50,100,100};
g.drawPolygon(x,y,3);
Similarly you can draw any shape using as many points as you want.
You can use Processing library:
https://processing.org/reference/PGraphics.html
There is a method called triangle():
g.triangle(x1,y1,x2,y2,x3,y3)

Categories