PHP 5.0創(chuàng)建圖形的實(shí)用方法完整篇第2/3頁(yè)
在運(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à)值:您可以按照任何順序來(lái)創(chuàng)建對(duì)象,并可以通過(guò)調(diào)整每個(gè)對(duì)象的 z 值來(lái)調(diào)整彼此之間的相對(duì)位置。
在這段代碼中,z 值排序是在這個(gè)庫(kù)之外實(shí)現(xiàn)的。讓我們通過(guò)創(chuàng)建一個(gè)新容器對(duì)象 Group 來(lái)實(shí)現(xiàn)這種功能,其中保存了一組 GraphicsObject 對(duì)象。Group 對(duì)象然后再處理排序的問(wèn)題。
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ù)組,然后在畫(huà)圖時(shí),逐個(gè)對(duì)對(duì)象zo進(jìn)行排序和畫(huà)圖。
更新后的測(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)來(lái)說(shuō)是很好的一個(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 中寫(xiě)入數(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)該用來(lái)進(jìn)行制圖。BoxObject 在 render 方法中實(shí)現(xiàn) viewport 的轉(zhuǎn)換,并使用物理坐標(biāo)來(lái)調(diào)用 draw 方法。使用這種方法,Line、Oval 和 Rectangle 類都可以利用 viewport 坐標(biāo),而不需要擔(dān)心坐標(biāo)轉(zhuǎn)換的問(wè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)境來(lái)進(jìn)行坐標(biāo)轉(zhuǎn)換的工作。
相關(guān)文章
一個(gè)不易被發(fā)現(xiàn)的PHP后門(mén)代碼解析
這篇文章主要介紹了一個(gè)不易被發(fā)現(xiàn)的PHP后門(mén)代碼解析,對(duì)于網(wǎng)絡(luò)安全來(lái)說(shuō)非常重要,需要的朋友可以參考下2014-07-07
探討:php中在foreach中使用foreach ($arr as &$value) 這種類型的解釋
本篇文章是對(duì)php中在foreach中使用foreach ($arr as &$value) 這種類型的解釋進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
php關(guān)聯(lián)數(shù)組快速排序的方法
這篇文章主要介紹了php關(guān)聯(lián)數(shù)組快速排序的方法,涉及php數(shù)組排序的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法
這篇文章主要介紹了php+ajax實(shí)時(shí)輸入自動(dòng)搜索匹配的方法,實(shí)例分析了兩種實(shí)現(xiàn)方法,是非常實(shí)用的技巧,需要的朋友可以參考下2014-12-12
php計(jì)數(shù)排序算法的實(shí)現(xiàn)代碼(附四個(gè)實(shí)例代碼)
計(jì)數(shù)排序(Counting sort)是一種根據(jù)小整數(shù)鍵對(duì)一組對(duì)象排序的算法;也就是說(shuō),它是一個(gè)整數(shù)排序算法。它通過(guò)計(jì)算具有不同鍵值的對(duì)象的數(shù)量,并對(duì)這些數(shù)量使用算術(shù)來(lái)確定輸出序列中每個(gè)鍵值的位置2020-03-03
幾個(gè)有用的php字符串過(guò)濾,轉(zhuǎn)換函數(shù)代碼
幾個(gè)有用的php字符串過(guò)濾,轉(zhuǎn)換函數(shù),主要是一些字符的安全處理與字符串處理2012-05-05
PHP實(shí)現(xiàn)快速向MySQL插入千萬(wàn)條數(shù)據(jù)
在開(kāi)發(fā)中,有時(shí)需要向數(shù)據(jù)庫(kù)中插入大量數(shù)據(jù),本文將探討如何使用PHP來(lái)快速向MySQL數(shù)據(jù)庫(kù)插入1000萬(wàn)條數(shù)據(jù),并分享一些優(yōu)化方法,以確保性能的最優(yōu)2023-08-08
微信自定義菜單的創(chuàng)建/查詢/取消php示例代碼
這篇文章主要為大家詳細(xì)介紹了微信自定義菜單的創(chuàng)建/查詢/取消php示例代碼,感興趣的小伙伴們可以參考一下2016-08-08

