使正弦图移动
Making a sine graph move
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
class 好像你要的是
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
*/
在这个库中,只要您调用 line
或 circle
等绘制方法,它就会有条件地重新绘制框架。通过将 int
参数传递给 draw
方法,它会将所有绘画方法转换为 "animation mode" 并推迟重新绘制框架,直到您调用 draw()
(无参数)。
要使其具有动画效果,您必须使 while
循环的每次迭代都为 1 个动画帧,每一帧都需要与前一帧不同。您可以通过在循环外部使用一个变量来将每个帧偏移一个小的量来做到这一点。我称之为 offset
使用此信息,您可以将循环更改为:
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 在你绘制每个 "dot" 的循环中你正在增加 .5
。因为那个 X 值实际上是 1 个像素,所以你不会通过 .5
而不是 1
获得任何东西。从字面上看,1 是您在此环境中可以目视看到的最小值。我建议至少要 x+=1
for (double x = -450; x <= 450; x += 1)
2 您正在使用 .line
方法但绘制到同一点。您可以通过仅计算每 3 个像素的 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();
}
}
我没有动画录像机所以这是一张照片
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
class 好像你要的是
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
*/
在这个库中,只要您调用 line
或 circle
等绘制方法,它就会有条件地重新绘制框架。通过将 int
参数传递给 draw
方法,它会将所有绘画方法转换为 "animation mode" 并推迟重新绘制框架,直到您调用 draw()
(无参数)。
要使其具有动画效果,您必须使 while
循环的每次迭代都为 1 个动画帧,每一帧都需要与前一帧不同。您可以通过在循环外部使用一个变量来将每个帧偏移一个小的量来做到这一点。我称之为 offset
使用此信息,您可以将循环更改为:
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 在你绘制每个 "dot" 的循环中你正在增加 .5
。因为那个 X 值实际上是 1 个像素,所以你不会通过 .5
而不是 1
获得任何东西。从字面上看,1 是您在此环境中可以目视看到的最小值。我建议至少要 x+=1
for (double x = -450; x <= 450; x += 1)
2 您正在使用 .line
方法但绘制到同一点。您可以通过仅计算每 3 个像素的 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();
}
}
我没有动画录像机所以这是一张照片