青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

【譯】構建CCS Sprites快而優的矩形打包算法

構建CCS Sprites快而優的矩形打包算法

介紹

(譯者注:略)

內容

(譯者注:略)

安裝

(譯者注:略)

簡單的解決方案

這有幾個簡單的方案講述如何打包多個矩形到一個封閉的矩形中:

你可以將所有矩形在水平方向上一字排開,就像這樣:


這很簡單也很快,并且可以在所有矩形高度一致時表現的很好。

或者你可以在水平方向上排列,就像這樣:


這依舊簡單快捷,并且當所有矩形寬度一致時表現良好。

但是,這些方案在這些矩陣擁有不同的寬度和高度時留下大量被浪費的空間。這很煩人。所以接下來我們將關注在打包不同寬度和高度矩形時將這種浪費最小化,當然也要盡可能的快和簡單。

基本算法

打包多個矩形到盡可能小的封閉矩形的基本算法在Richard E. Korf的文章有有被描述:Optimal Rectangle Packing: Initial Results

1.根據高度對矩形進行排序,最高的排第一。

2.閉合矩形初始設置為:高度為最高矩形的高度,寬度無限大。

3.將矩形一個個的放入封閉矩形中,由最高的矩形開始,到最矮的矩形結束。放置每個矩形時盡可能靠左。如果有多個左邊位置,使用最高的那個(If there are several left most locations, use the highest one )。比如:

a) 

b) 

c) 

d) 

e) 

4.讓閉合矩形的寬度等于弄好的所有矩形的總寬度。即:將閉合矩形的右邊緣向左移動,直到接觸到最右邊矩形的右邊緣。這樣的話,閉合矩形寬度正合適。

5.你已經將所有矩形放置在閉合矩形內了嗎?如果這樣的話:

如果你得到的這個閉合矩形是目前最小的且“成功”的,將它保存起來。

試著寬度減一來獲取更小的閉合區域。

6.然而,如果你沒有全部將矩形放置在閉合矩形內,很顯然閉合矩形小了。如果這樣的話,將高度加一。(譯者注:就這樣重復執行放置矩形到閉合矩形內,直到得到一個原始最佳寬度減一×原始高度不斷加一加到能將所有矩形都放入這個新閉合矩形內,其實并不是笨笨的加一,往下看,改進基本算法部分有提到這步具體做法)請注意,減寬度加高度實際上意味著我們將閉合矩形的范圍從矮寬到高瘦。比如,當寬度被減少、高度被增加幾次后,你可能會得到如下的序列:

a) 

b) 

c) 

d) 

e) 

 

7.如果你得到的閉合矩形的總面積(寬×高)比所有將放入其中的矩形的面積之和還要小,那這明顯不是一個可行的閉合矩形。高度增加一直到你得到一個可行的閉合矩形。然后進入到下一步。

8.如果你獲得的這個閉合矩形比迄今為止最好的閉合矩形要大,那么對它進行測試并無意義。寬度減一然后重復第七步來確保不是小了,否則進入下一步。

