Using Public Arrays in Different Classes - java

I am a beginning Java user and I am experiencing errors when using two public arrays in a different class. The program is supposed to model 3 interstellar bodies through mathematical integration. Note: I am new to this website and haven't been able to figure the formatting yet.
package gravitationalmodel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class GravitationalModel
{
private Object timer;
private GravitationalObject G1;
private GravitationalObject G2;
private GravitationalObject G3;
public static double[] xArray;
public static double[] yArray;
final public double gravConst = 0.000000000067;
final public int refreshRate = 25;
public GravitationalModel()
{
Timer timer = new Timer(refreshRate, (ActionListener) this); // refreshes model every 25 milliseconds
}
public static void main(String[] args)
{
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates 3 interstellar objects taking x position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y position, x veleocity component, y velocity component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass of the object
xArray = new double[1920]; // assigns all elements of array to 0
for (int x = 0; x < 1920; ++x)
{
xArray[x] = 0;
//System.out.println(xArray[x]);
}
yArray = new double[1200];
for (int x = 0; x < 1200; ++x)
{
yArray[x] = 0;
//System.out.println(yArray[x]);
}
}
public void actionPerformed(ActionEvent e) // refreshes model
{
G1.refreshVectorField();
G2.refreshVectorField();
G3.refreshVectorField();
G1.refreshObjects();
G2.refreshObjects();
G3.refreshObjects();
}
}
package gravitationalmodel;
public class GravitationalObject
{
private double xPos; //location and speed of gravitational object
private double yPos;
private double vX;
private double vY;
private double mass;
public GravitationalObject(double x, double y, double xv, double yv, double m)
{
xPos = x;
yPos = y;
vX = xv;
vY = yv;
mass = m;
}
public void refreshVectorField() // calculates gravitational field
{
int k = 1;
for (int x = 0; x < 1920; ++x)
{
if (xPos > x)
k = 1;
else
k= -1;
if (xPos - x == 0)
++x;
xArray[x] += k * (gravConst * mass) / Math.sqrt(xPos - x, 2.0); // errors on this line
}
for (int y = 0; y < 1200; ++y)
{
if (yPos < y)
k = 1;
else
k= -1;
yArray[y] += (gravConst * mass) / Math.sqrt(Math.abs(yPos - y), 2); //errors on this line
}
}
public void refreshObjects()
{
vX += refreshRate/1000 * xArray[xPos]; // errors on these lines
vY += refreshRate/1000 * yArray[yPos];
xPos += refreshRate/1000 * vX;
xPos += refreshRate/1000 * vX;
}
}

You are trying to access GravitationalModel.xArray from GravitationalObject without fully qualifying the static field. Either fully qualify the field, or create a method in GravitationalModel to do the work.
Note that public mutable fields are generally frowned upon in Java, because it breaks encapsulation. It's better to have your objects encapsulate data and behavior via methods, and keep the variables private.

