这个问题是出于学习目的。我正在编写自己的函数来绘制方程式。例如:
function e(x) { return sin(x); }
plot(e);
我写了一个将函数作为参数的绘图函数。绘图代码很简单,x从某个值运行到某个值并逐步增加。这是plot()
设法生成的情节。
但是有问题。它不能像x 2 + y 2 = 1那样表达圆方程。所以问题是如何绘制图和方程函数以便能够处理两个变量
注意到我不仅对两个圆方程感兴趣。用两个变量绘制函数的更通用的方法。
答案 0 :(得分:1)
函数的定义:函数f接受输入x,并返回单个输出f(x)。
现在它意味着任何输入都会有一个唯一的输出。像y = sin(x)
一样。这是x
和y
定义函数的函数。
与(x*x) + (y*y) = 1
相同。单个值为x的y
有两个可能的值,因此它不能被称为函数的有效等式。
如果您需要绘制它,那么一种可能的解决方案是为x
的单个值绘制两个点,即sqrt(1-(x*x))
和其他-1*sqrt(1-(x*x))
。绘制两个值(一个将为正,另一个将为负,具有相同的绝对值)。
答案 1 :(得分:1)
为了绘制非函数1D方程(x,y
变量),你有3个选择:
转换为参数形式
所以例如x^2 + y^2 = 1
将成为:
x = cos(t);
y = sin(t);
t = <0,2*PI>
因此,当t
用作参数时,将每个函数绘制为1D函数图。但是为此你需要利用数学身份和替代...这不是很容易做到的。
转换为1D功能
非功能意味着某些1
值的值超过y
x
。如果将方程式分成间隔并除以覆盖整个图的所有情况,则可以绘制每个派生函数。
所以你得出y
代数(再假设单位圆):
x^2 + y^2 = 1
y^2 = 1 - x^2
y = +/- sqrt (1 - x^2)
----------------------
y1 = +sqrt (1 - x^2)
y2 = -sqrt (1 - x^2)
x = <-1,+1>
这也不容易以编程方式完成,但比#1 更容易。
使用公式作为谓词
进行2D绘图简单地将视图循环遍历所有像素,并仅渲染等式为真的那些像素。所以再次单位圈:
for (x=-1.0;x<=+1.0;x+=0.001)
for (y=-1.0;y<=+1.0;y+=0.001)
if (fabs((x*x)+(y*y)-1.0)<=1e-6)
plot_pixel(x,y,some_color); // x,y should be rescaled and offset to the actual plot view
所以你只需将等式转换为隐式形式:
x^2 + y^2 = 1
-----------------
x^2 + y^2 - 1 = 0
并与某个阈值进行比较(以避免FPU准确性问题):
| x^2 + y^2 - 1 | <= threshold_near_zero
阈值是绘图线宽度的一半。因此,通过这种方式,您可以轻松地将绘图宽度更改为任何像素大小......正如您所看到的,这很容易以编程方式完成,但由于您需要遍历绘图视图的所有像素,因此绘图较慢。 x,y
for
循环的步骤应与视图比例的像素大小匹配。
同样在使用方程式作为谓词时,您应该处理数学奇点,就像盲目探测一样,您很可能会遇到一些像零除,asin,acos,sqrt
的域错误等等。
因此,任意 1D 非功能使用#3 。除非你为#1 或#2 获得了一些强大的符号数学引擎。