Initial commit

This commit is contained in:
2026-09-03 11:24:19 +02:00
commit 6ed3153f36
1897 changed files with 538007 additions and 0 deletions
+977
View File
@@ -0,0 +1,977 @@
<?php
/*=========================================================================*/
/* Name: ClipLine.php */
/* Uses: Used for clipping a line in a define square */
/* Date: 12/7/2007 */
/* Authors: */
/* Andrew Que (http://www.DrQue.net/) */
/* References: */
/* This unit was constructed mostly from an example in Wikipedia, which */
/* had the following credit: */
/* "Mark S. Sobkow, Paul Pospisil and Yee-Hong Yang. A Fast Two- */
/* Dimensional Line Clipping Algorithm via Line Encoding//Computer & */
/* Graphics, Vol. 11, No. 4, pp. 459-467, 1987." */
/* The port to PHP was done by Andrew Que */
/* Revisions: */
/* 1.0 - 12/7/2007 - QUE - Creation */
/* 1.1 - 12/31/2007 - QUE - Clipping for complete out-of-bounds */
/* */
/* ----------------------------------------------------------------------- */
/* */
/* Line clipping function */
/* Copyright (C) 2007 Andrew Que */
/* */
/* This program is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/* ----------------------------------------------------------------------- */
/* */
/* (C) Copyright 2007 */
/* Andrew Que */
/* ð|> */
/*=========================================================================*/
/**
* Used for clipping a line in a define square
*
* <p>
* This unit was constructed mostly from an example in Wikipedia, which
* had the following credit:
* <p>
* "Mark S. Sobkow, Paul Pospisil and Yee-Hong Yang. A Fast Two-
* Dimensional Line Clipping Algorithm via Line Encoding//Computer &
* Graphics, Vol. 11, No. 4, pp. 459-467, 1987."
* <p>
* The port to PHP was done by Andrew Que
*
* @package XY_Plot
* @author Andrew Que ({@link http://www.DrQue.net/})
* @copyright Copyright (c) 2007, Andrew Que
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/
/**
* Implementation of the Fast-Clipping algorithm.
*
* This is a class, but acts more like a function. The reason
* implementation is done this way is because of the sub-functions that
* need access to the local variables.
*/
class ClipLine
{
/**#@+ @ignore */
public $x;
public $y;
public $xx;
public $yy;
public $X_Min;
public $Y_Min;
public $X_Max;
public $Y_Max;
/**#@-*/
/**
* Constructor
* @param x Left corner of line
* @param y Top corner of line
* @param xx Right corner of line
* @param yy Bottom corner of line
* @param X_Min Left edge of frame
* @param Y_Min Top edge of frame
* @param X_Max Right edge of frame
* @param Y_Max Bottom edge of frame
*/
public function __construct
(
&$x , &$y , &$xx , &$yy ,
$X_Min , $Y_Min , $X_Max , $Y_Max
)
{
// Set local variables
$this->x = &$x;
$this->y = &$y;
$this->xx = &$xx;
$this->yy = &$yy;
$this->X_Min = &$X_Min;
$this->Y_Min = &$Y_Min;
$this->X_Max = &$X_Max;
$this->Y_Max = &$Y_Max;
// Clip the line
$this->Clip();
}
//------------------------------------------------------
// Clipping function
// (There is one clipping function for each of the 8 areas)
//------------------------------------------------------
/**
* Start top
*/
private function clipStartTop()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->x += $DeltaX * ( $this->Y_Min - $this->y ) / $DeltaY;
$this->y = $this->Y_Min;
}
/**
* Start bottom
*/
private function clipStartBottom()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->x += $DeltaX * ( $this->Y_Max - $this->y ) / $DeltaY;
$this->y = $this->Y_Max;
}
/**
* Start right
*/
private function clipStartRight()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->y += $DeltaY * ( $this->X_Max - $this->x ) / $DeltaX;
$this->x = $this->X_Max;
}
/**
* Start left
*/
private function clipStartLeft()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->y += $DeltaY * ( $this->X_Min - $this->x ) / $DeltaX;
$this->x = $this->X_Min;
}
/**
* End top
*/
private function clipEndTop()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->xx += $DeltaX * ( $this->Y_Min - $this->yy ) / $DeltaY;
$this->yy = $this->Y_Min;
}
/**
* End bottom
*/
private function clipEndBottom()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->xx += $DeltaX * ( $this->Y_Max - $this->yy ) / $DeltaY;
$this->yy = $this->Y_Max;
}
/**
* End right
*/
private function clipEndRight()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->yy += $DeltaY * ( $this->X_Max - $this->xx ) / $DeltaX;
$this->xx = $this->X_Max;
}
/**
* End Left
*/
private function clipEndLeft()
{
$DeltaX = $this->xx - $this->x;
$DeltaY = $this->yy - $this->y;
$this->yy += $DeltaY * ( $this->X_Min - $this->xx ) / $DeltaX;
$this->xx = $this->X_Min;
}
/**
* Main body of clipping function
*
* This function does all the clipping work
*/
private function Clip()
{
$LineCode = 0;
// Figure out which sides clip
if ( $this->y < $this->Y_Min )
$LineCode |= 0x80; // BIT8
else
if ( $this->y > $this->Y_Max )
$LineCode |= 0x40; // BIT7
if ( $this->x > $this->X_Max )
$LineCode |= 0x20; // BIT6
else
if ( $this->x < $this->X_Min )
$LineCode |= 0x10; // BIT5
if ( $this->yy < $this->Y_Min )
$LineCode |= 0x08; // BIT4
else
if ( $this->yy > $this->Y_Max )
$LineCode |= 0x04; // BIT3
if ( $this->xx > $this->X_Max )
$LineCode |= 0x02; // BIT2
else
if ( $this->xx < $this->X_Min )
$LineCode |= 0x01; // BIT1
// Completely out of bounds? (i.e. not visible on screen)
if ( ( ( $LineCode & ( 0x80 | 0x08 ) ) == ( 0x80 | 0x08 ) )
|| ( ( $LineCode & ( 0x40 | 0x04 ) ) == ( 0x40 | 0x04 ) )
|| ( ( $LineCode & ( 0x20 | 0x02 ) ) == ( 0x20 | 0x02 ) )
|| ( ( $LineCode & ( 0x10 | 0x01 ) ) == ( 0x10 | 0x01 ) ) )
{
$this->x = $this->y = $this->xx = $this->yy = 0;
return;
}
// 9 - 8 - A
// | | |
// 1 - 0 - 2
// | | |
// 5 - 4 - 6
switch ( $LineCode )
{
//------------------------------
// Center
//------------------------------
case 0x00:
{
// Line is perfect, no clipping needed
break;
}
case 0x01:
{
$this->clipEndLeft();
break;
}
case 0x02:
{
$this->clipEndRight();
break;
}
case 0x04:
{
$this->clipEndBottom();
break;
}
case 0x05:
{
$this->clipEndLeft();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
case 0x06:
{
$this->clipEndRight();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
case 0x08:
{
$this->clipEndTop();
break;
}
case 0x09:
{
$this->clipEndLeft();
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
break;
}
case 0x0A:
{
$this->clipEndRight();
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
break;
}
//------------------------------
// Left
//------------------------------
case 0x10:
{
$this->clipStartLeft();
break;
}
case 0x12:
{
$this->clipStartLeft();
$this->clipEndRight();
break;
}
case 0x14:
{
$this->clipStartLeft();
if ( $this->y > $this->Y_Max )
break;
$this->clipEndBottom();
break;
}
case 0x16:
{
$this->clipStartLeft();
if ( $this->y > $this->Y_Max )
break;
$this->clipEndBottom();
if ( $this->xx > $this->X_Max )
$this->clipEndRight();
break;
}
case 0x18:
{
$this->clipStartLeft();
if ( $this->y < $this->Y_Min )
break;
$this->clipEndTop();
break;
}
case 0x1A:
{
$this->clipStartLeft();
if ( $this->y < $this->Y_Min )
break;
$this->clipEndTop();
if ( $this->xx > $this->X_Max )
$this->clipEndRight();
break;
}
//------------------------------
// Right
//------------------------------
case 0x20:
{
$this->clipStartRight();
break;
}
case 0x21:
{
$this->clipStartRight();
$this->clipEndLeft();
break;
}
case 0x24:
{
$this->clipStartRight();
if ( $this->y > $this->Y_Max )
break;
$this->clipEndBottom();
break;
}
case 0x25:
{
$this->clipStartRight();
if ( $this->y > $this->Y_Max )
break;
$this->clipEndBottom();
if ( $this->xx < $this->X_Min )
$this->clipEndLeft();
break;
}
case 0x28:
{
$this->clipStartRight();
if ( $this->y < $this->Y_Min )
break;
$this->clipEndTop();
break;
}
case 0x29:
{
$this->clipStartRight();
if ( $this->y < $this->Y_Min )
break;
$this->clipEndTop();
if ( $this->xx < $this->X_Min )
$this->clipEndLeft();
break;
}
//------------------------------
// Bottom
//------------------------------
case 0x40:
{
$this->clipStartBottom();
break;
}
case 0x41:
{
$this->clipStartBottom();
if ( $this->x < $this->X_Min )
break;
$this->clipEndLeft();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
case 0x42:
{
$this->clipStartBottom();
if ( $this->x > $this->X_Max )
break;
$this->clipEndRight();
break;
}
case 0x48:
{
$this->clipStartBottom();
$this->clipEndTop();
break;
}
case 0x49:
{
$this->clipStartBottom();
if ( $this->x < $this->X_Min )
break;
$this->clipEndLeft();
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
break;
}
case 0x4A:
{
$this->clipStartBottom();
if ( $this->x > $this->X_Max )
break;
$this->clipEndRight();
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
break;
}
//------------------------------
// Bottom-left
//------------------------------
case 0x50:
{
$this->clipStartLeft();
if ( $this->y > $this->Y_Max )
$this->clipStartBottom();
break;
}
case 0x52:
{
$this->clipEndRight();
if ( $this->yy > $this->Y_Max )
break;
$this->clipStartBottom();
if ( $this->x < $this->X_Min )
$this->clipStartLeft();
break;
}
case 0x58:
{
$this->clipEndTop();
if ( $this->xx < $this->X_Min )
break;
$this->clipStartBottom();
if ( $this->x < $this->X_Min )
$this->clipStartLeft();
break;
}
case 0x5A:
{
$this->clipStartLeft();
if ( $this->y < $this->Y_Min )
break;
$this->clipEndRight();
if ( $this->yy > $this->Y_Max )
break;
if ( $this->y > $this->Y_Max )
$this->clipStartBottom();
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
break;
}
//------------------------------
// Bottom-right
//------------------------------
case 0x60:
{
$this->clipStartRight();
if ( $this->y > $this->Y_Max )
$this->clipStartBottom();
break;
}
case 0x61:
{
$this->clipEndLeft();
if ( $this->yy > $this->Y_Max )
break;
$this->clipStartBottom();
if ( $this->x > $this->X_Max )
$this->clipStartRight();
break;
}
case 0x68:
{
$this->clipEndTop();
if ( $this->xx > $this->X_Max )
break;
$this->clipStartRight();
if ( $this->y > $this->Y_Max )
$this->clipStartBottom();
break;
}
case 0x69:
{
$this->clipEndLeft();
if ( $this->yy > $this->Y_Max )
break;
$this->clipStartRight();
if ( $this->y < $this->Y_Min )
break;
if ( $this->yy < $this->Y_Min )
$this->clipEndTop();
if ( $this->y > $this->Y_Max )
$this->clipStartBottom();
break;
}
//------------------------------
// Top
//------------------------------
case 0x80:
{
$this->clipStartTop();
break;
}
case 0x81:
{
$this->clipStartTop();
if ( $this->x < $this->X_Min )
break;
$this->clipEndLeft();
break;
}
case 0x82:
{
$this->clipStartTop();
if ( $this->x > $this->X_Max )
break;
$this->clipEndRight();
break;
}
case 0x84:
{
$this->clipStartTop();
$this->clipEndBottom();
break;
}
case 0x85:
{
$this->clipStartTop();
if ( $this->x < $this->X_Min )
break;
$this->clipEndLeft();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
case 0x86:
{
$this->clipStartTop();
if ( $this->x > $this->X_Max )
break;
$this->clipEndRight();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
//------------------------------
// Top-left
//------------------------------
case 0x90:
{
$this->clipStartLeft();
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
break;
}
case 0x92:
{
$this->clipEndRight();
if ( $this->yy < $this->Y_Min )
break;
$this->clipStartTop();
if ( $this->x < $this->X_Min )
$this->clipStartLeft();
break;
}
case 0x94:
{
$this->clipEndBottom();
if ( $this->xx < $this->X_Min )
break;
$this->clipStartLeft();
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
break;
}
case 0x96:
{
$this->clipStartLeft();
if ( $this->y > $this->Y_Max )
break;
$this->clipEndRight();
if ( $this->yy < $this->Y_Min )
break;
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
break;
}
//------------------------------
// Top-right
//------------------------------
case 0xA0:
{
$this->clipStartRight();
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
break;
}
case 0xA1:
{
$this->clipEndLeft();
if ( $this->yy < $this->Y_Min )
break;
$this->clipStartTop();
if ( $this->x > $this->X_Max )
$this->clipStartRight();
break;
}
case 0xA4:
{
$this->clipEndBottom();
if ( $this->xx > $this->X_Max )
break;
$this->clipStartRight();
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
break;
}
case 0xA5:
{
$this->clipEndLeft();
if ( $this->yy < $this->Y_Min )
break;
$this->clipStartRight();
if ( $this->y > $this->Y_Max )
break;
if ( $this->yy > $this->Y_Max )
$this->clipEndBottom();
if ( $this->y < $this->Y_Min )
$this->clipStartTop();
break;
}
}
// Round result
$this->x = round( $this->x );
$this->y = round( $this->y );
$this->xx = round( $this->xx );
$this->yy = round( $this->yy );
}
}
/**
* Clip line
*
* <p>
* This will take the corners of a line segment and clip them in a define
* area.
* <p>
* Examples of use:
* <code>
* $x = 5;
* $y = 8;
* $xx = 70;
* $yy = 65;
* ClipLine(
* $x , $y , $xx , $yy ,
* 10 , 10 , 50 , 50 );
* </code>
* <p>
* In this example, the values in <var>$x</var>, <var>$y</var>,
* <var>$xx</var>, <var>$yy</var> will be adjusted so they are within
* the (10,10) (50,50) window.
* @param x Left corner of line
* @param y Top corner of line
* @param xx Right corner of line
* @param yy Bottom corner of line
* @param X_Min Left edge of frame
* @param Y_Min Top edge of frame
* @param X_Max Right edge of frame
* @param Y_Max Bottom edge of frame
* @return x, y, xx, yy are all modified (if necessary)
*/
function ClipLine(
&$x , &$y , &$xx , &$yy ,
$X_Min , $Y_Min , $X_Max , $Y_Max )
{
// All of the work is done simply by creating a clip class
$Clip = new
ClipLine
(
$x , $y , $xx , $yy ,
$X_Min , $Y_Min , $X_Max , $Y_Max
);
}
/**
* Draw clipped line
*
* <p>
* Draw a line that has been clipped into the specified image.
* <p>
* Examples of use:
* <code>
* DrawClippedLine(
* $Image ,
* 5 , 8 , 70 , 65 ,
* 10 , 10 , 50 , 50 ,
* $Black );
* </code>
* In this example, a line will be drawn onto <var>$Image</var> clipped
* within the window (10,10) (50,50).
* @param image Image to draw line on
* @param x Left corner of line
* @param y Top corner of line
* @param xx Right corner of line
* @param yy Bottom corner of line
* @param X_Min Left edge of frame
* @param Y_Min Top edge of frame
* @param X_Max Right edge of frame
* @param Y_Max Bottom edge of frame
* @param Color Color of line
*/
function DrawClippedLine(
$Image ,
$x , $y , $xx , $yy ,
$X_Min , $Y_Min , $X_Max , $Y_Max ,
$Color )
{
// Clip this line
ClipLine(
$x , $y , $xx , $yy ,
$X_Min , $Y_Min , $X_Max , $Y_Max );
// Draw the results
imageline( $Image , $x , $y , $xx , $yy , $Color );
}
// "Those who dream by day are cognizant of many things which escape those
// who dream only by night." - Edgar Allan Poe
?>