/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* This file is part of the libmspub project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
//TODO : Adjust handles, glue points
#include "VectorTransformation2D.h"
#include <math.h>
namespace libmspub
{
VectorTransformation2D::VectorTransformation2D() : m_m11(1), m_m12(0), m_m21(0), m_m22(1), m_x(0), m_y(0)
{
}
//We choose by convention to make function composition LEFT-multiplication, rather than right.
VectorTransformation2D operator*(const VectorTransformation2D &l, const VectorTransformation2D &r)
{
VectorTransformation2D ret;
ret.m_m11 = l.m_m11 * r.m_m11 + l.m_m12 * r.m_m21;
ret.m_m12 = l.m_m11 * r.m_m12 + l.m_m12 * r.m_m22;
ret.m_m21 = l.m_m21 * r.m_m11 + l.m_m22 * r.m_m21;
ret.m_m22 = l.m_m21 * r.m_m12 + l.m_m22 * r.m_m22;
ret.m_x = l.m_m11 * r.m_x + l.m_m12 * r.m_y + l.m_x;
ret.m_y = l.m_m21 * r.m_x + l.m_m22 * r.m_y + l.m_y;
return ret;
}
VectorTransformation2D VectorTransformation2D::fromFlips(bool flipH, bool flipV)
{
VectorTransformation2D ret;
ret.m_m21 = ret.m_m12 = 0;
ret.m_m11 = flipH ? -1 : 1;
ret.m_m22 = flipV ? -1 : 1;
return ret;
}
VectorTransformation2D VectorTransformation2D::fromTranslate(double x, double y)
{
VectorTransformation2D ret;
ret.m_m11 = ret.m_m22 = 1;
ret.m_m21 = ret.m_m12 = 0;
ret.m_x = x;
ret.m_y = y;
return ret;
}
VectorTransformation2D VectorTransformation2D::fromCounterRadians(double theta)
{
VectorTransformation2D ret;
ret.m_m11 = cos(theta);
ret.m_m12 = -sin(theta);
ret.m_m21 = sin(theta);
ret.m_m22 = cos(theta);
return ret;
}
Vector2D VectorTransformation2D::transform(Vector2D v) const
{
double x = m_m11 * v.m_x + m_m12 * v.m_y + m_x;
double y = m_m21 * v.m_x + m_m22 * v.m_y + m_y;
return Vector2D(x, y);
}
Vector2D VectorTransformation2D::transformWithOrigin(Vector2D v, Vector2D origin) const
{
return transform(v - origin) + origin;
}
Vector2D operator+(const Vector2D &l, const Vector2D &r)
{
double x = l.m_x + r.m_x;
double y = l.m_y + r.m_y;
return Vector2D(x, y);
}
Vector2D operator-(const Vector2D &l, const Vector2D &r)
{
double x = l.m_x - r.m_x;
double y = l.m_y - r.m_y;
return Vector2D(x, y);
}
double VectorTransformation2D::getRotation() const
{
if (fabs(getHorizontalScaling()) > 0.0001)
{
return atan2(m_m21, m_m11);
}
if (fabs(getVerticalScaling()) > 0.0001)
{
return atan2(-m_m12, m_m22);
}
return 0;
}
double VectorTransformation2D::getHorizontalScaling() const
{
return m_m11 * m_m11 + m_m21 * m_m21;
}
double VectorTransformation2D::getVerticalScaling() const
{
return m_m12 * m_m12 + m_m22 * m_m22;
}
bool VectorTransformation2D::orientationReversing() const
{
// Is the determinant negative?
return m_m11 * m_m22 < m_m12 * m_m21;
}
}
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */