swf2ass/src/Shape.php

90 lines
2.3 KiB
PHP

<?php
namespace swf2ass;
use MartinezRueda\Algorithm;
use MartinezRueda\Polygon;
class Shape {
/** @var Record[] */
private array $edges = [];
private bool $isFlat = true;
/**
* @param Record[] $edges
*/
public function __construct(array $edges = []) {
array_map([$this, "addRecord"], $edges);
}
public function addRecord(Record $record){
if(!($record instanceof MoveRecord) and !($record instanceof LineRecord)){
$this->isFlat = false;
}
$this->edges[] = $record;
}
public function start(): Vector2 {
return reset($this->edges)->getStart();
}
public function end(): Vector2 {
return end($this->edges)->getEnd();
}
public function is_closed(): bool {
return $this->start()->equals($this->end());
}
/**
* @return Record[]
*/
public function getRecords() : array{
return $this->edges;
}
public function merge(Shape $shape): Shape {
$newShape = new Shape([]);
$newShape->edges = array_merge($this->edges, $shape->edges);
$newShape->isFlat = $shape->isFlat === $this->isFlat ? $this->isFlat : false;
return $newShape;
}
public function flatten() : Shape{
if($this->isFlat){
return $this;
}
$newShape = new Shape();
//TODO: b-spline
foreach ($this->edges as $edge){
if($edge instanceof QuadraticCurveRecord){
array_map([$newShape, "addRecord"], $edge->toLineRecords());
}else if($edge instanceof CubicCurveRecord){
array_map([$newShape, "addRecord"], $edge->toLineRecords());
}else if($edge instanceof LineRecord){
$newShape->addRecord($edge);
}else if($edge instanceof MoveRecord){
$newShape->addRecord($edge);
}else{
throw new \Exception("unimplemented");
}
}
return $newShape;
}
public function equals(Shape $other) : bool{
if(count($this->edges) !== count($other->edges) and $this->isFlat === $other->isFlat){
return false;
}
foreach ($this->edges as $i => $record){
if(!$record->equals($other->edges[$i])){
return false;
}
}
return true;
}
}