You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							240 lines
						
					
					
						
							7.1 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							240 lines
						
					
					
						
							7.1 KiB
						
					
					
				
								// This file is part of Eigen, a lightweight C++ template library
							 | 
						|
								// for linear algebra.
							 | 
						|
								//
							 | 
						|
								// Copyright (C) 2010-2011 Hauke Heibel <heibel@gmail.com>
							 | 
						|
								//
							 | 
						|
								// 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/.
							 | 
						|
								
							 | 
						|
								#include "main.h"
							 | 
						|
								
							 | 
						|
								#include <unsupported/Eigen/Splines>
							 | 
						|
								
							 | 
						|
								// lets do some explicit instantiations and thus
							 | 
						|
								// force the compilation of all spline functions...
							 | 
						|
								template class Spline<double, 2, Dynamic>;
							 | 
						|
								template class Spline<double, 3, Dynamic>;
							 | 
						|
								
							 | 
						|
								template class Spline<double, 2, 2>;
							 | 
						|
								template class Spline<double, 2, 3>;
							 | 
						|
								template class Spline<double, 2, 4>;
							 | 
						|
								template class Spline<double, 2, 5>;
							 | 
						|
								
							 | 
						|
								template class Spline<float, 2, Dynamic>;
							 | 
						|
								template class Spline<float, 3, Dynamic>;
							 | 
						|
								
							 | 
						|
								template class Spline<float, 3, 2>;
							 | 
						|
								template class Spline<float, 3, 3>;
							 | 
						|
								template class Spline<float, 3, 4>;
							 | 
						|
								template class Spline<float, 3, 5>;
							 | 
						|
								
							 | 
						|
								Spline<double, 2, Dynamic> closed_spline2d()
							 | 
						|
								{
							 | 
						|
								  RowVectorXd knots(12);
							 | 
						|
								  knots << 0,
							 | 
						|
								    0,
							 | 
						|
								    0,
							 | 
						|
								    0,
							 | 
						|
								    0.867193179093898,
							 | 
						|
								    1.660330955342408,
							 | 
						|
								    2.605084834823134,
							 | 
						|
								    3.484154586374428,
							 | 
						|
								    4.252699478956276,
							 | 
						|
								    4.252699478956276,
							 | 
						|
								    4.252699478956276,
							 | 
						|
								    4.252699478956276;
							 | 
						|
								
							 | 
						|
								  MatrixXd ctrls(8,2);
							 | 
						|
								  ctrls << -0.370967741935484,   0.236842105263158,
							 | 
						|
								    -0.231401860693277,   0.442245185027632,
							 | 
						|
								    0.344361228532831,   0.773369994120753,
							 | 
						|
								    0.828990216203802,   0.106550882647595,
							 | 
						|
								    0.407270163678382,  -1.043452922172848,
							 | 
						|
								    -0.488467813584053,  -0.390098582530090,
							 | 
						|
								    -0.494657189446427,   0.054804824897884,
							 | 
						|
								    -0.370967741935484,   0.236842105263158;
							 | 
						|
								  ctrls.transposeInPlace();
							 | 
						|
								
							 | 
						|
								  return Spline<double, 2, Dynamic>(knots, ctrls);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/* create a reference spline */
							 | 
						|
								Spline<double, 3, Dynamic> spline3d()
							 | 
						|
								{
							 | 
						|
								  RowVectorXd knots(11);
							 | 
						|
								  knots << 0,
							 | 
						|
								    0,
							 | 
						|
								    0,
							 | 
						|
								    0.118997681558377,
							 | 
						|
								    0.162611735194631,
							 | 
						|
								    0.498364051982143,
							 | 
						|
								    0.655098003973841,
							 | 
						|
								    0.679702676853675,
							 | 
						|
								    1.000000000000000,
							 | 
						|
								    1.000000000000000,
							 | 
						|
								    1.000000000000000;
							 | 
						|
								
							 | 
						|
								  MatrixXd ctrls(8,3);
							 | 
						|
								  ctrls <<    0.959743958516081,   0.340385726666133,   0.585267750979777,
							 | 
						|
								    0.223811939491137,   0.751267059305653,   0.255095115459269,
							 | 
						|
								    0.505957051665142,   0.699076722656686,   0.890903252535799,
							 | 
						|
								    0.959291425205444,   0.547215529963803,   0.138624442828679,
							 | 
						|
								    0.149294005559057,   0.257508254123736,   0.840717255983663,
							 | 
						|
								    0.254282178971531,   0.814284826068816,   0.243524968724989,
							 | 
						|
								    0.929263623187228,   0.349983765984809,   0.196595250431208,
							 | 
						|
								    0.251083857976031,   0.616044676146639,   0.473288848902729;
							 | 
						|
								  ctrls.transposeInPlace();
							 | 
						|
								
							 | 
						|
								  return Spline<double, 3, Dynamic>(knots, ctrls);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/* compares evaluations against known results */
							 | 
						|
								void eval_spline3d()
							 | 
						|
								{
							 | 
						|
								  Spline3d spline = spline3d();
							 | 
						|
								
							 | 
						|
								  RowVectorXd u(10);
							 | 
						|
								  u << 0.351659507062997,
							 | 
						|
								    0.830828627896291,
							 | 
						|
								    0.585264091152724,
							 | 
						|
								    0.549723608291140,
							 | 
						|
								    0.917193663829810,
							 | 
						|
								    0.285839018820374,
							 | 
						|
								    0.757200229110721,
							 | 
						|
								    0.753729094278495,
							 | 
						|
								    0.380445846975357,
							 | 
						|
								    0.567821640725221;
							 | 
						|
								
							 | 
						|
								  MatrixXd pts(10,3);
							 | 
						|
								  pts << 0.707620811535916,   0.510258911240815,   0.417485437023409,
							 | 
						|
								    0.603422256426978,   0.529498282727551,   0.270351549348981,
							 | 
						|
								    0.228364197569334,   0.423745615677815,   0.637687289287490,
							 | 
						|
								    0.275556796335168,   0.350856706427970,   0.684295784598905,
							 | 
						|
								    0.514519311047655,   0.525077224890754,   0.351628308305896,
							 | 
						|
								    0.724152914315666,   0.574461155457304,   0.469860285484058,
							 | 
						|
								    0.529365063753288,   0.613328702656816,   0.237837040141739,
							 | 
						|
								    0.522469395136878,   0.619099658652895,   0.237139665242069,
							 | 
						|
								    0.677357023849552,   0.480655768435853,   0.422227610314397,
							 | 
						|
								    0.247046593173758,   0.380604672404750,   0.670065791405019;
							 | 
						|
								  pts.transposeInPlace();
							 | 
						|
								
							 | 
						|
								  for (int i=0; i<u.size(); ++i)
							 | 
						|
								  {
							 | 
						|
								    Vector3d pt = spline(u(i));
							 | 
						|
								    VERIFY( (pt - pts.col(i)).norm() < 1e-14 );
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/* compares evaluations on corner cases */
							 | 
						|
								void eval_spline3d_onbrks()
							 | 
						|
								{
							 | 
						|
								  Spline3d spline = spline3d();
							 | 
						|
								
							 | 
						|
								  RowVectorXd u = spline.knots();
							 | 
						|
								
							 | 
						|
								  MatrixXd pts(11,3);
							 | 
						|
								  pts <<    0.959743958516081,   0.340385726666133,   0.585267750979777,
							 | 
						|
								    0.959743958516081,   0.340385726666133,   0.585267750979777,
							 | 
						|
								    0.959743958516081,   0.340385726666133,   0.585267750979777,
							 | 
						|
								    0.430282980289940,   0.713074680056118,   0.720373307943349,
							 | 
						|
								    0.558074875553060,   0.681617921034459,   0.804417124839942,
							 | 
						|
								    0.407076008291750,   0.349707710518163,   0.617275937419545,
							 | 
						|
								    0.240037008286602,   0.738739390398014,   0.324554153129411,
							 | 
						|
								    0.302434111480572,   0.781162443963899,   0.240177089094644,
							 | 
						|
								    0.251083857976031,   0.616044676146639,   0.473288848902729,
							 | 
						|
								    0.251083857976031,   0.616044676146639,   0.473288848902729,
							 | 
						|
								    0.251083857976031,   0.616044676146639,   0.473288848902729;
							 | 
						|
								  pts.transposeInPlace();
							 | 
						|
								
							 | 
						|
								  for (int i=0; i<u.size(); ++i)
							 | 
						|
								  {
							 | 
						|
								    Vector3d pt = spline(u(i));
							 | 
						|
								    VERIFY( (pt - pts.col(i)).norm() < 1e-14 );
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void eval_closed_spline2d()
							 | 
						|
								{
							 | 
						|
								  Spline2d spline = closed_spline2d();
							 | 
						|
								
							 | 
						|
								  RowVectorXd u(12);
							 | 
						|
								  u << 0,
							 | 
						|
								    0.332457030395796,
							 | 
						|
								    0.356467130532952,
							 | 
						|
								    0.453562180176215,
							 | 
						|
								    0.648017921874804,
							 | 
						|
								    0.973770235555003,
							 | 
						|
								    1.882577647219307,
							 | 
						|
								    2.289408593930498,
							 | 
						|
								    3.511951429883045,
							 | 
						|
								    3.884149321369450,
							 | 
						|
								    4.236261590369414,
							 | 
						|
								    4.252699478956276;
							 | 
						|
								
							 | 
						|
								  MatrixXd pts(12,2);
							 | 
						|
								  pts << -0.370967741935484,   0.236842105263158,
							 | 
						|
								    -0.152576775123250,   0.448975001279334,
							 | 
						|
								    -0.133417538277668,   0.461615613865667,
							 | 
						|
								    -0.053199060826740,   0.507630360006299,
							 | 
						|
								    0.114249591147281,   0.570414135097409,
							 | 
						|
								    0.377810316891987,   0.560497102875315,
							 | 
						|
								    0.665052120135908,  -0.157557441109611,
							 | 
						|
								    0.516006487053228,  -0.559763292174825,
							 | 
						|
								    -0.379486035348887,  -0.331959640488223,
							 | 
						|
								    -0.462034726249078,  -0.039105670080824,
							 | 
						|
								    -0.378730600917982,   0.225127015099919,
							 | 
						|
								    -0.370967741935484,   0.236842105263158;
							 | 
						|
								  pts.transposeInPlace();
							 | 
						|
								
							 | 
						|
								  for (int i=0; i<u.size(); ++i)
							 | 
						|
								  {
							 | 
						|
								    Vector2d pt = spline(u(i));
							 | 
						|
								    VERIFY( (pt - pts.col(i)).norm() < 1e-14 );
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void check_global_interpolation2d()
							 | 
						|
								{
							 | 
						|
								  typedef Spline2d::PointType PointType;
							 | 
						|
								  typedef Spline2d::KnotVectorType KnotVectorType;
							 | 
						|
								  typedef Spline2d::ControlPointVectorType ControlPointVectorType;
							 | 
						|
								
							 | 
						|
								  ControlPointVectorType points = ControlPointVectorType::Random(2,100);
							 | 
						|
								
							 | 
						|
								  KnotVectorType chord_lengths; // knot parameters
							 | 
						|
								  Eigen::ChordLengths(points, chord_lengths);
							 | 
						|
								
							 | 
						|
								  // interpolation without knot parameters
							 | 
						|
								  {
							 | 
						|
								    const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3);  
							 | 
						|
								
							 | 
						|
								    for (Eigen::DenseIndex i=0; i<points.cols(); ++i)
							 | 
						|
								    {
							 | 
						|
								      PointType pt = spline( chord_lengths(i) );
							 | 
						|
								      PointType ref = points.col(i);
							 | 
						|
								      VERIFY( (pt - ref).matrix().norm() < 1e-14 );
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  // interpolation with given knot parameters
							 | 
						|
								  {
							 | 
						|
								    const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3,chord_lengths);  
							 | 
						|
								
							 | 
						|
								    for (Eigen::DenseIndex i=0; i<points.cols(); ++i)
							 | 
						|
								    {
							 | 
						|
								      PointType pt = spline( chord_lengths(i) );
							 | 
						|
								      PointType ref = points.col(i);
							 | 
						|
								      VERIFY( (pt - ref).matrix().norm() < 1e-14 );
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								void test_splines()
							 | 
						|
								{
							 | 
						|
								  CALL_SUBTEST( eval_spline3d() );
							 | 
						|
								  CALL_SUBTEST( eval_spline3d_onbrks() );
							 | 
						|
								  CALL_SUBTEST( eval_closed_spline2d() );
							 | 
						|
								  CALL_SUBTEST( check_global_interpolation2d() );
							 | 
						|
								}
							 |