how to draw the arc for three point angle in java - java

In java I have three points denoting two line with making an angle. Now I have to create the angle arc about 10 pixel apart from common point. with showing angle on the arc. I am able to calculate the angle but how to draw the arc and to show the angle on the arc. Please tell me some code view or link where I can find solution for this. CODE snippet is as below.
public void paintComponent(Graphics g){
Graphics2D g2=(Graphics2D)g;
Point p1=new Point(100,100);
Point p2=new Point(200,100);
Point p3=new Point(100,0);
Line2D line1=new Line2D.Double(p1, p2);
Line2D line2=new Line2D.Double(p1, p3);
g2.draw(line1);
g2.draw(line2);
double angle=getAngle(line1,line2);
System.out.println(angle);
//g2.drawArc(110, 100, 20, 20, 100, 30);
}
public double getAngle(Line2D line1,Line2D line2){
double angle1=Math.atan2(line1.getY1()-line1.getY2(), line1.getX1()-line1.getX2());
double angle2=Math.atan2(line2.getY1()-line2.getY2(), line2.getX1()-line2.getX2());
return Math.toDegrees(angle1-angle2);
}
I don't know how to use DrawArc to draw exact arc which i want and also to put the angle on that.
Thanks & Regards.

From the documentation drawArc's arguments are:
int x, int y, int width, int height, int startAngle, int arcAngle
the x and y are your common point (p1), and your width and height are probably both 10 (to draw a circular arc with radius 10pixels)
The angle that you have computed is the last argument (arcAngle) which measure the sweep of the arc in a counter-clockwise direction. So that last part you need to work out is the start angle, which is probably your angle1 or angle2 (0 in this case is the positive x-axis or 3 o'clock position).
Keep in mind, as written you will sometimes be drawing an arc of > 180 degrees, you will need more logic if you want to always find the smallest angle between the two lines.
As for the text you can use drawString and figure out the x and y using some trigonometry with half your sweep angle and your desired radius. Though for optimal placement you might need to figure out what quadrant you are drawing in and adjust from there.

Related

Point SVG shape in a direction around a circle

What I'm trying to do:
Create a compass when given a direction in degrees (0 - 360). Like so:
What I have done:
I have managed to get the SVG image to point in the right direction but I can't seem to get it to rotate around the circle. To attempt a solution around the circle, I have decided to try get the positioning using the ellipse tool and this formula. This is what it looks like at the moment:
(notice how the arrow faces a different direction to the ellipse, in the circle, on the axis - given the center point is the middle of the green circle)
void setDirection(float value, int radius) {
fill(secondaryColour);
float origin_x = (1280 - (width-400)/2);
float origin_y = height/2;
float x = origin_x + radius * cos(radians(value));
float y = origin_y +radius * sin(radians(value));
//grey circle
ellipse(x, y, 20, 20);
//arrow SVG
pushMatrix();
translate(200, 300);
rotate(radians(value));
scale(0.5);
shape(arrow);
popMatrix();
}
Please note: value is in degrees and radius is the radius I want the arrow to sit on. What am I doing wrong with the ellipse? and how can I bring them both together?
I found that the starting angle started on the white line, but I was assuming it would start on the red (similar to the angle of the arrow). To resolve the issue I needed to subtract 90 degrees from the variable value before converting it into radians.

Check if a rectangle is near another rectangle

I have a my rectangle.
The application generates another rectangle.
It can be more smaller or larger than my rectangle.
How can I tell when its rect near of the mine using their X, Y, Weight and Hight?? I do not want to know if is into my rectangle.
Draw 1 or more non-visible shapes that are relative to your rectangle's position that fit your definition of "near", then check to see if these shape(s) intersect with the application-generated rectangle in question.
For example, one way you might implement this is drawing a non-visible rectangle that surrounds your rectangle, then checking to see if the surrounding rectangle intersects with the application-generated rectangle.
I found the solution!
I have calculated the middle point of my rectangle.
If the rectangle generated have into the point, is near!
You can use the Math formula to calculate the distance between two points like this:
double getDistance(int x, int y, int x2, int y2) {
double distance;
distance = Math.sqrt( Math.pow( Math.abs(x2 - x) , 2 ) + Math.pow( Math.abs(y2 - y) , 2 ) );
return distance;
}

how to use drawArc()

i want to draw this arc in a panel that the preferedSize is set to (200,50):
i found it hard to understand what does the parameters in drawArc(). how to draw this one?
To understand the arguements read the javadoc: http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawArc(int,%20int,%20int,%20int,%20int,%20int)
drawArc(int x, int y, int width, int length, int startAngle, int arcAngle)
Used to draw an arc inside an imaginary rectangle whose upper left corner is at (x,y). The arc is drawn from the startAngle to startAngle + arcAngle and is measured in degrees. A startAngle of 0º points horizontally to the right (like the unit circle in math). Positive is a counterclockwise rotation starting at 0º

Make oval/rectangle using float/double values

I want to draw a figure using float or double values, to be precise.
I use:
g.drawOval(0, 0, 10, 10);
to draw a circle, but I only can use integer values.
Is there any statement that use float/double values that do the same?
Here is a picture: Problem
The circles have to be centered, and I can't. Any solution?
Code:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JPanel;
public class Bulls_EYE extends JPanel
{
int red, green, blue;
int height, width;
int heightOval = 475, widthOval = 475;
Random rValue = new Random();
public void paint (Graphics g)
{
super.paint(g);
for (int idx = 0; idx < 100; idx++)
{
g.setColor(new Color(red = 1 + rValue.nextInt(255), green = 1 + rValue.nextInt(255), blue = 1 + rValue.nextInt(255)));
g.fillOval(width+2*idx, height+2*idx, widthOval-5*idx, heightOval-5*idx);
}
}
}
I think it's an interesting question but needs more context. Drawing primitives are usually expressed in pixel coordinates so fractions of a pixel do not make much sense.
If you want precision like a CAD application note that what is displayed on the screen is only an approximation of the underlying model due to the limitations of the display.
You can represent your models precisely in memory (with limitations in floating point representation) and draw the approximation on the screen.
Update
Based on your last update:
We know from the JavaDoc that fillOval takes as parameters (x, y, w, h) where x, y are the upper left coordinates, and w, h are the width and height.
If for each concentric circle you move the upper left coordinates inward, in this case by 2 px, to keep them centered, you must also reduce the width and height by twice that amount. Change the following line:
g.fillOval(width+2*idx, height+2*idx, widthOval-5*idx, heightOval-5*idx);
To
int dx, dy, dw, dh;
dx = 2*idx;
dy = 2*idx;
dw = 2*dx; // note this is 4*idx not 5*idx like you have currently
dh = 2*dy;
g.fillOval(width+dx, height+dy, widthOval-dw, heightOval-dh);
Note that your width and height variables being used in the first and second parameters really doesn't have anything to do with width and height but instead are providing a beginning offset from the origin where the oval is drawn.
There is no reason you should do this, because when drawing an oval with the given coordinates, they are referred to pixels on the screen. Since you can't draw between pixels, 1 is the smallest unit you can use. If you want to round the values before drawing, you can use
g.drawOval(Math.round(a),Math.round(b),Math.round(x),Math.round(y)
which will round the float a, b, x and y before drawing the oval. The only reason I can see is that you calculate the coordinates and the result is a float, then you need to round it like above.
You can use the Arc2D class for drawing circles with float/double precision, since it is a Shape and the Graphics2D class can draw shapes.
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Shape circle = new Arc2D.Double(
// Same values as used in the fillOval function,
// but with double precision.
x, y, width, height,
// Draw a full circle (yes, in degrees).
0, 360,
// Connect the endpoint with the startpoint.
Arc2D.CORD
);
// Paint the circle.
g2d.fill(circle);
}
In a similar way, you can draw rectangles by using the Rectangle2D class.
Also, please use the paintComponent function instead of the paint function, as explained here.

Some help on a Java program to draw a rainbow

I'll be candid about this; it is a homework assignment, but can someone guide me in the right direction and explain to me how some parts of the code are supposed to work? The directions are below the code and the questions.
This is my code so far:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rainbow extends JPanel
{
// Declare skyColor:
private final Color skyColor = Color.CYAN;
public Rainbow()
{
setBackground(skyColor);
}
// Draws the rainbow.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// Declare and initialize local int variables xCenter, yCenter
// that represent the center of the rainbow rings:
int xCenter = width/2;
int yCenter = (height * 3) /4;
// Declare and initialize the radius of the large semicircle:
int largeRadius = width/4;
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter,yCenter,largeRadius,height,0,180);
// Declare and initialize the radii of the small and medium
// semicircles and draw them:
int smallRadius = height/4;
g.setColor(Color.MAGENTA);
g.fillArc(xCenter,yCenter,width,height,0,180);
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
g.setColor(Color.GREEN);
g.fillArc(xCenter,yCenter,width,height,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
// so that the width of the middle (green) ring is the
// arithmetic mean of the widths of the red and magenta rings:
// Draw the sky-color semicircle:
g.fillArc(xCenter,yCenter,width,height,0,180);
}
public static void main(String[] args)
{
JFrame w = new JFrame("Rainbow");
w.setBounds(300, 300, 300, 200);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = w.getContentPane();
c.add(new Rainbow());
w.setVisible(true);
}
}
My questions: How exactly does fillArc work; I understand what goes in the parameter, but what must one do so each arc differs from one another?
How does one set one color for each arc? I tried doing so, and I ended up with the color listed closest the end showing up and overriding the others.
I'll probably have more as a I continue to code.
These were the directions:
![enter image description here][1]
The “rainbow” is made of four overlapping semicircles. The outer ring is red (Color.RED), the middle one is green (Color.GREEN), and the inner ring has the magenta color (Color.MAGENTA). The innermost semicircle has the same color as the background.
Follow the instructions below and fill in the blanks in Rainbow.java.
Start the Rainbow project.
Add a complete comment header with your name before the class declaration at the top of the file.
Add to the Rainbow class a declaration of a private final field skyColor of the type Color, initialized to Color.CYAN (the color of the sky). In Rainbow’s constructor, set the window’s background to skyColor rather than Color.WHITE.
In the paint method, declare local integer variables xCenter and yCenter that represent the coordinates of the center of the rings. Initialize them to 1/2 width and 3/4 height (down) of the content pane, respectively. (Recall that the origin of graphics coordinates in Java is at the upper left corner of the content pane with the y-axis pointing down.) Do not plug in fixed numbers from the window’s dimensions.
Declare a local variable largeRadius that represents the radius of the largest (red) semicircle and initialize it to 1/4 of width.
A method call g.fillArc(x, y, size, size, from, degrees) (with all integer arguments) draws a sector of a circle. x and y are the coordinates of the upper left corner of the rectangle (in this case a square) into which the oval is (logically) inscribed; size is the side of the square (and the diameter of the circle); from is the starting point of the arc in degrees (with 0 at the easternmost point of the horizontal diameter), and degrees (a positive number) is the measure of the arc, going counterclockwise. Add a statement to the paint method to draw the largest (red) semicircle. Test your program.
Add statements to display the medium (green) and small (magenta) semicircles. The radius of the magenta semicircle should be 1/4 of height. The radius of the green one should be the geometric mean (the square root of the product) of the radius of the red semicircle and the radius of the magenta semicircle, rounded to the nearest integer. (A call to Math.sqrt(x) returns the value of square root of x, a double.) Retest your program.
Add statements to display the innermost semicircle of the background (“sky”) color to complete the rainbow. Use the skyColor constant for this semicircle’s color. Choose the radius of the sky-color semicircle in such a way that the width of the middle (green) ring is the arithmetic mean of the widths of the red and magenta rings.
Test your program.
Submit your completed program and run output. Your run output (the rainbow picture) can be included by capturing the screen output (Alt-PrintScrn), pasting it into a graphics program (such as MS Paint) and then saving the image to your Eclipse project directory.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Rainbow extends JPanel
{
//Declare skyColor:
private final Color skyColor = Color.CYAN;
public Rainbow()
{
setBackground(skyColor);
}
// Draws the rainbow.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
// Declare and initialize local int variables xCenter, yCenter
// that represent the center of the rainbow rings:
int xCenter = width/2;
int yCenter = (height * 3) /4;
// Declare and initialize the radius of the large semicircle:
int largeRadius = width/4;
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter - largeRadius,yCenter - largeRadius ,largeRadius,largeRadius,0,180);
// Declare and initialize the radii of the small and medium
//semicircles and draw them:
int smallRadius = height/4;
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
g.setColor(Color.GREEN);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter- (largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.setColor(Color.MAGENTA);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
// so that the width of the middle (green) ring is the
// arithmetic mean of the widths of the red and magenta rings:
int skyRadius = (int)((2 * Math.sqrt(smallRadius * largeRadius)) - width/4);
// Draw the sky-color semicircle:
g.setColor(skyColor);
g.fillArc(xCenter-skyRadius,yCenter-skyRadius,skyRadius,skyRadius,0,180);
}
public static void main(String[] args)
{
JFrame w = new JFrame("Rainbow");
w.setBounds(300, 300, 300, 200);
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = w.getContentPane();
c.add(new Rainbow());
w.setVisible(true);
}
}
fillArc() fills in a section of the circle based upon the parameters you gave it. For example your first arc.
You're drawing the fill arc, which in this case is a semi-circle, of the color red.
//Set the arc color
g.setColor(Color.RED);
// Draw the large semicircle:
g.fillArc(xCenter,yCenter,largeRadius,height,0,180);
There's our fillArc. That doesn't look anything like a rainbow. In order to get the rainbow shape, we have to draw a smaller arc inside of it. In your case the next one is green. So we do fillArc again after setting the color to green. But we shrunk the radius a little bit so the green doesn't cover the entire red section.
Keep in mind when we draw, we're drawing on top, so if you drew the green on first it would be covered by the red one.
Then we draw another arc inside this once more, but make this one the color of the sky (white in this case). This creates the final rainbow shape. So we do fillArc again, but with a slightly smaller radius and the color white.
And there, we drew a rainbow.
To center this beautiful creation, we have to understand a few things about the fillArc function.
The parameters are:
public abstract void fillArc(int x,
int y,
int width,
int height,
int startAngle,
int arcAngle)
int x and int y represent the coordinates for the upper left hand corner of the arc that you are drawing. The reason your code isn't centering is because of how you're drawing the arc.
g.fillArc(xCenter - largeRadius,yCenter - largeRadius,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
I took out a few of the excess stuff. You see how you're subtracting the (largeRadius+smallRadius)/2 and (largeRadius+mediumRadius)/2? This is shifting the rainbow to make it off center. What you should have is instead:
g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
This will properly center the rainbow. Here's why.
That's the point where they will start the drawing the arc from. If you want to center the entire rainbow, you'd shift it over by half of it's entire width. So if you want to center the red arc, you'd do
xCenter - (largeRadius/2)
As this is setting the x start to the left by half. You wouldn't include largeRadius in the other arcs, as you're centering them around this point. Thus you'd want to shift them over by half of their individual widths, which is why their x positions are
xCenter-(mediumRadius)/2
xCenter-(smallRadius)/2
Centering on the Y-axis works differently. You have to consider that the height of the rainbow overall is 1/4 the largeRadius. Your code uses yCenter = 3/4 * height, so that changes it a bit.
This is my solution
g.fillArc(xCenter - largeRadius/2,yCenter - largeRadius/2 + largeRadius/4 -height/4,largeRadius,largeRadius,0,180);
g.fillArc(xCenter-(mediumRadius)/2,yCenter-(mediumRadius)/2 + largeRadius/4 -height/4,mediumRadius,mediumRadius,0,180);
g.fillArc(xCenter-(smallRadius)/2,yCenter-(smallRadius)/2 + largeRadius/4 -height/4,smallRadius,smallRadius,0,180);
Let's take a look. I subtracted the largeRadius/2 (and respective radiuses) for the same principle as in x. But then I added largeRadius/4 because we have to shift the entire rainbow down. This is because subtracting the respective radius/2 only centers the rainbow as if it were an entire circle, not semi-circles.
Adding largeRadius/4 shifts the rainbow down by overall half of it's height, centering it correctly for a semi-circle. Finally, subtracting height/4 makes changes the yCenter to height/2, since 3/4 * height is a requirement in your assignment.
Sorry about all the problems in the comments, hope this cleared it up.
I've modified part of your code so you could get an idea. Remember that your xCenter and yCenter represent the center of your circle, not the coordinates you need to use in the fillArc method. The instructions you provided explain it pretty well. You can get an idea from what I did here and figure the rest by yourself.
// First declare and initialize all radiuses
int largeRadius = width/4;
int smallRadius = height/4;
int mediumRadius = (int) Math.sqrt(smallRadius * largeRadius);
//Then draw each arc in descending order from the largest one
g.setColor(Color.RED);
g.fillArc(xCenter-largeRadius,yCenter-largeRadius,largeRadius,largeRadius,0,180);
g.setColor(Color.GREEN);
g.fillArc(xCenter-(largeRadius+mediumRadius)/2,yCenter-(largeRadius+mediumRadius)/2,mediumRadius,mediumRadius,0,180);
g.setColor(Color.MAGENTA);
g.fillArc(xCenter-(largeRadius+smallRadius)/2,yCenter-(largeRadius+smallRadius)/2,smallRadius,smallRadius,0,180);
// Calculate the radius of the innermost (sky-color) semicircle
For you skyRadius consider:
Red width = large radius - medium radius
green width = medium - small
magenta width = small radius - skyradius
if I did the math rightyou get: skyRadius = smallRadius - 2*(mediumRadius-smallRadius)+largeRadius-mediumRadius
int skRadius=smallRadius-2*(mediumRadius-smallRadius)+largeRadius-mediumRadius;
g.setColor(skyColor);
g.fillArc(xCenter-(largeRadius+skRadius)/2,yCenter-(largeRadius+skRadius)/2,skRadius,skRadius,0,180);
A much simpler equation for skyRadius is:
int skyRadius = largeRadius - 3 * mediumRadius + 3 * smallRadius;

Categories

Resources