2017-03-16 17 views
2

我目前正在C中做一些2D幾何圖形,大多數是相交的線條。這些線條有各種各樣的斜坡:從0.001到1000(例如,我甚至不知道)。C浮點數:如何在二維幾何圖形中繞過它們(線條)

我到目前爲止使用的是浮點數,並且不必擔心值是否非常小(然後浮點數將存儲0,0011作爲1e-3而沒有舍入)或非常高(然後1001會是存儲爲1e3),在這兩種情況下,相關的精度損失很小。

但現在我想嘗試沒有浮動,整數。如何保持我的計算精度?我可以有一面旗幟告訴我坡度是大還是小,然後考慮十分之一的大斜坡和十倍的小坡度,這樣對於小坡地來說,四捨五入就不成問題,並且在大坡度的情況下沒有溢流。但那感覺像是頭痛。

基本上我需要仍然能夠區分0.2和0.4的斜率,以及1000和2000的斜率(假設在1000處溢出的內部溢出 - 這裏沒有問題)。

還有其他想法嗎?

+2

除了存儲上升和運行? –

+2

使用「double」並與不精確度相符?爲什麼你需要超過15位十進制精度的有效數字?這個精確度足以測量從這裏到冥王星的距離,單位爲釐米。 – Bathsheba

+1

做計算幾何時,你總會有不精確的地方,因爲你總會有不合理的數字。 –

回答

6

商店斜率作爲一對整數

struct slope { 
    int delta_y; 
    int delta_x; 
}; 

的這允許像0+/- 1/INT_MAX ... +/- INT_MAX,甚至垂直廣泛斜坡。通過仔細的編碼,可以進行精確的計算。

Tardy信用:這很像@Ignacio Vazquez-Abrams comment

+1

這是個不錯的主意,特別是如果你可以使用'slope'實例而不必計算梯度。儘管我可能會考慮讓其中一個成員'unsigned',但是我想你可以在構造上理清這種事情,因爲無論如何你都可以「正常化」輸入(例如{-2,-4})是與{1,2}相同)。 – Bathsheba

+0

@Bathsheba同意make一個字段'unsigned'和'int numerator;無符號的分母;'。它使一些計算有點tricker,但。 'int delta_y,delta_x;'似乎是向OP介紹想法的好方法。 – chux

+1

你也可以進入熱水中,不需要將簽名參數提升爲未簽名參數的類型。 – Bathsheba

0

查找fixed point arithmetic如果您想以一般方式使用int。

您也可以設計自己的算法,以便您不需要子整數精度(例如查詢Bresenham's linecircle繪圖算法)就可以進行每項計算。

針對您的特定問題,您可以嘗試分開保留商和分數,換句話說就是使用有理數。或者換句話說,將delta X和delta Y作爲兩個數字。

3

一般來說,對於任意方向的線條,不建議使用斜率/截距表示y = mx + p,但使用隱式方程a x + b y + c = 0。後者更爲各向同性,支持垂直線條,併爲您提供額外的靈活性來縮放係數。

會議@ chux的答案,係數可以是增量,(假設行由兩點定義,DxDy很可能不會溢出)。在c上仍有可能溢出,您可以使用變體Dy (x - x0) - Dx (y - y0) = 0

無論如何,諸如交叉點的中間計算可能需要更大的範圍,即雙倍長度的整數。

標記大/小值的想法有點起反作用:它實際上是一種做浮點的原始方式,即將尾標與尾數分開。以這種方式工作,您將以某種方式重新設計一個foaming-point系統,這個系統比內置類型功能強大,並且讓您流汗和流淚。


不幸的是,高範圍算術無法避免。實際上,兩條直線的交點由克拉默給出的公式

x = (c b' - c' b)/(a b' - a' b), 
y = (a c' - a' c)/(a b' - a' b) 

其中產品要被評估的數量級比初始係數較大的一個數量級。這可以通過準平行線具有很遠的交點來解釋。

相關問題