setArray([ $a, $b, $c, $d, $tx, $ty ]); } /** * Applies translation to the matrix. * * @param float $x Translation along the x axis. * @param float $y Translation along the y axis. * @return ImageAffineMatrix */ public function translate($x, $y) { $this->tx += $x; $this->ty += $y; return $this; } /** * Applies scaling transformation to the matrix. * * @param float $x Coefficient of the x axis. * @param float $y Coefficient of the y axis. * @return ImageAffineMatrix */ public function scale($x, $y) { $this->multiply(new self($x, 0, 0, $y, 0, 0)); return $this; } /** * Applies rotation transformation to the matrix. * * @param float $a Rotation angle in radians. * @return ImageAffineMatrix */ public function rotate($a) { $cosA = cos($a); $sinA = sin($a); $this->multiply(new self($cosA, $sinA, -$sinA, $cosA, 0, 0)); return $this; } /** * Applies skewing transformation to the matrix. * * @param float $x Skew angle along the x axis in radians. * @param float $y Skew angle along the y axis in radians. * @return ImageAffineMatrix */ public function skew($x, $y) { $this->multiply(new self(1, tan($y), tan($x), 1, 0, 0)); return $this; } /** * Causes this matrix to perform an opposite transformation. * * @return ImageAffineMatrix * @throws RuntimeException if the matrix is non-invertible. */ public function invert() { $determinant = $this->getDeterminant(); if($determinant == 0) throw new \RuntimeException('The matrix is non-invertible'); $this->setArray([ $this->d / $determinant, -$this->b / $determinant, -$this->c / $determinant, $this->a / $determinant, ( $this->c * $this->ty) - ($this->d * $this->tx) / $determinant, (-$this->a * $this->ty) + ($this->b * $this->tx) / $determinant ]); return $this; } /** * Multiplies this matrix by another matrix. * * @param ImageAffineMatrix $other The other matrix. * @return ImageAffineMatrix */ public function multiply(self $other) { $this->setArray([ $this->a * $other->getA() + $this->c * $other->getB(), $this->b * $other->getA() + $this->d * $other->getB(), $this->a * $other->getC() + $this->c * $other->getD(), $this->b * $other->getC() + $this->d * $other->getD(), $this->a * $other->getTx() + $this->c * $other->getTy() + $this->tx, $this->b * $other->getTx() + $this->d * $other->getTy() + $this->ty ]); return $this; } /** * Returns a transformed point. * * @param float $x The x coordinate of a point. * @param float $y The y coordinate of a point. * @return array [ x, y ] */ public function transformPoint($x, $y) { return array($this->a * $x + $this->c * $y + $this->tx, $this->b * $x + $this->d * $y + $this->ty); } /** * Returns a transformed image. (Requires PHP >= 5.5.0 and GD 2 library) * * @param resource $image An image resource. * @return resource */ public function transformImage($image) { return imageAffine($image, $this->getArray()); } /** * Returns the determinant of this matrix. * * @return float */ public function getDeterminant() { return ($this->a * $this->d) - ($this->b * $this->c); } /** * Sets the values of the matrix to the ones found in an array. * * @param array $values [ a, b, c, d, tx, ty ] * @return void */ public function setArray($values) { $this->setA($values[0]); $this->setB($values[1]); $this->setC($values[2]); $this->setD($values[3]); $this->setTx($values[4]); $this->setTy($values[5]); } /** * Returns an array of values from this matrix. * * @return array [ a, b, c, d, tx, ty ] */ public function getArray() { return [ $this->a, $this->b, $this->c, $this->d, $this->tx, $this->ty ]; } /** * Returns a string for this matrix that can be used for SVG transform attribute or CSS transform property. * * @return string */ public function getTransform() { return "matrix({$this->a},{$this->b},{$this->c},{$this->d},{$this->tx},{$this->ty})"; } /** * Sets the 'a' component of the matrix. * * @param float $a The new value of 'a'. * @return void */ public function setA($a = 1) { $this->a = (float)$a; } /** * Returns the 'a' component of the matrix. * * @return float */ public function getA() { return $this->a; } /** * Sets the 'b' component of the matrix. * * @param float $b The new value of 'b'. * @return void */ public function setB($b = 0) { $this->b = (float)$b; } /** * Returns the 'b' component of the matrix. * * @return float */ public function getB() { return $this->b; } /** * Sets the 'c' component of the matrix. * * @param float $c The new value of 'c'. * @return void */ public function setC($c = 0) { $this->c = (float)$c; } /** * Returns the 'c' component of the matrix. * * @return float */ public function getC() { return $this->c; } /** * Sets the 'd' component of the matrix. * * @param float $d The new value of 'd'. * @return void */ public function setD($d = 1) { $this->d = (float)$d; } /** * Returns the 'd' component of the matrix. * * @return float */ public function getD() { return $this->d; } /** * Sets the translation along the x axis. * * @param float $x * @return void */ public function setTx($x) { $this->tx = (float)$x; } /** * Returns the translation along the x axis. * * @return float */ public function getTx() { return $this->tx; } /** * Sets the translation along the y axis. * * @param float $y * @return void */ public function setTy($y) { $this->ty = (float)$y; } /** * Returns the translation along the y axis. * * @return float */ public function getTy() { return $this->ty; } }