As a beginner, you should not hurry. Soon you would be able to write cool programs. There are lot of errors in this program and even program does not make any logic. You should practice some small programs first to get basics. Like you created following objects which you are not using at all.
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates 3 interstellar objects taking x position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y position, x veleocity component, y velocity component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass of the object
Now comes to errors in program.
If you want to access instance variables gravConst or refreshRate in other class, you need to create object of class and access them.
or you can create them static and import them to class like this
import static gravitationalmodel.GravitationalModel.xArray;
import static gravitationalmodel.GravitationalModel.yArray;
import static gravitationalmodel.GravitationalModel.gravConst;
import static gravitationalmodel.GravitationalModel.refreshRate;
Math.sqrt(double) does not take 2 arguments so I think you want to use xArray[x] += k * (gravConst * mass) / Math.pow(xPos - x, 2.0);
and cast double to int as index of array can only be integer as follows
vX += refreshRate / 1000 * xArray[(int)xPos];
vY += refreshRate / 1000 * yArray[(int)yPos];
So your final program is below:
package gravitationalmodel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class GravitationalModel {
private Object timer;
private GravitationalObject G1;
private GravitationalObject G2;
private GravitationalObject G3;
public static double[] xArray;
public static double[] yArray;
final static public double gravConst = 0.000000000067;
final static public int refreshRate = 25;
public GravitationalModel() {
Timer timer = new Timer(refreshRate, (ActionListener) this); // refreshes
// model
// every
// 25
// milliseconds
}
public static void main(String[] args) {
GravitationalObject G1 = new GravitationalObject(500, 500, 10, 10, 10); // creates
// 3
// interstellar
// objects
// taking
// x
// position,
GravitationalObject G2 = new GravitationalObject(400, 400, 10, 10, 10); // y
// position,
// x
// veleocity
// component,
// y
// velocity
// component
GravitationalObject G3 = new GravitationalObject(600, 600, 10, 10, 10); // mass
// of
// the
// object
xArray = new double[1920]; // assigns all elements of array to 0
for (int x = 0; x < 1920; ++x) {
xArray[x] = 0;
// System.out.println(xArray[x]);
}
yArray = new double[1200];
for (int x = 0; x < 1200; ++x) {
yArray[x] = 0;
// System.out.println(yArray[x]);
}
}
public void actionPerformed(ActionEvent e) // refreshes model
{
G1.refreshVectorField();
G2.refreshVectorField();
G3.refreshVectorField();
G1.refreshObjects();
G2.refreshObjects();
G3.refreshObjects();
}
}
and second class as
package gravitationalmodel;
import static gravitationalmodel.GravitationalModel.xArray;
import static gravitationalmodel.GravitationalModel.yArray;
import static gravitationalmodel.GravitationalModel.gravConst;
import static gravitationalmodel.GravitationalModel.refreshRate;
public class GravitationalObject {
private double xPos; // location and speed of gravitational object
private double yPos;
private double vX;
private double vY;
private double mass;
public GravitationalObject(double x, double y, double xv, double yv,
double m) {
xPos = x;
yPos = y;
vX = xv;
vY = yv;
mass = m;
}
public void refreshVectorField() // calculates gravitational field
{
int k = 1;
for (int x = 0; x < 1920; ++x) {
if (xPos > x)
k = 1;
else
k = -1;
if (xPos - x == 0)
++x;
xArray[x] += k * (gravConst * mass) / Math.pow(xPos - x, 2.0); // errors
// on
// this
// line
}
for (int y = 0; y < 1200; ++y) {
if (yPos < y)
k = 1;
else
k = -1;
yArray[y] += (gravConst * mass) / Math.pow(Math.abs(yPos - y), 2); // errors
// on
// this
// line
}
}
public void refreshObjects() {
vX += refreshRate / 1000 * xArray[(int)xPos]; // errors on these lines
vY += refreshRate / 1000 * yArray[(int)yPos];
xPos += refreshRate / 1000 * vX;
xPos += refreshRate / 1000 * vX;
}
}

Related

In what ratio does the intersection point divide the line segments?

