PHP 5.0創(chuàng)建圖形的實(shí)用方法完整篇第2/3頁
在運(yùn)行這個(gè)程序時(shí),test.png 文件應(yīng)該如圖 5 所示。
圖5. 紅圓在黑方框之后

現(xiàn)在修改下面的代碼:
$gobjs []= new Oval( 200, "red", 50, 50, 150, 150 ); $gobjs []= new Rectangle( 100, "black", 100, 100, 300, 300 ); |
再次運(yùn)行這個(gè)代碼,突然這個(gè)橢圓就在這個(gè)方框上面了,如圖 6 所示。
圖6. 紅圓現(xiàn)在在黑方框上面了

紅圓現(xiàn)在就出現(xiàn)在黑方框上面了,盡管它是先創(chuàng)建的,也是首先添加到數(shù)組中的。這就是 z 值的實(shí)際價(jià)值:您可以按照任何順序來創(chuàng)建對(duì)象,并可以通過調(diào)整每個(gè)對(duì)象的 z 值來調(diào)整彼此之間的相對(duì)位置。
在這段代碼中,z 值排序是在這個(gè)庫(kù)之外實(shí)現(xiàn)的。讓我們通過創(chuàng)建一個(gè)新容器對(duì)象 Group 來實(shí)現(xiàn)這種功能,其中保存了一組 GraphicsObject 對(duì)象。Group 對(duì)象然后再處理排序的問題。
Group 類的代碼如清單 5 所示。
清單 5. Group 類
function zsort( $a, $b ) { if ( $a->z() < $b->z() ) return -1; if ( $a->z() > $b->z() ) return 1; return 0; } class Group extends GraphicsObject { private $z; protected $members = array(); public function __construct( $z ) { $this->z = $z; } public function add( $member ) { $this->members []= $member; } public function render( $ge ) { usort( $this->members, "zsort" ); foreach( $this->members as $gobj ) { $gobj->render( $ge ); } } public function z() { return $this->z; } } |
Group 對(duì)象的任務(wù)是保持一個(gè)對(duì)象數(shù)組,然后在畫圖時(shí),逐個(gè)對(duì)對(duì)象zo進(jìn)行排序和畫圖。
更新后的測(cè)試代碼如清單 6 所示。
清單 6. 更新后的測(cè)試代碼
<?php require_once( "glib.php" ); $ge = new GraphicsEnvironment( 400, 400 ); $ge->addColor( "black", 0, 0, 0 ); $ge->addColor( "red", 255, 0, 0 ); $ge->addColor( "green", 0, 255, 0 ); $ge->addColor( "blue", 0, 0, 255 ); $g1 = new Group( 0 ); $g1->add( new Oval( 200, "red", 50, 50, 150, 150 ) ); $g1->add( new Rectangle( 100, "black", 100, 100, 300, 300 ) ); $g1->render( $ge ); $ge->saveAsPng( "test.png" ); ?> |
現(xiàn)在所有的客戶機(jī)需要做的是創(chuàng)建一個(gè) Group 對(duì)象。它會(huì)處理排序和其他操作。
[NextPage]
創(chuàng)建 viewport
viewport 是一個(gè)人造的坐標(biāo)系統(tǒng),可以轉(zhuǎn)換成圖像的物理坐標(biāo)系統(tǒng)。viewport 的擴(kuò)展可以是您希望的任何東西。例如,x 和 y 軸的起點(diǎn)和終點(diǎn)可以是 -2 和 2,這樣 viewport 坐標(biāo)平面的中心就是 0, 0。這對(duì)于三角圖形(例如 sin 和 cosine)來說是很好的一個(gè) viewport?;蛘?,這個(gè) viewport 也可以是不對(duì)稱的,其中 y 值的范圍從 -1 到 1,x 值的范圍是從 0 到 10,000,這取決于您的需要。
這個(gè) viewport 的其他值可以確保構(gòu)建一個(gè) 400X400 的圖像所采用的邏輯與構(gòu)建一個(gè) 4000X2000 的圖像所采用的邏輯是相同的。代碼負(fù)責(zé)向這個(gè) viewport 中寫入數(shù)據(jù),然后這個(gè) viewport 自動(dòng)實(shí)現(xiàn)到圖像的物理尺寸的自動(dòng)映射。
要讓您的 viewport 正常工作,您需要將這個(gè) viewport 的范圍從 0,0 修改為 1,1,這可以讓圖形對(duì)象回調(diào)圖形環(huán)境,從而將 viewport 的坐標(biāo)轉(zhuǎn)換成物理坐標(biāo)。您可以將所有的代碼都放到 BoxObject 基類中進(jìn)行簡(jiǎn)化。
圖 7 顯示了有關(guān)新添加的代碼的兩個(gè)內(nèi)容。首先是添加的 tx 和 ty 方法,這會(huì)將 x 和 y 坐標(biāo)從 viewport 轉(zhuǎn)換成物理圖像的坐標(biāo)。第二個(gè)是對(duì) BoxObject 增加了 draw 方法,它的派生類應(yīng)該用來進(jìn)行制圖。BoxObject 在 render 方法中實(shí)現(xiàn) viewport 的轉(zhuǎn)換,并使用物理坐標(biāo)來調(diào)用 draw 方法。使用這種方法,Line、Oval 和 Rectangle 類都可以利用 viewport 坐標(biāo),而不需要擔(dān)心坐標(biāo)轉(zhuǎn)換的問題。
圖 7. 所添加的圖形環(huán)境 viewport 轉(zhuǎn)換

