/******************************************************************/ /* This file is part of the homework assignments for CSCI-427/527 */ /* at The College of William & Mary and authored by Pieter Peers. */ /* No part of this file, whether altered or in original form, can */ /* be distributed or used outside the context of CSCI-427/527 */ /* without consent of either the College of William & Mary or */ /* Pieter Peers. */ /******************************************************************/ #include "transformation3d.h" ////////////////// // Constructors // ////////////////// transformation3d::transformation3d(void) { _translation = vec3d(); _transformation = mat3d(1.0f); _inverseTransformation = mat3d(1.0f); } transformation3d::transformation3d(const vec3d& translation, const mat3d& transformation, const mat3d& inverseTransformation) { _translation = translation; _transformation = transformation; _inverseTransformation = inverseTransformation; } transformation3d::transformation3d(const transformation3d& t) { _translation = t._translation; _transformation = t._transformation; _inverseTransformation = t._inverseTransformation; } ////////////// // Operator // ////////////// transformation3d& transformation3d::operator=(const transformation3d& t) { _assign(t); return *this; } transformation3d transformation3d::operator*(const transformation3d& t) const { return transformation3d( transformPoint(t._translation), _transformation * t._transformation, t._inverseTransformation * _inverseTransformation); } transformation3d& transformation3d::operator*=(const transformation3d& t) { *this = *this * t; return *this; } ////////////// // Mutators // ////////////// transformation3d& transformation3d::invert(void) { _translation = _inverseTransformation * (-_translation); swap(_transformation, _inverseTransformation); return *this; } ///////////// // Methods // ///////////// vec3d transformation3d::transformPoint(const vec3d& p) const { // first transform, then translate vec3d transformed = _transformation * p; transformed += _translation; // Done. return transformed; } vec3d transformation3d::transformDirection(const vec3d& d) const { // Only apply transformation vec3d transformed = _transformation * d; // Done. return transformed.normalize(); } vec3d transformation3d::transformNormal(const vec3d& n) const { // Don't apply translation. // n' = (_transformation^T)^-1 * n // n'^T = n^T * _transformation^-1 // n'^T = n^T * _inverseTransformation vec3d transformed = n * _inverseTransformation; // Done. return transformed.normalize(); } vec3d transformation3d::inverseTransformPoint(const vec3d& p) const { // for undo translation, then invert the transformation vec3d transformed = p - _translation; transformed = _inverseTransformation * transformed; // Done. return transformed; } vec3d transformation3d::inverseTransformDirection(const vec3d& d) const { // Only invert the transformation vec3d transformed = _inverseTransformation * d; // Done. return transformed.normalize(); } vec3d transformation3d::inverseTransformNormal(const vec3d& n) const { // Don't apply translation. Undo (transformation^T)^-1 vec3d transformed = n * _transformation; // Done. return transformed.normalize(); } /////////////////////// // Protected Methods // /////////////////////// void transformation3d::_swap(transformation3d& t) { std::swap(_translation, t._translation); std::swap(_transformation, t._transformation); std::swap(_inverseTransformation, t._inverseTransformation); } void transformation3d::_assign(const transformation3d& t) { // avoid copying when self-assigning if(&t == this) return; // Copy _translation = t._translation; _transformation = t._transformation; _inverseTransformation = t._inverseTransformation; // Done. } void transformation3d::_print(std::ostream& s) const { s << "{"; s << "Translation = " << _translation << ", "; s << "Transformation = " << _transformation << ", "; s << "Inverse Trans. = " << _inverseTransformation; s << "}"; }