What I made:
I drew X and Y Axises and my segments;
I wrote a code, that returns true if the segments intersect.
I wrote a code, that returns the coordinate of an intersection point.
But how I can calculate a ratio does the intersection point divide line segments?
Thanks a lot for your help. ^^
My code is:
package com.staaankey;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Cartesian {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CartesianFrame frame = new CartesianFrame();
frame.showUI();
}
});
}
}
class CartesianFrame extends JFrame {
CartesianPanel panel;
public CartesianFrame() {
panel = new CartesianPanel();
add(panel);
}
public void showUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Main");
setSize(700, 700);
setVisible(true);
}
}
class CartesianPanel extends JPanel {
// x-axis coord constants
public static final int X_AXIS_FIRST_X_COORD = 50;
public static final int X_AXIS_SECOND_X_COORD = 600;
public static final int X_AXIS_Y_COORD = 600;
// y-axis coord constants
public static final int Y_AXIS_FIRST_Y_COORD = 50;
public static final int Y_AXIS_SECOND_Y_COORD = 600;
public static final int Y_AXIS_X_COORD = 50;
//arrows of axis are represented with "hipotenuse" of
//triangle
// now we are define length of cathetas of that triangle
public static final int FIRST_LENGHT = 10;
public static final int SECOND_LENGHT = 5;
// size of start coordinate lenght
public static final int ORIGIN_COORDINATE_LENGHT = 6;
// distance of coordinate strings from axis
public static final int AXIS_STRING_DISTANCE = 20;
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// x-axis
g2.drawLine(X_AXIS_FIRST_X_COORD, X_AXIS_Y_COORD,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
// y-axis
g2.drawLine(Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD,
Y_AXIS_X_COORD, Y_AXIS_SECOND_Y_COORD);
// x-axis arrow
g2.drawLine(X_AXIS_SECOND_X_COORD - FIRST_LENGHT,
X_AXIS_Y_COORD - SECOND_LENGHT,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
g2.drawLine(X_AXIS_SECOND_X_COORD - FIRST_LENGHT,
X_AXIS_Y_COORD + SECOND_LENGHT,
X_AXIS_SECOND_X_COORD, X_AXIS_Y_COORD);
// y-axis arrow
g2.drawLine(Y_AXIS_X_COORD - SECOND_LENGHT,
Y_AXIS_FIRST_Y_COORD + FIRST_LENGHT,
Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD);
g2.drawLine(Y_AXIS_X_COORD + SECOND_LENGHT,
Y_AXIS_FIRST_Y_COORD + FIRST_LENGHT,
Y_AXIS_X_COORD, Y_AXIS_FIRST_Y_COORD);
// draw origin Point
g2.fillOval(
X_AXIS_FIRST_X_COORD - (ORIGIN_COORDINATE_LENGHT / 2),
Y_AXIS_SECOND_Y_COORD - (ORIGIN_COORDINATE_LENGHT / 2),
ORIGIN_COORDINATE_LENGHT, ORIGIN_COORDINATE_LENGHT);
// draw text "X" and draw text "Y"
g2.drawString("X", X_AXIS_SECOND_X_COORD - AXIS_STRING_DISTANCE / 2,
X_AXIS_Y_COORD + AXIS_STRING_DISTANCE);
g2.drawString("Y", Y_AXIS_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_FIRST_Y_COORD + AXIS_STRING_DISTANCE / 2);
g2.drawString("(0, 0)", X_AXIS_FIRST_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_SECOND_Y_COORD + AXIS_STRING_DISTANCE);
// numerate axis
int xCoordNumbers = 10;
int yCoordNumbers = 10;
int xLength = (X_AXIS_SECOND_X_COORD - X_AXIS_FIRST_X_COORD)
/ xCoordNumbers;
int yLength = (Y_AXIS_SECOND_Y_COORD - Y_AXIS_FIRST_Y_COORD)
/ yCoordNumbers;
// draw x-axis numbers
for(int i = 1; i < xCoordNumbers; i++) {
g2.drawLine(X_AXIS_FIRST_X_COORD + (i * xLength),
X_AXIS_Y_COORD - SECOND_LENGHT,
X_AXIS_FIRST_X_COORD + (i * xLength),
X_AXIS_Y_COORD + SECOND_LENGHT);
g2.drawString(Integer.toString(i),
X_AXIS_FIRST_X_COORD + (i * xLength) - 3,
X_AXIS_Y_COORD + AXIS_STRING_DISTANCE);
}
//draw y-axis numbers
for(int i = 1; i < yCoordNumbers; i++) {
g2.drawLine(Y_AXIS_X_COORD - SECOND_LENGHT,
Y_AXIS_SECOND_Y_COORD - (i * yLength),
Y_AXIS_X_COORD + SECOND_LENGHT,
Y_AXIS_SECOND_Y_COORD - (i * yLength));
g2.drawString(Integer.toString(i),
Y_AXIS_X_COORD - AXIS_STRING_DISTANCE,
Y_AXIS_SECOND_Y_COORD - (i * yLength));
}
//draw first section
int fX1 = 125;
int fY1 = 75;
int fX2 = 135;
int fY2 = 75;
g2.drawLine(fX1, fY1, fX2, fY2);
//draw second section
int sX1 = 130;
int sY1 = 50;
int sX2 = 140;
int sY2 = 150;
g2.drawLine(sX1, sY1, sX2, sY2);
int v1 = (sX2 - sX1) * (fY1 - sY1) - (sY2 - sY1) * (fX1 - sX1);
int v2 = (sX2 - sX1) * (fY2 - sX1) - (sY2 - sY1) * (fX2 - sX1);
int v3 = (fX2 - fX1) *(sY1 - fY1) - (fY2 - fY1) * (sX1 - fX1);
int v4 = (fX2 - fX1) * (sY2 - fY1) - (fY2 - fY1) * (sX2 - fX1);
Boolean result;
if((v1 * v2 < 0) && (v3 * v4 < 0)){
result = true;
}
else{
result = false;
}
System.out.println(result);
int detL1 = det(fX1, fY1, fX2, fY2);
int detL2 = det(sX1, sY1, sX2, sY2);
int x1mx2 = fX1 - fX2;
int x3mx4 = sX1 - sX2;
int y1my2 = fY1 - fY2;
int y3my4 = sY1 - sY2;
int denom = det(x1mx2, y1my2, x3mx4, y3my4);
if(denom == 0){
return;
}
int xnom = det(detL1 ,x1mx2, detL2, x3mx4);
int ynom = det(detL1, y1my2, detL2, y3my4);
int ixOut = xnom / denom;
int iYOut = ynom / denom;
System.out.println("ixOut: ");
System.out.println("iYOut: ");
System.out.println(ixOut);;
System.out.println(iYOut);
}
public int det(int x1, int y1, int x2, int y2){
return x1 * y2 - y1 * x2;
}
}
Use the distance formula, Math.hypot() to calculate the length of the segments. That would be from one end of the line (it's x,y location) to the intersection point. Then from the other lines x,y location to the intersection point. Then divide the smaller length by the larger length. Make certain you use floating point math for the result.
Example:
// some arbitrary line with slope = 5 and y-intercept = 23
UnaryOperator<Integer> y = x->5*x + 23;
int endx = 2;
int endy = y.apply(endx);
int otherendx = 10;
int otherendy = y.apply(otherendx);
int intx = 5;
int inty = y.apply(intx);
double seg1Length = Math.hypot(endx-intx, endy - inty);
double seg2Length = Math.hypot(otherendx-intx, otherendy - inty);
double ratio = Math.min(seg1Length,seg2Length)/Math.max(seg1Length,seg2Length);
prints
Ratio = 0.6

I'm trying to draw a new dot every 250 milliseconds but it only draws a dot once

//I'm trying to draw a new dot every 250 milliseconds but it only draws the dot a single time. I have tried fixing it many times, but it still will only paint a single dot, rather than one after 250 milliseconds. Is this a problem with the timer or the paint method? Here is the code:
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public double t = 0;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
//this is the place where i make the dots but it only makes one.
//used to be a for loop but i altered it to an if statement so i could paint one dot at a time
public void drawDots(Graphics g)
{
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
if(t<=time)
{
t+=0.025;
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
//where i make the timer
//250 mill
public void dostuff()
{
int delay = 250;
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
repaint();
}
};
new Timer(delay, taskPerformer).start();
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}
This is the original version of the code that displays the projectile's motion, but it does not wait 250 milliseconds between drawing each point:
import javax.swing.JPanel;
import java.awt.*;
public class Window extends JPanel{
private int size;
private static double maxValue;
private double elevation;
private double vertV;
public double horizV;
public double gravity;
public double range;
public double time;
public Window(int s, double v, double e, double v2, double g,double h,double r,double t){
size = s;
maxValue = v;
elevation = e;
vertV = v2;
gravity = g;
horizV = h;
range = r;
time = t;
setPreferredSize(new Dimension(size, size));
}
public void paintComponent(Graphics g){
g.drawLine(size/25, 0,size/25, size);
g.drawLine(0, size - (size/25), size, size - (size/25));
double[] lines = getLine();
int x = size/5 + (size/25), y = size - (size/25);
int x2 = x;
for(int i = 0; i < 4; i++){
g.drawLine(x, y+5, x, y-5);
g.drawString(lines[i]+"",x-size/50,y+size/30);
x+=x2;
}
int yx = size/25, yy = size - (size/5 + (size/25));
int y2 = size/5 + (size/25);
for(int i=0;i<4;i++){
g.drawLine(yx-5, yy, yx+5, yy);
g.drawString(lines[i]+"",yx-size/25,yy+size/30);
yy -= y2;
}
drawDots(g);
}
public void drawDots(Graphics g){
double ratio = (size-((size/25)*2))/maxValue;
double fx;
double xvalue;
// This for loop is where dots are drawn, each iteration draws one dot. It starts at zero, and counts up to the time variable t.
for(double t=0;t<=time; t+=0.025){
t = Math.round(t*1000.0)/1000.0;
fx = function(t);
xvalue = xfunction(t);
if(fx >= 0){
System.out.print("Time: " + t + " " + "Range: " + xvalue + " " + "Height: ");
System.out.println(fx);
g.drawLine((int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)),
(int)(size/25+(ratio*xvalue)), (int)((size-(size/25))-(ratio*fx)));
}
}
}
public double xfunction(double t){
double x = 0.0;
x = Math.round(horizV * t * 1000.0)/1000.0;
return x;
}
public double function(double t){
double fx = 0.0;
fx = Math.round((vertV*t + .5*(-(gravity))*(t*t) + elevation)*1000.0)/1000.0;
return fx;
}
private static double[] getLine(){
double increment = maxValue / 4;
double currentLine = 0;
double[] lines = new double[4];
for(int i = 0; i < 4; i++){
currentLine+=increment;
lines[i] = Math.round(currentLine * 10.0)/10.0;
}
return lines;
}
}

Java: Draw a circular spiral using drawArc

I'm working on a java programming exercise where we have to draw a circular spiral using the drawArc method so that the result looks similar to this:
I've been working on this for a while and this is what I have so far:
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class CircSpiral extends JPanel {
public void paintComponent(Graphics g) {
int x = 100;
int y = 120;
int width = 40;
int height = 60;
int startAngle = 20;
int arcAngle = 80;
for (int i = 0; i < 5; i++) {
g.drawArc(x, y, width, height, startAngle, arcAngle);
g.drawArc(x + 10, y + 10, width, height, startAngle + 10, arcAngle);
x = x + 5;
y = y + 5;
startAngle = startAngle - 10;
arcAngle = arcAngle + 10;
}
}
public static void main(String[] args) {
CircSpiral panel = new CircSpiral();
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(300, 300);
application.setVisible(true);
}
}
My code gives me this result:
I know the problem lies in my arguments for the drawArc method because the numbers aren't right, but I don't know how to go about making the numbers go in a circular manner. Any help is appreciated. Thank you!
Your idea is almost right. I did some modifications. You need to inverse the angle to draw the other side of the spiral and use fixed point to startAngle.
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class CircSpiral extends JPanel {
public void paintComponent(Graphics g) {
int x = getSize().width / 2 - 10;
int y = getSize().height/ 2 - 10;
int width = 20;
int height = 20;
int startAngle = 0;
int arcAngle = 180;
int depth = 10;
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
// g.drawArc(x + 10, y + 10, width, height, startAngle + 10, -arcAngle);
// x = x - 5;
y = y - depth;
width = width + 2 * depth;
height = height + 2 * depth;
g.drawArc(x, y, width, height, startAngle, -arcAngle);
} else {
// g.drawArc(x + 10, y + 10, width, height, startAngle + 10, arcAngle);
x = x - 2 * depth;
y = y - depth;
width = width + 2 * depth;
height = height + 2 * depth;
g.drawArc(x, y, width, height, startAngle, arcAngle);
}
}
}
public static void main(String[] args) {
CircSpiral panel = new CircSpiral();
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(300, 300);
application.setVisible(true);
}
}
If this were my project, yes I'd draw my arcs in a loop, but within the loop, I'd try to make the arc's bounding box bigger but still centered over the same location. To do this I'd decrement x and y by some small constant, say DELTA (which I'd set to == 1), and I'd increment width and height by 2 * DELTA. I'd also leave my arcAngle unchanged but rather would change my startAngle in the loop like so: startAngle = startAngle - arcAngle;.
For example, this:
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class CircSpiral extends JPanel {
private static final int DELTA = 1;
private static final int ARC_ANGLE = 20;
private static final int PREF_W = 300;
private static final int PREF_H = PREF_W;
private static final int LOOP_MAX = 400;
public void paintComponent(Graphics g) {
int x = PREF_W / 2;
int y = PREF_H / 2;
int width = 1;
int height = 1;
int startAngle = 0;
int arcAngle = ARC_ANGLE;
for (int i = 0; i < LOOP_MAX; i++) {
g.drawArc(x, y, width, height, startAngle, arcAngle);
x = x - DELTA;
y = y - DELTA;
width += 2 * DELTA;
height += 2 * DELTA;
startAngle = startAngle - arcAngle;
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
public static void main(String[] args) {
CircSpiral panel = new CircSpiral();
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.pack();
application.setLocationRelativeTo(null);
application.setVisible(true);
}
}
Would result in this:
The following code will output this image:
import java.awt.Graphics;
import javax.swing.JPanel;
import javax.swing.JFrame;
public class CircSpiral extends JPanel {
public void paintComponent(Graphics g) {
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
int numIterations = 5;
int arcWidth = 10;
int arcGrowDelta = 30;
for (int i = 0; i < numIterations; i++) {
g.drawArc(centerX - arcWidth, centerY - arcWidth, 2 * arcWidth, 2 * arcWidth, 0, 180);
arcWidth += arcGrowDelta;
g.drawArc(centerX - arcWidth, centerY - arcWidth, 2 * arcWidth - arcGrowDelta, 2 * arcWidth, 180, 180);
}
}
public static void main(String[] args) {
CircSpiral panel = new CircSpiral();
JFrame application = new JFrame();
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.setSize(300, 300);
application.setVisible(true);
}
}
The idea is very simple, just draw the upper half of a circle, like this:
Then increment the arc size by a constant factor and draw the bottom half of the circle but making the end point of this circle and the upper circle match, for it, just substrate the arcGrowDelta from the bottom circle width:
And repeat.
This is my solution:
package mainpack;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;
public class SpiralPanel extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
int width = 10;
int height = 10;
int startAngle = 0;
int arcAngle = 180;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
int i = 0;
int t = 0;
while (i < 36) {
g2d.drawArc(x + t, y, width, height, startAngle, arcAngle);
if (i % 2 == 0) {
t -= 10;
}
y -= 5;
width += 10;
height += 10;
startAngle += 180;
i++;
}
}
}
I am a beginner to java and finally managed how to create the spiral.
Here is my code:
int lineLength = 20; //starting line length
int x = getWidth() / 2; //start drawing from center of JPanel
int y = getHeight() / 2; //start drawing from center of JPanel
for( int counter = 0; counter < 10; counter++ )
{
g.drawArc( x, y, lineLength, lineLength, 0, 180 ); //draws top semicircle of equal width and height
lineLength += 20; //increases arc diameter
x -= 20; //moves x coordinate left
g.drawArc( x, y - 10, lineLength, lineLength, 0, -180 ); //draws bottom semicircle; 'y - 10' joins the 2 semicircles
lineLength += 20; //increases arc diameter
y -= 20; //moves y coordinate up
}
If you're willing to let some good old trigonometry do the work, you could use this:
import java.awt. *;
import javax.swing. *;
import java.math.*;
public class Spiral extends JFrame {
public Spiral()
{
// Set Window
setTitle("Spirale");
setSize(1500, 1500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public void paint(Graphics g)
{
super.paint(g);
for(double i = 1; i < 50000; i++)
{
int locY = 600 - (int) (Math.cos((Math.PI*i)/1800)*i/50);
int locX = 600 - (int) (Math.sin((Math.PI*i)/1800)*i/50);
g.drawLine(locX, locY, locX, locY);
}
}
public static void main(String[] args) {
new Spiral();
}
}

Java - Objects follow each other, when given diffrent tasks

I have been working on this java application.
So far it has no meaning, just a randomly colored ball bouncing around.
But now, when i wanted to add another ball to the bouncing app, the balls followed each other.
This is my code so far.
import java.awt.*;
import javax.swing.*;
public class MainFrame extends JPanel implements Runnable {
Color color = Color.red;
int dia = 60;
Diameter of the objects.
long delay = 20;
Delay time.
private int x = (int)Math.floor(Math.random() * 580);
private int y = (int)Math.floor(Math.random() * 900);
private int xx = (int)Math.floor(Math.random() * 580);
private int yy = (int)Math.floor(Math.random() * 900);
Above is the objects position.
private int dx = (int)Math.floor(Math.random() * 7);
private int dy = (int)Math.floor(Math.random() * 7);
private int dxx = (int)Math.floor(Math.random() * 7);
private int dyy = (int)Math.floor(Math.random() * 7);
Above is object speed.
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(color);
g.fillOval(x,y,60,60);
g.setColor(color);
g.fillOval(xx,yy,60,60);
}
The graphics.
And below is just calculations, thread.sleep and the JFrame.
public void run() {
while(isVisible()) {
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
System.out.println("interrupted");
}
move();
repaint();
}
}
public void move() {
if(x + dx < 0 || x + dia + dx > getWidth()) {
dx *= -1;
color = getColor();
}
if(y + dy < 0 || y + dia + dy > getHeight()) {
dy *= -1;
color = getColor();
}
if(xx + dxx < 0 || xx + dia + dxx > getWidth()) {
dxx *= -1;
color = getColor();
}
if(yy + dyy < 0 || yy + dia + dyy > getHeight()) {
dyy *= -1;
color = getColor();
}
x += dx;
y += dy;
xx += dx;
yy += dy;
}
private Color getColor() {
int rval = (int)Math.floor(Math.random() * 256);
int gval = (int)Math.floor(Math.random() * 256);
int bval = (int)Math.floor(Math.random() * 256);
return new Color(rval, gval, bval);
}
private void start() {
while(!isVisible()) {
try {
Thread.sleep(25);
} catch(InterruptedException e) {
System.exit(1);
}
}
Thread thread = new Thread(this);
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
}
public static void main(String[] args) {
MainFrame test = new MainFrame();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(test);
f.setSize(640, 960);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(dim.width/2-f.getSize().width/2, dim.height/2-f.getSize().height/2);
f.setVisible(true);
test.start();
}
}
I just can not figure it out.
I know the answer is going to be simple.
You should define a single class Ball and create two instances of it rather than repeating the variables and have an x,y co-ordinate and velocity dx and dy inside that class.
The two follow each other ebcause you add the same velocity to both balls all the time:
x += dx;
y += dy;
xx += dx;
yy += dy;

how to build a brick pryramid using nested for loops

I'm working on a problem I'm having lots of trouble with. The concept of the question is to build a pyramid using bricks. The entire pyramid of bricks is centered in the window. I can draw one brick, then two, then three all the way up until 12 which makes up the base of the pyramid but all of the bricks are alined on the left edge on the left of the window instead of being centered in the window.
Using getWidth() and getHeight() i can do (getWidth()-BRICK_WIDTH) / 2; to get the center for the x coordinate of the brick. And then (getHeight() -BRICK_HEIGHT) / 2; for the center of the y coordinate of one brick. The only problem is i don't understand where to enter that code so it applies to all the bricks so each row of bricks is centered in the window.
import acm.program.*;
import acm.graphics.*;
public class Pyramid extends GraphicsProgram {
public void run() {
double xCoordinate = (getWidth() - BRICKWIDTH) / 2;
double yCoordinate = (getHeight() - BRICK_HEIGHT / 2);
for (int i = 0; i < BRICKS_IN_BASE; i++) {
for (int j = 0; j < i; j++) {
double x = j * BRICK_WIDTH;
double y = i * BRICK_HEIGHT;
GRect square = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
add(square);
}
}
}
private static final int BRICK_WIDTH = 50;
private static final int BRICK_HEIGHT = 25;
private static final int BRICKS_IN_BASE = 12;
}
You should try something like this :
import acm.program.*;
import acm.graphics.*;
public class Pyramid extends GraphicsProgram
{
public void run()
{
// We calculate some values in order to center the pyramid vertically
int pyramidHeight = BRICKS_IN_BASE * BRICK_HEIGHT;
double pyramidY = (getHeight() - pyramidHeight) / 2;
// For each brick layer...
for (int i=BRICKS_IN_BASE ; i >= 1; i--)
{
// We calculate some values in order to center the layer horizontally
int layerWidth = BRICKWIDTH * i;
double layerX = (getWidth() - layerWidth) / 2;
double layerY = pyramidY + (i-1) * BRICK_HEIGHT;
// For each brick in the layer...
for(int j=0 ; j<i ; j++)
{
GRect square = new GRect(layerX + j*BRICK_WIDTH, layerY, BRICK_WIDTH, BRICK_HEIGHT);
add(square);
}
}
}
private static final int BRICK_WIDTH = 50;
private static final int BRICK_HEIGHT = 25;
private static final int BRICKS_IN_BASE = 12;
}
In this implementation, we first calculate the global width of the layer (because we already know how many bricks there will be in it) and we use it to find a global "point of start" of the layer, from which we find all the coordinates for all the rectangles.
You mean something like that?
double x = xCoordinate + j * BRICK_WIDTH;
double y = yCoordinate + i * BRICK_HEIGHT;

Categories

Resources