Branch data Line data Source code
1 : : /*************************************************************************** 2 : : Bezier3D.cpp 3 : : ------------ 4 : : copyright : (C) 2004 by Marco Hugentobler 5 : : email : mhugent@geo.unizh.ch 6 : : ***************************************************************************/ 7 : : 8 : : /*************************************************************************** 9 : : * * 10 : : * This program is free software; you can redistribute it and/or modify * 11 : : * it under the terms of the GNU General Public License as published by * 12 : : * the Free Software Foundation; either version 2 of the License, or * 13 : : * (at your option) any later version. * 14 : : * * 15 : : ***************************************************************************/ 16 : : 17 : : #include "Bezier3D.h" 18 : : #include "qgslogger.h" 19 : : #include "Vector3D.h" 20 : : #include "MathUtils.h" 21 : : 22 : 0 : void Bezier3D::calcFirstDer( float t, Vector3D *v ) 23 : : { 24 : 0 : if ( v && mControlPoly ) 25 : : { 26 : 0 : v->setX( 0 ); 27 : 0 : v->setY( 0 ); 28 : 0 : v->setZ( 0 ); 29 : : 30 : 0 : if ( mControlPoly->count() < 2 ) 31 : : { 32 : 0 : return; 33 : : } 34 : : 35 : 0 : for ( int n = 1; n <= int( mControlPoly->count() - 1 ); n++ ) 36 : : { 37 : 0 : double bernst = MathUtils::calcBernsteinPoly( mControlPoly->count() - 2, n - 1, t ); 38 : 0 : v->setX( v->getX() + ( ( *mControlPoly )[n]->x() - ( *mControlPoly )[n - 1]->x() )*bernst ); 39 : 0 : v->setY( v->getY() + ( ( *mControlPoly )[n]->y() - ( *mControlPoly )[n - 1]->y() )*bernst ); 40 : 0 : v->setZ( v->getZ() + ( ( *mControlPoly )[n]->z() - ( *mControlPoly )[n - 1]->z() )*bernst ); 41 : 0 : } 42 : 0 : v->setX( v->getX() * ( mControlPoly->count() - 1 ) ); 43 : 0 : v->setY( v->getY() * ( mControlPoly->count() - 1 ) ); 44 : 0 : v->setZ( v->getZ() * ( mControlPoly->count() - 1 ) ); 45 : 0 : } 46 : : 47 : : else 48 : : { 49 : 0 : QgsDebugMsg( QStringLiteral( "warning: null pointer" ) ); 50 : : } 51 : 0 : } 52 : : 53 : 0 : void Bezier3D::calcPoint( float t, QgsPoint *p ) 54 : : { 55 : : 56 : 0 : if ( p && mControlPoly ) 57 : : { 58 : 0 : p->setX( 0 ); 59 : 0 : p->setY( 0 ); 60 : 0 : p->setZ( 0 ); 61 : : 62 : 0 : for ( int n = 1; n <= int( mControlPoly->count() ); n++ ) 63 : : { 64 : 0 : double bernst = MathUtils::calcBernsteinPoly( mControlPoly->count() - 1, n - 1, t ); 65 : 0 : p->setX( p->x() + ( *mControlPoly )[n - 1]->x()*bernst ); 66 : 0 : p->setY( p->y() + ( *mControlPoly )[n - 1]->y()*bernst ); 67 : 0 : p->setZ( p->z() + ( *mControlPoly )[n - 1]->z()*bernst ); 68 : 0 : } 69 : 0 : } 70 : : 71 : : else 72 : : { 73 : 0 : QgsDebugMsg( QStringLiteral( "warning: null pointer" ) ); 74 : : } 75 : 0 : } 76 : : 77 : 0 : void Bezier3D::calcSecDer( float t, Vector3D *v ) 78 : : { 79 : 0 : if ( v && mControlPoly ) 80 : : { 81 : 0 : v->setX( 0 ); 82 : 0 : v->setY( 0 ); 83 : 0 : v->setZ( 0 ); 84 : : 85 : 0 : int nodes = mControlPoly->count(); 86 : 0 : if ( nodes < 3 ) 87 : : { 88 : 0 : return; 89 : : } 90 : : 91 : 0 : for ( int n = 1; n <= int( nodes - 2 ); n++ ) 92 : : { 93 : 0 : double bernst = MathUtils::calcBernsteinPoly( nodes - 3, n - 1, t ); 94 : 0 : v->setX( v->getX() + ( ( *mControlPoly )[n + 1]->x() - 2 * ( *mControlPoly )[n]->x() + ( *mControlPoly )[n - 1]->x() )*bernst ); 95 : 0 : v->setY( v->getY() + ( ( *mControlPoly )[n + 1]->y() - 2 * ( *mControlPoly )[n]->y() + ( *mControlPoly )[n - 1]->y() )*bernst ); 96 : 0 : v->setZ( v->getZ() + ( ( *mControlPoly )[n + 1]->z() - 2 * ( *mControlPoly )[n]->z() + ( *mControlPoly )[n - 1]->z() )*bernst ); 97 : 0 : } 98 : 0 : v->setX( v->getX()*MathUtils::faculty( nodes - 1 ) / MathUtils::faculty( nodes - 3 ) ); 99 : 0 : v->setY( v->getY()*MathUtils::faculty( nodes - 1 ) / MathUtils::faculty( nodes - 3 ) ); 100 : 0 : v->setZ( v->getZ()*MathUtils::faculty( nodes - 1 ) / MathUtils::faculty( nodes - 3 ) ); 101 : 0 : } 102 : : 103 : : else 104 : : { 105 : 0 : QgsDebugMsg( QStringLiteral( "warning: null pointer" ) ); 106 : : } 107 : 0 : } 108 : : 109 : : 110 : 0 : void Bezier3D::changeDirection()//does this work correctly? more testing is needed. 111 : : { 112 : 0 : if ( mControlPoly ) 113 : : { 114 : 0 : QgsPoint **pointer = new QgsPoint*[mControlPoly->count()];//create an array to temporarily store pointer to the control points 115 : 0 : for ( int i = 0; i < mControlPoly->count(); i++ )//store the points 116 : : { 117 : 0 : pointer[i] = ( *mControlPoly )[i]; 118 : 0 : } 119 : : 120 : 0 : for ( int i = 0; i < mControlPoly->count(); i++ ) 121 : : { 122 : 0 : mControlPoly->insert( i, pointer[( mControlPoly->count() - 1 ) - i] ); 123 : 0 : } 124 : 0 : delete [] pointer; 125 : 0 : } 126 : : 127 : : else 128 : : { 129 : 0 : QgsDebugMsg( QStringLiteral( "warning: null pointer" ) ); 130 : : } 131 : 0 : } 132 : : 133 : : 134 : : 135 : : 136 : : 137 : : 138 : : 139 : : 140 : : 141 : : 142 : : 143 : : 144 : : 145 : : 146 : : 147 : : 148 : : 149 : : 150 : : 151 : : 152 : : 153 : : 154 : : 155 : : 156 : : 157 : : 158 : : 159 : : 160 : : 161 : : 162 : : 163 : :