這個(gè)新庫(kù)的代碼如清單 7 所示:
清單 7. 具有 viewport 支持的圖形庫(kù)
<?php class GraphicsEnvironment { public $width; public $height; public $gdo; public $colors = array(); public function __construct( $width, $height ) { $this->width = $width; $this->height = $height; $this->gdo = imagecreatetruecolor( $width, $height ); $this->addColor( "white", 255, 255, 255 ); imagefilledrectangle( $this->gdo, 0, 0, $width, $height, $this->getColor( "white" ) ); } public function width() { return $this->width; } public function height() { return $this->height; } public function addColor( $name, $r, $g, $b ) { $this->colors[ $name ] = imagecolorallocate( $this->gdo, $r, $g, $b ); } public function getGraphicObject() { return $this->gdo; } public function getColor( $name ) { return $this->colors[ $name ]; } public function saveAsPng( $filename ) { imagepng( $this->gdo, $filename ); } public function tx( $x ) { return $x * $this->width; } public function ty( $y ) { return $y * $this->height; } } abstract class GraphicsObject { abstract public function render( $ge ); abstract public function z(); } function zsort( $a, $b ) { if ( $a->z() < $b->z() ) return -1; if ( $a->z() > $b->z() ) return 1; return 0; } class Group extends GraphicsObject { private $z; protected $members = array(); public function __construct( $z ) { $this->z = $z; } public function add( $member ) { $this->members []= $member; } public function render( $ge ) { usort( $this->members, "zsort" ); foreach( $this->members as $gobj ) { $gobj->render( $ge ); } } public function z() { return $this->z; } } abstract class BoxObject extends GraphicsObject { protected $color; protected $sx; protected $sy; protected $ex; protected $ey; protected $z; public function __construct( $z, $color, $sx, $sy, $ex, $ey ) { $this->z = $z; $this->color = $color; $this->sx = $sx; $this->sy = $sy; $this->ex = $ex; $this->ey = $ey; } public function render( $ge ) { $rsx = $ge->tx( $this->sx ); $rsy = $ge->ty( $this->sy ); $rex = $ge->tx( $this->ex ); $rey = $ge->ty( $this->ey ); $this->draw( $rsx, $rsy, $rex, $rey, $ge->getGraphicObject(), $ge->getColor( $this->color ) ); } abstract public function draw( $sx, $sy, $ex, $ey, $gobj, $color ); public function z() { return $this->z; } } class Line extends BoxObject { public function draw( $sx, $sy, $ex, $ey, $gobj, $color ) { imageline( $gobj, $sx, $sy, $ex, $ey, $color ); } } class Rectangle extends BoxObject { public function draw( $sx, $sy, $ex, $ey, $gobj, $color ) { imagefilledrectangle( $gobj, $sx, $sy, $ex, $ey, $color ); } } class Oval extends BoxObject { public function draw( $sx, $sy, $ex, $ey, $gobj, $color ) { $w = $ex - $sx; $h = $ey - $sy; imagefilledellipse( $gobj, $sx + ( $w / 2 ), $sy + ( $h / 2 ), $w, $h, $color ); } } ?> |
GraphicsEnvironment 類中的 viewport 轉(zhuǎn)換代碼是高亮顯示的,正如 GraphicsObject 中的 render 代碼一樣,這會(huì)回調(diào)圖形環(huán)境來進(jìn)行坐標(biāo)轉(zhuǎn)換的工作。
相關(guān)文章
一個(gè)不易被發(fā)現(xiàn)的PHP后門代碼解析
這篇文章主要介紹了一個(gè)不易被發(fā)現(xiàn)的PHP后門代碼解析,對(duì)于網(wǎng)絡(luò)安全來說非常重要,需要的朋友可以參考下2014-07-07探討:php中在foreach中使用foreach ($arr as &$value) 這種類型的解釋
本篇文章是對(duì)php中在foreach中使用foreach ($arr as &$value) 這種類型的解釋進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06php關(guān)聯(lián)數(shù)組快速排序的方法
這篇文章主要介紹了php關(guān)聯(lián)數(shù)組快速排序的方法,涉及php數(shù)組排序的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法
這篇文章主要介紹了php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法,實(shí)例分析了兩種實(shí)現(xiàn)方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-12-12php計(jì)數(shù)排序算法的實(shí)現(xiàn)代碼(附四個(gè)實(shí)例代碼)
計(jì)數(shù)排序(Counting sort)是一種根據(jù)小整數(shù)鍵對(duì)一組對(duì)象排序的算法;也就是說,它是一個(gè)整數(shù)排序算法。它通過計(jì)算具有不同鍵值的對(duì)象的數(shù)量,并對(duì)這些數(shù)量使用算術(shù)來確定輸出序列中每個(gè)鍵值的位置2020-03-03幾個(gè)有用的php字符串過濾,轉(zhuǎn)換函數(shù)代碼
幾個(gè)有用的php字符串過濾,轉(zhuǎn)換函數(shù),主要是一些字符的安全處理與字符串處理2012-05-05PHP實(shí)現(xiàn)快速向MySQL插入千萬條數(shù)據(jù)
在開發(fā)中,有時(shí)需要向數(shù)據(jù)庫(kù)中插入大量數(shù)據(jù),本文將探討如何使用PHP來快速向MySQL數(shù)據(jù)庫(kù)插入1000萬條數(shù)據(jù),并分享一些優(yōu)化方法,以確保性能的最優(yōu)2023-08-08微信自定義菜單的創(chuàng)建/查詢/取消php示例代碼
這篇文章主要為大家詳細(xì)介紹了微信自定義菜單的創(chuàng)建/查詢/取消php示例代碼,感興趣的小伙伴們可以參考一下2016-08-08