java - 使正弦图移动

标签 java stddraw

public class SimpleHarmonic {
    public static void main(String[] args) {
        StdDraw.setXscale(0,900);
        StdDraw.setYscale(0,700);

        while (true) {
            StdDraw.setPenColor(StdDraw.BLACK);
            StdDraw.line(0,350,900,350); // x-axis
            StdDraw.line(450,0,450,900); // y-axis
            StdDraw.setPenColor(StdDraw.RED);

            for (double x = -450; x <= 450; x += 0.5) {
                double y = 50 * Math.sin(x * (Math.PI / 180));
                int Y = (int) y;
                int X = (int) x;
                StdDraw.line(450 + X, 350 - Y, 450 + X, 350 - Y);
            }
            StdDraw.clear();

        }
    }
}

在这段代码中,我尝试模拟简谐振动。但是,我只能绘制静态图,但我需要它连续移动。

我相信我需要使用循环来不断重绘点,但我不知道该怎么做。

如何让当前的正弦图连续移动?

编辑:投票结束为非编程? 什么?

最佳答案

我查看了您正在使用的 StdDraw 类,看起来您想要的是

StdDRaw.show(int) 方法,该方法注释指出:

/**
 * Display on screen, pause for t milliseconds, and turn on
 * <em>animation mode</em>: subsequent calls to
 * drawing methods such as {@code line()}, {@code circle()}, and {@code square()}
 * will not be displayed on screen until the next call to {@code show()}.
 * This is useful for producing animations (clear the screen, draw a bunch of shapes,
 * display on screen for a fixed amount of time, and repeat). It also speeds up
 * drawing a huge number of shapes (call {@code show(0)} to defer drawing
 * on screen, draw the shapes, and call {@code show(0)} to display them all
 * on screen at once).
 * @param t number of milliseconds
 */

在此库中,每当您调用绘制方法(例如linecircle)时,它都会有条件地重新绘制框架。通过将 int 参数传递给 draw 方法,它将把所有绘画方法转换为“动画模式”,并推迟重新绘制帧,直到您调用 draw()(无参数)。

<小时/>

要使其具有动画效果,您必须使 while 循环 1 个动画帧的每次迭代,每个帧都需要与前一帧不同。您可以通过在循环外部使用变量来将每个帧偏移一小部分来实现此目的。我将其称为偏移

有了这些信息,您可以将循环更改为:

    double offset = 0;
    while (true) {
        offset+=1; // move the frame slightly
        StdDraw.show(10); // defer repainting for 10 milisecoinds

        StdDraw.clear(); // clear before painting

        StdDraw.setPenColor(StdDraw.BLACK);
        StdDraw.line(0,350,900,350); // x-axis
        StdDraw.line(450,0,450,900); // y-axis
        StdDraw.setPenColor(StdDraw.RED);

        for (double x = -450; x <= 450; x += 0.5) {
            // apply the offset inside of calculation of Y only such that it 
            // slowly "moves" the sin wave
            double y = 50 * Math.sin((offset+x) * (Math.PI / 180));
            int Y = (int) y;
            int X = (int) x;
            StdDraw.line(450 + X, 350 - Y, 450 + X, 350 - Y);
        }

        StdDraw.show(); // end animation frame. force a repaint 
    }

<小时/> 代码中的一些改进

1 在循环中绘制每个“点”,并按 .5 递增。因为 X 值实际上是 1 像素,所以通过使用 .5 而不是 1,您不会获得任何结果。 1 确实是您在该环境中可以目视看到的最小的。我建议至少将其设为 x+=1

for (double x = -450; x <= 450; x += 1)

2 您正在使用 .line 方法,但绘制到同一点。通过仅计算每第三个像素的 Y 值并连接这些点,您可以显着加快程序速度。例如

double prevX = -450;
double prevY = 50 * Math.sin((prevX+offset) * (Math.PI / 180)); // seed the previous Y to start
for (double x = 0; x <= 450; x += 3) {
    double y = 50 * Math.sin((x+offset) * (Math.PI / 180));
    StdDraw.line(450 + (int)prevX, 350 - (int)prevY, 450 + (int)x, 350 - (int)y);
    prevX = x;
    prevY = y;
}

3 这不是您的代码,但在 StdDraw.init 方法中您可以设置一些渲染提示以允许更清晰的线条。这应该会让它看起来更好

offscreen.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, 
                           RenderingHints.VALUE_STROKE_PURE);
<小时/>

将所有这些内容结合起来就是我写的

public static void main(String[] args) {
    StdDraw.setXscale(0,900);
    StdDraw.setYscale(0,700);

    double offset = 0;
    while (true) {
        StdDraw.show(10);
        StdDraw.clear();
        offset-=1;

        StdDraw.setPenColor(StdDraw.BLACK);
        StdDraw.line(0,350,900,350); // x-axis
        StdDraw.line(450,0,450,900); // y-axis
        StdDraw.setPenColor(StdDraw.RED);


        double prevX = 0;
        double prevY = 50 * Math.sin((prevX+offset) * (Math.PI / 180)); // seed the previous Y to start
        StdDraw.filledCircle(450 + prevX, 350 - prevY, 5);

        for (double x = 0; x <= 450; x += 3) {
            double y = 50 * Math.sin((x+offset) * (Math.PI / 180));
            StdDraw.line(450 + (int)prevX, 350 - (int)prevY, 450 + (int)x, 350 - (int)y);
            prevX = x;
            prevY = y;
        }
        StdDraw.show();

    }
}

我没有动画录制器,所以这是一张图片 Screenshot

关于java - 使正弦图移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37648830/

相关文章:

java - 随机游走解决方案问题

java - 使用递归绘制树

java - 如何为 StdDraw 导入正确的包?

java - 如何正确 stub 外部方法?模拟语句上的 NullPointer

java - 在 Java 程序中存储动画 GIF 图像

java - 如何从 JFrame 获取文本

java - Comparator<T> 如何成为函数式接口(interface)?

java - 如何使用Spring+Hibernate查询join表