我正在使用以下代码生成正弦波:

此动画的速度是慢-快-慢。
码:

public static final double SINE_TO_180 = 114.58865012930961, TIMES = 180, SINE_OF_90 = Math.sin(Math.toRadians(90));

public static void main(String[] args) throws Exception{
    float velc = 200;
    float angle = 45;
    float resistance = 0f;
    double multiple = (velc * 2.5 / SINE_TO_180);
    int offset = 0;
    double y = 0;
    double x = 0;
    double h = 0;
    double cos = Math.cos(Math.toRadians(angle));
    double sin = Math.sin(Math.toRadians(angle));
    for(int i = offset; i < TIMES + 1 + offset; i ++){
        y += ((Math.sin(Math.toRadians(i * 2)))) * multiple * sin;
        if(y >= h)
            h = y;
        x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
//          x += multiple * cos;
//          if(i + offset < TIMES / 2){
//              x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
//          }else{
//              x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
//          }
    }
    y = Math.round(y);
    //do round x?
    x = Math.round(x);
    System.out.println("X: " + x);
    JFrame frm = new JFrame("Projectile!");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    BufferedImage b = new BufferedImage((int)x + 1, (int)h + 1, BufferedImage.TYPE_INT_RGB);
    Graphics g = b.getGraphics();
    y = 0;
    x = 0;

    JLabel l = new JLabel(new ImageIcon(b));
    frm.add(l);
    frm.pack();
    frm.setVisible(true);

    for(int i = offset; i < TIMES + 1 + offset; i ++){
        y += ((Math.sin(Math.toRadians(i * 2)))) * multiple * sin;

        x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
 //         x += multiple * cos;
//          if(i + offset < TIMES / 2){
//              x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
//          }else{
//              x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
//          }
        g.setColor(Color.red);
        g.drawLine((int)x, (int)(h - y), (int)x, (int)(h - y));
        l.setIcon(new ImageIcon(b));
        frm.repaint();
        Thread.sleep((int)(1000.0 / 24.0));
    }
    ImageIO.write(b, "png", new File("C:\\proj.png"));
}


现在,我想将正弦动画更改为快-慢-快,使其在峰值时变慢,因此我尝试了以下结果并得到了这个结果:我希望它是一样的,只是动画速度不同。码:

public static void main(String[] args) throws Exception{
    float velc = 200;
    float angle = 45;
    float resistance = 0f;
    double multiple = (velc * 2.5 / SINE_TO_180);
    int offset = 0;
    double y = 0;
    double x = 0;
    double h = 0;
    double cos = Math.cos(Math.toRadians(angle));
    double sin = Math.sin(Math.toRadians(angle));
    for(int i = offset; i < TIMES + 1 + offset; i ++){
        y += (1 - Math.sin(Math.toRadians(i * 2))) * multiple * sin;
        if(y >= h)
            h = y;
//          x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
        x += 2;
        //          x += multiple * cos;
//          if(i + offset < TIMES / 2){
//              x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
//          }else{
//              x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
//          }
    }
    y = Math.round(y);
    //do round x?
    x = Math.round(x);
    System.out.println("X: " + x);
    JFrame frm = new JFrame("Projectile!");
    frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    BufferedImage b = new BufferedImage((int)x + 1, (int)h + 1, BufferedImage.TYPE_INT_RGB);
    Graphics g = b.getGraphics();
    y = 0;
    x = 0;

    JLabel l = new JLabel(new ImageIcon(b));
    frm.add(l);
    frm.pack();
    frm.setVisible(true);

    for(int i = offset; i < TIMES + 1 + offset; i ++){
        y += (1 - Math.sin(Math.toRadians(i * 2))) * multiple * sin;
        x += 2;
//          x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5) * Math.abs(cos);
//          x += multiple * cos;
//          if(i + offset < TIMES / 2){
//              x += Math.sin(Math.toRadians(i)) * multiple * ((1 - resistance) * 1.5);
//          }else{
//              x += Math.sin(Math.toRadians(TIMES / 2)) * multiple * (1 - resistance);
//          }
        g.setColor(Color.red);
        g.drawLine((int)x, (int)(h - y), (int)x, (int)(h - y));
        l.setIcon(new ImageIcon(b));
        frm.repaint();
        Thread.sleep((int)(1000.0 / 24.0));
    }
    ImageIO.write(b, "png", new File("C:\\proj2.png"));
}


有人知道我在做错什么,因为我希望结果与第一个相同,只是动画速度不同?

最佳答案

如果您想要一个平滑的动画,我将数据和动画分开;

首先创建数据-这是一个(数学的)函数[含义f(x)-> y],因此您可以简单地将数组用于数据

private int endOfX = 100; //adjust as you wish
private int[] data;
public void calculateData(){
    data = new int[amendOfX ountPixels];
    for(int x = 0; x < endOfX ; x++){
        y = x*x; //this is an example, use your mathematical function here
    }
}


所以-现在您可以轻松地使用这些数据来提供平滑的动画

public class AnimationOfFunction(){
    public static void main(String[] args){
        new AnimationOfFunktion().createAndShowGui(); //as from java tutorials
    }

    private BufferedImage img;
    private Graphics gr;
    private void createAndShowGui(){
        calculateData(); first of all we create the data!
        JFrame frame = new JFrame();//then create your frame here
        JPanel panel = createContent(); //create your drawing panel here
        frame.add(panel);//adding drawing panel
        frame.pack(); //setting the proper size of frame
        frame.setVisible(true); //show frame
        startAnimation(panel); //this is important - after showing the frame you start your animation here!
    }
}


所以-这将是您应用程序的开始,现在该怎么办?首先创建一个适当的绘图面板:

private JPanel createContent(){
    //create a anonym class
    @surpress serial
    JPanel panel = new JPanel(){

        @override
        public void paintComponent(Graphics gr){
            super.paintComponent(gr);
            gr.drawImage(img, 0,0, null);
        }

    }
    panel.setPreferredSize(new Dimension(img.getWidth(), img.getHeight() ));
    return panel;
}


也是最重要的-您必须开始动画:

private void startAnimation(final JPanel panel){
    //create a anonym class
    Runnable r = new Runnable(){
        private int py = 0; //previous values
        private int py = 0; //previous values
        @overrdie
        public void run(){
            for(int x = 0; x < endOfX ; x++){
                int y = data[x];
                //now we have x and y, so you can plot your function;
                gr.drawLine(px, py, x,y); //you can scale here
                int sleeptime = calculateSleepTime(px,py, x,y);
                Thread.sleep(sleeptime);

                //set the previouse values;
                px = x;
                py = y;

                //important - repaint your panel to create an 'animation'
                panel.repaint();

            }
        }
    }

    //having that runnable we must start that runnable within an thread
    Thread thread = new Thread(r);
    thread.setDaemon(true);
    thread.start();
}


那么还剩下什么呢?我们必须计算出睡眠时间:如果两点之间的距离``大'',我们睡得更长一些;如果两点之间的距离很短,我们睡得更少...

public int calculateSleeptime(int px, int py, int x, int y){
    int distance = (y-py)*(y-py)+(x-px)*(x-px);
    distance = (int)(Math.sqrt(distance);
    int sleepTime = distance*100; //play with this value!
    return sleeptime;
}


我已经写完了所有代码,我没有任何IDE可以检查它是否包含任何拼写错误或编译错误,请自己动手做,以及我没有启动BufferedImage img ang Graphics gr 。但显然您已经可以做到!

关于java - Java-绘制正弦波,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25560701/

10-12 02:06