2012-03-14 155 views
2

我想創建一個小型控制器,有點像汽車裏的車速表,只是它只能跨越180度。如何計算旋轉圖像的正確位置偏移量?

要呈現控件我使用兩個圖像文件。第一個只是測量儀的背景,顯示了一個從0度的綠色變爲180度的紅色的半圓。第二個圖像是一個垂直箭頭,高度與半圓半徑大致相同,略低於背景圖像的高度。

我使用以下標記來呈現控制:

<div class="gauge" id="@Model.ClientID"> 
    <img class="gauge" alt="" src="@Url.Content("~/images/icons/gauge-bg.png")" /> 
    <img class="arrow" alt="" src="@Url.Content("~/images/icons/gauge-arrow.png")" /> 
</div> 

的圖像被以使它們重疊相對定位在div內部。背景圖像是120x63像素,箭頭圖像是12x58像素(WxH),但如果解決問題更容易,可以進行調整。在應用任何旋轉之前,箭頭圖像會直線向上。

我有一個百分比(從0到100),我轉化爲箭頭圖像(從-90至90),它看起來像這樣的旋轉角度:

// input value for the offset calculations (see below) 
public double ArrowRotationDegrees 
{ 
    // 0 for 0%, 90 for 50% and 180 for 100% 
    get { return 180.0 * Percent/100; } 
} 

// input value for the jquery rotate plugin as our base arrow points vertically up 
public double ArrowRotationDegreesRelative // -90 for 0%, 0 for 50% and 90 for 100% 
{ 
    // -90 for 0%, 0 for 50% and 90 for 100% 
    get { return ArrowRotationDegrees - 90; } 
} 

爲了執行旋轉我正在使用jquery-rotate,它似乎總是圍繞圖像的中心旋轉。

<script type="text/javascript"> 
    $(document).ready(function() { 
     var arrow = $('#@Model.ClientID').find('img.arrow'); 
     arrow.rotate(@Model.ArrowRotationDegreesRelative); 
     arrow.css({left: @Model.ArrowLeftShiftPixels, top: @Model.ArrowTopShiftPixels}); 
    }); 
</script> 

但是我怎麼計算重新定位旋轉的圖像正確的偏移,使得箭頭總是從背景圖像的確切中心底點?

更新 - 解

基於埃裏克J.答案我能調整我的代碼,並獲得工作的結果,而不改變標記:

public int ArrowLeftShiftPixels // used to position rotated image correctly horizontally 
{ 
    // default offset (no rotation) is left:55 
    get { return 55 - GetArrowLeftShift(ArrowRotationDegrees); } 
} 

public int ArrowTopShiftPixels // used to position rotated image correctly vertically 
{ 
    // default offset (no rotation) is top:5 
    // formula output is shifted (max appears where min should be); add 29 to reverse this effect 
    get { return 34 - GetArrowTopShift(ArrowRotationDegrees); } 
} 

public int GetArrowLeftShift(double degrees) 
{ 
    var result = (58.0/2) * Math.Cos(degrees * Math.PI/180); 
    return (int) Math.Round(result, 0); 
} 

public int GetArrowTopShift(double degrees) 
{ 
    var result = (58.0/2) * Math.Sin(degrees * Math.PI/180); 
    return (int) Math.Round(result, 0); 
} 

感謝所有幫助和建議!

回答

1

我還沒有詳細看過問題的具體數字(是指在底部指出的箭頭,反之亦然?),但是您可能會發現箭頭的提示向左或向右移動圖片的中心由(half it's length) * cos(Angle),而他們上移或下移(half it's length) * sin (Angle)。確保在指定角度時使用弧度或角度,以適合用於計算sin和cos的trig庫。

如果您在C#中計算服務器端的sincos,請使用弧度。

Here's an explanation如何旋轉任意角度(匹配我剛剛解釋,但圖表可能會有所幫助)。注意在你的情況下,初始角度爲0,因此初始公式是

x = 0時(因爲COS(0)= 0) Y = R(由於r * SIN(0)= R)

+0

起初,我無法完成這項工作,直到我創建了工作/預期輸出值表並將其與計算結果進行比較。 TopShift值會以某種方式發生變化(最小值出現在最大值出現的位置),但一旦發現問題很容易進行補償。謝謝! – 2012-03-15 00:06:16

1

您可以在兩個維度中生成大約是圖像大小兩倍的div。然後,您將圖像放置在該div的內部,因此圖像的樞軸點(箭頭的底部)位於div的一半高度和寬度處。然後,您可以將div轉換爲正確的區域(因此圖像的關鍵點位於正確的區域),然後在div上執行旋轉。

編輯:這裏有一個的jsfiddle解釋它 http://jsfiddle.net/pVpE7/

+0

我嘗試添加一個包裝div,但是我無法想出任何有效的工作,所以我回去計算偏移量。它看起來應該工作,如果我做了正確的事情,所以+1) – 2012-03-15 00:12:15

1

看一看this example。說明:

rotate插件不允許您指定錨點 - 它總是圍繞中心旋轉。我簡單地將箭頭的大小加倍,以便在儀表寬度上延伸。旋轉此箭頭可以獲得所需的效果。對CSS進行微小的調整以保持控制中的箭頭溢出部分。

+0

我也看了這個,你顯然有一些工作(+1),但我無法將其轉化爲一些東西爲我工作。 – 2012-03-15 00:13:32