22declare(strict_types=1);
29use
function iterator_to_array;
34use
const PHP_ROUND_HALF_UP;
37 public function __construct(
43 public static function zero() :
Vector3{
45 return new self(0, 0, 0);
48 public function getX() :
float|
int{
52 public function getY() :
float|
int{
56 public function getZ() :
float|
int{
60 public function getFloorX() :
int{
61 return (
int) floor($this->x);
64 public function getFloorY() :
int{
65 return (
int) floor($this->y);
68 public function getFloorZ() :
int{
69 return (
int) floor($this->z);
72 public function add(
float|
int $x,
float|
int $y,
float|
int $z) :
Vector3{
73 return new Vector3($this->x + $x, $this->y + $y, $this->z + $z);
77 return $this->add($v->x, $v->y, $v->z);
80 public function subtract(
float|
int $x,
float|
int $y,
float|
int $z) :
Vector3{
81 return $this->add(-$x, -$y, -$z);
85 return $this->add(-$v->x, -$v->y, -$v->z);
88 public function multiply(
float $number) :
Vector3{
89 return new Vector3($this->x * $number, $this->y * $number, $this->z * $number);
92 public function divide(
float $number) :
Vector3{
93 return new Vector3($this->x / $number, $this->y / $number, $this->z / $number);
96 public function ceil() :
Vector3{
97 return new Vector3((
int) ceil($this->x), (
int) ceil($this->y), (
int) ceil($this->z));
100 public function floor() :
Vector3{
101 return new Vector3((
int) floor($this->x), (
int) floor($this->y), (
int) floor($this->z));
107 public function round(
int $precision = 0,
int $mode = PHP_ROUND_HALF_UP) :
Vector3{
108 return $precision > 0 ?
109 new
Vector3(
round($this->x, $precision, $mode),
round($this->y, $precision, $mode),
round($this->z, $precision, $mode)) :
110 new
Vector3((int)
round($this->x, $precision, $mode), (int)
round($this->y, $precision, $mode), (int)
round($this->z, $precision, $mode));
113 public function abs() :
Vector3{
114 return new
Vector3(abs($this->x), abs($this->y), abs($this->z));
120 public function getSide(
int $side,
int $step = 1){
121 [$offsetX, $offsetY, $offsetZ] = Facing::OFFSET[$side] ?? [0, 0, 0];
123 return $this->add($offsetX * $step, $offsetY * $step, $offsetZ * $step);
129 public function down(
int $step = 1){
130 return $this->getSide(Facing::DOWN, $step);
136 public function up(
int $step = 1){
137 return $this->getSide(Facing::UP, $step);
143 public function north(
int $step = 1){
144 return $this->getSide(Facing::NORTH, $step);
150 public function south(
int $step = 1){
151 return $this->getSide(Facing::SOUTH, $step);
157 public function west(
int $step = 1){
158 return $this->getSide(Facing::WEST, $step);
164 public function east(
int $step = 1){
165 return $this->getSide(Facing::EAST, $step);
177 foreach(
Facing::ALL as $facing){
178 yield $facing => $this->getSide($facing, $step);
187 public function sidesArray(
bool $keys =
false,
int $step = 1) : array{
188 return iterator_to_array($this->sides($step), $keys);
200 foreach(
Facing::ALL as $facing){
201 if(Facing::axis($facing) !== $axis){
202 yield $facing => $this->getSide($facing, $step);
211 return new
Vector3($this->x, $this->y, $this->z);
214 public function distance(
Vector3 $pos) : float{
215 return sqrt($this->distanceSquared($pos));
218 public function distanceSquared(Vector3 $pos) : float{
219 return (($this->x - $pos->x) ** 2) + (($this->y - $pos->y) ** 2) + (($this->z - $pos->z) ** 2);
222 public function maxPlainDistance(Vector3|Vector2|
float $x,
float $z = 0) : float{
223 if($x instanceof Vector3){
224 return $this->maxPlainDistance($x->x, $x->z);
225 }elseif($x instanceof Vector2){
226 return $this->maxPlainDistance($x->x, $x->y);
228 return max(abs($this->x - $x), abs($this->z - $z));
232 public function length() : float{
233 return sqrt($this->lengthSquared());
236 public function lengthSquared() : float{
237 return $this->x * $this->x + $this->y * $this->y + $this->z * $this->z;
240 public function normalize() : Vector3{
241 $len = $this->lengthSquared();
243 return $this->divide(sqrt($len));
246 return new Vector3(0, 0, 0);
249 public function dot(Vector3 $v) : float{
250 return $this->x * $v->x + $this->y * $v->y + $this->z * $v->z;
253 public function cross(Vector3 $v) : Vector3{
255 $this->y * $v->z - $this->z * $v->y,
256 $this->z * $v->x - $this->x * $v->z,
257 $this->x * $v->y - $this->y * $v->x
261 public function equals(Vector3 $v) : bool{
262 return $this->x == $v->x and $this->y == $v->y and $this->z == $v->z;
270 $xDiff = $v->x - $this->x;
271 if(($xDiff * $xDiff) < 0.0000001){
275 $f = ($x - $this->x) / $xDiff;
277 if($f < 0 or $f > 1){
280 return new Vector3($x, $this->y + ($v->y - $this->y) * $f, $this->z + ($v->z - $this->z) * $f);
289 $yDiff = $v->y - $this->y;
290 if(($yDiff * $yDiff) < 0.0000001){
294 $f = ($y - $this->y) / $yDiff;
296 if($f < 0 or $f > 1){
299 return new Vector3($this->x + ($v->x - $this->x) * $f, $y, $this->z + ($v->z - $this->z) * $f);
308 $zDiff = $v->z - $this->z;
309 if(($zDiff * $zDiff) < 0.0000001){
313 $f = ($z - $this->z) / $zDiff;
315 if($f < 0 or $f > 1){
318 return new Vector3($this->x + ($v->x - $this->x) * $f, $this->y + ($v->y - $this->y) * $f, $z);
322 public function __toString(){
323 return "Vector3(x=" . $this->x .
",y=" . $this->y .
",z=" . $this->z .
")";
332 if($x !== null || $y !== null || $z !== null){
333 return new self($x ?? $this->x, $y ?? $this->y, $z ?? $this->z);
347 foreach($vectors as $position){
348 $x = max($x, $position->x);
349 $y = max($y, $position->y);
350 $z = max($z, $position->z);
352 return new Vector3($x, $y, $z);
364 foreach($vectors as $position){
365 $x = min($x, $position->x);
366 $y = min($y, $position->y);
367 $z = min($z, $position->z);
369 return new Vector3($x, $y, $z);
372 public static function sum(Vector3 ...$vector3s) : Vector3{
374 foreach($vector3s as $vector3){
379 return new Vector3($x, $y, $z);
getIntermediateWithZValue(Vector3 $v, float $z)
sidesAroundAxis(int $axis, int $step=1)
getIntermediateWithXValue(Vector3 $v, float $x)
getIntermediateWithYValue(Vector3 $v, float $y)
sidesArray(bool $keys=false, int $step=1)
round(int $precision=0, int $mode=PHP_ROUND_HALF_UP)
withComponents(float|int|null $x, float|int|null $y, float|int|null $z)
static maxComponents(Vector3 $vector, Vector3 ... $vectors)
static minComponents(Vector3 $vector, Vector3 ... $vectors)
getSide(int $side, int $step=1)