initial add of libarea files
This commit is contained in:
committed by
Yorik van Havre
parent
f52401715d
commit
797a6f1ddb
624
src/Mod/Path/libarea/kurve/Matrix.cpp
Normal file
624
src/Mod/Path/libarea/kurve/Matrix.cpp
Normal file
@@ -0,0 +1,624 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3d geometry classes - implements some 3d stuff
|
||||
//
|
||||
// g.j.hawkesford August 2003
|
||||
//
|
||||
// This program is released under the BSD license. See the file COPYING for details.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "geometry.h"
|
||||
using namespace geoff_geometry;
|
||||
|
||||
#ifdef PEPSDLL
|
||||
#include "vdm.h"
|
||||
#include "pepsdll.h"
|
||||
#include "realds.h"
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// matrix
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
namespace geoff_geometry {
|
||||
|
||||
Matrix::Matrix(){
|
||||
Unit();
|
||||
}
|
||||
Matrix::Matrix(double m[16]) {
|
||||
memcpy(e, m, sizeof(e));
|
||||
this->IsUnit();
|
||||
this->IsMirrored();
|
||||
}
|
||||
|
||||
Matrix::Matrix( const Matrix& m)
|
||||
{
|
||||
*this = m;
|
||||
}
|
||||
|
||||
bool Matrix::operator==(const Matrix &m)const{
|
||||
// m1 == m2
|
||||
if(this->m_unit != m.m_unit || this->m_mirrored != m.m_mirrored) return false;
|
||||
for(int i = 0; i < 16; i++)
|
||||
if(FEQ(this->e[i], m.e[i], TIGHT_TOLERANCE) == false) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
const Matrix& Matrix::operator=( Matrix &m) {
|
||||
for(int i = 0; i < 16; i++) e[i] = m.e[i];
|
||||
m_unit = m.m_unit;
|
||||
m_mirrored = m.m_mirrored;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
void Matrix::Unit()
|
||||
{
|
||||
// homogenous matrix - set as unit matrix
|
||||
memset(e, 0, sizeof(e));
|
||||
e[0] = e[5] = e[10] = e[15] = 1;
|
||||
m_unit = true;
|
||||
m_mirrored = false;
|
||||
}
|
||||
|
||||
void Matrix::Get(double* p) const
|
||||
{
|
||||
// copy the matrix
|
||||
memcpy(p, e, sizeof(e));
|
||||
}
|
||||
void Matrix::Put(double* p)
|
||||
{
|
||||
// assign the matrix
|
||||
memcpy(e, p, sizeof(e));
|
||||
m_unit = false; // don't know
|
||||
m_mirrored = -1; // don't know
|
||||
|
||||
}
|
||||
void Matrix::Translate(double x, double y, double z)
|
||||
{
|
||||
// translation
|
||||
e[3] += x;
|
||||
e[7] += y;
|
||||
e[11] += z;
|
||||
m_unit = false;
|
||||
}
|
||||
|
||||
void Matrix::Rotate(double angle, Vector3d *rotAxis) {
|
||||
/// Rotation about rotAxis with angle
|
||||
Rotate(sin(angle), cos(angle), rotAxis);
|
||||
}
|
||||
|
||||
void Matrix::Rotate(double sinang, double cosang, Vector3d *rotAxis) {
|
||||
/// Rotation about rotAxis with cp & dp
|
||||
Matrix rotate;
|
||||
double oneminusc = 1.0 - cosang;
|
||||
|
||||
rotate.e[0] = rotAxis->getx() * rotAxis->getx() * oneminusc + cosang;
|
||||
rotate.e[1] = rotAxis->getx() * rotAxis->gety() * oneminusc - rotAxis->getz() * sinang;
|
||||
rotate.e[2] = rotAxis->getx() * rotAxis->getz() * oneminusc + rotAxis->gety() * sinang;
|
||||
|
||||
rotate.e[4] = rotAxis->getx() * rotAxis->gety() * oneminusc + rotAxis->getz() * sinang;
|
||||
rotate.e[5] = rotAxis->gety() * rotAxis->gety() * oneminusc + cosang;
|
||||
rotate.e[6] = rotAxis->gety() * rotAxis->getz() * oneminusc - rotAxis->getx() * sinang;
|
||||
|
||||
rotate.e[8] = rotAxis->getx() * rotAxis->getz() * oneminusc - rotAxis->gety() * sinang;
|
||||
rotate.e[9] = rotAxis->gety() * rotAxis->getz() * oneminusc + rotAxis->getx() * sinang;
|
||||
rotate.e[10] = rotAxis->getz() * rotAxis->getz() * oneminusc + cosang;
|
||||
Multiply(rotate); // concatinate rotation with this matrix
|
||||
m_unit = false;
|
||||
m_mirrored = -1; // don't know
|
||||
}
|
||||
|
||||
|
||||
void Matrix::Rotate(double angle, int Axis)
|
||||
{ // Rotation (Axis 1 = x , 2 = y , 3 = z
|
||||
Rotate(sin(angle), cos(angle), Axis);
|
||||
}
|
||||
|
||||
void Matrix::Rotate(double sinang, double cosang, int Axis)
|
||||
{ // Rotation (Axis 1 = x , 2 = y , 3 = z
|
||||
Matrix rotate;
|
||||
rotate.Unit();
|
||||
|
||||
switch(Axis)
|
||||
{
|
||||
case 1:
|
||||
// about x axis
|
||||
rotate.e[5] = rotate.e[10] = cosang;
|
||||
rotate.e[6] = -sinang;
|
||||
rotate.e[9] = sinang;
|
||||
break;
|
||||
case 2:
|
||||
// about y axis
|
||||
rotate.e[0] = rotate.e[10] = cosang;
|
||||
rotate.e[2] = sinang;
|
||||
rotate.e[8] = -sinang;
|
||||
break;
|
||||
case 3:
|
||||
// about z axis
|
||||
rotate.e[0] = rotate.e[5] = cosang;
|
||||
rotate.e[1] = -sinang;
|
||||
rotate.e[4] = sinang;
|
||||
break;
|
||||
}
|
||||
Multiply(rotate); // concatinate rotation with this matrix
|
||||
m_unit = false;
|
||||
m_mirrored = -1; // don't know
|
||||
}
|
||||
|
||||
void Matrix::Scale(double scale)
|
||||
{
|
||||
// add a scale
|
||||
Scale(scale, scale, scale);
|
||||
}
|
||||
|
||||
void Matrix::Scale(double scalex, double scaley, double scalez)
|
||||
{
|
||||
// add a scale
|
||||
Matrix temp;
|
||||
temp.Unit();
|
||||
|
||||
temp.e[0] = scalex;
|
||||
temp.e[5] = scaley;
|
||||
temp.e[10] = scalez;
|
||||
Multiply(temp);
|
||||
m_unit = false;
|
||||
m_mirrored = -1; // don't know
|
||||
}
|
||||
void Matrix::Multiply(Matrix& m)
|
||||
{
|
||||
// multiply this by give matrix - concatinate
|
||||
int i, k, l;
|
||||
Matrix ret;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
l = i - (k = (i % 4));
|
||||
ret.e[i] = m.e[l] * e[k] + m.e[l+1] * e[k+4] + m.e[l+2] * e[k+8] + m.e[l+3] * e[k+12];
|
||||
}
|
||||
|
||||
*this = ret;
|
||||
this->IsUnit();
|
||||
}
|
||||
|
||||
void Matrix::Transform(double p0[3], double p1[3]) const
|
||||
{
|
||||
// transform p0 thro' this matrix
|
||||
if(m_unit)
|
||||
memcpy(p1, p0, 3 * sizeof(double));
|
||||
else {
|
||||
p1[0] = p0[0] * e[0] + p0[1] * e[1] + p0[2] * e[2] + e[3];
|
||||
p1[1] = p0[0] * e[4] + p0[1] * e[5] + p0[2] * e[6] + e[7];
|
||||
p1[2] = p0[0] * e[8] + p0[1] * e[9] + p0[2] * e[10] + e[11];
|
||||
}
|
||||
}
|
||||
void Matrix::Transform2d(double p0[2], double p1[2]) const
|
||||
{
|
||||
// transform p0 thro' this matrix (2d only)
|
||||
if(m_unit)
|
||||
memcpy(p1, p0, 2 * sizeof(double));
|
||||
else {
|
||||
p1[0] = p0[0] * e[0] + p0[1] * e[1] + e[3];
|
||||
p1[1] = p0[0] * e[4] + p0[1] * e[5] + e[7];
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix::Transform(double p0[3]) const
|
||||
{
|
||||
double p1[3];
|
||||
if(!m_unit) {
|
||||
Transform(p0, p1);
|
||||
memcpy(p0, p1, 3 * sizeof(double));
|
||||
}
|
||||
}
|
||||
|
||||
int Matrix::IsMirrored()
|
||||
{
|
||||
// returns true if matrix has a mirror
|
||||
if(m_unit)
|
||||
m_mirrored = false;
|
||||
else if(m_mirrored == -1) {
|
||||
|
||||
m_mirrored = ((e[0] * (e[5] * e[10] - e[6] * e[9])
|
||||
- e[1] * (e[4] * e[10] - e[6] * e[8])
|
||||
+ e[2] * (e[4] * e[9] - e[5] * e[8])) < 0);
|
||||
}
|
||||
return m_mirrored;
|
||||
}
|
||||
int Matrix::IsUnit() {
|
||||
// returns true if unit matrix
|
||||
for(int i = 0; i < 16; i++) {
|
||||
if(i == 0 || i == 5 || i == 10 || i == 15) {
|
||||
if(e[i] != 1) return m_unit = false;
|
||||
}
|
||||
else {
|
||||
if(e[i] != 0) return m_unit = false;
|
||||
}
|
||||
}
|
||||
m_mirrored = false;
|
||||
return m_unit = true;
|
||||
}
|
||||
|
||||
void Matrix::GetTranslate(double& x, double& y, double& z) const
|
||||
{
|
||||
// return translation
|
||||
x = e[3];
|
||||
y = e[7];
|
||||
z = e[11];
|
||||
}
|
||||
void Matrix::GetScale(double& sx, double& sy, double& sz) const
|
||||
{
|
||||
// return the scale
|
||||
if(m_unit) {
|
||||
sx = sy = sz = 1;
|
||||
}
|
||||
else {
|
||||
sx = sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
||||
sy = sqrt(e[4] * e[4] + e[5] * e[5] + e[6] * e[6]);
|
||||
sz = sqrt(e[8] * e[8] + e[9] * e[9] + e[10] * e[10]);
|
||||
}
|
||||
}
|
||||
bool Matrix::GetScale(double& sx) const
|
||||
{
|
||||
// return a uniform scale (false if differential)
|
||||
double sy, sz;
|
||||
if(m_unit) {
|
||||
sx = 1;
|
||||
return true;
|
||||
}
|
||||
GetScale(sx, sy, sz);
|
||||
return (fabs(fabs(sx) - fabs(sy)) < 0.000001)?true : false;
|
||||
}
|
||||
void Matrix::GetRotation(double& ax, double& ay, double& az) const
|
||||
{
|
||||
// return the rotations
|
||||
if(m_unit) {
|
||||
ax = ay = az = 0;
|
||||
return;
|
||||
}
|
||||
double a; /* cos(bx) */
|
||||
double b; /* sin(bx) */
|
||||
double c; /* cos(by) */
|
||||
double d; /* sin(by) */
|
||||
double ee; /* cos(bz) */
|
||||
double f; /* sin(bz) */
|
||||
double sx, sy, sz;
|
||||
GetScale(sx, sy, sz);
|
||||
if(this->m_mirrored == -1) FAILURE(L"Don't know mirror - use IsMirrored method on object");
|
||||
if(this->m_mirrored) sx = -sx;
|
||||
|
||||
// solve for d and decide case and solve for a, b, c, e and f
|
||||
d = - e[8] / sz;
|
||||
if((c = (1 - d) * (1 + d)) > 0.001)
|
||||
{
|
||||
// case 1
|
||||
c = sqrt( c );
|
||||
a = e[10] / sz / c;
|
||||
b = e[9] / sz / c;
|
||||
ee = e[0] / sx / c;
|
||||
f = e[4] / sy / c;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 2
|
||||
double coef;
|
||||
double p, q;
|
||||
|
||||
d = ( d < 0 ) ? -1 : 1 ;
|
||||
c = 0 ;
|
||||
p = d * e[5] / sy - e[2] / sx;
|
||||
q = d * e[6] / sy + e[1] / sx;
|
||||
if((coef = sqrt( p * p + q * q )) > 0.001) {
|
||||
a = q / coef;
|
||||
b = p / coef;
|
||||
ee = b;
|
||||
f = -d * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* dependent pairs */
|
||||
a = e[5] / sy;
|
||||
b = -e[6] / sy;
|
||||
ee = 1 ;
|
||||
f = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
// solve and return ax, ay and az
|
||||
ax = atan2( b, a );
|
||||
ay = atan2( d, c );
|
||||
az = atan2( f, ee );
|
||||
}
|
||||
|
||||
Matrix Matrix::Inverse()
|
||||
{
|
||||
// matrix inversion routine
|
||||
|
||||
// a is input matrix destroyed & replaced by inverse
|
||||
// method used is gauss-jordan (ref ibm applications)
|
||||
|
||||
double hold , biga ;
|
||||
int i , j , k , nk , kk , ij , iz ;
|
||||
int ki , ji , jp , jk , kj , jq , jr , ik;
|
||||
|
||||
int n = 4; // 4 x 4 matrix only
|
||||
Matrix a = *this;
|
||||
int l[4], m[4];
|
||||
|
||||
if(a.m_unit) return a; // unit matrix
|
||||
|
||||
// search for largest element
|
||||
nk = - n ;
|
||||
for ( k = 0 ; k < n ; k++ ) {
|
||||
nk += n ;
|
||||
l [ k ] = m [ k ] = k ;
|
||||
kk = nk + k ;
|
||||
biga = a.e[ kk ] ;
|
||||
|
||||
for ( j = k ; j < n ; j++ ) {
|
||||
iz = n * j ;
|
||||
for ( i = k ; i < n ; i++ ) {
|
||||
ij = iz + i ;
|
||||
if ( fabs ( biga ) < fabs ( a.e[ ij ] ) ) {
|
||||
biga = a.e[ ij ] ;
|
||||
l[ k ] = i ;
|
||||
m[ k ] = j ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// interchange rows
|
||||
j = l[ k ] ;
|
||||
if ( j > k ) {
|
||||
ki = k - n ;
|
||||
|
||||
for ( i = 0 ; i < n ; i++ ) {
|
||||
ki += n ;
|
||||
hold = - a.e[ ki ] ;
|
||||
ji = ki - k + j ;
|
||||
a.e[ ki ] = a.e[ ji ] ;
|
||||
a.e[ ji ] = hold ;
|
||||
}
|
||||
}
|
||||
|
||||
// interchange columns
|
||||
i = m[ k ] ;
|
||||
if ( i > k ) {
|
||||
jp = n * i ;
|
||||
for ( j = 0 ; j < n ; j++ ) {
|
||||
jk = nk + j ;
|
||||
ji = jp + j ;
|
||||
hold = - a.e[ jk ] ;
|
||||
a.e[ jk ] = a.e[ ji ] ;
|
||||
a.e[ ji ] = hold ;
|
||||
}
|
||||
}
|
||||
|
||||
// divide columns by minus pivot (value of pivot element is contained in biga)
|
||||
if ( fabs ( biga ) < 1.0e-10 )FAILURE(getMessage(L"Singular Matrix - Inversion failure",GEOMETRY_ERROR_MESSAGES, -1)); // singular matrix
|
||||
|
||||
for ( i = 0 ; i < n ; i++ ) {
|
||||
if ( i != k ) {
|
||||
ik = nk + i ;
|
||||
a.e[ ik ] = - a.e[ ik ] /biga ;
|
||||
}
|
||||
}
|
||||
|
||||
// reduce matrix
|
||||
for ( i = 0 ; i < n ; i++ ) {
|
||||
ik = nk + i ;
|
||||
hold = a.e[ ik ] ;
|
||||
ij = i - n ;
|
||||
|
||||
for ( j = 0 ; j < n ; j++ ) {
|
||||
ij = ij + n ;
|
||||
if ( i != k && j != k ) {
|
||||
kj = ij - i + k ;
|
||||
a.e[ ij ] = hold * a.e[ kj ] + a.e[ ij ] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// divide row by pivot
|
||||
kj = k - n ;
|
||||
for ( j = 0 ; j < n ; j++ ) {
|
||||
kj = kj + n ;
|
||||
if ( j != k ) a.e[ kj] = a.e[ kj ] /biga ;
|
||||
}
|
||||
|
||||
// replace pivot by reciprocal
|
||||
a.e[ kk ] = 1 / biga ;
|
||||
}
|
||||
|
||||
// final row and column interchange
|
||||
k = n - 1 ;
|
||||
|
||||
while ( k > 0 ) {
|
||||
i = l[ --k ] ;
|
||||
if ( i > k ) {
|
||||
jq = n * k ;
|
||||
jr = n * i ;
|
||||
|
||||
for ( j = 0 ; j < n ; j++ ) {
|
||||
jk = jq + j ;
|
||||
hold = a.e[jk] ;
|
||||
ji = jr + j ;
|
||||
a.e[jk] = - a.e[ji] ;
|
||||
a.e[ji] = hold ;
|
||||
}
|
||||
}
|
||||
|
||||
j = m[ k ] ;
|
||||
if ( j > k ) {
|
||||
ki = k - n ;
|
||||
|
||||
for ( i = 1 ; i <= n ; i ++ ) {
|
||||
ki = ki + n ;
|
||||
hold = a.e[ ki ] ;
|
||||
ji = ki - k + j ;
|
||||
a.e[ ki ] = - a.e[ ji ] ;
|
||||
a.e[ ji ] = hold ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
#ifdef PEPSDLL
|
||||
void Matrix::ToPeps(int id)
|
||||
{
|
||||
int set = PepsVdmMake(id, VDM_MATRIX_TYPE , VDM_LOCAL);
|
||||
if(set < 0) FAILURE(L"Failed to create Matrix VDM");
|
||||
struct kgm_header pepsm;
|
||||
|
||||
Get(pepsm.matrix);
|
||||
pepsm.off_rad = 0;
|
||||
pepsm.off_dir = pepsm.origin_id = 0;
|
||||
|
||||
PepsVdmWriteTmx(set , &pepsm );
|
||||
|
||||
PepsVdmClose(set);
|
||||
|
||||
}
|
||||
|
||||
void Matrix::FromPeps(int id)
|
||||
{
|
||||
// if(id) {
|
||||
int set = PepsVdmOpen(id, VDM_MATRIX_TYPE , VDM_READ_ONLY | VDM_LOCAL);
|
||||
if(set < 0) FAILURE(L"Failed to open Matrix VDM");
|
||||
|
||||
struct kgm_header pepsm;
|
||||
PepsVdmReadTmx(set , &pepsm);
|
||||
memcpy(e, pepsm.matrix, sizeof(pepsm.matrix));
|
||||
m_unit = true;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
// copy over matrix and check for unit matrix
|
||||
if(i == 0 || i == 5 || i == 10 || i == 15) {
|
||||
if((e[i] = pepsm.matrix[i]) != 1) m_unit = false;
|
||||
}
|
||||
else {
|
||||
if((e[i] = pepsm.matrix[i]) != 0) m_unit = false;
|
||||
}
|
||||
}
|
||||
PepsVdmClose(set);
|
||||
m_mirrored = IsMirrored();
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
Matrix UnitMatrix; // a global unit matrix
|
||||
|
||||
|
||||
// vector
|
||||
Vector2d::Vector2d(const Vector3d &v){
|
||||
if(FEQZ(v.getz())) FAILURE(L"Converting Vector3d to Vector2d illegal");
|
||||
dx = v.getx();
|
||||
dy = v.gety();
|
||||
}
|
||||
|
||||
bool Vector2d::operator==(const Vector2d &v)const {
|
||||
return FEQ(dx, v.getx(), 1.0e-06) && FEQ(dy, v.gety(), 1.0e-06);
|
||||
}
|
||||
|
||||
void Vector2d::Transform(const Matrix& m) {
|
||||
// transform vector
|
||||
if(m.m_unit == false) {
|
||||
double dxt = dx * m.e[0] + dy * m.e[1];
|
||||
double dyt = dx * m.e[4] + dy * m.e[5];
|
||||
dx = dxt;
|
||||
dy = dyt;
|
||||
}
|
||||
this->normalise();
|
||||
}
|
||||
|
||||
void Vector3d::Transform(const Matrix& m) {
|
||||
// transform vector
|
||||
if(m.m_unit == false) {
|
||||
double dxt = dx * m.e[0] + dy * m.e[1] + dz * m.e[2];
|
||||
double dyt = dx * m.e[4] + dy * m.e[5] + dz * m.e[6];
|
||||
double dzt = dx * m.e[8] + dy * m.e[9] + dz * m.e[10];
|
||||
dx = dxt;
|
||||
dy = dyt;
|
||||
dz = dzt;
|
||||
}
|
||||
this->normalise();
|
||||
}
|
||||
|
||||
void Vector3d::arbitrary_axes(Vector3d& x, Vector3d& y){
|
||||
// arbitrary axis algorithm - acad method of generating an arbitrary but
|
||||
// consistant set of axes from a single normal ( z )
|
||||
// arbitrary x & y axes
|
||||
|
||||
if ( ( fabs ( this->getx() ) < 1.0/64.0 ) && (fabs(this->gety()) < 1.0/64.0))
|
||||
x = Y_VECTOR ^ *this;
|
||||
else
|
||||
x = Z_VECTOR ^ *this;
|
||||
|
||||
y = *this ^ x;
|
||||
}
|
||||
|
||||
int Vector3d::setCartesianAxes(Vector3d& b, Vector3d& c) {
|
||||
#define a *this
|
||||
// computes a RH triad of Axes (Cartesian) starting from a (normalised)
|
||||
// if a & b are perpendicular then c = a ^ b
|
||||
// if a & c are perpendicular then b = c ^ a
|
||||
// if neither are perpendicular to a, then return arbitrary axes from a
|
||||
|
||||
// calling sequence for RH cartesian
|
||||
// x y z
|
||||
// y z x
|
||||
// z x y
|
||||
if(a == NULL_VECTOR) FAILURE(L"SetAxes given a NULL Vector");
|
||||
double epsilon = 1.0e-09;
|
||||
bool bNull = (b == NULL_VECTOR);
|
||||
bool cNull = (c == NULL_VECTOR);
|
||||
bool abPerp = !bNull;
|
||||
if(abPerp) abPerp = (fabs(a * b) < epsilon);
|
||||
|
||||
bool acPerp = !cNull;
|
||||
if(acPerp) acPerp = (fabs(a * c) < epsilon);
|
||||
|
||||
if(abPerp) {
|
||||
c = a ^ b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(acPerp) {
|
||||
b = c ^ a;
|
||||
return 1;
|
||||
}
|
||||
|
||||
arbitrary_axes(b, c);
|
||||
b.normalise();
|
||||
c.normalise();
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
void Plane::Mirrored(Matrix* tmMirrored) {
|
||||
// calculates a mirror transformation that mirrors 2d about plane
|
||||
|
||||
Point3d p1 = this->Near(Point3d(0.,0.,0.));
|
||||
if(tmMirrored->m_unit == false) tmMirrored->Unit();
|
||||
|
||||
double nx = this->normal.getx();
|
||||
double ny = this->normal.gety();
|
||||
double nz = this->normal.getz();
|
||||
|
||||
// the translation
|
||||
tmMirrored->e[ 3] = -2. * nx * this->d;
|
||||
tmMirrored->e[ 7] = -2. * ny * this->d;
|
||||
tmMirrored->e[11] = -2. * nz * this->d;
|
||||
|
||||
// the rest
|
||||
tmMirrored->e[ 0] = 1. - 2. * nx * nx;
|
||||
tmMirrored->e[ 5] = 1. - 2. * ny * ny;
|
||||
tmMirrored->e[10] = 1. - 2. * nz * nz;
|
||||
tmMirrored->e[ 1] = tmMirrored->e[ 4] = -2. * nx * ny;
|
||||
tmMirrored->e[ 2] = tmMirrored->e[ 8] = -2. * nz * nx;
|
||||
tmMirrored->e[ 6] = tmMirrored->e[ 9] = -2. * ny * nz;
|
||||
|
||||
tmMirrored->m_unit = false;
|
||||
tmMirrored->m_mirrored = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user