我重新实现Processing的rotate()方法的错误

时间:2016-07-03 23:59:34

标签: rotation processing renderer

为了更好地理解Processing的绘图技巧(特别是translate()rotate()函数),我开始寻求重新实现translate()rotate()和{ {1}}方法。

在这样做的时候,我很快就经历了游戏结束,当我完全陷入point()方法时,其行为只是疯了。显示围绕多个轴的一些奇怪的(3D)旋转。

Comparison of my reimplementation (left) to the language's implementation (right)

为每个点执行旋转的代码:

 
rotate()

完整代码

x = x * c - y * s; // cos(a) * cos(b) - sin(a) * sin(b)
y = y * c + x * s; // sin(a) * cos(b) + cos(a) * sin(b)

1 个答案:

答案 0 :(得分:0)

在结束我的问题时,我发现了错误。写下来可能有所帮助。如何再次重复初学者的错误仍然令人尴尬!

我仍然上传了这个问题,因为我已经写完了。可能对某人有帮助,但我不知道。

错误过早地覆盖了class MyRenderer { /* Added to every point - set through translation. */ int xOffset = 0; int yOffset = 0; /** Prevents unnecessary rotations around an angle of 0. Owed to the architecture. */ boolean rotated = false; /** The values of c(osine) and s(ine) in the unit circle, for the given angle. * This way they don't have to be recalculated for every single point. */ float c, s; private void myTranslate(final int x, final int y) { xOffset += x; yOffset += y; } /** Actual rotation, transforming each point's coordinates, done in myPoint() */ private void myRotate(final int deg) { c = cos(radians(deg)); s = sin(radians(deg)); rotated = true; } /** Draws the points to the screen with respect to the set translation and rotation. */ private void myPoint(float x, float y) { // First rotate... if (rotated) { // Only do the transformation if a rotation actually occured. x = x * c - y * s; // cos(a) * cos(b) - sin(a) * sin(b) y = y * c + x * s; // sin(a) * cos(b) + cos(a) * sin(b) } // ... then translate. x += xOffset; y += yOffset; // Finally draw. point(x, y); } // Needed to reset the translation and rotation with every draw call - like the original. private int debugAngle = 0; public void myDraw() { reset(); background(255); myTranslate(50, 50); myRotate(debugAngle++); // Point cloud in shape of a square. myPoint(0, 0); myPoint(-10, -10); myPoint( 0, -10); myPoint( 10, -10); myPoint( 10, 0); myPoint( 10, 10); myPoint( 0, 10); myPoint(-10, 10); myPoint(-10, 0); } /** Reset all scene transforms, mirroring the behavior of Processing's draw() method. */ private void reset() { xOffset = 0; yOffset = 0; c = 1; // cos for 0 degrees. s = 0; // sin for 0 degrees. rotated = false; } } /* ========================================================================================= */ MyRenderer r; void setup() { size(200, 100, FX2D); frameRate(30); r = new MyRenderer(); } int debugAngle = 0; void draw() { r.myDraw(); debugRender(); } /** Diplay a second 'rectangle' to compare the results of my renderer reimplementation to. */ void debugRender() { translate(100, 50); rotate(radians(debugAngle++)); // Point cloud in shape of a square. point(0, 0); point(-10, -10); point( 0, -10); point( 10, -10); point( 10, 0); point( 10, 10); point( 0, 10); point(-10, 10); point(-10, 0); } ,错误地使用已经旋转的x值而不是非变换的x导致x误算。

而不是

y

必须对转换后的x进行缓冲,直到完全依赖原始x的所有计算完成:

x = x * c - y * s; <== ERROR
y = y * c + x * s;