From d17e83cb97e4621a558f9cbc4f268c99c9a1b710 Mon Sep 17 00:00:00 2001 From: Dhaiven Date: Sun, 19 Nov 2023 10:42:30 +0100 Subject: [PATCH 1/3] Vecttor3 is now immutable --- src/Vector3.php | 74 ++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/src/Vector3.php b/src/Vector3.php index ca8701d..3d58d80 100644 --- a/src/Vector3.php +++ b/src/Vector3.php @@ -33,7 +33,8 @@ use function sqrt; use const PHP_ROUND_HALF_UP; -class Vector3{ +readonly class Vector3{ + public function __construct( public float|int $x, public float|int $y, @@ -45,27 +46,27 @@ public static function zero() : Vector3{ return new self(0, 0, 0); } - public function getX() : float|int{ + final public function getX() : float|int{ return $this->x; } - public function getY() : float|int{ + final public function getY() : float|int{ return $this->y; } - public function getZ() : float|int{ + final public function getZ() : float|int{ return $this->z; } - public function getFloorX() : int{ + final public function getFloorX() : int{ return (int) floor($this->x); } - public function getFloorY() : int{ + final public function getFloorY() : int{ return (int) floor($this->y); } - public function getFloorZ() : int{ + final public function getFloorZ() : int{ return (int) floor($this->z); } @@ -73,15 +74,15 @@ public function add(float|int $x, float|int $y, float|int $z) : Vector3{ return new Vector3($this->x + $x, $this->y + $y, $this->z + $z); } - public function addVector(Vector3 $v) : Vector3{ + final public function addVector(Vector3 $v) : Vector3{ return $this->add($v->x, $v->y, $v->z); } - public function subtract(float|int $x, float|int $y, float|int $z) : Vector3{ + final public function subtract(float|int $x, float|int $y, float|int $z) : Vector3{ return $this->add(-$x, -$y, -$z); } - public function subtractVector(Vector3 $v) : Vector3{ + final public function subtractVector(Vector3 $v) : Vector3{ return $this->add(-$v->x, -$v->y, -$v->z); } @@ -114,54 +115,33 @@ public function abs() : Vector3{ return new Vector3(abs($this->x), abs($this->y), abs($this->z)); } - /** - * @return Vector3 - */ - public function getSide(int $side, int $step = 1){ + final public function getSide(int $side, int $step = 1) : Vector3{ [$offsetX, $offsetY, $offsetZ] = Facing::OFFSET[$side] ?? [0, 0, 0]; return $this->add($offsetX * $step, $offsetY * $step, $offsetZ * $step); } - /** - * @return Vector3 - */ - public function down(int $step = 1){ + final public function down(int $step = 1) : Vector3{ return $this->getSide(Facing::DOWN, $step); } - /** - * @return Vector3 - */ - public function up(int $step = 1){ + final public function up(int $step = 1) : Vector3{ return $this->getSide(Facing::UP, $step); } - /** - * @return Vector3 - */ - public function north(int $step = 1){ + final public function north(int $step = 1) : Vector3{ return $this->getSide(Facing::NORTH, $step); } - /** - * @return Vector3 - */ - public function south(int $step = 1){ + final public function south(int $step = 1) : Vector3{ return $this->getSide(Facing::SOUTH, $step); } - /** - * @return Vector3 - */ - public function west(int $step = 1){ + final public function west(int $step = 1) : Vector3{ return $this->getSide(Facing::WEST, $step); } - /** - * @return Vector3 - */ - public function east(int $step = 1){ + final public function east(int $step = 1) : Vector3{ return $this->getSide(Facing::EAST, $step); } @@ -173,7 +153,7 @@ public function east(int $step = 1){ * @return \Generator|Vector3[] * @phpstan-return \Generator */ - public function sides(int $step = 1) : \Generator{ + final public function sides(int $step = 1) : \Generator{ foreach(Facing::ALL as $facing){ yield $facing => $this->getSide($facing, $step); } @@ -184,7 +164,7 @@ public function sides(int $step = 1) : \Generator{ * * @return Vector3[] */ - public function sidesArray(bool $keys = false, int $step = 1) : array{ + final public function sidesArray(bool $keys = false, int $step = 1) : array{ return iterator_to_array($this->sides($step), $keys); } @@ -196,7 +176,7 @@ public function sidesArray(bool $keys = false, int $step = 1) : array{ * @return \Generator|Vector3[] * @phpstan-return \Generator */ - public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{ + final public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{ foreach(Facing::ALL as $facing){ if(Facing::axis($facing) !== $axis){ yield $facing => $this->getSide($facing, $step); @@ -207,15 +187,15 @@ public function sidesAroundAxis(int $axis, int $step = 1) : \Generator{ /** * Return a Vector3 instance */ - public function asVector3() : Vector3{ + final public function asVector3() : Vector3{ return new Vector3($this->x, $this->y, $this->z); } - public function distance(Vector3 $pos) : float{ + final public function distance(Vector3 $pos) : float{ return sqrt($this->distanceSquared($pos)); } - public function distanceSquared(Vector3 $pos) : float{ + final public function distanceSquared(Vector3 $pos) : float{ return (($this->x - $pos->x) ** 2) + (($this->y - $pos->y) ** 2) + (($this->z - $pos->z) ** 2); } @@ -229,11 +209,11 @@ public function maxPlainDistance(Vector3|Vector2|float $x, float $z = 0) : float } } - public function length() : float{ + final public function length() : float{ return sqrt($this->lengthSquared()); } - public function lengthSquared() : float{ + final public function lengthSquared() : float{ return $this->x * $this->x + $this->y * $this->y + $this->z * $this->z; } @@ -378,4 +358,4 @@ public static function sum(Vector3 ...$vector3s) : Vector3{ } return new Vector3($x, $y, $z); } -} +} \ No newline at end of file From ab522181c6288ee03b40d74bed1050549b55fc88 Mon Sep 17 00:00:00 2001 From: Dhaiven Date: Sun, 12 May 2024 18:45:37 +0200 Subject: [PATCH 2/3] Full immutable --- src/Vector3.php | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Vector3.php b/src/Vector3.php index 3d58d80..39783ab 100644 --- a/src/Vector3.php +++ b/src/Vector3.php @@ -36,9 +36,9 @@ readonly class Vector3{ public function __construct( - public float|int $x, - public float|int $y, - public float|int $z + protected float|int $x, + protected float|int $y, + protected float|int $z ){} public static function zero() : Vector3{ @@ -75,7 +75,7 @@ public function add(float|int $x, float|int $y, float|int $z) : Vector3{ } final public function addVector(Vector3 $v) : Vector3{ - return $this->add($v->x, $v->y, $v->z); + return $this->add($v->getX(), $v->getY(), $v->getZ()); } final public function subtract(float|int $x, float|int $y, float|int $z) : Vector3{ @@ -83,7 +83,7 @@ final public function subtract(float|int $x, float|int $y, float|int $z) : Vecto } final public function subtractVector(Vector3 $v) : Vector3{ - return $this->add(-$v->x, -$v->y, -$v->z); + return $this->add(-$v->getX(), -$v->getY(), -$v->getZ()); } public function multiply(float $number) : Vector3{ @@ -201,7 +201,7 @@ final public function distanceSquared(Vector3 $pos) : float{ public function maxPlainDistance(Vector3|Vector2|float $x, float $z = 0) : float{ if($x instanceof Vector3){ - return $this->maxPlainDistance($x->x, $x->z); + return $this->maxPlainDistance($x->getX(), $x->getZ()); }elseif($x instanceof Vector2){ return $this->maxPlainDistance($x->x, $x->y); }else{ @@ -227,19 +227,19 @@ public function normalize() : Vector3{ } public function dot(Vector3 $v) : float{ - return $this->x * $v->x + $this->y * $v->y + $this->z * $v->z; + return $this->x * $v->getX() + $this->y * $v->getY() + $this->z * $v->getZ(); } public function cross(Vector3 $v) : Vector3{ return new Vector3( - $this->y * $v->z - $this->z * $v->y, - $this->z * $v->x - $this->x * $v->z, - $this->x * $v->y - $this->y * $v->x + $this->y * $v->getZ() - $this->z * $v->getY(), + $this->z * $v->getX() - $this->x * $v->getZ(), + $this->x * $v->getY() - $this->y * $v->getX() ); } public function equals(Vector3 $v) : bool{ - return $this->x == $v->x and $this->y == $v->y and $this->z == $v->z; + return $this->x == $v->getX() and $this->y == $v->getY() and $this->z == $v->getZ(); } /** @@ -247,7 +247,7 @@ public function equals(Vector3 $v) : bool{ * passed in vector, or null if not possible. */ public function getIntermediateWithXValue(Vector3 $v, float $x) : ?Vector3{ - $xDiff = $v->x - $this->x; + $xDiff = $v->getX() - $this->x; if(($xDiff * $xDiff) < 0.0000001){ return null; } @@ -257,7 +257,7 @@ public function getIntermediateWithXValue(Vector3 $v, float $x) : ?Vector3{ if($f < 0 or $f > 1){ return null; }else{ - return new Vector3($x, $this->y + ($v->y - $this->y) * $f, $this->z + ($v->z - $this->z) * $f); + return new Vector3($x, $this->y + ($v->getY() - $this->y) * $f, $this->z + ($v->getZ() - $this->z) * $f); } } @@ -266,7 +266,7 @@ public function getIntermediateWithXValue(Vector3 $v, float $x) : ?Vector3{ * passed in vector, or null if not possible. */ public function getIntermediateWithYValue(Vector3 $v, float $y) : ?Vector3{ - $yDiff = $v->y - $this->y; + $yDiff = $v->getY() - $this->y; if(($yDiff * $yDiff) < 0.0000001){ return null; } @@ -276,7 +276,7 @@ public function getIntermediateWithYValue(Vector3 $v, float $y) : ?Vector3{ if($f < 0 or $f > 1){ return null; }else{ - return new Vector3($this->x + ($v->x - $this->x) * $f, $y, $this->z + ($v->z - $this->z) * $f); + return new Vector3($this->x + ($v->getX() - $this->x) * $f, $y, $this->z + ($v->getZ() - $this->z) * $f); } } @@ -285,7 +285,7 @@ public function getIntermediateWithYValue(Vector3 $v, float $y) : ?Vector3{ * passed in vector, or null if not possible. */ public function getIntermediateWithZValue(Vector3 $v, float $z) : ?Vector3{ - $zDiff = $v->z - $this->z; + $zDiff = $v->getZ() - $this->z; if(($zDiff * $zDiff) < 0.0000001){ return null; } @@ -295,7 +295,7 @@ public function getIntermediateWithZValue(Vector3 $v, float $z) : ?Vector3{ if($f < 0 or $f > 1){ return null; }else{ - return new Vector3($this->x + ($v->x - $this->x) * $f, $this->y + ($v->y - $this->y) * $f, $z); + return new Vector3($this->x + ($v->getX() - $this->x) * $f, $this->y + ($v->getY() - $this->y) * $f, $z); } } @@ -321,13 +321,13 @@ public function withComponents(float|int|null $x, float|int|null $y, float|int|n * @param Vector3 ...$vectors */ public static function maxComponents(Vector3 $vector, Vector3 ...$vectors) : Vector3{ - $x = $vector->x; - $y = $vector->y; - $z = $vector->z; + $x = $vector->getX(); + $y = $vector->getY(); + $z = $vector->getZ(); foreach($vectors as $position){ - $x = max($x, $position->x); - $y = max($y, $position->y); - $z = max($z, $position->z); + $x = max($x, $position->getX()); + $y = max($y, $position->getY()); + $z = max($z, $position->getZ()); } return new Vector3($x, $y, $z); } @@ -338,13 +338,13 @@ public static function maxComponents(Vector3 $vector, Vector3 ...$vectors) : Vec * @param Vector3 ...$vectors */ public static function minComponents(Vector3 $vector, Vector3 ...$vectors) : Vector3{ - $x = $vector->x; - $y = $vector->y; - $z = $vector->z; + $x = $vector->getX(); + $y = $vector->getY(); + $z = $vector->getZ(); foreach($vectors as $position){ - $x = min($x, $position->x); - $y = min($y, $position->y); - $z = min($z, $position->z); + $x = min($x, $position->getX()); + $y = min($y, $position->getY()); + $z = min($z, $position->getZ()); } return new Vector3($x, $y, $z); } @@ -352,9 +352,9 @@ public static function minComponents(Vector3 $vector, Vector3 ...$vectors) : Vec public static function sum(Vector3 ...$vector3s) : Vector3{ $x = $y = $z = 0; foreach($vector3s as $vector3){ - $x += $vector3->x; - $y += $vector3->y; - $z += $vector3->z; + $x += $vector3->getX(); + $y += $vector3->getY(); + $z += $vector3->getZ(); } return new Vector3($x, $y, $z); } From 65eb1efa63a6fefe939bc024d295b4d075d0a92c Mon Sep 17 00:00:00 2001 From: Dhaiven Date: Sun, 12 May 2024 18:54:39 +0200 Subject: [PATCH 3/3] Fix bugs --- src/AxisAlignedBB.php | 12 ++++++------ src/VoxelRayTrace.php | 18 +++++++++--------- tests/phpunit/Vector3Test.php | 6 +++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/AxisAlignedBB.php b/src/AxisAlignedBB.php index cf4a3e2..bd6e533 100644 --- a/src/AxisAlignedBB.php +++ b/src/AxisAlignedBB.php @@ -370,14 +370,14 @@ public function intersectsWith(AxisAlignedBB $bb, float $epsilon = 0.00001) : bo * Returns whether the specified vector is within the bounds of this AABB on all axes. */ public function isVectorInside(Vector3 $vector) : bool{ - if($vector->x <= $this->minX or $vector->x >= $this->maxX){ + if($vector->getX() <= $this->minX or $vector->getX() >= $this->maxX){ return false; } - if($vector->y <= $this->minY or $vector->y >= $this->maxY){ + if($vector->getY() <= $this->minY or $vector->getY() >= $this->maxY){ return false; } - return $vector->z > $this->minZ and $vector->z < $this->maxZ; + return $vector->getZ() > $this->minZ and $vector->getZ() < $this->maxZ; } /** @@ -409,21 +409,21 @@ public function getVolume() : float{ * Returns whether the specified vector is within the Y and Z bounds of this AABB. */ public function isVectorInYZ(Vector3 $vector) : bool{ - return $vector->y >= $this->minY and $vector->y <= $this->maxY and $vector->z >= $this->minZ and $vector->z <= $this->maxZ; + return $vector->getY() >= $this->minY and $vector->getY() <= $this->maxY and $vector->getZ() >= $this->minZ and $vector->getZ() <= $this->maxZ; } /** * Returns whether the specified vector is within the X and Z bounds of this AABB. */ public function isVectorInXZ(Vector3 $vector) : bool{ - return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->z >= $this->minZ and $vector->z <= $this->maxZ; + return $vector->getX() >= $this->minX and $vector->getX() <= $this->maxX and $vector->getZ() >= $this->minZ and $vector->getZ() <= $this->maxZ; } /** * Returns whether the specified vector is within the X and Y bounds of this AABB. */ public function isVectorInXY(Vector3 $vector) : bool{ - return $vector->x >= $this->minX and $vector->x <= $this->maxX and $vector->y >= $this->minY and $vector->y <= $this->maxY; + return $vector->getX() >= $this->minX and $vector->getX() <= $this->maxX and $vector->getY() >= $this->minY and $vector->getY() <= $this->maxY; } /** diff --git a/src/VoxelRayTrace.php b/src/VoxelRayTrace.php index dbbb10e..a757f2e 100644 --- a/src/VoxelRayTrace.php +++ b/src/VoxelRayTrace.php @@ -74,20 +74,20 @@ public static function betweenPoints(Vector3 $start, Vector3 $end) : \Generator{ $radius = $start->distance($end); - $stepX = $directionVector->x <=> 0; - $stepY = $directionVector->y <=> 0; - $stepZ = $directionVector->z <=> 0; + $stepX = $directionVector->getX() <=> 0; + $stepY = $directionVector->getY() <=> 0; + $stepZ = $directionVector->getZ() <=> 0; //Initialize the step accumulation variables depending how far into the current block the start position is. If //the start position is on the corner of the block, these will be zero. - $tMaxX = self::rayTraceDistanceToBoundary($start->x, $directionVector->x); - $tMaxY = self::rayTraceDistanceToBoundary($start->y, $directionVector->y); - $tMaxZ = self::rayTraceDistanceToBoundary($start->z, $directionVector->z); + $tMaxX = self::rayTraceDistanceToBoundary($start->getX(), $directionVector->getX()); + $tMaxY = self::rayTraceDistanceToBoundary($start->getY(), $directionVector->getY()); + $tMaxZ = self::rayTraceDistanceToBoundary($start->getZ(), $directionVector->getZ()); //The change in t on each axis when taking a step on that axis (always positive). - $tDeltaX = $directionVector->x == 0 ? 0 : $stepX / $directionVector->x; - $tDeltaY = $directionVector->y == 0 ? 0 : $stepY / $directionVector->y; - $tDeltaZ = $directionVector->z == 0 ? 0 : $stepZ / $directionVector->z; + $tDeltaX = $directionVector->getX() == 0 ? 0 : $stepX / $directionVector->getX(); + $tDeltaY = $directionVector->getY() == 0 ? 0 : $stepY / $directionVector->getY(); + $tDeltaZ = $directionVector->getZ() == 0 ? 0 : $stepZ / $directionVector->getZ(); while(true){ yield $currentBlock; diff --git a/tests/phpunit/Vector3Test.php b/tests/phpunit/Vector3Test.php index 64b6d9c..eebe233 100644 --- a/tests/phpunit/Vector3Test.php +++ b/tests/phpunit/Vector3Test.php @@ -125,9 +125,9 @@ public function testSum(array $vectors) : void{ $vec = $vec->addVector($vector); } $vec2 = Vector3::sum(...$vectors); - self::assertLessThan(0.000001, abs($vec->x - $vec2->x)); - self::assertLessThan(0.000001, abs($vec->y - $vec2->y)); - self::assertLessThan(0.000001, abs($vec->z - $vec2->z)); + self::assertLessThan(0.000001, abs($vec->getX() - $vec2->getX())); + self::assertLessThan(0.000001, abs($vec->getY() - $vec2->getY())); + self::assertLessThan(0.000001, abs($vec->getZ() - $vec2->getZ())); } /**