I have a diagonal line and I have also a circles having a 100 meters in distance. The problem is that the circles are not really to the center of the line. I know this is quiet easy but I'm just confused on how to do it.. Could someone help me how to put the circles at the center of the line?
Here's what I've tried so far :
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setBackground(Color.white);
int x0_pixel = 0;
int y0_pixel = 0;
int x1_pixel = getWidth();
int y1_pixel = getHeight();
int x0_world = 0;
int y0_world = 0;
double x1_world = 2000; // meters
double y1_world = 1125; // meters
double x_ratio = (double) x1_pixel / x1_world;
double y_ratio = (double) y1_pixel / y1_world;
int xFrom = 0;
int yFrom = 0;
double xTo = x1_world;
double yTo = y1_world;
int FromX_pixel = convertToPixelX(xFrom, x_ratio);
int FromY_pixel = convertToPixelY(y1_pixel, yFrom, y_ratio);
int ToX_pixel = convertToPixelX((int) xTo, x_ratio);
int ToY_pixel = convertToPixelY(y1_pixel, (int) yTo, y_ratio);
g2d.setColor(Color.RED);
g2d.drawLine(FromX_pixel, FromY_pixel, ToX_pixel, ToY_pixel);
double theta = Math.atan(yTo / xTo);
int len = (int) Math.sqrt(xTo * xTo + yTo * yTo);
int interval = 100;
final double cosTheta = Math.cos(theta);
final double sinTheta = Math.sin(theta);
for (int distance = xFrom; distance <= len; distance += interval)
{
double distance_x = distance * cosTheta;
double distance_y = distance * sinTheta;
int x_circle_pixel = convertToPixelX(distance_x, x_ratio);
int y_circle_pixel = convertToPixelY(y1_pixel, distance_y, y_ratio);
g2d.drawOval(x_circle_pixel, y_circle_pixel, 50, 50);
g2d.setColor(Color.BLUE);
}
Toolkit.getDefaultToolkit().
sync();
g2d.dispose();
}
private static int convertToPixelY(int y_offset, double y_world, double y_ratio)
{
return (int) (y_offset - (y_world * y_ratio));
}
private static int convertToPixelX(double x_world, double x_ratio)
{
return (int) (x_world * x_ratio);
}
When you draw an oval, the first two parameters are the upper-left corner of the rectangle that holds the oval. The next two parameters are the width and height of this same bounding rectangle. Your current code places the upper-left corner on the line itself, but what you actually want is that the center of the bounding rectangle be placed on the line. The solution to your problem is to simply shift the upper-left corner over by 1/2 the diameter. Your code should have something like so:
public class GraphicsFoo extends JPanel {
// avoid using magic numbers:
private static final int CIRCLE_DIAMETER = 50;
//....
// override a JComponent's paintComponent method, not its paint method
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setBackground(Color.white);
// make your graphics smooth
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// ...
final double cosTheta = Math.cos(theta);
final double sinTheta = Math.sin(theta);
for (int distance = xFrom; distance <= len; distance += interval)
{
//....
// *** here's the key: ***
g2d.drawOval(
x_circle_pixel - CIRCLE_DIAMETER / 2,
y_circle_pixel - CIRCLE_DIAMETER / 2,
CIRCLE_DIAMETER, CIRCLE_DIAMETER);
g2d.setColor(Color.BLUE);
}
Related
I'm trying to get the map to paint the set scaleX left side by 180 to 360 longitude and the right side 0 to 180 but I'm abit unsure on a way to make convert these coordinates around as I can't add extra parameters to filRect as I'm only allowed 4 parameters. If I set ScaleX to 0, 360 I get the map the wrong way round. I have 2 classes Plot and Plotmap
My plot class
import javax.swing.*;
import java.awt.*;
public class Plot extends JComponent {
int width = 1200, height = 1200;
double xmin = 0, xmax = 1, ymin = 0, ymax = 1, lmin = 0, lmax = 180;
public int scaleX(double x){
return (int) (width * (x - xmin) / (xmax + xmin));
}
public int scaleY ( double y){
return (int) (height * (ymin - y) / (ymax - ymin) + height);
}
public void setScaleX ( double min, double max){
xmin = min;
xmax = max;
}
public void setScaleY ( double min, double max){
ymin = min;
ymax = max;
}
}
My plot map class
public class Plotmap extends Plot {
Earth e;
int point = 20;
public Plotmap(String filename) throws FileNotFoundException {
e = new Earth();
e.readDataArray(filename);
setScaleX(0, 360);
setScaleY(-90, 90);
//setScaleXR(180, 360);
//setScaleYR(-90, 90);
}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
this.width = getWidth();
this.height = getHeight();
for (int i = 0; i < e.array.length; i++) {
double longitude = e.array[i][0];
double latitude = e.array[i][1];
double alti = e.array[i][2];
if (alti < 0)
g2d.setColor(new Color(0, 90, 139));
else
g2d.setColor(new Color(0, 0, 139));
g.fillRect(scaleX(longitude), scaleY(latitude), point, point);
}
}
}
I am having some trouble graphing a simple polar equation. The equation is r = cos(3Ѳ). I want to plot each r as theta increments, but instead, I am getting a linear line when it should be something like a 3 petal flower.
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
double dt = Math.PI / 720;
int w = getWidth() / 2;
int h = getHeight() / 2;
path.reset();
path.moveTo(w, h);
for (double t = 0; t < 6 * Math.PI; t += dt) {
double r = Math.cos(3*t);
double x = r * Math.cos(t);
double y = r * Math.sin(t);
path.lineTo(x, y);
}
g2d.setColor(Color.blue);
g2d.draw(path);
}
I have a drawShapeAt method in a class that should print a shape at a given location
#Override
public void drawShapeAt(int x, int y) {
try {
canvas.removeMouseListener(ml);
} catch (Exception e) {
}
polygon = new RegularPolygon(x, y, Integer.parseInt(polygonRadius), Integer.parseInt(polygonLines));
BufferedImage image = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
Random rand = new Random();
graphics.setColor(new Color(rand.nextInt(0xFFFFFF)));
graphics.fill(polygon);
System.out.println("Painting polygon..");
canvas.paintComponents(graphics);
}
}
If I write for example canvas.setBackground it will change the background, yet it will not print the shape. My RegularPolygon is as follows:
public class RegularPolygon extends Polygon {
public RegularPolygon(int x0, int y0, int radius, int sides) {
double alpha = 2 * Math.PI / sides;
for (int i = 0; i < sides; i++) {
double x = x0 + radius * Math.cos(alpha * i);
double y = y0 + radius * Math.sin(alpha * i);
this.addPoint((int) x, (int) y);
}
}
}
I checked for wrong variables, but all are ok (x,y, polygonRadius, polygonLines).
I'm having trouble finding what's wrong with my program. When I execute it, it appears to get stuck into an infinite loop (or something similar) and I can't figure out what's wrong with my program. Here's what I have so far:
public class Spiral extends JComponent{
int WIDTH = 0;
int HEIGHT = 0;
public Spiral(int WIDTH, int HEIGHT) {
this.WIDTH = WIDTH;
this.HEIGHT = HEIGHT;
}
public void paintSpiral(Graphics g){
double a = 3;
double b = 0;
double t = 0;
double theta = Math.toRadians(t);
double r = theta * a + b;
double pi = Math.PI/180;
double end = 720 * pi;
int middle_x = WIDTH / 2;
int middle_y = HEIGHT / 2;
for (theta = 0; theta < end; theta += pi) {
double x = Math.cos(theta) * r + middle_x;
double y = Math.sin(theta) * r + middle_y;
int xx = (int) Math.round(x);
int yy = (int) Math.round(y);
g.drawLine(xx, yy, xx + 10, yy + 20);
}
}
public void paintComponent(Graphics g) {
paintSpiral(g);
}
public static void main(String[] args) {
int WINDOW_WIDTH = 1024;
int WINDOW_HEIGHT = 1024;
JFrame frame = new JFrame();
frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
// Set the title of the window
frame.setTitle("Archimedean Spiral");
// Make a new Spiral, add it to the window, and make it visible
Spiral d = new Spiral(1024, 1024);
frame.add(d);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I have to use Graphics which is why I have the Math.round changing the x values to integers so I can actually draw the lines. That is what I suspect is the problem, but I can't seem to fix it. Any suggestions?
The loop variable t is of type int, so t += pi is effectively a no-op, resulting in an infinite loop.
t should be of type double. Furthermore, it should be local to paintSpiral and not a member of the class. I don't understand why you're using t (which is zero) to initialize r.
Also, your degrees and radians seem all confused.
I am creating line graph using outputs from a thread, the threads are simulations of incoming and outgoing bill that run over a course of 52 seconds and this will be dipicted on a line graph as shown below to show the bank balance over the 52 seconds!
The problem is I cannot seem to get the Y Axis calculating properly.
The code below show output the red marker at the top right hand side of the axis but it does not
public void paintComponent(Graphics g) {
int y = 10000; // balance
int x = 52 ; // weeks
int prevX, prevY;
int maxX = 52;
int maxY = 10000;
int Xleft = 200;
int Xright = 900;
int Ytop = 50;
int Ybottom = 330;// defining axis
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.BLUE);
BasicStroke pen = new BasicStroke(4F);
g2.setStroke(pen);
g2.drawLine(Xleft,Ytop,Xleft,Ybottom);
g2.drawLine(Xleft,280,Xright,280);
Font f = new Font("Serif", Font.BOLD, 14);
g2.setFont(f);
g2.drawString("Account Balance (£)", 35, 200);
g2.drawString("Elapsed Time (Weeks)", 475, 340);
//retrieve values from your model for the declared variables
//calculate the coords line on the canvas
double balance = (((double)y / maxY) * Y_AXIS_LENGTH) - Y_AXIS_OFFSET; //floating point arithmetic
double weeks = (((double)x / maxX) * X_AXIS_LENGTH) + X_AXIS_OFFSET;
int xPos = (int) Math.round (weeks);
int yPos = (int)Math.round(balance); // changing back to int to be used in drawing oval
g2.setColor(Color.RED);
g.drawOval( xPos, yPos, 2, 2);
System.out.println(xPos + " " + yPos);
}
Shouldn't this:
double balance = (((double)y / maxY) * Y_AXIS_LENGTH) - Y_AXIS_OFFSET;
be this?
double balance = Y_AXIS_OFFSET - (((double)y / maxY) * Y_AXIS_LENGTH);