Draw curved lines,any suggestions - java

Hello guys I need to draw the curved lines in bold mainly those starting N - S and if possible the ones getting 350-10 340-20 and so on. I have tried QuadCurve2D and drawArc, but none of those worked. Is there any way possible to avoid the use of drawPolyline(xPoints, yPoints, WIDTH) because it will take hundreds of pairs to draw just one line.
This is part of the code in order to avoid your loss of time testing yourself :
public class PaintMyQuad extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
QuadCurve2D.Double curve = new QuadCurve2D.Double(200,0,200,100,200,200);
QuadCurve2D.Double curve1 = new QuadCurve2D.Double(200,0,180,100,200,200);
QuadCurve2D.Double curve2 = new QuadCurve2D.Double(200,0,160,100,200,200);
//etc
g2d.setColor(Color.RED);
g2d.draw(curve);
g2d.draw(curve1);
g2d.draw(curve2);
g2d.drawOval(100,100,200,200);
g2d.drawArc(100,100, 100, 200, 90, 180);
g2d.drawArc(100, 100, 100, 200, 180, 360);
g2d.drawArc(100, 100, 0, 200, 90, 180);
g2d.drawRect(100, 100, 200, 200);

If you need bold lines, try so:
....
Graphics2D g2d = (Graphics2D)g;
BasicStroke pen1 = new BasicStroke(5); // this is stroke with 5px width,
g2d.setStroke(pen1);
g2d.drawArc(100,100, 100, 200, 90, 180);
g2d.drawArc(100, 100, 100, 200, 180, 360);
...
Make 2 strokes for two types of lines, and use it.

