swf2ass/src/PathSegment.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;
}
}