缩放绘制函数的algorithm

我在android中做游戏,我需要绘制一个函数,我的algorithm是这样的:

@Override protected void onDraw(Canvas canvas) { float e = 0.5f; //from -x axis to +x evaluate f(x) for (float x = -z(canvas.getWidth()); x < z(canvas.getWidth()); x+=e) { float x1,y1; x1 = x; y1 = f(x); canvas.drawPoint((canvas.getWidth()/2)+x1, (canvas.getHeight()/2)-y1, paintWhite); } super.onDraw(canvas); } 

这是如何工作的。 如果我的函数是,例如f(x)= x ^ 2,那么z(x)是sqrt(x)。 我评估-z(x)到z(x)之间的每个点,然后绘制它们。 正如你所看到的,我使用屏幕大小的一半将function放在屏幕中间。 问题不是代码不工作,实际上是绘制函数。 但是,如果屏幕是320 * 480那么这个function将会像下面的图片一样非常小。 我的问题是:如何改变这个algorithm来缩放函数? 顺便说一句,我真正想要做的是追踪一个路线,以后显示一个animation精灵,所以实际上缩放这个图像不会帮助我。 我需要改变algorithm,以绘制相同的间隔,但在一个更大的空间。 任何提示帮助,谢谢!

当前的工作结果

在这里输入图像说明

期望的结果

在这里输入图像说明

更新:我会尽力解释更多的问题是什么。 给定这个区间[-15 … 15](-z(x)到z(x)),我需要把这个点分成更大的区间[-320 … 320](-x到x)。 例如,当你使用这样的一些绘图软件。 虽然包含函数的div具有640像素的宽度,但您不会看到间隔是从-320到320,您会看到间隔是从-6到6.我怎样才能实现这个目标?

就像Anastasios提到的那样,最好为自己创建一个“虚拟坐标空间”,计算这个虚拟空间中的所有东西,然后在绘制时转换为像素坐标。

基本上,对于水平轴,您可以创建一个从虚拟坐标<=>像素坐标转换的函数。 在c + +伪代码将是这样的:

 int virtualToScreenX(float vx) { return floorf(((vx - virtualMinX) / (virtualMaxX - virtualMinX)) * physicalWidth); } float screenToVirtualX(int sx) { return virtualMinX + (sx / (float)physicalWidth) * (virtualMaxX - virtualMinX); } 

然后,您可以通过replace相应的variables名称来为Y轴执行相同的操作。 这些可以通过预先计算和caching一些项来优化,并且通过预先计算的项将分割转换为乘法。 如果您的窗口更改了维度,则可能需要重新计算caching的术语。

你也应该关心宽高比。 要做到这一点,你select你的“主”轴,通常是Y,然后你通过这个纵横比在另一个轴上缩放你的虚拟范围。

像这样:

 const float virtualMinY = -1.0f; const float virtualMaxY = 1.0f; const float aspect = physicalWidth / (float)physicalHeight; const float virtualMinX = -1.0f * aspect; const float virtualMaxX = 1.0f * aspect; 

现在,不管纵横比如何,你的function或精灵path总是看起来是正确的。

看起来你并不是真的想要缩放,但是为了完整起见,你只需要缩放你的虚拟坐标范围(virtualMinX,virtualMaxX,virtualMinY,virtualMaxY)。

要放大3倍,缩放系数是1.0f / 3.0f。 要缩小5倍,是5.0f;

(请记住在更改缩放级别后重新计算任何caching的值)

只要findf(x)垂直不在屏幕上的值即可。 然后,将屏幕缩放到该x值。

所以,从函数的中间开始,找出f(x)值超出屏幕的范围,并将其缩放到那里。

如果你想“缩放”function,你应该改变你的input范围(或在math术语的function领域)。 我建议你让你的域名与屏幕大小无关。 此外,为了使您的显示与屏幕尺寸无关,您应该使用标准化坐标(例如[-1 … 1]或[0 … 1])。 屏幕坐标标准化非常简单,只需将屏幕的大小分开即可。