Hello I am fairly new to java and have been stuck on this problem for awhile so hopefully someone will be able to save me. Basically I am creating a program that can graph an equation and right now I'm testing out x^2 between -10 and 10. I can get the points to graph in the right spots but I can't figure out how to fill in the spots in between the points so it looks like a real graph.
Here's my code:
import java.util.Scanner;
import javax.swing.JFrame;
import java.awt.*;
class PlotGraph extends JFrame{
public void paint(Graphics l){
l.drawLine(50, 300, 550, 300); //x axis
l.drawLine(300, 550, 300, 50); //y axis
//Orignin x = 300 y = 300
int xmin, xmax, y, tmin, tmax;
xmin =(-10);
xmax = 10;
int x_bet, y_bet;
while(xmin<=xmax){
y = 300-(xmin*xmin);
l.drawLine(xmin+300, y, xmin+300, y);
//while(x_bet>xmin){
//l.drawLine(, , , );
//}
xmin++;
}
}
public static void main(String [] args) {
PlotGraph graph = new PlotGraph();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setSize(600, 600);
graph.setVisible(true);
graph.setTitle("PlotGraph");
}
}
Another way to do it is to create a GeneralPath, like this.
import javax.swing.JFrame;
import java.awt.*;
import java.awt.geom.*;
class PlotGraph extends JFrame{
public void paint(Graphics l){
l.drawLine(50, 300, 550, 300); //x axis
l.drawLine(300, 550, 300, 50); //y axis
int xmin, xmax, y, tmin, tmax;
xmin =(-10);
xmax = 10;
int x_bet, y_bet;
GeneralPath gp = new GeneralPath();
y = 300-(xmin*xmin);
gp.moveTo((double)xmin+300, (double)y);
while(xmin<=xmax){
y = 300-(xmin*xmin);
gp.lineTo((double)xmin+300, (double)y);
xmin++;
}
Graphics2D g2 = (Graphics2D)l;
g2.setColor(Color.RED);
g2.draw(gp);
}
public static void main(String [] args) {
PlotGraph graph = new PlotGraph();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setSize(600, 600);
graph.setVisible(true);
graph.setTitle("PlotGraph");
}
}
This source still has problems though:
GUI updates should be done on the EDT.
Custom painting is either best done in a JPanel/JComponent or a BufferedImage displayed in a JLabel.
The 'graph component' should declare a preferred size, rather than setting a size for the frame..
Maybe try this:
int x = xmin;
int last_y = 300-(x*x);
for (x = xmin+1; x<=xmax; x++);
y = 300-(x*x);
l.drawLine(x-1, last_y, x, y);
last_y = y;
}
You want the line to be drawn between previous x and y coordinates and the current ones. That's what last_y is for.
There are several ways to do this. If this is an assignment then I'm guessing that your professor is looking to see what methods you come up with. At the most basic level you just draw a line from the last point to the current point. How else could you accomplish this? Maybe a polyline in a different color? Maybe use a little math to draw larger circles a then run a line through them?
Here is one simple way to address the specific problem. I wouldn't recommend turning this in (if it's an assignment) but it shows you the basic principle.
import java.util.Scanner;
import javax.swing.JFrame;
import java.awt.*;
class PlotGraph extends JFrame{
public void paint(Graphics l){
l.drawLine(50, 300, 550, 300); //x axis
l.drawLine(300, 550, 300, 50); //y axis
int xmin, xmax, y, tmin, tmax;
int z = 0;
xmin =(-10);
xmax = 10;
int x_bet, y_bet;
while(xmin<=xmax){
y = 300-(xmin*xmin);
l.drawLine(xmin+300, y, xmin+300, y);
if(z!=0)
l.drawLine(xmin+300, y, xmin+300, z);
z=y;
xmin++;
}
}
public static void main(String [] args) {
PlotGraph graph = new PlotGraph();
graph.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
graph.setSize(600, 600);
graph.setVisible(true);
graph.setTitle("PlotGraph");
}
}
Related
I tried to create a code that printed n random circles in a 500 x 500 frame but it didn't work.
Can somebody tell me why this code isn't running?
When I run this code, it lets me enter the number of random circles I want but the frame always appear to be empty - no circles are drawn.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.util.Scanner;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class RandomCircles extends JComponent
{
private int n;
public RandomCircles(int N)
{
n = N;
}
public void PaintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
double x = Math.random() * 500;
double y = Math.random() * 500;
double diameter = Math.random() * 500;
// Making sure the circle stays within the frame
for (int i = 0; i < n; i++)
{
while(x + diameter <= 500 || y + diameter <= 500)
{
Ellipse2D.Double circle
= new Ellipse2D.Double(x, y, diameter, diameter);
g2.draw(circle);
}
}
}
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.println("Enter number of circles here: ");
int n = in.nextInt();
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setTitle("Random Circles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RandomCircles circle = new RandomCircles(n);
frame.add(circle);
// Add PaintComponent method somewhere here?
frame.setVisible(true);
}
}
I have a feeling that I need to add in the public void PaintComponent(Graphics g) somewhere to print it out, but I am not sure how.
The problem is on this line:
public void PaintComponent(Graphics g)
You are attempting to override the paintComponent(Graphics) method. You need to be careful that you get the name and the parameters right. Notice you spelled your method with an upper case P.
It is advisable that you add the annotation #Override on methods that are supposed to override a super class' method. That way you get a notification if you get the signature wrong.
So your method should look like this:
#Override
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
...
}
== Edit after comments ==
The while loop is also causing an issue. Try doing this instead.
for (int i = 0; i < n; i++)
{
double x = Math.random() * 500;
double y = Math.random() * 500;
double diameter = Math.random() * 500;
Ellipse2D.Double circle
= new Ellipse2D.Double(x, y, diameter, diameter);
g2.draw(circle);
}
Notice that I moved the random number generation inside the loop. This does not guarantee the circle fitting in the frame but that is something you can modify later.
A and C images are far away.
At this time, B image is created from the coordinate values of A
For each iteration, x, y must be moved to arrive at the C image coordinate value.
For example,
A (100,100), C (300,300)
Starting at B (100,100),
Each time it is repeated, x, y must be moved to reach
B (300,300).
This is the method for entering the current moving source.
Public void Attack () {
int x1 = a.getX ();
int y1 = a.getY ();
int x2 = c.getX ();
int y2 = c.getY ();
if(b.getX ()==c.getX&&b.getY () == c.getY())'
{
system.out.println ("ok");'
}else {
b.setbounds (help1,help2,100,50)
}
}
Here, I want to know the code to enter help1 help2.
Pythagorean formula
Between A and C images
I want to know how to make the B image move along a virtual straight line.
Like a tower defense game.
A image is a tower
B image is bullet
The C image is the enemy.
I want the bullets fired from the tower to move to enemy locations.
I am Korean.
I used a translator
The following code is an mre of using a straight line equation y = mx + c to draw a moving object along such line.
To test the code copy the entire code into MoveAlongStraightLine.java and run, or run it online:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class MoveAlongStraightLine extends JFrame {
public MoveAlongStraightLine(){
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
ShootinBoard shootingBoard = new ShootinBoard();
JButton fire = new JButton("Fire");
fire.addActionListener(e->shootingBoard.fire());
add(shootingBoard);
add(fire, BorderLayout.SOUTH);
pack();
setVisible(true);
}
public static void main(String[]args){
SwingUtilities.invokeLater(()->new MoveAlongStraightLine());
}
}
class ShootinBoard extends JPanel{
//use constants for better readability
private static final double W = 600, H = 400;
private static final int DOT_SIZE = 10, SPEED = 2;
private final int dX = 1; //x increment
private final Timer timer;
private final Point2D.Double shooter, target;
private Point2D.Double bullet;
public ShootinBoard() {
setPreferredSize(new Dimension((int)W, (int)H));
shooter = new Point2D.Double(50,350);
bullet = shooter; //place bullet at start point
target = new Point2D.Double(550,50);
timer = new Timer(SPEED, e->moveBullet());
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3));
//draw source
g2.setColor(Color.blue);
g2.draw(new Ellipse2D.Double(shooter.getX(), shooter.getY(),DOT_SIZE , DOT_SIZE));
//draw bullet
g2.setColor(Color.black);
g2.draw(new Ellipse2D.Double(bullet.getX(), bullet.getY(),DOT_SIZE , DOT_SIZE));
//draw target
g2.setColor(Color.red);
g2.draw(new Ellipse2D.Double(target.getX(), target.getY(),DOT_SIZE , DOT_SIZE));
}
void fire(){
timer.stop();
bullet = shooter; //place bullet at start point
timer.start();
}
void moveBullet() {
if(target.x == bullet.x && target.y == bullet.y) {
timer.stop();
}
//y = mx + c for more details see https://www.usingmaths.com/senior_secondary/java/straightline.php
double m = (target.y - bullet.y)/ (target.x - bullet.x);//slope
double c = (target.x * bullet.y - bullet.x * target.y)/(target.x - bullet.x);
double newBulletX = bullet.x+dX; //increment x
double newBulletY = m * newBulletX + c; //calculate new y
bullet = new Point2D.Double(newBulletX,newBulletY);
repaint();
}
}
I'm trying to get the red dot to move straight down the y-axis. Please help. Right now it is not moving. I need it to move down at x = 235, y = 0 Until x = 235, y = 235 to create the illusion of motion. Here is the code (it is messy because I changed the ball movement from left right, but can't get it to got downward).
import java.awt.Color;
import java.awt.Graphics;
public class Animation {
public static void main(String [] args) {
DrawingPanel panel = new DrawingPanel(350, 350);
Graphics g = panel.getGraphics();
background(g);
ballroll(panel, g);
}
public static void ballroll(DrawingPanel panel, Graphics g) {
//draw and roll the ball now
g.setColor(Color.RED);
int x = 245, y = 0, direction=1;
while(y<245){
g.fillOval(235, 0, 20, 20);
//if (x==0){
y+=60;
direction *= -1;
}
//else if (x < 115){
//direction *= -1;
//y+=60;
//}
y+=direction*15;
System.out.println(x);
panel.sleep(80);
}
panel.sleep(350);
//}
}
You counting the y value up but you didn't use it.
I think it should be g.fillOval(235, y, 20, 20);
I'm currently working on a program which enables user to draw various geometric shapes. However, I got some issues on calculating and placing the angle objects onto my Canvas panel accurately. The angle object is basically an extension of the Arc2D object, which provides a additional method called computeStartAndExtent(). Inside my Angle class, this method computes and finds the necessary starting and extension angle values:
private void computeStartAndExtent()
{
double ang1 = Math.toDegrees(Math.atan2(b1.getY2() - b1.getY1(), b1.getX2() - b1.getX1()));
double ang2 = Math.toDegrees(Math.atan2(b2.getY2() - b2.getY1(), b2.getX2() - b2.getX1()));
if(ang2 < ang1)
{
start = Math.abs(180 - ang2);
extent = ang1 - ang2;
}
else
{
start = Math.abs(180 - ang1);
extent = ang2 - ang1;
}
start -= extent;
}
It is a bit buggy code that only works when I connect two lines to each other, however, when I connect a third one to make a triangle, the result is like the following,
As you see the ADB angle is the only one that is placed correctly. I couldn't figure how to overcome this. If you need some additional info/code please let me know.
EDIT: b1 and b2 are Line2D objects in computeStartAndExtent() method.
Thank you.
There are some of things that can be made to simplify the calculation:
Keep the vertices ordered, so that it is always clear how to calculate the vertex angles pointing away from the corner
Furthermore, always draw the polygon to the same direction; then you can always draw the angles to the same direction. The example below assumes the polygon is drawn clockwise. The same angle calculation would result in the arcs drawn outside given a polygon drawn counterclockwise.
Example code; is not quite the same as yours as I don't have your code, but has similar functionality:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Arc2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Polygon extends JPanel {
private static final int RADIUS = 20;
private final int[] xpoints = {
10, 150, 80, 60
};
private final int[] ypoints = {
10, 10, 150, 60
};
final Arc2D[] arcs;
Polygon() {
arcs = new Arc2D[xpoints.length];
for (int i = 0; i < arcs.length; i++) {
// Indices of previous and next corners
int prev = (i + arcs.length - 1) % arcs.length;
int next = (i + arcs.length + 1) % arcs.length;
// angles of sides, pointing outwards from the corner
double ang1 = Math.toDegrees(Math.atan2(-(ypoints[prev] - ypoints[i]), xpoints[prev] - xpoints[i]));
double ang2 = Math.toDegrees(Math.atan2(-(ypoints[next] - ypoints[i]), xpoints[next] - xpoints[i]));
int start = (int) ang1;
int extent = (int) (ang2 - ang1);
// always draw to positive direction, limit the angle <= 360
extent = (extent + 360) % 360;
arcs[i] = new Arc2D.Float(xpoints[i] - RADIUS, ypoints[i] - RADIUS, 2 * RADIUS, 2 * RADIUS, start, extent, Arc2D.OPEN);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(160, 160);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawPolygon(xpoints, ypoints, xpoints.length);
Graphics2D g2d = (Graphics2D) g;
for (Shape s : arcs) {
g2d.draw(s);
}
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Polygon");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Polygon());
frame.pack();
frame.setVisible(true);
}
});
}
}
Results in:
I'm a novice programmer trying to overlay two 2D circles on top of each other. Each circle has different dimensions and I understand that adding or subrtracting from xCenter and yCenter will move the shape on an axis, but how do I know with certainty they are centered? Unfortunately I am a novice without many tools under my belt, so the simplest information possible would be greatly appreciated. Thank you!
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class RedCross extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int xCenter = getWidth() / 2;
int yCenter = getHeight() / 2;
g.setColor(Color.BLUE);
g.fillOval(xCenter, yCenter, 40, 40);
g.setColor(Color.RED);
g.fillOval(xCenter, yCenter, 10, 10);
}
public static void main(String[] args)
{
JFrame window = new JFrame("Target");
window.setBounds(300, 300, 200, 200);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RedCross panel = new Target();
panel.setBackground(Color.WHITE);
Container c = window.getContentPane();
c.add(panel);
window.setVisible(true);
}
}
The center of an object is window/2 - self/2
In code:
int xPanel = getWidth();
int yPanel = getHeight();
int sizeCircleOne = 40;
int sizeCircleTwo = 10;
// Drawing circle 1
g.setColor(Color.BLUE);
g.fillOval(
xPanel/2 - sizeCircleOne/2,
yPanel/2 - sizeCircleOne/2,
sizeCircleOne,
sizeCircleOne
);
// Drawing circle 2
g.setColor(Color.RED);
g.fillOval(
xPanel/2 - sizeCircleTwo/2,
yPanel/2 - sizeCircleTwo/2,
sizeCircleTwo,
sizeCircleTwo
);
Let me know if it works.
Happy coding :) -Charlie
The method you use to center your circles is how one should center objects. Just take a point on half of the width, and half of the height, and that's your center. This is because the center of a circle has all points on the circle equidistant from the center point. That's the definition of a circle.