Im not sure if this is an really an answer - but have I have run into a resolution problem. I have tried anti-aliasing but it looked worse.
One way you could do it is in the for loop put an if statement for odd and even numbers.Happy for some advice on this, I was thinking there maybe a better library to get nicer circles.
Maybe I'm doing it the old school way?
import java.awt.*;
import javax.swing.*;
public class Stereonet{
private static int centreX, centreY, radius;
private Color colour;
/**Stereonet template contructor takes 3 int parameters
* x, y for centre position and radius for stereonet radius*/
public Stereonet(int x , int y, int radius, Color colour){
centreX = x;
centreY = y;
this.radius = radius;
this.colour = colour;
}
public void draw(Graphics g){
Graphics2D g2D = (Graphics2D) g;
g2D.setStroke(new BasicStroke(2F));
g.setColor(colour);
g.drawOval(centreX - radius , centreY - radius, radius * 2 , radius * 2);
g2D.setStroke(new BasicStroke(1F));
g.drawLine(centreX, centreY - radius, centreX, centreX + radius);
g.drawLine(centreX - radius, centreY, centreX + radius, centreY);
g2D.setStroke(new BasicStroke(1F));
for(int degrees = 10; degrees <= 80; degrees += 10){
double greatRadius = radius / (Math.cos(Math.toRadians(degrees))); // radius of great circle
int greatX1 = (int)Math.round(centreX + radius * (Math.tan(Math.toRadians(degrees)))
- greatRadius); // x coord of great circle left hemisphere
int greatX2 = (int)Math.round(centreX - (radius * (Math.tan(Math.toRadians(degrees))))
- greatRadius); // x coord of great circle right hemisphere
int greatY = (int)Math.round(centreY - greatRadius); // y coord of great circle
double smallRadius = (radius / (Math.tan(Math.toRadians(degrees))));
int smallY1 = (int)Math.round((centreY - (radius / (Math.sin(Math.toRadians(degrees)))) - smallRadius));
int smallY2 = (int)Math.round((centreY + (radius / (Math.sin(Math.toRadians(degrees)))) - smallRadius));
int smallX = (int)Math.round(centreX - smallRadius);
g.drawArc(greatX1, greatY, 2 * (int)Math.round(greatRadius), 2 * (int)Math.round(greatRadius),
90 + degrees, 180 - ( 2 * degrees));
g.drawArc(greatX2, greatY, 2 * (int)Math.round(greatRadius), 2 * (int)Math.round(greatRadius),
270 + degrees, 180 - ( 2 * degrees));
g.drawArc(smallX, smallY1, 2 * (int)Math.round(smallRadius), 2 * (int)Math.round(smallRadius),
270 - degrees, 180 - ( 2 * (90 - degrees)));
g.drawArc(smallX, smallY2, 2 * (int)Math.round(smallRadius), 2 * (int)Math.round(smallRadius),
90 - degrees, 180 - ( 2 * (90 - degrees)));
}
}
public static int getRadius(){
return radius;
}
public static int getX(){
return centreX;
}
public static int getY(){
return centreY;
}

Related

How to make a shape that follows the cursor, without setting the background to the draw function in Java?

I'm working on a basic Java project in Processing for school. It's a simple doodling program that makes random shapes when you click and drag. I am happy with how it has turned out so far, but I want the shape to appear and follow the cursor before the user clicks, so they can see what shape it is before it gets drawn onto the background. Most of the pertinent advice I could find elsewhere involved having the background in the draw function, but since the point is for the user to create a persistent picture (until they choose to reset it), that does not really work with my current setup as far as I can tell. Is there some other way to create a shape that follows the cursor? Or would I have to rework some or all of the code?
The code is set to determine the value of shape at random when the program is first ran and when the mouse is released, and then print whichever shape when the mouse is clicked and dragged, so I pretty much need to find a way to make that shape appear and follow the cursor before it is clicked and changed. I'm basically new to Java so I am not familiar with possible options to explore for achieving this. Any advice is greatly appreciated!
The whole program is only 70 lines, so here it is in its entirety minus the .wav files for the sound effects:
`
import processing.sound.*;
SoundFile file;
SoundFile fileb;
float x;
float y;
float w;
float h;
float r;
float b;
float g;
float re;
float gr;
float bl;
float shape = random(0, 30);
float c;
void setup() {
size(640, 360);
re = random(0, 256);
gr = random(0, 256);
bl = random(0, 256);
background(re, gr, bl);
rectMode (CENTER);
noStroke();
file = new SoundFile(this,"whoosh.wav");
fileb = new SoundFile(this,"pen.wav");
file.amp(.2);
fileb.amp(.15);
}
void draw() {
if (mousePressed) {
if (shape < 10) {
rect (mouseX, mouseY, w, h);
}
if (shape >= 20) {
ellipse(mouseX, mouseY, w, h);
}
if (shape >= 10 && shape < 20) {
triangle(mouseX - (w / 2), mouseY + (h / 2), mouseX + (w / 2), mouseY + (h / 2), mouseX, mouseY - (h / 2));
}
}
}
void mousePressed() {
c = random(0, 17);
fileb.cue(c);
fileb.play();
w = random(5, 125);
h = random(5, 125);
r = random(0, 256);
g = random(0, 256);
b = random(0, 256);
fill(r, g, b);
}
void mouseReleased() {
fileb.stop();
shape = random(0, 30);
}
void keyPressed() {
re = random(0, 256);
gr = random(0, 256);
bl = random(0, 256);
background(re, gr, bl);
file.play();
}
`

Rotation of collision bounds

I'm working on my 2D java game and I have a problem with rotation of collision bounds.
I have an Attack Class:
public void render(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
AffineTransform old = g2d.getTransform();
g2d.rotate(Math.toRadians(player.getDir()), (double) player.getX() + 16, (double) player.getY() + 16);
g2d.setComposite(makeTransparent(alpha));
g.setColor(Color.gray);
g.fillRect((int) x, (int) y, 32, 32);
g2d.setComposite(makeTransparent(1));
g.setColor(Color.red); // drawing the results
g2d.draw(getBounds()); // drawing the getBounds();
g2d.setTransform(old);
}
private AlphaComposite makeTransparent(float alpha) {
int type = AlphaComposite.SRC_OVER;
return (AlphaComposite.getInstance(type, alpha));
}
public Rectangle getBounds() {
return new Rectangle((int) x, (int) y, (int) width + 32, (int) height + 32);
}
But in practice it only "deals damage" to the right of the character - like no rotation happens. I was trying to use:
https://stackoverflow.com/a/5925715/5502471
solution, but I kinda failed and not sure what I'm doing wrong.
Few hints:
Attack is a seperate class,
Attack is caused from a Player Class by Keyboard input,
Collision happens in enemy class,
if (tempObject.getId() == ID.Attack){
if (getBounds().intersects(tempObject.getBounds())){
health-=3;
}
}
I was looking for some "easy" way to do it, since I was hoping to use this in many many things ;) If there is no easy way, then the hard way will do too - challenge accepted!
I found a pretty simple solution (somewhere at stackoverlow.com ;P). It's not perfect but, well, at least it works ;). Just useing a method to move around the starting point of drawing the rectangle bounds.
public Rectangle getBounds() {
double newX = 0;
double newY = 0;
Rectangle attack = new Rectangle((int) newX, (int) newY, 32, 32);
double[] pt = { x, y };
AffineTransform
.getRotateInstance(Math.toRadians(player.getDir()), (double) player.getX(), (double) player.getY())
.transform(pt, 0, pt, 0, 1);
//playeer.getDir() - method to return the rotation angle in degress
newX = pt[0];
newY = pt[1];
attack = new Rectangle((int) newX, (int) newY, 32, 32);
return attack;
}
Results
I hope you find out it usefull. Cheers!

