-
Notifications
You must be signed in to change notification settings - Fork 0
/
AxisPlacementStrategy.php
92 lines (79 loc) · 2.66 KB
/
AxisPlacementStrategy.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
namespace Aternos\Plop\Placement;
use Aternos\Plop\Placement\Util\Axis;
use Aternos\Plop\Placement\Util\AxisStrategy;
use Aternos\Plop\Structure\Elements\Element;
class AxisPlacementStrategy extends PlacementStrategy
{
public function __construct(
protected array $order = [Axis::X, Axis::Z, Axis::Y],
protected AxisStrategy $strategy = AxisStrategy::ASCENDING,
protected ?AxisStrategy $x = null,
protected ?AxisStrategy $y = null,
protected ?AxisStrategy $z = null,
public int $perTick = 1
)
{
}
public function getPlacements(): array
{
$elements = $this->getElements();
usort($elements, function ($a, $b) {
return $this->compareElements($a, $b);
});
$orderedElements = [];
$currentEqualBatch = [];
foreach ($elements as $element) {
if (empty($currentEqualBatch)) {
$currentEqualBatch[] = $element;
continue;
}
if ($this->compareElements($currentEqualBatch[0], $element) === 0) {
$currentEqualBatch[] = $element;
continue;
}
shuffle($currentEqualBatch);
$orderedElements = array_merge($orderedElements, $currentEqualBatch);
$currentEqualBatch = [$element];
}
shuffle($currentEqualBatch);
$orderedElements = array_merge($orderedElements, $currentEqualBatch);
return $this->generatePlacements($orderedElements, $this->perTick);
}
protected function compareElements(Element $a, Element $b): int
{
$order = array_reverse($this->order);
foreach ($order as $axis) {
$strategy = match ($axis) {
Axis::X => $this->getXStrategy(),
Axis::Y => $this->getYStrategy(),
Axis::Z => $this->getZStrategy()
};
$result = $this->compareOnAxis($strategy, $a->getAxis($axis), $b->getAxis($axis));
if ($result !== 0) {
return $result;
}
}
return 0;
}
protected function compareOnAxis(AxisStrategy $strategy, float $a, float $b): int
{
return match ($strategy) {
AxisStrategy::ASCENDING => $a <=> $b,
AxisStrategy::DESCENDING => $b <=> $a,
default => 0,
};
}
protected function getXStrategy(): AxisStrategy
{
return $this->x ?? $this->strategy;
}
protected function getYStrategy(): AxisStrategy
{
return $this->y ?? $this->strategy;
}
protected function getZStrategy(): AxisStrategy
{
return $this->z ?? $this->strategy;
}
}