I was trying to create a 2D Animation in Java of a moving line on Panel(A line moving from one point to another in the Panel). I hope its possible. Here's the code I used.
private void movingline(int length) throws InterruptedException {
for(int i = 0; i + length < width; i++){
for(int j = 0; j + length < height; j++){
eraseline();
drawLine(Color.cyan, i, j, i+length, j+length);
erase = true;
}
}
}
private void eraseline() {
if(erase){
fillCanvas(Color.BLUE);
}
}
On running the code, the Panel doesn't show up.
Here's the code to draw the line.
public void drawLine(Color c, int x1, int y1, int x2, int y2) {
int pix = c.getRGB();
int dx = x2 - x1;
int dy = y2 - y1;
canvas.setRGB(x1, y1, pix);
if (dx != 0) {
float m = (float) dy / (float) dx;
float b = y1 - m*x1;
dx = (x2 > x1) ? 1 : -1;
while (x1 != x2) {
x1 += dx;
y1 = Math.round(m*x1 + b);
canvas.setRGB(x1, y1, pix);
}
}
repaint();
}
On running the code the Panel doesn't show up with the moving line. Any help would be much appreciated.
I think the biggest problem is that you're trying to change the appearance of the GUI from (I'm guessing) a Thread that's not the Event Dispatching Thread.
The solution is to wrap the activity (specifically, the calls to eraseLine and drawLine) in a Runnable and call that Runnable using SwingUtilities.invokeAndWait().
EDIT: Java's graphics components don't really let you manipulate the canvas yourself. Only the components themselves do any drawing, and then only when called on to paint themselves. Directly drawing on the canvas, even if you could get it to work, would work badly because you'd be interfering with what the component does.
Rather than go into a lot more explanation, I've gone and implemented what I think is the "proper" way to do this.
http://pastebin.com/etfmKbjj
The coding's commented where necessary, I hope it gives you some ideas. For more background, read the official tutorials on Swing and Graphics.
Related
Hi I am trying to create parabolic curves using lines in awt java but previous lines are getting removed as soon as some new lines are drawn.
I am using this code in paint method
static int x1 = 0;
static int y1 = 300;
static int x2 = 300;
static int y2 = 300;
#Override
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
g.setColor(Color.RED);
for(int i = 0; i < 15;i++,x1 += 4, y2 -= 2) {
g.drawLine(x2, y2, x1, y1);
}
//repaint();
}
but if i iterate loop for 10 times then only its drawing lines correctly.
My ouput
what I want to acheive is draw parabolic curves in each quadrant like this
ignore the red text in second image.
Ref - https://www.mrsmilewski.com/parabolic-curve.html
Any help appreciated.
I tried to create and translate a polygon in openGL, I create a function for translation but this create a white line from x0 to v_size and I don't understand why ?
This is my function for polygon translation
public void translate1(GL2 gl, double x0, double x1, double y0, double y1){
double step = 0.2;
for(double i = 0; i < v_size; i += step){
gl.glBegin(GL2.GL_POLYGON);
gl.glVertex2d(x0 + i, y0);
gl.glVertex2d(x0 + i, y1);
gl.glVertex2d(x1 + i, y1);
gl.glVertex2d(x1 + i, y0);
gl.glEnd();
}
}
Initial x0 = 0, x1 = 10, y0 = 20, y1 = 30.
Thanks !
Have a nice day!
The reason for this is, that you draw squares every step units away from each other. Since nothing gets cleared in the meantime, the overlapping quads form a line.
It is rather unclear what you are trying to achieve. A translation would usually not draw multiple quads. If you are trying to do an animation, then you'll have to split the movement over multiple frames and draw exactly one square in every frame.
nothing is showing up at all..
I have tried moving Random rand = new Random() to outside of the loop, but it still doesnt work at all.
Nor does the frame exit on close.
public class myMain {
public static void main(String args[]) {
Frame frame = new Frame();
}
}
public class Frame extends JFrame {
public Frame(){
super("Fancy Triangle");
setSize(1024, 768);
myPanel panel = new myPanel();
add(panel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
}
public class myPanel extends JPanel {
int x1 = 512;
int y1 = 109;
int x2 = 146;
int y2 = 654;
int x3 = 876;
int y3 = 654;
int x = 512;
int y = 382;
int dx, dy;
Random rand;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < 50000; i++) {
g.drawLine(x, y, x, y);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
rand = new Random();
int random = 1 + rand.nextInt(3);
if (random == 1) {
dx = x - x1;
dy = y - y1;
} else if (random == 2) {
dx = x - x2;
dy = y - y2;
} else {
dx = x - x3;
dy = y - y3;
}
x = x - (dx / 2);
y = y - (dy / 2);
}
}
}
This:
Thread.sleep(300);
is not doing what you intend it to do. I think that you're trying to draw with a delay, but that's not what this does. Instead you're calling sleep on the Swing event thread puts the whole application to sleep, since the thread cannot do what it needs to do, including drawing the application and interacting with the user. Even worse, you're doing this within a painting method, a method that is required to be extremely fast since often the perceived responsiveness of a Swing application is determined by painting speed.
Instead use a Swing Timer (Swing Timer tutorial) to change the state of fields of the class, and then call repaint. Have your paintComponent use those changed fields to decide what to draw and where. Since a Sierpinski triangle is composed of dots, consider creating an ArrayList<Point>, getting rid of the for loop inside your painting method, and using the Swing Timer to replace this for loop. Within the Timer's ActionListener, place the semi-random points into the ArrayList and call repaint. Then within paintComponent, iterate through the ArrayList, drawing each point that it contains.
Alternatively, you could draw the points onto a BufferedImage in your Swing Timer and then simply have your paintComponent display the BufferedImage via g.drawImage(...) method call. This would likely be more efficient.
I created a Java Applet which has a graph that is a parabola but my parabola is upside down? How can I rotate my drawLine?
What I extended and implemented:
public class Parabola extends Applet implements AdjustmentListener {
//bunch of my code is in here ...
public void paint(Graphics g) {
//bunch of my code in here ...
for (int i = 0; i <= 999; i++) {
y1 = (int)(p[i] * 100) + 100;
y2 = (int)(p[i+1] * 100) + 100;
g.drawLine(i + 20, y1, (i + 1) + 20, y2); //its upside down, needs to be rotated
}
}
}
Actually, I figured it out from this website -- it's bascially trigonometry.
But, if there is an easier way, please do share.
We use:
X2 =X1*cos(theta)-Y1*sin(theta);
Y2 =X1*sin(theta)+Y1*cos(theta);
Original line:
g.drawLine(200,200,x1+200,200-y1);
Rotated line:
g.drawLine(200,200,x2+200,200-y2);
I'm trying to move an object on the click of a mouse while the object remains animated. There are a few similar posts on this website, and I've based my code off this answer:
An efficient algorithm to move ostrichs along a line at a constant speed
But I want to use a thread to keep the object animated. How should I do this? Here's my code:
public void movePlayer(Graphics g, int finalX, int finalY)
{
int length = finalX - xpos;
int height = finalY - ypos;
int oldXpos = xpos;
int oldYpos = ypos;
double speed = 20;
double distanceX = (length)/speed;
double distanceY = (height)/speed;
double distance = (Math.hypot(length,height));
double distanceTraveled = 0;
//This currently doesn't work:
move = new Thread(this);
{
while (distanceTraveled<distance)
{
//move the object by increments
xpos += distanceX;
ypos += distanceY;
distanceTraveled = Math.hypot(xpos-oldXpos, ypos - oldYpos);
drawPlayer(img, g);
for(int x = 0; x < 100000; x ++);
}
}
}
If this is Swing, why not simply use a MouseListener to help you drag the object? If you want to animate separate from the mouse, don't use a while(true) loop unless you want to freeze the event thread. Use a Swing Timer instead. If this isn't Swing, tell us more details (shoot, do this anyway)!