9.如果你的新的閉合區域比最寬的矩形要窄,你就可以停下了,并且匯報你得到的最佳閉合矩形。這是因為我們這個算法從不會增加閉合矩形的寬度,并且如果最寬矩形都放不下,這明顯不需要再測試這個閉合矩形了。(If your new enclosing rectangle is narrower than the widest rectangle, you can stop now, and report the best enclosing rectangle you found so far. This is because the algorithm never increases the width of the enclosing rectangle, and if the widest rectangle won't fit, there is obviously no point in testing the enclosing rectangle.)

10.現在你的新閉合矩形既不太小,也不太大,返回第三步去看看你是否可以將所有矩形放進去。

這個算法已經在下載工程Mapper中的類MapperOptimalEfficiency的函數Mapping中實現了。

稍后我們將看看如何將這個基本算法做的更快些。但是首先讓我們看看如何將矩形放入閉合區域中,最主要的是如何記錄已放入的矩形來防止新加入矩形與他們重疊。

在一個給定的閉合矩形內安放矩形而不與其他矩形重疊

上面基本算法中的第三步寫到“將矩形一個個的放入閉合矩形內,從最高的矩形開始,最矮的結束。放置每個矩形時盡可能的靠左,如果有好幾個左邊位置,用最高的那個。”

為了找到最左最高的位置來放置一個給定寬度和高度矩形而不與其他矩形重疊,我們需要用一些數據結構來記錄閉合矩形中已被占用的區域。并且這個數據結構必須既簡單(這樣不容易出錯)又能快速找到矩形可以被放置的那個最左最高位置。

可以使用一個二維布爾數組,每個格子代表閉合區域中的一個像素。每個布爾標記這個像素是否被占用還是空閑。然而,當你為一個矩形找空時需要訪問很多像素,這個方案簡單但效率低下。

另一個方案,可以保存閉合矩形中每個矩形的寬和高以及他們的X/Y方向的偏移。這個數據結構比起二維像素數據擁有更少的成員變量,但是在空間足夠的情況下,計算出這個最左最高的位置使用這個結構將既復雜又慢。

我想出的解決方法是:使用一個動態的二維布爾數組表示占用或空閑,但是為每行存儲一個高度,每列存儲一個寬度,這樣列數和行數可以保持在最小。這樣既減少復雜度又降低了需要訪問的格子數(和因此花費的時間)。下面是添加矩形時這個方法如何工作的(白色格子是未被占用,綠色格子是被占用,暗綠色格子是剛被最后一次添加矩形占用的):

1.首先,只有一行和閉合矩形一樣高,一列和閉合矩形一樣寬。這意味著只有一個格子。


2.當添加第一個矩形時,找出最左最高的格子很輕松,因為這兒只有一個。確保他對于這個矩形足夠大也很簡單。所以我們繼續,并把它放置在格子的左上角。

我們現在有個格子被部分占用,部分沒有被占用。然而一個格子只能是一種狀態。為了解決這個問題,將單行分開、單列分開,這樣我們就獲得了四個格子,這樣他們要么被占用,要么沒有被占用:


3.該添加第二個矩形了。首先檢查最左邊的列。從上到下遍歷這個列中所有的格子直到你找到一個空閑的格子。然后檢查是否能將矩形放在那兒。

最左列有一個空閑格,但是垂直方向上不夠放下這個矩形。那么在右邊一列如法炮制的查找。

第二列中,最高的那個格子是空間的,并且足夠放置矩形,那么這很簡單。將矩形放在那。和第一個格子放置時一樣,矩形相對于格子比較小,導致一個格子部分被占用,部分未占用。所以分割該格子的行和列來確保格子又回到不是被占用就是未被占用的狀態。注意結果,第一個矩形所占用的格子現在被劃分為二了,這沒關系的。


4.第三個矩形也走同樣的流程。然而,因為這個矩形有點矮,所以最左列有足夠的空間來放置他。再一次,在這個格子中相交的行列被分割了,來取保所有格子要么是占用要么是未被占用。


5.第四個矩形走同樣的流程。如果最左列剩余垂直空間不足,那就在他右邊試試。最左列最高的那個格子足夠高來放置矩形,但是不夠寬。所以測試右邊的列看是不是有足夠空閑的格子來安放矩形。可以看到起始列和他右邊的列組合起來在水平方向上就有足夠的空間安放這個矩形,也就是說這個矩形可以用兩個格子來放置。再一次格子在行列上被分割,確保格子被占用或非占用。


6.第五個矩形,依舊從左到右的檢查列。第二列有一個空閑格,但是對于該矩形在垂直方向上沒有足夠的空間。第三列有兩個不相連的空閑格子,但是他倆高度都不夠,并且垂直空間上也無法和其他格子結合湊足垂直空間來放置矩形。

在第四列,有一個空間格子,他既不夠高也不夠寬來安放矩形。所以檢查右邊列的格子和下面行的格子看是不是有足夠空閑的格子可以組合來容納矩形。在這種情況下,這證明是可行的。再一次,發生了行列分割來保證格子占用或非占用的唯一性。


通過運行下載文件中的網站,你可以看到更多的例子。他也演示了不是所有矩形都能放置的情況。

找到可以放置矩形的最左最高格子和檢查周圍格子的代碼在下載中的Mapper工程的Canvas類中可以找到。二維動態數組在DynamicTwoDimensionalArray類中實現。因為他被經常使用,這個類為了性能被高度優化,尤其是分割行和列時。

對基本算法的改進

當學習下載的test site中生成的測試例子時,下面的改進會很明顯。在寫改進在下載的代碼中有的。我在文獻中沒有找到這些改進的方法,所有你可以先讀一下他們:

減小封閉區域寬度后,增加足夠的高度

放置所有矩形失敗后,增加足夠的高度

通過設置效率的上限獲得加速

減小封閉區域寬度后,增加足夠的高度

看下下面那個一輪基本算法生成的閉合矩形:


根據基本算法,你應該將閉合矩形的寬度減一,然后試著重新安放所有矩形。然而,如果你簡單的將寬度減一,你知道暗綠色矩形一定會超出閉合矩形的右手邊界,對它來說無處容身了就,所以下次嘗試安放所有矩形時一定會失敗。

另外,算法說當失敗的時候將閉合矩形的高度加一。但是,因為暗綠色矩形的高度是十個像素,明顯高度加一是不夠的。所以基本算法接下來一定會進行十次失敗的嘗試去安放所有矩形,這很費也沒啥必要。

可以通過記錄接觸到閉合矩形右手邊界最高矩形的高度來進行優化。如果你成功安放好所有矩形并將閉合矩形的寬度減一后,可以將閉合矩形的高度加上超出閉合矩形右方的最高矩形的高度。這樣算法可以在新的閉合矩形內為超出右方的最高矩形找到新的位置:


放置所有矩形失敗后,增加足夠的高度

看看下面的序列。使用該算法安放好四個矩形后,放置第五個矩形時失敗了。

1 2 3 4 放置矩形失敗

    

這次失敗后,基本算法將對閉合矩形的高度加一,然后重新放置矩形。但是僅僅加一的話,前四個矩形還是安放在一模一樣的位置,最終安放第五個矩形還是失敗。這個算法將會繼續高度加一繼續嘗試,可能還是這種情況,周而復始。這些毫無意義的嘗試占用了大量的時間。

使用下面兩個高度中較小的值,來代替高度加一。

1.無法安放的矩形的高度

2.可以讓閉合矩形對前四個矩形可以進行和之前不同排列的高度——這樣至少給算法一個機會來安放第五個矩形

通過選擇兩項中較小的一個,你將可能得到更接近最小的閉合矩形。

算出上面第二點中提到的高度并不難,只要你意識到這個算法首先試著在最左列放置每個矩形,如果失敗了就查看右邊這列再次嘗試,直到成功。每次在列中放置矩形失敗,那是因為列的底部空閑區域對于矩形來說太矮了——空閑高度不足。

拿第二個矩形來說,第一列還差30個像素的空閑高度:


也就是說,如果閉合矩形再高那么30個像素,第二個矩形就可以放在最左邊那列了。

同樣的,第三個矩形要放在極左列的高度還差25像素,在第二行還差15像素。所以如果閉合矩形再高15個像素,第三個矩形放置的就會不同了:


第四個矩形在極左列還差10像素的空閑高度。所以如果閉合矩形如果高10個像素,第四個矩形也可能被放置在第一列。


我們想要增加閉合矩形所需最小的高度使矩形能排的不同即可。這里,最小的所有列所需空閑高度是10個像素(應用于第四個矩形放在極左列)。由于第五個矩形高了10個像素放置失敗,我們需要將閉合矩形的高度增加10像素,希望在下次嘗試時放置第五個矩形:(Seeing that the fifth rectangle that failed to be placed is higher than 10px, we need to increase the height of the enclosing rectangle by 10px to have any hope of placing the fifth rectangle at the next try: )

1 2 3 4 5

    

這意味著為了防止那么多的失敗閉合矩形,算法需要簡單的記錄下來在列中放置矩形時最小的空閑高度差額。當放置矩形失敗的時候,可以用這個最小空閑高度差額增加閉合矩形的高度——如果無法放置矩形的高度更小的話就用他。

這種優化不能確保下一次嘗試就能得到成功的閉合矩形。比如,新的高度下,閉合矩形可能會比目前的最佳閉合矩形要打,這種情況下算法將要開始減小他的寬度。這樣的話可能會在下次嘗試時無法安置所有的矩形因為降低了寬度。此優化是為了減少嘗試的次數而非一次成功。

閉合矩形大小和速度間的取舍

如果你決定你可以忍受一定水平的空間浪費,一種方法是減少計算時間來產生閉合矩形,就是當達到這個水平時讓代碼停止繼續獲得更小的閉合矩形。

另一種方法提高速度是當找到預設次數成功閉合矩形后就讓算法停止。你可以設置限制為一次或兩次。這很有吸引力,當你發現這種方法可以讓你得到一個足夠好的結果并且提高了不少速度。

為了讓你自己選,在MapperOptimalEfficiency類中提供了第二個構造函數,通過額外的參數設置這兩個選項(with additional parameters to set these two cut offs )

矩形打包器的軟件接口

下載Mapper項目中有文章中描述的矩形打包器的實現。他給外部提供了一個良好的接口。test side使用了這個接口。為了讓你更容易的學習或者在你的項目使用這些代碼,下面提供了接口的描述。

你會發現代碼涉及到的是圖片和精靈而不是矩形和封閉矩形。這是因為他是打算作為實時精靈生成器項目(還未完成)的一部分實現的。

接口

(譯者注:略)

實現

(譯者注:略)

用法

(譯者注:略)

歷史記錄

(譯者注:略)

許可

(譯者注:略)

關于作者

(譯者注:略)

 

 

 

posted on 2014-10-24 18:11 王聰 閱讀(1827) 評論(0)  編輯 收藏 引用

<2014年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

導航

統計

常用鏈接

留言簿

隨筆檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久影院亚洲| 中日韩午夜理伦电影免费| 黑人巨大精品欧美一区二区小视频| 久久五月天婷婷| 久久一区中文字幕| 蜜桃av综合| 欧美日本免费| 国产精品白丝av嫩草影院| 国产精品草莓在线免费观看| 欧美体内谢she精2性欧美| 国产精品久久久久久久久久久久久久| 国产精品久久久久久久久久久久久| 国产欧美一区二区精品秋霞影院| 黄色小说综合网站| 日韩五码在线| 久久成人国产精品| 欧美大片免费观看在线观看网站推荐 | 99re热这里只有精品免费视频| 欧美高清视频一区二区| 欧美专区中文字幕| 久久亚裔精品欧美| 亚洲理伦电影| 欧美一区二区三区四区在线| 久久亚洲图片| 国产精品午夜在线观看| 亚洲第一在线综合在线| 亚洲图片欧美一区| 美女91精品| 亚洲一区二区三区免费观看| 麻豆成人精品| 国产亚洲亚洲| 一本色道久久综合亚洲精品不卡| 久久精品国产第一区二区三区最新章节 | 国产日韩欧美在线视频观看| 亚洲国内自拍| 久久成人一区二区| 亚洲国产合集| 日韩一级二级三级| 久久久噜噜噜久久人人看| 欧美性感一类影片在线播放 | 欧美一区91| 欧美性一二三区| 日韩视频免费在线| 欧美福利电影在线观看| 午夜免费日韩视频| 欧美无乱码久久久免费午夜一区| 亚洲福利av| 久久天天狠狠| 香蕉精品999视频一区二区| 欧美日韩国产不卡| 亚洲精品网址在线观看| 欧美ab在线视频| 欧美在线短视频| 国产精品日韩在线播放| 亚洲新中文字幕| 亚洲精品影视在线观看| 欧美高清视频一区| 日韩午夜高潮| 亚洲精品国产精品国自产在线| 久久精品观看| 国产一区二区三区高清| 先锋资源久久| 欧美一区二区啪啪| 国产一区再线| 久久亚洲精选| 久久综合色88| 亚洲精品老司机| 亚洲福利视频一区| 欧美激情按摩| 亚洲综合导航| 亚洲欧美精品| 影音先锋亚洲电影| 欧美激情综合色| 久久成人精品电影| 国产日韩欧美精品一区| 久久精品成人一区二区三区| 欧美在线综合| 亚洲黄色大片| 欧美色中文字幕| 午夜欧美不卡精品aaaaa| 亚洲综合第一页| 精品电影在线观看| 欧美大片一区二区三区| 欧美高清hd18日本| 亚洲男人的天堂在线观看| 亚洲欧美资源在线| 亚洲国产高清在线观看视频| 亚洲精品乱码久久久久久| 国产精品美女久久久浪潮软件| 久久国产精品72免费观看| 久久精品五月婷婷| 99re6热只有精品免费观看| 亚洲中无吗在线| 亚洲国产精品999| avtt综合网| 一区在线观看视频| 亚洲欧洲另类国产综合| 国产视频在线观看一区| 欧美高清在线一区二区| 国产精品成人av性教育| 老色鬼精品视频在线观看播放| 欧美91大片| 欧美一区二区日韩| 欧美激情四色| 久久婷婷色综合| 欧美香蕉大胸在线视频观看| 免费在线国产精品| 国产精品福利网| 欧美激情1区2区| 国产日韩一级二级三级| 亚洲大片精品永久免费| 国产伦精品一区二区三区四区免费| 欧美大香线蕉线伊人久久国产精品| 国产精品国产三级国产普通话三级| 另类图片国产| 国产亚洲精品久久飘花| 一本色道久久综合亚洲精品不卡| 亚洲第一网站免费视频| 欧美亚洲三区| 香蕉亚洲视频| 欧美视频精品在线观看| 亚洲国产一区视频| 狠狠综合久久av一区二区老牛| 亚洲午夜精品视频| 一本久道久久综合婷婷鲸鱼| 美女国内精品自产拍在线播放| 亚洲一区在线免费观看| 欧美中文字幕第一页| 欧美亚洲免费| 欧美日本在线视频| 欧美日韩在线精品| 欧美福利在线观看| 国产一区二区精品丝袜| 一本色道久久99精品综合| 亚洲国产精品一区二区久| 欧美伦理一区二区| 黄网动漫久久久| 亚洲一区二区高清| 亚洲免费观看在线观看| 另类春色校园亚洲| 久热成人在线视频| 韩国自拍一区| 久久久久国产精品厨房| 久久视频在线视频| 国产精品日韩欧美一区| 午夜日韩视频| 亚洲一二三区在线观看| 欧美日韩中文精品| 亚洲精品乱码久久久久| 亚洲精品一区中文| 久久只有精品| 亚洲国产成人精品久久久国产成人一区| 激情综合激情| 噜噜噜在线观看免费视频日韩| 欧美激情欧美激情在线五月| 91久久夜色精品国产网站| 欧美承认网站| 亚洲免费久久| 久久丁香综合五月国产三级网站| 国产免费成人在线视频| 午夜视频一区二区| 男人的天堂成人在线| 日韩亚洲欧美成人一区| 欧美午夜视频在线| 久久不射电影网| 在线亚洲电影| 午夜久久一区| 麻豆精品91| 日韩视频永久免费| 欧美性大战久久久久久久| 欧美一区二区三区视频在线观看| 免费亚洲电影在线| 亚洲午夜av电影| 狠狠干综合网| 欧美系列亚洲系列| 久久婷婷影院| 亚洲视频在线观看免费| 久久综合给合久久狠狠狠97色69| 亚洲精品国精品久久99热| 国产精品日本一区二区| 91久久精品国产91久久性色| 欧美紧缚bdsm在线视频| 午夜宅男久久久| 亚洲国产欧美不卡在线观看| 午夜一区二区三区不卡视频| 亚洲国产人成综合网站| 国产精品一区二区你懂得| 欧美成人精品| 久久se精品一区二区| 一区二区三区四区蜜桃| 欧美freesex8一10精品| 欧美一区二区三区视频免费| 亚洲精品一区二区三区婷婷月| 国产午夜亚洲精品不卡| 欧美日韩国产精品一区| 久久久欧美精品| 性欧美暴力猛交另类hd| 在线视频一区二区| 91久久精品国产91久久性色| 久久久久久久久久久成人|