Java 等式 5((θ/β) - cos(2πθ/β)) 的 Swing GUI - 绘制连续图形

Java Swing GUI for equation 5((θ/β) - cos(2πθ/β)) - to draw continuous graph

这是我之前问题的扩展post在这里 --

我已经根据 post 中提供的答案实施了 Java 程序,这是我的程序:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class DisplacementFunctionNew extends JFrame {
    public DisplacementFunctionNew() {
        setLayout(new BorderLayout());
        add(new CosGraph(), BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        DisplacementFunctionNew frame = new DisplacementFunctionNew();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(6000, 6000);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);
        frame.setTitle("SineWave");
    }

    class CosGraph extends JPanel {
        public void paintComponent(Graphics g) {

            int graphHeight = 5; // Declared this to set the height of graph based on the value given here.

            super.paintComponent(g);
            int xBase = 100;
            int top = 100;
            int yScale = 100;
            int xAxis = 360;

            int yBase = top + yScale;

            g.drawLine(xBase, top, xBase, top + 2 * yScale);
            g.drawLine(xBase, yBase, xBase + xAxis, yBase);

            g.setColor(Color.red);

            double maxY = 0;
            for (int i = 0; i < 360; i++) {
                maxY = Math.max(maxY, Math.abs(getValue(i)));
            }

            int x, y;


            for (int i = 0; i < 360; i++) {

                x = xBase + i;
                y = yBase - (int) (getValue(i)*graphHeight / maxY * yScale);
                g.drawLine(x, y, x, y);

            }
        }

        private double getValue(int theta) {
            int beta = 45;
            double b = (theta / (double) beta);
            double angle = 2 * Math.PI * (b);
            double c = Math.cos(angle);

            double s = (b - c);
            return s;
        }
    }
}

现在在这个程序中我想要一个名为 graphHeight 的变量来帮助增加图形的高度。如果我将变量的值指定为 1 那么我可以看到这样的输出:

现在,如果我尝试将高度增加到 5,那么我会得到图形,但它显示的不是平滑的或连续的曲线,我得到的输出如下:

有人可以帮助我如何获得平滑连续曲线的输出吗?

您使用 graphHeight 定义下一个要绘制的点的 y g.drawLine(x, y, x, y);。绘制点之间的距离将与 graphHeight 变量有关

您正在使用点绘制曲线。您在 x 轴上的每个位置放置一个点——这样做很有意义。

当图很小的时候,看起来还不错,因为这些点的y间隔比较小。但是,随着图形大小的增加,此缺陷变得更加明显。

这里的解决方法是用线条填充垂直的space。您有几个选项可以准确实施此操作:

  1. 从 [x(i), y(i)][x(i+1),y(i+1)] 画一条线 -- 这很简单,但看起来可能不是您想要的样子。
  2. 从 [x(i), y(i)][x(i),y(i+1)] 画一条线 -- 这仍然很简单,但它不会很正确:你继续向上,这样你就可以成为一个完整的人像素关闭。
  3. 从 [x(i), y(i)][x(i),(y(i)+y(i+1))/2] 画一条线,然后从 [x(i+1), (y(i)+y(i+1))/2][x(i+1),y(i+1)] 画一条线——这就是 1 应该做的(忽略抗锯齿) ), 并且将是您可能的选项中最正确的。

我建议数字 3。请注意,您可以使用以下形式的循环来实现它:

        int lastY = yBase - (int) (getValue(0)*graphHeight / maxY * yScale);
        for (int i = 1; i < 360; i++) {

            x = xBase + i;
            y = yBase - (int) (getValue(i)*graphHeight / maxY * yScale);
            g.drawLine(x-1, lastY, x-1, (y+lastY)/2);
            g.drawLine(x, (y+lastY)/2, x, y);

        }

如果一个像素的重叠让您感到困扰,您可以让它更复杂一点,例如第二行从 +/- 1 像素开始(取决于函数是增加还是减少)。


或者,您可以通过使用 for 循环手动绘制直线来实现数字 3,基本上编写 Bresenham 直线算法的特例版本。