所以目前我正在开发一个类的项目,我需要通过drawLine()方法绘制sin(x)函数。目前这是我用来实现这个目的的循环:
int xShift = getWidth() / 50;
int xShift2 = getWidth() / 100;
int yShift = getHeight() / 10;
int yShift2 = getHeight() / 17;
int xStart = xShift;
int xEnd = xShift;
int yStart = getHeight() / 2;
int yEnd = getHeight() / 2;
int scale = getHeight() / 2;
for (double i = Math.PI / 32; i <= Math.PI * 2; i+= Math.PI / 32){
xEnd += getWidth() / 64;
yEnd = scale - ((int) Math.round(Math.sin(i) * scale));
g.drawLine(xStart, yStart, xEnd, yEnd);
xStart = xEnd;
yStart = yEnd;
}
这会输出如下内容:
我想要改变的是图表将在蓝色虚线的约束范围内,并且它也将到达2pi标记所在的灰色线的末尾(由蓝色箭头标记)。我该如何进行这些更改?
注意:这是我最大化窗口时的样子:
出于某种原因,sin图超出了我想要的范围。
感谢您的时间,感谢您提供的任何帮助。
答案 0 :(得分:1)
首先,让我们看看你在计算Y时所做的事情。
yEnd = scale - ((int) Math.round(Math.sin(i) * scale));
由于实际正弦函数介于-1和1之间,这意味着您的yEnd
将介于scale - scale
和scale + scale
之间。这意味着它将介于0(窗口边缘)和2×刻度之间。由于您的比例是窗口高度的一半,因此2倍比例表示窗口的整个高度。再次 - 窗口的边缘。
首先,想想如果您的规模较小会发生什么。如果不是高度/ 2,比例是(高度/ 2 - 10),那么2倍比例将是窗口高度 - 20.这或多或少是你想要的幅度 - 但它仍然按比例缩放 - 所以它仍然开始从边缘(试试吧!)。进一步缩小比例会降低振幅,但仍然会从边缘开始。
为防止这种情况,您应该更改公式。它不应该将正弦添加到scale
。想想:当正弦为-1时,你希望它与窗口中间的距离最远。当它为+1时,您希望线条距离窗口中间的距离最远。既然您更改了scale
,它就不再是窗口高度的一半,所以您不应该将它用作基线。
你应该有一个参数说“我的图形的基本高度是什么”,还有一个参数说“我的图形的最大振幅是多少”。这两个参数不应该相同:
int baseHeight = getHeight() / 2;
int amplitude = getHeight() / 2 - getHeight() / 50;
...
// In the loop
yEnd = baseHeight + ((int) Math.round(Math.sin(i) * amplitude));
使用这些参数,您将看到它们如何影响绘制图形的方式。
现在你的X.你想做64步代表2π。但是,如果您希望图形不如窗口宽,则步长不能为getWidth() / 64
。您从边缘开始width/50
,向其添加63 * getWidth() / 64
。由于width/50
超过width/64
,因此您的绘图宽度将超过宽度。
所以你需要计算图形的实际最终宽度:它应该是总宽度,不包括右边距和左边距。所以getWidth() - 2 * getWidth()/50
是实际宽度,每一步应该是 的1/64。
int step = ( getwidth() - getWidth() / 25 ) / 64;
...
// In the loop
xEnd += step;