2014-01-12 61 views
1

我正在研究一個用於畫布的庫,我無法弄清楚我應該如何圍繞對象的中心進行旋轉。下面是我用來渲染它們的函數以及我給它的一個示例對象。自定義旋轉算法需要可擴展性

我覺得有一個更好的方法來做4 if陳述,但我無法弄清楚它的數學。目前,我正在拍攝物體的每個「像素」並圍繞中心旋轉,但我無法看到擴展空間。我究竟做錯了什麼?

//Rendering function 
Display.prototype.renderObject = function(object, direction) { 
    if (typeof object.rotation !== 'number') object.rotation = 0; 
    for (x=0;x<object.bounds.x;x++) { 
     for (y=0;y<object.bounds.y;y++) { 
      rotation = 45; 
      if (x==0 && y==0) rotation += 0; 
      if (x==0 && y==1) rotation += 90; 
      if (x==1 && y==0) rotation += 270; 
      if (x==1 && y==1) rotation += 180; 
      display.drawRect(object.color[x][y], 
       (display.width/2) - (players[playerIndex].position.x * 16) + (object.position.x * 16) - (object.bounds.x * object.scale)/4 - (object.bounds.x/3 * object.scale * Math.cos((object.rotation+rotation)*(Math.PI/180))), 
       (display.height/2) + (players[playerIndex].position.y * 16) - (object.position.y * 16) - (object.bounds.y * object.scale)/4 - (object.bounds.y/3 * object.scale * Math.sin((object.rotation+rotation)*(Math.PI/180))), 
       object.scale, object.scale, object.rotation * (direction || 1)); 
     } 
    } 
}; 

// Example object 
block = { 
    "color": [ 
     ["#FFF","#CCC"], // Some colors to make 
     ["#999","#666"] // a shaded illusion 
    ], 
    "position": { 
     "x": 0, 
     "y": 0 
    }, 
    "bounds": { 
     "x": 2, // color[0].length 
     "y": 2 // color.length 
    }, 
    "rotation": 0, // 0 to 360 
    "scale": 4 // real pixels per object pixel 
} 

// Example usage 
Display.renderObject(block); 

- 編輯 -

也許我需要把它計算每個像素的中心座標會是這樣,那麼獲取對象的原點和旋轉每個像素將是來自距離抵消在。

如果x = 0y = 0,那麼它的+45度罪和-45度COS +45度罪。如果(object.bounds.x-1)/2爲我們提供了用於處理x的中心座標系,那麼Math.sqrt(Math.pow(x,2)+Math.pow(y,2))給出了從對象中心開始的顏色塊的半徑。我不確定該從哪裏出發。

回答

2

我不是100%肯定你問的,但如果它是如何繞點中心點你所有的點翻譯,讓你的對象旋轉圍繞origin或居中如果你喜歡,請點[0, 0]

旋轉矩陣總是圍繞原點旋轉,所以沒有辦法繞過(沒有雙關語意)。

因此,在旋轉點之前,請計算在旋轉之前應用的增量值,然後旋轉然後反轉增量值,然後再次應用以相對於原點的偏移量來返回對象。

所以,第一步是計算三角洲以找出需要多少轉換點以使它們進入中心。

對於一個矩形很容易:這是它的x和y位置以及其寬度的一半和高度:

deltaX = x + width * 0.5; 
deltaY = y + height * 0.5; 

這個值,那麼你需要減去的點。你如何應用這個三角洲取決於你:你可以預先對每個點進行操作,或者將它直接注入到公式中。

然後旋轉,完成後,只需將增量值再次添加到每個點。

這是基於my article here較短版本的旋轉矩陣:

var a = rotation * Math.PI/180; /// calculate angle once 
x -= deltaX;      /// apply pre-translation 
y -= deltaY; 

/// rotate and apply post-translation 
nx = x * Math.cos(a) + y * Math.sin(a) + deltaX; 
ny = y * -Math.sin(a) + x * Math.cos(a) + deltaY; 

if是你正在使用似乎都來自於該用這個角度的優化代碼;當你使用0和90時,cos和sin分別產生1和0。然而,你並沒有利用這種優化,因爲當這些情況發生時,你可以簡單地將x換成y等等。然而,你綁定到x和y位置,所以我不確定你在這裏實現了什麼。

我建議你只是刪除他們爲你計算並反正適用正弦/餘弦 - 你可以代替緩存正弦和餘弦並使用這些所有的點:

var angle = rotation * Math.PI/180; 
    sin = Math.sin(angle), 
    cos = Math.cos(angle), 
    ...calc deltas here... 

...enter loop here, then for each point:... 
x -= deltaX; 
y -= deltaY; 
nx = x * cos + y * sin + deltaX; 
ny = y * -sin + x * cos + deltaY; 

現在成本較低每個點和您的計算將會執行得更快。

希望這會有所幫助。