<?php
namespace App\Helper;

class Line
{
  protected $origin;
  protected $length;
  protected $direction;

  public function __construct($point_a, $point_b)
  {
    $this->origin = $point_a;
    $this->length = $this->distance($point_a, $point_b);
    $this->direction = $this->gradient($point_a, $point_b);
  }
  public function origin()
  {
    return $this->origin;
  }
  public function length()
  {
    return $this->length;
  }
  public function direction()
  {
    return $this->direction;
  }
  /**
   * Calculate the gradient to move from point a to point b
   * @param  array $point_a [Vector]
   * @param  array $point_b [Vector]
   * @return array          [Vector]
   */
  public function gradient($point_a, $point_b)
  {
    $distance = $this->distance($point_a, $point_b);
    return array_map(function($a, $b) use ($distance) {
      return ($a - $b) / $distance;
    }, $point_b, $point_a);
  }
  // sqrt((a0-b0)²+(a1-b1)²+(a2-b2)²)
  public function distance($point_a, $point_b)
  {
    return sqrt(array_sum(array_map(function($a, $b) {
      return pow($a - $b, 2);
    }, $point_a, $point_b)));
  }
  /**
   * Move from point in the direction of the gradient acording to step_size
   * @param  array $point     [Vector]
   * @param  int $step_size [step size]
   * @return array            [Vector]
   */
  public function move($point, $step_size)
  {
    $gradient = $this->direction;
    return array_map(function($a, $b) use ($step_size) {
      return $a + $b * $step_size;
    }, $point, $gradient);
  }
}
