howardjones/network-weathermap

View on GitHub
lib/Weathermap/Core/CurvedLinkGeometry.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php
namespace Weathermap\Core;

/**
 * All the parts of LinkGeometry that are specific to curved links
 *
 * @package Weathermap\Core
 */
class CurvedLinkGeometry extends LinkGeometry
{
    protected function calculateSpine($pointsPerSpan = 32)
    {
        // duplicate the first and last points, so that all points are drawn
        // (C-R normally would draw from x[1] to x[n-1]
        array_unshift($this->controlPoints, $this->controlPoints[0]);
        array_push($this->controlPoints, $this->controlPoints[count($this->controlPoints) - 1]);

        $nPoints = count($this->controlPoints);

        // Add the very first point manually. The CRSpan function counts from 1 to avoid
        // duplication of points later in the curve
        $this->curvePoints->addPoint($this->controlPoints[0]);

        // Loop through (nearly) all the points. C-R consumes 3 points after the one we specify, so
        // don't go all the way to the end of the list. Note that for a straight line, that means we
        // do this once only. (two original points, plus our two duplicates).
        for ($i = 0; $i < ($nPoints - 3); $i++) {
            $this->calculateCRSpan($i, $pointsPerSpan);
        }
    }

    private function calculateCRSpan($startIndex, $pointsPerSpan = 32)
    {
        $xGenerator = new CatmullRom1D($this->controlPoints[$startIndex]->x, $this->controlPoints[$startIndex + 1]->x, $this->controlPoints[$startIndex + 2]->x, $this->controlPoints[$startIndex + 3]->x);
        $yGenerator = new CatmullRom1D($this->controlPoints[$startIndex]->y, $this->controlPoints[$startIndex + 1]->y, $this->controlPoints[$startIndex + 2]->y, $this->controlPoints[$startIndex + 3]->y);

        for ($i = 1; $i <= $pointsPerSpan; $i++) {
            $t = $i / $pointsPerSpan;

            $x = $xGenerator->calculate($t);
            $y = $yGenerator->calculate($t);

            $this->curvePoints->addPoint(new Point($x, $y));
        }
    }

    protected function generateOutlines()
    {
        MapUtility::debug("Calculating curved-style outline\n");

        foreach ($this->directions as $direction) {
            $there = array();
            $back = array();
            $width = $this->linkWidths[$direction];

            for ($i = 0; $i <= $this->arrowIndexes[$direction]; $i++) {
                $here = $this->splitCurves[$direction]->getPoint($i);
                $tangent = $here->vectorToPoint($this->splitCurves[$direction]->getPoint($i + 1));
                $normal = $tangent->getNormal();

                $there[] = $here->copy()->addVector($normal, $width);
                array_unshift($back, $here->copy()->addVector($normal, -$width));
            }

            $arrow = $this->generateArrowhead($this->arrowPoints[$direction], $this->midPoint, $this->linkWidths[$direction], $this->arrowWidths[$direction]);
            $outline = array_merge($there, $arrow, $back);

            $this->drawnCurves[$direction] = $outline;
        }
    }
}