Java draw circle and lines on Swing

I'm trying to draw a circle with a random center inside a big bigger circular surface. (I'm actually trying to simulate a human and his eyesight inside a room!) I need to draw a random line (call it line1) passing through its center which will intersect with the surface. line1 does not necessarily pass the center of circular surface. I also need to draw two lines forming 60 degree, facing on one side of line1. Can anyone help me with that?
I created an example of what I need to draw.
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;
import javax.swing.JFrame;
public class ShapeTest extends JFrame{
int width=500;
int height=500;
public ShapeTest(){
setSize(width,height);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String a[]){
new ShapeTest();
}
public void paint(Graphics g){
// Circular Surface
drawCircleByCenter(g, width/2, height/2, width/2);
Random r = new Random();
Point center = new Point();
center.x=r.nextInt(width/2);
center.y=r.nextInt(width/2);
drawCircleByCenter(g, center.x, center.y, width/15);
}
void drawCircleByCenter(Graphics g, int x, int y, int radius){
//g.setColor(Color.LIGHT_GRAY);
g.drawOval(x-radius, y-radius, 2*radius, 2*radius);
}
}
Start by changing your method to draw a circle based on its center and radius to a method which returns a Ellipse2D object representing the circle. This will allow us to do some clipping and other things with the shape besides just draw it.
Setting the clip to be the shape of your large circle prevents stray marks from being made where you don't want them (think "color inside the lines"). This is important because when we draw the circles and lines inside the big circle, some of them will be too big and would otherwise mark outside the bounds of the big circle.
Once we set the clip, we use the method Line2D getVector(Point2D, double, length) with an origin at the center of the large circle, a random angle and a random length (capped to keep the small blue circle inside the big circle). Think of this a random polar coordinate with the center of the large circle as the origin. The end point of this vector is used to mark the center of the small circle.
Using the center of the small circle as a starting point, we can generate two vectors in opposite directions (just negate the length of one to get it going the other direction) by using a random direction angle. We use a length equal to the diameter of the big circle to make certain that the lines will always go all the way up to the edge of the big circle (but not past, thanks to our clip).
We simply add 60 and 120 degrees to the angle of our blue dashed line and draw two green lines calculating the vectors the same way we did for the two blue dashed lines, except we don't need to create ones with negated lengths. We can also add a normal vector in for good measure simply by adding 90 degrees to the angle of the blue dashed line.
Lastly, we pick some random polar coordinates (just like we did for the small blue circle) to represent some people, and using the intersection of the people with the areas created by the various lines, we can see where they are at and draw them up with color coded values.
Now that we have all the people, we eliminate the clip and draw the big circle and voila!
Check out Draw a line at a specific angle in Java for details on how I calculated the vectors for the lines.
But enough talk, here's the code:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ShapeTest extends JFrame {
private static final long serialVersionUID = 1L;
private int width = 500;
private int height = 500;
private int padding = 50;
private BufferedImage graphicsContext;
private JPanel contentPanel = new JPanel();
private JLabel contextRender;
private Stroke dashedStroke = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 2f, new float[] {3f, 3f}, 0f);
private Stroke solidStroke = new BasicStroke(3.0f);
private RenderingHints antialiasing;
private Random random = new Random();
public static void main(String[] args) {
//you should always use the SwingUtilities.invodeLater() method
//to perform actions on swing elements to make certain everything
//is happening on the correct swing thread
Runnable swingStarter = new Runnable()
{
#Override
public void run(){
new ShapeTest();
}
};
SwingUtilities.invokeLater(swingStarter);
}
public ShapeTest(){
antialiasing = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphicsContext = new BufferedImage(width + (2 * padding), width + (2 * padding), BufferedImage.TYPE_INT_RGB);
contextRender = new JLabel(new ImageIcon(graphicsContext));
contentPanel.add(contextRender);
contentPanel.setSize(width + padding * 2, height + padding * 2);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setContentPane(contentPanel);
//take advantage of auto-sizing the window based on the size of its contents
this.pack();
this.setLocationRelativeTo(null);
this.paint();
setVisible(true);
}
public void paint() {
Graphics2D g2d = graphicsContext.createGraphics();
g2d.setRenderingHints(antialiasing);
//Set up the font to print on the circles
Font font = g2d.getFont();
font = font.deriveFont(Font.BOLD, 14f);
g2d.setFont(font);
FontMetrics fontMetrics = g2d.getFontMetrics();
//clear the background
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, graphicsContext.getWidth(), graphicsContext.getHeight());
//set up the large circle
Point2D largeCircleCenter = new Point2D.Double((double)width / 2 + padding, (double)height / 2 + padding);
double largeCircleRadius = (double)width / 2;
Ellipse2D largeCircle = getCircleByCenter(largeCircleCenter, largeCircleRadius);
//here we build the small circle
Point2D smallCircleCenter = new Point2D.Double();
double smallCircleRadius = 15;
//we need to make certain it is confined inside the larger circle
//so we choose the following values carefully
//we want to go a random direction from the circle, so chose an
//angle randomly in any direction
double smallCenterVectorAngle = random.nextDouble() * 360.0d;
//and we want to be a random distance from the center of the large circle, but
//we limit the distance based on the radius of the small circle to prevent it
//from appearing outside the large circle
double smallCenterVectorLength = random.nextDouble() * (largeCircleRadius - smallCircleRadius);
Line2D vectorToSmallCenter = getVector(largeCircleCenter, smallCenterVectorAngle, smallCenterVectorLength);
//the resulting end point of the vector is a random distance from the center of the large circle
//in a random direction, and guaranteed to not place the small circle outside the large
smallCircleCenter.setLocation(vectorToSmallCenter.getP2());
Ellipse2D smallCircle = getCircleByCenter(smallCircleCenter, smallCircleRadius);
//before we draw any of the circles or lines, set the clip to the large circle
//to prevent drawing outside our boundaries
g2d.setClip(largeCircle);
//chose a random angle for the line through the center of the small circle
double angle = random.nextDouble() * 360.0d;
//we create two lines that start at the center and go out at the angle in
//opposite directions. We use 2*largeCircleRadius to make certain they
//will be large enough to fill the circle, and the clip we set prevent stray
//marks outside the big circle
Line2D centerLine1 = getVector(smallCircleCenter, angle, largeCircleRadius * 2);
Line2D centerLine2 = getVector(smallCircleCenter, angle, -largeCircleRadius * 2);
//now we just add 20 and 120 to our angle for the center-line, start at the center
//and again, use largeCircleRadius*2 to make certain the lines are big enough
Line2D sightVector1 = getVector(smallCircleCenter, angle + 60, largeCircleRadius * 2);
Line2D sightVector2 = getVector(smallCircleCenter, angle + 120, largeCircleRadius * 2);
Path2D visible = new Path2D.Double();
visible.moveTo(sightVector1.getX2(), sightVector1.getY2());
visible.lineTo(smallCircleCenter.getX(), smallCircleCenter.getY());
visible.lineTo(sightVector2.getX2(), sightVector2.getY2());
visible.closePath();
Path2D greenSide = new Path2D.Double();
greenSide.moveTo(centerLine1.getX2(), centerLine1.getY2());
greenSide.lineTo(smallCircleCenter.getX(), smallCircleCenter.getY());
greenSide.lineTo(centerLine2.getX2(), centerLine2.getY2());
greenSide.lineTo(sightVector1.getX2(), sightVector1.getY2());
greenSide.closePath();
int personCount = 5;
Area visibleArea = new Area(visible);
visibleArea.intersect(new Area(largeCircle));
Area greenSideArea = new Area(greenSide);
greenSideArea.intersect(new Area(largeCircle));
//we create a list of the people in the circle to
//prevent overlap
ArrayList<Shape> people = new ArrayList<Shape>();
people.add(smallCircle);
int i = 0;
personLoop: while (i < personCount){
double personCenterVectorAngle = random.nextDouble() * 360.0d;
double personCenterVectorLength = random.nextDouble() * (largeCircleRadius - smallCircleRadius);
Line2D vectorToPersonCenter = getVector(largeCircleCenter, personCenterVectorAngle, personCenterVectorLength);
Point2D personCircleCenter = vectorToPersonCenter.getP2();
Ellipse2D personCircle = getCircleByCenter(personCircleCenter, smallCircleRadius);
//this little loop lets us skip a person if they have overlap
//with another person, since people don't generally overlap
Area personArea = new Area(personCircle);
for (Shape person : people)
{
Area overlapArea = new Area(person);
overlapArea.intersect(personArea);
//this means that we have found a conflicting
//person, so should skip them
if (!overlapArea.isEmpty()){
continue personLoop;
}
}
people.add(personCircle);
personArea.intersect(visibleArea);
Area greenSideAreaTest = new Area(personCircle);
greenSideAreaTest.intersect(greenSideArea);
if (personArea.isEmpty()){
if (greenSideAreaTest.isEmpty()){
g2d.setColor(Color.orange);
System.out.println("Person " + i + " is behind the blue line");
}
else {
System.out.println("Person " + i + " is in front of the blue line");
g2d.setColor(Color.cyan);
}
}
else
{
System.out.println("Person " + i + " is between the green lines");
g2d.setColor(Color.magenta);
}
//alternatively to circles intersecting the area of interest, we can check whether the center
//is in the area of interest which may make more intuitive sense visually
// if (visibleArea.contains(personCircleCenter)){
// System.out.println("Person " + i + " is between the green lines");
// g2d.setColor(Color.magenta);
// }
// else {
// if (greenSideArea.contains(personCircleCenter)) {
// System.out.println("Person " + i + " is in front of the blue line");
// g2d.setColor(Color.cyan);
// }
// else{
// g2d.setColor(Color.orange);
// System.out.println("Person " + i + " is behind the blue line");
// }
// }
g2d.fill(personCircle);
g2d.setColor(Color.black);
String itemString = "" + i;
Rectangle2D itemStringBounds = fontMetrics.getStringBounds(itemString, g2d);
double textX = personCircleCenter.getX() - (itemStringBounds.getWidth() / 2);
double textY = personCircleCenter.getY() + (itemStringBounds.getHeight()/ 2);
g2d.drawString("" + i, (float)textX, (float)textY);
i++;
}
//fill the small circle with blue
g2d.setColor(Color.BLUE);
g2d.fill(smallCircle);
//draw the two center lines lines
g2d.setStroke(dashedStroke);
g2d.draw(centerLine1);
g2d.draw(centerLine2);
//create and draw the black offset vector
Line2D normalVector = getVector(smallCircleCenter, angle + 90, largeCircleRadius * 2);
g2d.setColor(Color.black);
g2d.draw(normalVector);
//draw the offset vectors
g2d.setColor(new Color(0, 200, 0));
g2d.draw(sightVector1);
g2d.draw(sightVector2);
//we save the big circle for last, to cover up any stray marks under the stroke
//of its perimeter. We also set the clip back to null to prevent the large circle
//itselft from accidentally getting clipped
g2d.setClip(null);
g2d.setStroke(solidStroke);
g2d.setColor(Color.BLACK);
g2d.draw(largeCircle);
g2d.dispose();
//force the container for the context to re-paint itself
contextRender.repaint();
}
private static Line2D getVector(Point2D start, double degrees, double length){
//we just multiply the unit vector in the direction we want by the length
//we want to get a vector of correct direction and magnitute
double endX = start.getX() + (length * Math.sin(Math.PI * degrees/ 180.0d));
double endY = start.getY() + (length * Math.cos(Math.PI * degrees/ 180.0d));
Point2D end = new Point2D.Double(endX, endY);
Line2D vector = new Line2D.Double(start, end);
return vector;
}
private static Ellipse2D getCircleByCenter(Point2D center, double radius)
{
Ellipse2D.Double myCircle = new Ellipse2D.Double(center.getX() - radius, center.getY() - radius, 2 * radius, 2 * radius);
return myCircle;
}
}
The logic of the geometry turned out to be more tricky than I'd presumed, but this is what I think you are after.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
class HumanEyesightLines {
int rad = 150;
int radSmall = 15;
int pad = 10;
JPanel gui = new JPanel(new BorderLayout());
BufferedImage img = new BufferedImage(
2 * (rad + pad),
2 * (rad + pad),
BufferedImage.TYPE_INT_RGB);
Timer timer;
JLabel imgDisplay;
Random rnd = new Random();
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
HumanEyesightLines() {
imgDisplay = new JLabel(new ImageIcon(img));
gui.add(imgDisplay);
File f = new File(System.getProperty("user.home"));
final File f0 = new File("HumanEyesiteLines");
f0.mkdirs();
try {
Desktop.getDesktop().open(f0);
} catch (IOException ex) {
ex.printStackTrace();
}
ActionListener animationListener = new ActionListener() {
int ii = 0;
#Override
public void actionPerformed(ActionEvent e) {
paintImage();
ii++;
if (ii < 100) {
System.out.println(ii);
File f1 = new File(f0, "eg" + ii + ".png");
try {
ImageIO.write(img, "png", f1);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
};
timer = new Timer(100, animationListener);
paintImage();
}
float[] dash = {3f, 3f};
float phase = 0f;
private final void paintImage() {
Graphics2D g = img.createGraphics();
g.setRenderingHints(rh);
g.setStroke(new BasicStroke(2f));
// fill the BG
g.setColor(Color.WHITE);
g.fillRect(0, 0, 2 * (rad + pad), 2 * (rad + pad));
// draw the big circle
Point center = new Point(rad + pad, rad + pad);
Shape bigCircle = new Ellipse2D.Double(pad, pad, 2 * rad, 2 * rad);
g.setColor(Color.MAGENTA.darker());
g.fill(bigCircle);
// set the clip to that of the big circle
g.setClip(bigCircle);
// draw the small circle
int xOff = rnd.nextInt(rad) - rad / 2;
int yOff = rnd.nextInt(rad) - rad / 2;
int x = center.x - xOff;
int y = center.y - yOff;
Shape smallCircle = new Ellipse2D.Double(
x - radSmall, y - radSmall,
2 * radSmall, 2 * radSmall);
g.setColor(Color.YELLOW);
g.fill(smallCircle);
g.setColor(Color.ORANGE);
g.draw(smallCircle);
g.setStroke(new BasicStroke(
1.5f,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND,
2f,
dash,
phase));
// I don't know what the rule is for where the blue line goes, so
// will use the top left corner of the image as a 2nd anchor point.
int x0 = 0;
int y0 = 0;
double grad = (double) (y - y0) / (double) (x - x0);
// now calculate the RHS point from y = mx + b
// where b = 0 and m is the gradient
int x1 = 2 * (pad + rad);
int y1 = (int) (grad * x1);
Line2D.Double line1 = new Line2D.Double(x0, y0, x1, y1);
g.setColor(Color.BLUE);
g.draw(line1);
//find the perpendicular gradient.
double perpGrad = -1d / grad;
double perpTheta = Math.atan(perpGrad);
// angle from perp
double diffTheta = Math.PI / 6d;
g.setColor(Color.GREEN);
double viewLine1Theta = perpTheta + diffTheta;
Line2D.Double viewLine1 = getLine(x, y, viewLine1Theta);
double viewLine2Theta = perpTheta - diffTheta;
Line2D.Double viewLine2 = getLine(x, y, viewLine2Theta);
g.draw(viewLine1);
g.draw(viewLine2);
g.setColor(Color.BLACK);
Line2D.Double viewPerp = getLine(x, y, perpTheta);
g.draw(viewPerp);
g.setColor(Color.RED);
g.draw(bigCircle);
g.dispose();
imgDisplay.repaint();
}
/**
* Returns a Line2D starting at the point x1,y1 at angle theta.
*/
private final Line2D.Double getLine(double x1, double y1, double theta) {
double m;
double b;
double x2;
double y2;
if (theta < (-Math.PI / 2d)) {
System.out.println("CHANGE IT! " + theta);
m = Math.tan(theta);
b = y1 - (m * x1);
x2 = 0;
y2 = (m * x2) + b;
} else {
m = Math.tan(theta);
b = y1 - (m * x1);
x2 = 2 * (rad + pad);
y2 = (m * x2) + b;
}
/*
* System.out.println("Perp theta: " + theta); System.out.println("Line
* grad: " + m); System.out.println("Line off: " + b);
* System.out.println("x1,y1: " + x1 + "," + y1);
* System.out.println("x2,y2: " + x2 + "," + y2);
*
*/
return new Line2D.Double(x1, y1, x2, y2);
}
public JComponent getGui() {
return gui;
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
HumanEyesightLines hel = new HumanEyesightLines();
hel.start();
JOptionPane.showMessageDialog(null, hel.getGui());
hel.stop();
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}

The formula that I have in my code which is causing the error is the formula that was given for the assignment

//The error message I'm getting is saying "cannot find symbol- method second(double)
but I feel as though I have identified everything already. (I'm clearly wrong). I think there is a problem with the formula as well but that is the code I was given for the formula. Any help would be greatly appreciated.
import java.util.GregorianCalendar;
import javax.swing.JComponent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.*;//import * Class
public class ClockComponent extends JComponent
{
double hour;
double minute;
double second;
public void setCurrentTime()
{
GregorianCalendar calendar = new GregorianCalendar();
hour = calendar.get(calendar.HOUR_OF_DAY);
minute = calendar.get(calendar.MINUTE);
second = calendar.get(calendar.SECOND);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int xCoord = 40;
int yCoord = 25;
Ellipse2D.Double clockFace = new Ellipse2D.Double(xCoord, yCoord, 700, 700);
g2.setColor(Color.black);
g2.draw(clockFace);
g2.fill(clockFace);
g2.setColor(Color.red);
Font font1 = new Font("Old English Text MT",Font.BOLD,30);
g2.setFont(font1);
g2.drawString("John Doe", 305, 680);
g2.setColor(Color.yellow);
Font font2 = new Font("Arial",Font.BOLD,30);
g2.setFont(font2);
g2.drawString("III", xCoord + 670, yCoord + 355);
g2.drawString("VI", xCoord + 340, yCoord + 685);
g2.drawString("IX", xCoord + 10, yCoord + 355);
g2.drawString("XII", xCoord + 340, yCoord + 35);
int xCenter = 380;
int yCenter = 380;
double secondHandLength;
double minuteHandLength;
double hourHandLength;
double xSecond = xCenter + secondHandLength; cos(second (2*Math.PI/60));
double ySecond = yCenter - secondHandLength; sin(second (2*Math.PI/60));
double xMinute = xCenter + minuteHandLength; cos(2*Math.PI/60);
double yMinute = yCenter - minuteHandLength; sin(2*Math.PI/60);
double xHour = xCenter + hourHandLength; cos(2*Math.PI/60);
double yHour = yCenter - hourHandLength; sin(2*Math.PI/60);
g2.setColor(Color.blue);
Line2D.Double secHand = new Line2D.Double(xCenter,yCenter,xSecond,ySecond);
g2.setStroke(new BasicStroke(1));
g2.draw(secHand);
Line2D.Double minHand = new Line2D.Double(xCenter,yCenter,xMinute,yMinute);
g2.setStroke(new BasicStroke(7));
g2.draw(minHand);
Line2D.Double hourHand = new Line2D.Double(xCenter,yCenter,xHour,yHour);
g2.setStroke(new BasicStroke(13));
g2.draw(hourHand);
}
}
This probably isn't what you want:
(second (2*Math.PI/60))
Java is going to treat second as a method call, as it is immediately followed by an open-paren, with some value in it. Since that function doesn't exist, Java produces that compilation error.
If you were trying to get the product of the two, you have to explicitly provide the multiplication operator.
(second * (2*Math.PI/60))
EDIT: Now that I've had a moment to look at it, these statements also don't make sense:
double xSecond = xCenter + secondHandLength; cos(second (2*Math.PI/60));
Assuming the call to cos was valid, secondHandLength isn't defined anywhere. What's more, you're dropping the result of your calculation on the floor, which isn't what you likely intend to do. I'm not sure what a sane value would be for them, since they seem independent of the cosine of a circle, but those variables need to be defined.
I believe you are missing a multiplication symbol in the xSecond and ySecond calculation. Should be this:
double xSecond = xCenter + secondHandLength; cos(second * (2*Math.PI/60));
double ySecond = yCenter - secondHandLength; sin(second * (2*Math.PI/60));

How to rotate a series of lines and shapes drawn in drawing Panel?

I am wondering how to rotate things I have already drawn (like lines) in Java drawing Panel (not in JPanel).
I am trying to rotate a triangle i created by connecting 3 lines:
g.drawLine(size, size, 2*size, size);
g.drawLine(size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
g.drawLine(2*size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
How do I rotate that?
If you want to rotate a point like that, then you could:
double startX; // <------------|
double startY; // <------------|
double endX; // <------------|
double endY; // <-define these
double angle; // the angle of rotation in degrees
To draw the original line
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX, endY); //this is the original line
double length = Math.pow(Math.pow(startX-endX,2)+Math.pow(startY-endY,2),0.5);
double xChange = length * cos(Math.toRadians(angle));
double yChange = length * sin(Math.toRadians(angle));
To draw the new, rotated line
g.setColor(Color.GRAY);
g.fillRect(0,0,1000,1000); //paint over it
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX + xChange, endY + yChange);
Use graphics2D and Polygons
Graphics2D g2 = (Graphics2D) g;
int x2Points[] = {0, 100, 0, 100}; //these are the X coordinates
int y2Points[] = {0, 50, 50, 0}; //these are the Y coordinates
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length);
polyline.moveTo (x2Points[0], y2Points[0]);
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
};
g2.draw(polyline);
If you want to rotate it, just do it over but add, before
g2.rotate(Math.toRadians(angle), centerX, centerY);
Where "angle" is the amount you want to rotate it and (centerX, centerY) are the coordinates of the point you want to rotate it around.
I hope this helps

Categories