diff --git a/Engines/Builder/Map/OctocubeBuilder.php b/Engines/Builder/Map/OctocubeBuilder.php
new file mode 100644
index 0000000..1cbb8d2
--- /dev/null
+++ b/Engines/Builder/Map/OctocubeBuilder.php
@@ -0,0 +1,60 @@
+localLocation = Point3D::fromString($location->local);
+ }
+
+ private function getSector () : int {
+ return Octocube::getSectorFromPoint3D($this->localLocation);
+ }
+
+ /**
+ * Gets SQL RLIKE pattern for the specified sector
+ *
+ * @return string a SQL clause like "([0-9]+, -[0,9]+, [0,9]+)"
+ */
+ public function getRlikePattern() : string {
+ $sector = $this->getSector();
+
+ if ($sector == 0) {
+ return "(0, 0, 0)";
+ }
+
+ $vector = Octocube::getBaseVector($sector);
+
+ //x
+ if ($vector[0] == 1) {
+ $query = "([0-9]+, ";
+ } else {
+ $query = "(-[0-9]+, ";
+ }
+
+ //y
+ if ($vector[1] == 1) {
+ $query .= "[0-9]+, ";
+ } else {
+ $query .= "-[0-9]+, ";
+ }
+
+ //z
+ $query .= $this->localLocation->z . ")";
+
+ return $query;
+ }
+
+ static public function canBuildAt($location) : bool {
+ return $location->global == 'B00001002';
+ }
+
+}
diff --git a/Engines/Templates/Smarty/Plugins/modifier.sector.php b/Engines/Templates/Smarty/Plugins/modifier.sector.php
new file mode 100644
index 0000000..2b01819
--- /dev/null
+++ b/Engines/Templates/Smarty/Plugins/modifier.sector.php
@@ -0,0 +1,27 @@
+
+ * Name: sector
+ * Purpose: prints the sector from a location
+ */
+function smarty_modifier_sector (GeoLocation $location) : string {
+ $xyz = explode(',', substr($location->local, 1, -1));
+ $x = (int)$xyz[0];
+ $y = (int)$xyz[1];
+ $z = (int)$xyz[2];
+
+ return (string)Octocube::getSector($x, $y, $z);
+}
diff --git a/composer.json b/composer.json
index b5b0d53..b7499c6 100644
--- a/composer.json
+++ b/composer.json
@@ -1,29 +1,30 @@
{
"name": "zed/zed",
"description": "Hypership and galaxy",
"type": "project",
"require": {
"smarty/smarty": "dev-master",
"keruald/globalfunctions": "^0.5.1",
- "keruald/omnitools": "^0.1.0"
+ "keruald/omnitools": "^0.1.0",
+ "hypership/geo": "^0.1.0"
},
"require-dev": {
"nasqueron/codestyle": "^0.0.1",
"phan/phan": "^5.3.1",
"squizlabs/php_codesniffer": "^3.6",
"phpunit/phpunit": "^9.5"
},
"autoload": {
"psr-4": {
"Zed\\Engines\\": "Engines",
"Zed\\Tests\\": "dev/tests"
}
},
"license": "BSD-2-Clause",
"authors": [
{
"name": "Sébastien Santoro",
"email": "dereckson@espace-win.org"
}
]
}
diff --git a/controllers/builder.php b/controllers/builder.php
index 94d9373..edc6b1c 100644
--- a/controllers/builder.php
+++ b/controllers/builder.php
@@ -1,135 +1,137 @@
* @copyright 2010 Sébastien Santoro aka Dereckson
* @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2
* @version 0.1
* @link http://scherzo.dereckson.be/doc/zed
* @link http://zed.dereckson.be/
* @filesource
*/
+use Zed\Engines\Builder\Map\OctocubeBuilder;
+
require_once('includes/content/zone.php');
//
// Helper methods
//
/**
* Determines if a specified location is buildable
*
* @param GeoLocation $location the location to check
* @param string if the location isn't buildable, a textual description of why.
* @return bool true if the location is buildable ; otherwise, false
*
* @todo create a build.xml document to set what's buildable, and by who
*/
function is_buildable ($location, &$error = '') {
//We currently allow build only in the hypership tower and core.
if (!$location->body->hypership) {
$error = "You can only invoke the HyperShip builder facilities inside the HyperShip.";
return false;
}
//if ($build_location->place->code == "001") {
// //Don't allow custom builds in the corridor (T?C?)
//}
if ($build_location->place->code == "003") {
message_die("Bays aren't buildable.");
return false;
}
return true;
}
//
// Determines mode and initializes resources
//
switch ($build_mode = $url[1]) {
case 'map':
- require_once('includes/geo/octocube.php');
-
$build_mode = 'map';
//Get zones at this floor
- if ($CurrentPerso->location->global == 'B00001002') {
- $point = GeoPoint3D::fromString($CurrentPerso->location->local);
- $sector = GeoOctocube::getSectorFromPoint3D($point);
- $pattern = GeoOctocube::getRlikePatternFromSector($sector, $point->z);
- $zones = ContentZone::search($CurrentPerso->location->global, $pattern, true);
- } else {
+ if (!OctocubeBuilder::canBuildAt($CurrentPerso->location)) {
message_die(GENERAL_ERROR, "Can't map this area.", "Builder :: Map");
}
+ $builder = new OctocubeBuilder($CurrentPerso->location);
+ $zones = ContentZone::search(
+ $CurrentPerso->location->global,
+ $builder->getRlikePattern(),
+ true
+ );
+
//Template
define('DOJO', true);
$smarty->assign('zones', $zones);
$template = "builder_map.tpl";
break;
case '':
case 'hotglue':
//Temporary initialization code, to allow some build during the Zed alphatest
$build_location = $CurrentPerso->location;
$build_mode = 'hotglue';
$error = '';
if (!is_buildable($build_location, $error)) {
message_die(GENERAL_ERROR, $error, "Can't build");
}
//Gets or creates a new zone at build location
$zone = ContentZone::at($build_location->global, $build_location->local, true);
switch ($zone->type) {
case 'hotglue':
//All rulez
break;
case '':
//New zone
$zone->title = "Sandbox hotglue zone for $build_location->global $build_location->local";
$zone->type = 'hotglue';
$zone->save_to_database();
break;
default:
message_die("This isn't a zone managed by hotglue.");
}
unset($error);
//Template
$smarty->assign('location', $build_location);
$smarty->assign('zone', $zone);
$smarty->assign('IFRAME_SRC', '/apps/hotglue/index.php?zone_' . $zone->id . '/edit');
$template = 'builder_hotglue.tpl';
break;
default:
message_die(GENERAL_ERROR, "Unknown build mode: $build_mode");
}
//
// HTML output
//
//Serves header
$smarty->assign('PAGE_TITLE', 'Builder');
include('header.php');
//Serves content
$smarty->display($template);
//Serves footer
include('footer.php');
diff --git a/dev/quux.php b/dev/quux.php
index 54f34a6..21b9488 100644
--- a/dev/quux.php
+++ b/dev/quux.php
@@ -1,161 +1,162 @@
YubiKey';
if (!array_key_exists('YubiCloud', $Config)) {
message_die(GENERAL_ERROR, "YubiCloud authentication not configured. Add \$Config['YubiCloud']['ClientID'] and \$Config['YubiCloud']['SecretKey'] to your config.");
}
if (!$key = $_GET['OTP']) {
message_die(GENERAL_ERROR, "Please add in URL ?OTP=, then put your cursor at right of the = and press your YubiKey button");
}
$yubi = new Auth_Yubico($Config['YubiCloud']['ClientID'], $Config['YubiCloud']['SecretKey']);
if (!$data = $yubi->parsePasswordOTP($key)) {
message_die(GENERAL_ERROR, "This is not an YubiKey OTP.");
}
$prefix = $data['prefix'];
$auth = $yubi->verify($key);
if (@PEAR::isError($auth)) {
if ($auth->getMessage() == 'REPLAYED_OTP') {
message_die("This OTP has already been used.");
}
message_die(HACK_ERROR, "
Authentication failed: " . $auth->getMessage() . "
Debug: " . $yubi->getLastResponse() . "
"); } else { print "You are authenticated!
"; } break; - case 'GeoPointPolarZ': - require_once('includes/geo/pointPolarZ.php'); - echo "Name | Type | Cartesian coords | Spherical I | Spherical II | Pencil coordinates |
---|---|---|---|---|---|
$row[0] | $row[1] | $row[2] | "; $pt = $row[2]; echo '(', implode(', ', $pt->toSpherical()), ') | '; echo '(', implode(', ', $pt->toSphericalAlternative()), ') | '; $pt->translate(500, 300, 200, 2); echo '', $pt, ' | '; echo '
Method doesn't exist: $method
"; } if (array_key_exists('redirectTo', $_REQUEST)) { //If user JS disabled, you can add ?redirectTo= followed by an URL echo "Instead to print a callback value, redirects to $_REQUEST[redirectTo]
"; } } else { //Prod version doesn't prints warning <== silence operator if (method_exists('Actions', $method)) { $result = @call_user_func_array(['Actions', $method], $args); if (array_key_exists('redirectTo', $_REQUEST)) { //If user JS disabled, you can add ?redirectTo= followed by an URL header("location: " . $_REQUEST['redirectTo']); } else { echo json_encode($result); } } } diff --git a/includes/autoload.php b/includes/autoload.php index bbb4a16..3aca728 100644 --- a/includes/autoload.php +++ b/includes/autoload.php @@ -1,60 +1,57 @@ * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource */ +use Hypership\Geo\Point3D; + /** * Geo galaxy class - * - * This class provides methods to convert coordinate polars. - * - * @todo create a unit testing file dev/tests/GeoGalaxyTest.php - * @todo add unit testing for the normalizeAngle method in dev/tests/GeoGalaxyTest.php */ class GeoGalaxy { /* * ----------------------------------------------------------------------- * * Objects fetchers * ----------------------------------------------------------------------- * */ /** * Gets all the coordinates of the objects in the galaxy. * - * @return array An array of array. Each item is [string object_name, string object_type, GeoPoint3D coordinates] + * @return array An array of array. Each item is [string object_name, string object_type, Point3D coordinates] */ static function getCoordinates () { global $db; $sql = "SELECT * FROM geo_coordinates"; if (!$result = $db->sql_query($sql)) { message_die(SQL_ERROR, "Can't query geo_coordinates view.", '', __LINE__, __FILE__, $sql); } $objects = []; while ($row = $db->sql_fetchrow($result)) { //Demios ship xyz: [-50, 30, 40] //Kaos asteroid xyz: [150, -129, 10] - $objects[] = [$row[0], $row[1], GeoPoint3D::fromString($row[2])]; + $objects[] = [$row[0], $row[1], Point3D::fromString($row[2])]; } return $objects; } - /* - * ----------------------------------------------------------------------- * - * Helper methods - math - * ----------------------------------------------------------------------- * - */ - - /** - * Normalizes an angle, so 0 =< angle < 2 PI - * - * @param float $angle angle in radians (use deg2rad() if you've degrees) - * @return an angle in the 0 =< angle < 2 PI interval - */ - static function normalizeAngle ($angle) { - while ($angle < 0) { - $angle += 2 * M_PI; - } - while ($angle >= 2 * M_PI) { - $angle -= 2 * M_PI; - } - return $angle; - } - - /** - * Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates - * - * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels - * - * @param int $x the x coordinate - * @param int $y the y coordinate - * @param int $z the z coordinate - * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates - */ - static function cartesianToSpherical ($x, $y, $z) { - $rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²) - $theta= acos($z / $rho); //φ = acos z/φ - $phi = acos($x / sqrt($x * $x + $y * $y)); //θ = acos x / sqrt(x² + y²) - if (y < 0) { - $phi = 2 * M_PI - $phi; //∀ y < 0 θ = 2π - θ - } - - return [round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2)]; - } - - /** - * Converts (x, y, z) cartesian to (ρ, φ, θ) spherical coordinates - * - * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion - * - * @param int $x the x coordinate - * @param int $y the y coordinate - * @param int $z the z coordinate - * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates - */ - static function cartesianToSphericalAlternative ($x, $y, $z) { - $rho = sqrt($x * $x + $y * $y + $z * $z); //ρ = sqrt(x² + y² + z²) - $theta= atan2($y, $x); //φ = atan2 $y $x - $phi = acos($z / $rho); //θ = acos z/φ - - return [round($rho, 2), round(rad2deg($theta), 2), round(rad2deg($phi), 2)]; - } } diff --git a/includes/geo/location.php b/includes/geo/location.php index 1ae0834..026e8a4 100644 --- a/includes/geo/location.php +++ b/includes/geo/location.php @@ -1,447 +1,446 @@ * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource */ +use Hypership\Geo\Point3D; + require_once('body.php'); require_once('place.php'); -require_once('point3D.php'); require_once('includes/objects/ship.php'); /** * Geo location class * * This class contains properties to get, set or compare a location and * explore the geo classes linked to. * * It quickly allow to parse through the location classes in templates and * controllers. * * @todo Initialize $point3D from $body or $ship own locations * @todo Improve GeoLocation documentation (especially magic properties) */ class GeoLocation { /** * An array of strings containing location data. * * In the current class implementation, * the first element is the global location * and the second element is the local location. * * @var Array */ private $data; /** * A body object * * It contains a GeoBody value when the global location is a body * ie if $this->data[0][0] == 'B' * * Otherwise, its value is null. * * @var GeoBody */ public $body = null; /** * A place object * * It contains a GeoPlacevalue when the global location is a place * ie if $this->data[0][0] == 'B' && strlen($this->data[0]) == 9 * * Otherwise, its value is null. * * @var GeoPlace */ public $place = null; /** * A point identified by x, y, z coordinates - * - * @var GeoPoint3D */ - public $point3D = null; + public Point3D|null $point3D = null; /** * A ship object * * It contains a Ship value when the global location is a ship * ie if $this->data[0][0] == 'S' * * Otherwise, its value is null. * * @var Ship */ public $ship = null; /** * Initializes a new location instance * * @param string $global the global location * @param string local the locallocation * * @todo Improve local location handling */ function __construct ($global = null, $local = null) { if (!$global) { $this->data = []; } elseif (preg_match("/[BS][0-9]{5}[0-9]{3}/", $global)) { $this->data[0] = $global; } elseif (preg_match("/[BS][0-9]{5}/", $global)) { $this->data[0] = $global; } elseif (preg_match("/^xyz\:/", $global)) { $coords = sscanf($global, "xyz: [%d, %d, %d]"); if (count($coords) == 3) { $this->data[0] = $global; } else { throw new Exception("Invalid expression: $global"); } } else { global $db; $name = $db->sql_escape($global); $sql = "SELECT location_code FROM " . TABLE_LOCATIONS . " WHERE location_name LIKE '$name'"; $code = $db->sql_query_express($sql); if ($code) { $this->data[0] = $code; return; } throw new Exception("Invalid expression: $global"); } //TODO: handle $local in a better way: from the global location, gets //a local location handler. Or a some inheritance, like a class //HypershipGeoLocation extending GeoLocation. if ($local !== null) { $this->data[1] = $local; } $this->load_classes(); } /** * Gets $place, $body and $ship instances if they're needed */ function load_classes () { //No data, no class to load if (!count($this->data)) { return; } //Loads global classes $global = $this->data[0]; $code = substr($global, 1, 5); switch ($global[0]) { case 'B': switch (strlen($global)) { case 9: $this->place = GeoPlace::from_code($global); case 6: $this->body = new GeoBody($code); break; } break; case 'S': $this->ship = new Ship($code); break; case 'x': - $coords = sscanf($global, "xyz: [%d, %d, %d]"); + $coords = sscanf($global, "xyz: [%f, %f, %f]"); if (count($coords) == 3) { - $this->point3D = new GeoPoint3D($coords[0], $coords[1], $coords[2]); + $this->point3D = new Point3D(...$coords); } break; } } /** * Magic method called when a unknown property is get. * * Handles $global, $local, $type, $body_code, $ship_code, $place_code, * $body_kind, $containsGlobalLocation, $containsLocalLocation. */ function __get ($variable) { switch ($variable) { /* main variables */ case 'global': return $this->data[0]; break; case 'local': return (count($this->data) > 1) ? $this->data[1] : null; break; /* global location */ case 'type': return $this->data[0][0]; case 'body_code': if ($this->data[0][0] == 'B') { return substr($this->data[0], 1, 5); } return null; case 'place_code': if ($this->data[0][0] == 'B') { return substr($this->data[0], 6, 3); } return null; case 'ship_code': if ($this->data[0][0] == 'S') { return substr($this->data[0], 1, 5); } return null; case 'body_kind': if ($this->data[0][0] == 'B' && $this->body != null) { if ($kind = $this->body->kind()) { return $kind; } } elseif ($this->data[0][0] == 'S') { return 'ship'; } return 'place'; case 'containsGlobalLocation': return count($this->data) > 0; case 'containsLocalLocation': return count($this->data) > 1; default: throw new Exception("Unknown variable: $variable"); break; } } /** * Checks if the place exists * * @return bool true if the place exists ; otherwise, false. * * @todo Handle alias */ function exists () { $n = count($this->data); //If not defined, it doesn't exist if ($n == 0) { return false; } //Checks global location switch ($this->data[0][0]) { case 'B': switch (strlen($this->data[0])) { case 9: if (!$place = GeoPlace::from_code($this->data[0])) { return false; } break; case 6: $body = new GeoBody(substr($this->data[0], 1)); if ($body->lastError) { return false; } break; default: message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__); } break; case 'S': $ship = new Ship(substr($this->data[0], 1)); if ($body->lastError) { return false; } break; default: message_die(GENERAL_ERROR, "Invalid global location expression size: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__); return false; } if ($n > 1) { if (!isset($place)) { message_die(GENERAL_ERROR, "Can't check if a local place exists for the following location: " . $this->data[0], "GeoLocation exists method", __LINE__, __FILE__); } if (!$place->is_valid_local_location($this->data[1])) { return false; } } return true; } /** * Checks if the place is equals at the specified expression or place * * @return bool true if the places are equals ; otherwise, false. * * @todo Create a better set of rules to define when 2 locations are equal. */ function equals ($expression) { //Are global location equals? //TODO: create a better set of rules to define when 2 locations are equal. if (is_a($expression, 'GeoLocation')) { if (!$this->equals($expression->data[0])) { return false; } if (count($expression->data) + count($this->data) > 2) { return $expression->data[1] == $this->data[1]; } } if ($expression == $this->data[0]) { return true; } $n1 = strlen($expression); $n2 = strlen($this->data[0]); if ($n1 > $n2) { return substr($expression, 0, $n2) == $this->data[0]; } return false; } /** * Represents the current location instance as a string * * @return string a string representing the current location */ function __toString () { if (!$this->data[0]) { return ""; } switch ($this->data[0][0]) { case 'S': $ship = new Ship($this->ship_code); $location[] = $ship->name; break; case 'B': $body = new GeoBody($this->body_code); $location[] = $body->name ? $body->name : lang_get('UnknownBody'); if (strlen($this->data[0]) == 9) { $place = GeoPlace::from_code($this->data[0]); $location[] = $place->name ? $place->name : lang_get('UnknownPlace'); } break; case 'x': $pt = $this->point3D->toSpherical(); return sprintf("(%d, %d°, %d°)", $pt[0], $pt[1], $pt[2]); default: message_die(GENERAL_ERROR, "Unknown location identifier: $type.
- * // _____ _____
- * // / 5 / 6 /|
- * // /- - -/- - -/ |
- * // /_____/____ /| |
- * // | | | |/|
- * // | 7 | 8 | / | 2
- * // |_____|_____|/| |
- * // | | | |/
- * // | 3 | 4 | /
- * // |_____|_____|/
- *
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- * @return int the number of the sector (0 if x = y = z = 0 ; otherwise, 1 to 8)
- */
- static function getSector ($x, $y, $z) {
- //Cube center
- if ($x == 0 && $y == 0 && $z == 0) {
- return 0;
- }
-
- //One of the 8 cubes
- $sector = 1;
- if ($x >= 0) {
- $sector++; //we're at right
- }
- if ($y < 0) {
- $sector += 2; //we're at bottom
- }
- if ($z >= 0) {
- $sector += 4; //we're on the top layer
- }
-
- return $sector;
- }
-
- /**
- * Gets the sector from the (x, y, z) specified coordinates
- * @see getSector
- *
- * @param mixed $pt a GeoPoint3D object for the x, y, z coordinates or a parsable string
- * @return int the number of the sector (0 if x = y = z 0 ; otherwise, 1 to 8)
- */
- static function getSectorFromPoint3D ($pt) {
- if (is_string($pt)) {
- $pt = GeoPoint3D::fromString($pt);
- }
- return self::getSector($pt->x, $pt->y, $pt->z);
- }
-
- /**
- * Gets the base vector for the specified sector
- *
- * Example code:
- *
- * $vector = GeoOctocube::getBaseVector(4);
- * //$vector is a (1, -1, -1) array
- *
- * @param int $sector the sector number (0-8)
- * @return array if the sector is 0, (0, 0, 0) ; otherwise, an array with three signed 1 values.
- */
- static function getBaseVector ($sector) {
- switch ($sector) {
- case 0: return [0, 0, 0];
- case 1: return [-1, 1, -1];
- case 2: return [1, 1, -1];
- case 3: return [-1, -1, -1];
- case 4: return [1, -1, -1];
- case 5: return [-1, 1, 1];
- case 6: return [1, 1, 1];
- case 7: return [-1, -1, 1];
- case 8: return [1, -1, 1];
- default: message_die(GENERAL_ERROR, "Invalid sector: $sector", "GeoOctocube::getBaseVector");
- }
- }
-
-
- /**
- * Gets SQL RLIKE pattern for the specified sector
- *
- * @param int $sector the sector number (0-8)
- * @param int $z if not null, limits the query to the specified z coordinate [optional]
- * @return string a SQL clause like "([0-9]+, -[0,9]+, [0,9]+)"
- */
- static function getRlikePatternFromSector ($sector, $z = null) {
- if ($sector == 0) {
- return "(0, 0, 0)";
- }
-
- $vector = self::getBaseVector($sector);
-
- //x
- if ($vector[0] == 1) {
- $query = "([0-9]+, ";
- } else {
- $query = "(-[0-9]+, ";
- }
-
- //y
- if ($vector[1] == 1) {
- $query .= "[0-9]+, ";
- } else {
- $query .= "-[0-9]+, ";
- }
-
- //z
- if ($z !== null) {
- $query .= "$z)";
- } elseif ($vector[2] == "1") {
- $query .= "[0-9]+)";
- } else {
- $query .= "-[0-9]+)";
- }
-
- return $query;
- }
-}
diff --git a/includes/geo/point3D.php b/includes/geo/point3D.php
deleted file mode 100644
index 82cc85c..0000000
--- a/includes/geo/point3D.php
+++ /dev/null
@@ -1,239 +0,0 @@
-
- * @copyright 2010 Sébastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-require_once("galaxy.php");
-
-/**
- * Geo point 3D class.
- *
- * This class represents a x, y, z point.
- *
- * It implements IteratorAggregate to allow the foreach instruction
- * on a GeoPoint3D object:
- *
- *
- * $point = new GeoPoint3D(17, 24, -6);
- * foreach ($point as $axis => $coordinate) {
- * echo "\n\t$axis = $coordinate";
- * }
- * //This will output:
- * // x = 17
- * // y = 24
- * // z = -6
- *
- *
- * The point 3D representation is xyz: [x, y, z] ; you can print it as a string
- * and get this format:
- *
- *
- * $point = new GeoPoint3D(17, 24, -6);
- * echo (string)$point; //will output xyz: [17, 24, -6]
- *
- *
- */
-class GeoPoint3D implements IteratorAggregate {
- //
- // x, y, z public properties
- //
-
- /**
- * the x coordinate
- *
- * @var integer
- */
- public $x;
-
- /**
- * the y coordinate
- *
- * @var integer
- */
- public $y;
-
- /**
- * the z coordinate
- *
- * @var integer
- */
- public $z;
-
- //
- // constructor / toString
- //
-
- /**
- * Initializes a new instance of GeoPoint3D class
- *
- * @param int $x the x coordinate
- * @param int $y the y coordinate
- * @param int $z the z coordinate
- */
- function __construct ($x, $y, $z) {
- $this->x = (int)$x;
- $this->y = (int)$y;
- $this->z = (int)$z;
- }
-
- /**
- * Parses a string expression and gets a GeoPoint3D object
- *
- * Formats recognized are:
- * - xyz: [x, y, z]
- * - (x, y, z)
- *
- * @param string $expression the expression to parse
- * @return GeoPoint3D If the specified expression could be parsed, a GeoPoint3D instance ; otherwise, null.
- */
- static function fromString ($expression) {
- if (string_starts_with($expression, 'xyz:', false)) {
- $pos1 = strpos($expression, '[', 4) + 1;
- $pos2 = strpos($expression, ']', $pos1);
- if ($pos1 > -1 && $pos2 > -1) {
- $expression = substr($expression, $pos1, $pos2 - $pos1);
- $xyz = explode(',', $expression, 3);
- return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
- }
- } elseif ($expression[0] = '(') {
- $expression = substr($expression, 1, -1);
- $xyz = explode(',', $expression, 3);
- return new GeoPoint3D($xyz[0], $xyz[1], $xyz[2]);
- }
- return null;
- }
-
- /**
- * Returns a string representation of the point coordinates.
- *
- * @param $format the format to use
- * @return string a string representation of the coordinates
- *
- * To print a "xyz: [10, 20, 40]" string:
- * $point = new GeoPoint3D(10, 20, 40);
- * echo $point->sprintf("xyz: [%d, %d, %d]");
- *
- * //Of course, you could have (implicitly) use the __toString method:
- * echo $point;
- *
- * To print a (10, 20, 40) string:
- * $point = new GeoPoint3D(10, 20, 40);
- * echo $point->sprintf("(%d, %d, %d)");
- */
- function sprintf ($format) {
- return sprintf($format, $this->x, $this->y, $this->z);
- }
-
- /**
- * Returns a xyz: [x, y, z] string representation of the point coordinates.
- *
- * @return string a xyz: [x, y, z] string representation of the coordinates
- */
- function __toString () {
- return $this->sprintf("xyz: [%d, %d, %d]");
- }
-
- /**
- * Determines if this point is equal to the specified point.
- *
- * @param GeoPoint3D $point The point to compare
- * @return bool true if the two points are equal ; otherwise, false.
- */
- function equals ($point) {
- return ($this->x == $point->x) && ($this->y == $point->y) && ($this->z == $point->z);
- }
-
- //
- // Math
- //
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
- *
- * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSpherical () {
- return GeoGalaxy::cartesianToSpherical($this->x, $this->y, $this->z);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current x, y, z cartesian point
- *
- * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSphericalAlternative () {
- return GeoGalaxy::cartesianToSphericalAlternative($this->x, $this->y, $this->z);
- }
-
- /**
- * Translates the center and rescales.
- *
- * This method allow to help to represent coordinate in a new system
- *
- * This method is used to represent Zed objects in dojo with the following
- * parameters:
- *
- * $pointKaos = GeoPoint3D(800, 42, 220);
- * $pointKaos->translate(500, 300, 200, 2);
- * echo $pointKaos;
- * //This will output xyz: [150, -129, 10]
- *
- *
- * @param int $dx the difference between the old x and new x (ie the value of x = 0 in the new system)
- * @param int $dy the difference between the old y and new y (ie the value of y = 0 in the new system)
- * @param int $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
- * @param float $scale if specified, divides each coordinate by this value (optional)
- */
- function translate ($dx, $dy, $dz, $scale = 1) {
- if ($scale == 1) {
- $this->x += $dx;
- $this->y += $dy;
- $this->z += $dz;
- } elseif ($scale == 0) {
- $this->x = 0;
- $this->y = 0;
- $this->z = 0;
- } else {
- $this->x = $this->x * $scale + $dx;
- $this->y = $this->y * $scale + $dy;
- $this->z = $this->z * $scale + $dz;
- }
- }
-
- //
- // Implementing IteratorAggregate
- //
-
- /**
- * Retrieves class iterator. It traverses x, y and z.
- *
- * @return Traversable the iterator
- */
- function getIterator () {
- return new ArrayIterator($this);
- }
-
-
-}
diff --git a/includes/geo/pointPolarZ.php b/includes/geo/pointPolarZ.php
deleted file mode 100644
index 54039dc..0000000
--- a/includes/geo/pointPolarZ.php
+++ /dev/null
@@ -1,376 +0,0 @@
-
- * @copyright 2010 Sébastien Santoro aka Dereckson
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version 0.1
- * @link http://scherzo.dereckson.be/doc/zed
- * @link http://zed.dereckson.be/
- * @filesource
- */
-
-require_once("point3D.php");
-
-/**
- * Geo point polar+z class.
- *
- * This class represents a r, ρ, z point.
- *
- * They are useful to express coordinates in a cylinder shape, like a tower
- * where it make senses to use polar coordinates instead x, y but where the
- * height is not relative to a center, like it would be in a sphere.
- *
- * It implements IteratorAggregate to allow the foreach instruction
- * on a GeoPointPolarZ object:
- *
- *
- * $point = new GeoPointPolarZ(17, '24°', -6);
- * foreach ($point as $axis => $coordinate) {
- * echo "\n\t$axis = $coordinate";
- * }
- * //This will output:
- * // r = 17
- * // t = 24°
- * // z = -6
- *
- *
- * The point 3D representation is rtz: [ρ, θ, z] ; you can print it as a string
- * and get this format:
- *
- *
- * $point = new GeoPointPolarZ(17, '24°', -6);
- * echo (string)$point; //will output rρz: [17, 24°, -6]
- *
- *
- */
-class GeoPointPolarZ implements IteratorAggregate {
- //
- // ρ, θ, z public properties
- //
-
- /**
- * the ρ coordinate
- *
- * @var float
- */
- public $r;
-
- /**
- * the θ coordinate
- *
- * This coordinate could be expressed as:
- * - a string with a float, appended by "°" or " °" (in degree)
- * - as a float (in radian)
- *
- * @var mixed
- */
- public $t;
-
- /**
- * the z coordinate
- *
- * @var float
- */
- public $z;
-
- //
- // constructor / toString
- //
-
- /**
- * Initializes a new instance of GeoPointPolarZ class
- *
- * @param float $r the ρ coordinate
- * @param mixed $t the θ coordinate, in ° (string) or radian (float)
- * @param float $z the z coordinate
- */
- function __construct ($r, $t, $z) {
- $this->r = (float)$r;
- $this->t = trim($t);
- $this->z = (float)$z;
- }
-
- /**
- * Parses a string expression and gets a GeoPointPolarZ object
- *
- * Formats recognized are:
- * - rtz: [ρ, θ, z]
- * - (ρ, θ, z)
- *
- * @param string $expression the expression to parse
- * @return GeoPointPolarZ If the specified expression could be parsed, a GeoPointPolarZ instance ; otherwise, null.
- */
- static function fromString ($expression) {
- if (string_starts_with($expression, 'rtz:', false)) {
- $pos1 = strpos($expression, '[', 4) + 1;
- $pos2 = strpos($expression, ']', $pos1);
- if ($pos1 > -1 && $pos2 > -1) {
- $expression = substr($expression, $pos1, $pos2 - $pos1);
- $rtz = explode(',', $expression, 3);
- return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
- }
- } elseif ($expression[0] = '(') {
- $expression = substr($expression, 1, -1);
- $rtz = explode(',', $expression, 3);
- return new GeoPointPolarZ($rtz[0], $rtz[1], $rtz[2]);
- }
- return null;
- }
-
- /**
- * Returns a string representation of the point coordinates.
- *
- * @param $format the format to use
- * @return string a string representation of the coordinates
- *
- * To print a "rtz: [10, 20°, 40]" string:
- * $point = new GeoPointPolarZ(10, '20°', 40);
- * echo $point->sprintf("rtz: [%d, %s, %d]");
- *
- * //Of course, you could have (implicitly) use the __toString method:
- * echo $point;
- *
- * To print a (10, 20°, 40) string:
- * $point = new GeoPointPolarZ(10, 20°, 40);
- * echo $point->sprintf("(%d, %s, %d)");
- */
- function sprintf ($format) {
- return sprintf($format, $this->r, self::getDegrees($this->t), $this->z);
- }
-
- /**
- * Returns a rρz: [r, ρ, z] string representation of the point coordinates.
- *
- * @return string a rtz: [ρ, θ, z] string representation of the coordinates
- */
- function __toString () {
- return $this->sprintf("rtz: [%d, %s, %d]");
- }
-
- /**
- * Determines if this point is equal to the specified point.
- *
- * @param GeoPointPolarZ $point The point to compare
- * @return bool true if the two points are equal ; otherwise, false.
- */
- function equals ($point) {
- return ($this->r == $point->r) && self::areAngleEqual($this->t, $point->t) && ($this->z == $point->z);
- }
-
- /**
- * Determines if two angles are equal
- * @param mixed $angle1 the first angle value, ie a float (angle in radian) or a string formed by an integer appended by ° (degrees)
- * @param mixed $angle2 the second angle value, a float (angle in radian) or a string formed by an integer appended by ° (degrees)
- * @return bool true if the angles are equal ; otherwise, false.
- */
- static function areAngleEqual ($angle1, $angle2) {
- if ($angle1 === $angle2) {
- return true;
- }
- if (!is_numerical($angle1)) {
- $angle1 = deg2rad((float)$angle1);
- }
- if (!is_numerical($angle2)) {
- $angle2 = deg2rad((float)$angle2);
- }
- $angle1 = self::normalizeAngle($angle1);
- $angle2 = self::normalizeAngle($angle2);
- return ($angle1 == $angle2);
- }
-
- /**
- * Normalizes an angle (in radians) in the interval [0, π[ (or a custom interval)
- *
- * @param float $angle the angle (in radians)
- * @param float $min the radians value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the radians value the angle must be strictly lesser than [optional, default value: M_PI]
- * @param float $interval the increment interval [optional, default value: 360]
- */
- static function normalizeAngle ($angle, $min = 0, $max = M_PI, $interval = M_PI) {
- while ($angle < $min) {
- $angle += $interval;
- }
- while ($angle >= $max) {
- $angle -= $interval;
- }
- return $angle;
- }
-
- /**
- * Normalizes an angle (in degrees) in the interval [0, 360[ (or a custom interval)
- *
- * @param float $angle the angle to normalize, in degrees
- * @param float $min the degrees value the angle must be greater or equal than [optional, default value: 0]
- * @param float $max the degrees value the angle must be strictly lesser than [optional, default value: 360]
- * @param float $interval the increment interval [optional, default value: 360]
- */
- static function normalizeAngleInDegrees ($angle, $min = 0, $max = 360, $interval = 360) {
- while ($angle < $min) {
- $angle += $interval;
- }
- while ($angle >= $max) {
- $angle -= $interval;
- }
- return $angle;
- }
-
- /**
- * Gets the specified angle in radians
- *
- * @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
- * @return float the angle in radians
- */
- static function getRadians ($angle) {
- return is_numeric($angle) ? $angle : deg2rad((float)$angle);
- }
-
- /**
- * Gets the specified angle in degrees
- *
- * @param mixed $angle the angle, a float in radians or a string (a float + "°" or " °" in degrees
- * @return string the angle (float) in degrees followed by "°"
- */
- static function getDegrees ($angle) {
- return is_numeric($angle) ? rad2deg((float)$angle) . '°' : $angle;
- }
-
- /**
- * Converts a polar coordinate angle to a 0-360° CW angle
- */
- static function getNaturalDegrees ($angle) {
- return self::normalizeAngleinDegrees(90 - self::getDegrees($angle));
- }
-
- //
- // Math
- //
-
- /**
- * Gets the (x, y, z) cartesian coordinates from the current ρ, θ, z polar+z point
- *
- * @return array an array of 3 floats number, representing the (x, y, z) cartesian coordinates
- */
- function toCartesian () {
- $x = $this->r * cos(self::getRadians($this->t));
- $y = $this->r * sin(self::getRadians($this->t));
- return [$x, $y, $this->z];
- }
-
- /**
- * Converts the current GeoPointPolarZ instance to a GeoPoint3D instance
- *
- * @return GeoPoint3D an instance of the GeoPoint3D class representing the (x, y, z) cartesian coordinates
- */
- function toPoint3D () {
- $pt = $this->toCartesian();
- return new GeoPoint3D($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
- *
- * The algo used is from http://fr.wikipedia.org/wiki/Coordonn%C3%A9es_sph%C3%A9riques#Relation_avec_les_autres_syst.C3.A8mes_de_coordonn.C3.A9es_usuels
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSpherical () {
- $pt = $this->toCartesian();
- return GeoGalaxy::cartesianToSpherical($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Gets the (ρ, φ, θ) spherical coordinates from the current (ρ, θ, z) polar+z point
- *
- * The algo used is from http://www.phy225.dept.shef.ac.uk/mediawiki/index.php/Cartesian_to_polar_conversion
- *
- * @return array an array of 3 floats number, representing the (ρ, φ, θ) spherical coordinates
- */
- function toSphericalAlternative () {
- $pt = $this->toCartesian();
- return GeoGalaxy::cartesianToSphericalAlternative($pt[0], $pt[1], $pt[2]);
- }
-
- /**
- * Translates the center and rescales.
- *
- * This method allow to help to represent coordinate in a new system
- *
- * This method is used to represent Zed objects in dojo with the following
- * parameters:
- *
- * $pointKaos = GeoPointPolarZ(800, 42, 220);
- * $pointKaos->translate(500, 300, 200, 2);
- * echo $pointKaos;
- * //This will output rρz: [150, -129, 10]
- *
- *
- * @param float $dr the difference between the old ρ and new ρ (ie the value of ρ = 0 in the new system)
- * @param float $dt the difference between the old θ and new θ (ie the value of θ = 0 in the new system)
- * @param float $dz the difference between the old y and new z (ie the value of z = 0 in the new system)
- * @param int $scale if specified, divides each coordinate by this value (optional)
- */
- function translate ($dr, $dt, $dz, $scale = 1) {
- if ($scale == 1) {
- $this->r += $dr;
- $this->t += $dt;
- $this->z += $dz;
- } elseif ($scale == 0) {
- $this->r = 0;
- $this->t = 0;
- $this->z = 0;
- } else {
- $this->r = $this->r * $scale + $dr;
- $this->t = $this->t * $scale + $dt;
- $this->z = $this->z * $scale + $dz;
- }
- }
-
- /**
- * Calculates the section number the specified angle belongs
- *
- * @param $angle float The natural angle in degree (North 0°, East 90°, etc. clockwise)
- * @param int $count the number of sections (default value: 6)
- * @return $int the section number
- */
- static function calculateSection ($angle, $count = 6) {
- if ($angle < 90) {
- $angle += 270;
- } else {
- $angle -= 90;
- }
- return 1 + (int)($angle / (360/$count));
- }
-
- /**
- * Gets the section number the θ angle belongs to.
- *
- * @param int $count the number of sections
- * @return $int the section number
- */
- function getSection ($count = 6) {
- return self::calculateSection(self::getNaturalDegrees($this->t), $count);
- }
-
- //
- // Implementing IteratorAggregate
- //
-
- /**
- * Retrieves class iterator. It traverses ρ, θ and z.
- *
- * @return Traversable the iterator
- */
- function getIterator () {
- return new ArrayIterator($this);
- }
-}
diff --git a/skins/zed/builder_map.tpl b/skins/zed/builder_map.tpl
index dbdba27..fd4d732 100644
--- a/skins/zed/builder_map.tpl
+++ b/skins/zed/builder_map.tpl
@@ -1,49 +1,47 @@