97 lines
2.6 KiB
PHP
97 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace swf2ass;
|
|
|
|
class PathSegment {
|
|
/** @var VisitedPoint[] */
|
|
public array $points;
|
|
|
|
|
|
public function __construct(Vector2 $start) {
|
|
$this->points = [new VisitedPoint($start, false)];
|
|
}
|
|
|
|
public function flip() {
|
|
$this->points = array_reverse($this->points, false);
|
|
}
|
|
|
|
public function add_point(VisitedPoint $point) {
|
|
$this->points[] = $point;
|
|
}
|
|
|
|
public function start(): Vector2 {
|
|
return reset($this->points)->pos;
|
|
}
|
|
|
|
public function end(): Vector2 {
|
|
return end($this->points)->pos;
|
|
}
|
|
|
|
public function is_empty(): bool {
|
|
return count($this->points) <= 1;
|
|
}
|
|
|
|
public function is_closed(): bool {
|
|
return $this->start()->equals($this->end());
|
|
}
|
|
|
|
public function swap(PathSegment $other) {
|
|
[$this->points, $other->points] = [$other->points, $this->points];
|
|
}
|
|
|
|
public function merge(PathSegment $other) {
|
|
$this->points = array_merge($this->points, array_slice($other->points, 1));
|
|
}
|
|
|
|
public function try_merge(PathSegment $other, bool $directed): bool {
|
|
if ($other->end()->equals($this->start())) {
|
|
$this->swap($other);
|
|
$this->merge($other);
|
|
return true;
|
|
} else if ($this->end()->equals($other->start())) {
|
|
$this->merge($other);
|
|
return true;
|
|
} else if (!$directed and $this->end()->equals($other->end())) {
|
|
$other->flip();
|
|
$this->merge($other);
|
|
return true;
|
|
} else if (!$directed and $this->start()->equals($other->start())) {
|
|
$other->flip();
|
|
$this->swap($other);
|
|
$this->merge($other);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getShape(): Shape {
|
|
if ($this->is_empty()) {
|
|
throw new \Exception();
|
|
}
|
|
$shape = new Shape();
|
|
|
|
$first = reset($this->points);
|
|
|
|
$pos = new Vector2(0, 0);
|
|
$shape->edges[] = new MoveRecord($first->pos, $pos);
|
|
$pos = $first->pos;
|
|
|
|
while (($point = next($this->points)) !== false) {
|
|
if (!$point->is_bezier_control) {
|
|
$shape->edges[] = new LineRecord($point->pos, $pos);
|
|
$pos = $point->pos;
|
|
} else {
|
|
$end = next($this->points);
|
|
if ($end === false) {
|
|
throw new \Exception("Bezier without endpoint");
|
|
}
|
|
|
|
$shape->edges[] = new QuadraticCurveRecord($point->pos, $end->pos, $pos);
|
|
$pos = $end->pos;
|
|
}
|
|
}
|
|
|
|
return $shape;
|
|
}
|
|
} |