30#include "UnitsHelper.h"
33#include "common/NarrowCast.h"
34#include "dim/support/DimSupportStream.h"
35#include "spat/Matrix.h"
42 using namespace common;
77 template<
class Function,
class Base>
78 class Curve_Imp :
public Base{
82 using DataType =
typename Base::Data;
84 Curve_Imp() =
default;
85 Curve_Imp(
Real length ) noexcept
90 bool IsValid()
const noexcept override{
91 return f.IsValid() && L >= 0
_m;
98 const auto D1D1 = D1*D1;
100 return sqrt(k2(D1,D2,D1D1));
111 const auto D1D1 = D1*D1;
112 const auto k2_ = k2(D1,D2,D1D1);
139 if(
tan == Null<One> )
148 bundle.
P = f.P( ts );
149 bundle.
T = f.D1( ts ) /
Length{1};
150 if( bundle.
T == Null<One> )
153 bundle.
T.Normalize();
160 bundle.
P = f.P( ts );
161 if( D1 == Null<One> )
172 bundle.
T.Normalize();
173 bundle.
N = Null<One>;
177 bundle.
T.Normalize();
178 bundle.
N = D2 - (D1*D2)/(D1*D1) * D1;
181 if( bundle.
N.Length() < (1.0f + D2.Length()) * 10 *
epsilon )
186 D1 = f.D1(ts) /
Length{1};
187 D2 = f.D2(ts) /
Length{1};
189 if( D1 == Null<One> )
192 bundle.
N = D2 - (D1*D2)/(D1*D1) * D1;
194 if( bundle.
N.Length() < (1.0f + D2.Length()) * 10 *
epsilon )
195 bundle.
N =
Up % bundle.
T;
198 bundle.
N = bundle.
N - (bundle.
N * bundle.
T) * bundle.
T;
199 bundle.
N.Normalize();
205 frame.
B = frame.
T % frame.
N;
208 std::vector<Length> ZeroSet()
const override{
210 throw std::runtime_error(
"This curve has to be created prior to receiving the zero set." );
212 std::vector<Length> retval;
214 Transition( 0
_m, b2 );
223 Transition( s2, b2 );
224 if( b1.
N * b2.
N < -0.9 && !(b1.
T * b2.
T < -0.9) )
225 retval.push_back( CloseInOnCurvatureZero( s1, b1.
N, s2, b2.
N ) );
234 throw std::runtime_error(
"This curve has to be created prior to receiving its maximum range." );
241 Transition( 0
_m, retval );
249 return f.Mirror( mirrorPlane );
253 if(
this == &toCurve )
256 if(
auto pToCurve =
dynamic_cast<const Base*
>(&toCurve) )
257 return trax::Equals( GetData(), pToCurve->GetData(), range, epsilon_length, epsilon_angle );
267 const DataType& GetData()
const noexcept override{
307 assert( f.IsValid() );
309 assert( dtMax >
One{0} );
312 m_Samples.reserve(
static_cast<std::size_t
>(std::ceil(10
_m/ds)) + 1 );
317 m_Samples.push_back( 0 );
319 const auto d1 = f.D1(
t);
320 const auto d2 = f.D2(
t);
321 const Length D1 = d1.Length();
322 const Length D2 = d2.Length();
324 One dt = D2 > (2*dL/dtMax) ? 2*dL/D2 : dtMax;
338 m_Samples.push_back(
t - (
s - i*ds) / D1 );
342 m_Samples.push_back(
One{1} );
343 m_Samples.shrink_to_fit();
345 dsLast =
s - (i-1)*ds + epsilon__length;
352 if(
s <= 0
_m )
return 0;
353 if( L <=
s )
return 1;
356 Real fraction = std::modf(
s / ds, &integer );
357 const std::size_t i =
static_cast<std::size_t
>(integer);
359 if( i+1 == m_Samples.size()-1 )
360 fraction = fraction * ds / dsLast;
362 return (1.f - fraction) * m_Samples[i] + fraction * m_Samples[i+1];
367 if(
t <= 0 )
return 0
_m;
368 if(
t >= 1 )
return L;
372 const int middle = r.
Center();
373 t >= m_Samples[middle] ? r.
Near( middle ) : r.
Far( middle );
379 bool CheckSamples() const noexcept{
381 for( std::size_t i = 1; i < m_Samples.size(); ++i )
382 if( m_Samples[i] <= m_Samples[i-1] ){
383 std::cerr <<
"Samples are not monotonically increasing! At s=" << ds * i << std::endl;
390 const Length dL = epsilon__length;
391 const Length ds = 100 * epsilon__length;
392 const One dtMax = 1.0f/100;
393 const One dtMin = 1.0f/10000;
394 std::vector<One> m_Samples;
398 Length CloseInOnCurvatureZero(
Length s1,
const Vector<One>& N1,
Length s2,
const Vector<One>& N2 )
const{
403 VectorBundle2<Length,One> bundle;
404 Transition(
s, bundle );
406 if( N1 * bundle.
N < 0 )
407 return CloseInOnCurvatureZero( s1, N1,
s, bundle.
N );
408 else if( bundle.
N * N2 < 0 )
409 return CloseInOnCurvatureZero(
s, bundle.
N, s2, N2 );
414 inline Value<Dimension<-2,0,0>> k2(
const Vector<Length>& D1,
const Vector<Length>& D2,
Area D1D1 )
const{
415 if( D1D1 == 0
_m2 )
return Value<Dimension<-2,0,0>>{0};
416 const Value<Dimension<-2,0,0>> k2{ std::max( (D2*D2 - (
pow<2>(D1*D2)/D1D1))/D1D1/D1D1, 0
_1Im2 ) };
429 template<
class Function,
class Base>
433 return DTds(
s ).Length();
439 return -DBds(
s ) * N( T, DTds(
s ) );
442 using Curve_Imp<Function,Base>::Transition;
445 Transition(
s, bundle.
P );
446 Transition(
s, bundle.
T );
447 bundle.
N = N( bundle.
T, DTds(
s ) );
450 using Curve_Imp<Function,Base>::Range;
451 using Curve_Imp<Function,Base>::GetData;
453 using Curve_Imp<Function,Base>::f;
455 static inline const Length h4 = 0.15
_m;
464 return finite_difference_derivative6<Vector<AnglePerLength>>( T, Range().Deflate( h4 ).Clip(
s ) );
474 return finite_difference_derivative6<Vector<AnglePerLength>>( B, Range().Deflate( h4 ).Clip(
s ) );
479 if( dTds != Null<AnglePerLength> )
484 N = Parallel(
Up, Ex<One> ) ? Ey<One> : Ex<One>;
505 template<
class FunctionParametrizedByArcLength,
class Base>
508 FunctionParametrizedByArcLength f;
510 using DataType =
typename Base::Data;
514 bool IsValid()
const noexcept override{
519 return f.D2(s).Length();
525 const auto D2 = f.D2(s);
526 if(
const auto D2D2 = D2*D2 )
527 return (f.D1(s) % D2) * f.D3(s) / (D2D2);
550 if( bundle.
N.Length() < 10 *
epsilon ){
551 s += (s >= (f.Range().Normal() ? f.Range().Near() : f.Range().Far()) + epsilon__length ? -epsilon__length : +epsilon__length);
555 if( bundle.
N.Length() < 10 *
epsilon )
556 bundle.
N =
Up % bundle.
T;
559 bundle.
N = bundle.
N - (bundle.
N * bundle.
T) * bundle.
T;
560 bundle.
N.Normalize();
566 frame.
B = frame.
T % frame.
N;
569 std::vector<Length> ZeroSet()
const override{
571 throw std::runtime_error(
"This curve has to be created prior to receiving the zero set." );
582 Transition( 0
_m, retval );
590 return f.Mirror( mirrorPlane );
594 if(
this == &toCurve )
597 if(
auto pToCurve =
dynamic_cast<const Base*
>(&toCurve) )
598 return trax::Equals( GetData(), pToCurve->GetData(), range, epsilon_length, epsilon_angle );
608 const DataType& GetData()
const noexcept override{
618 template<
class Function>
619 class Reparametrization{
621 Reparametrization() noexcept
628 Reparametrization(
Real length ) noexcept
630 m_Length2 {m_Length*m_Length},
631 m_Length3 {m_Length*m_Length2}
633 assert( m_Length >= 0 );
636 Reparametrization(
const Reparametrization& ) =
default;
637 Reparametrization( Reparametrization&& ) =
default;
638 Reparametrization& operator=(
const Reparametrization& ) =
default;
639 Reparametrization& operator=( Reparametrization&& ) =
default;
640 ~Reparametrization() =
default;
644 assert( length >= 0 );
646 m_Length2 = m_Length*m_Length;
647 m_Length3 = m_Length*m_Length2;
654 bool IsValid()
const noexcept{
655 return f.IsValid() && m_Length >= 0;
663 return f( m_Length * t );
667 return m_Length * f.D1( m_Length * t );
671 return m_Length2 * f.D2( m_Length * t );
675 return m_Length3 * f.D3( m_Length * t );
679 return f.Mirror( mirrorPlane );
683 Length( f.Create(data).Length() );
687 const typename Function::DataType& GetData()
const noexcept{
699 template<
class MainBase>
701 public CurvatureStrecher{
705 m_CurvatureLimits = curvatureLimits;
708 this->Transition( s, E );
709 m_TargetOffset = (Z - E) * this->
Direction( s );
710 return this->Curvature(s);
713 template<
class FunctionType>
715 if( m_CurvatureLimits.Touches(bestGuess) ){
716 constexpr boost::uintmax_t maxit = 30;
717 boost::uintmax_t it = maxit;
725 boost::math::tools::eps_tolerance<Real>{std::numeric_limits<Real>::digits-3},
730 std::cout <<
"[" << bracket.
Near() <<
"," << bracket.
Far() <<
"] iterations: " << it <<
" k= " << k << std::endl;
732 if( it <= maxit && m_CurvatureLimits.Touches( k ) )
735 catch(
const boost::math::evaluation_error& e ){
736 std::cerr << e.what() << std::endl;
738 catch(
const std::invalid_argument& e ){
739 std::cerr << e.what() << std::endl;
Value type, dependend from dimensions.
Definition DimensionedValues.h:233
Square matrix with nColumns == nRows.
Definition Matrix.h:278
Definition Curve_Imp.h:701
One t(Length s) const noexcept
Parameter from arc length function to evaluate f.
Definition Curve_Imp.h:351
common::Interval< Length > Sample()
Definition Curve_Imp.h:306
Length SampleStep() const noexcept
Definition Curve_Imp.h:278
Length s(One t) const noexcept
Arc length s from parameter t calculated by bisection.
Definition Curve_Imp.h:366
If the curve function happens to be parameterized by arc length, this implementation for a curve can ...
Definition Curve_Imp.h:506
This calculates the normal vector, curvature and torsion numerically using the relations derived from...
Definition Curve_Imp.h:430
constexpr T pow(T val) noexcept
power function with templated integer exponent.
Definition Helpers.h:61
constexpr bool Equals(T a, T b, T epsilon) noexcept
Tests equality in the sense |a-b| < epsilon.
Definition Helpers.h:66
Target narrow_cast(Source v)
Safe cast for casting numeric values.
Definition NarrowCast.h:60
Value< Dimension< 2, 0, 0 > > Area
Area.
Definition DimensionedValues.h:325
constexpr Value< Dimension< L/2, M/2, T/2 > > sqrt(Value< Dimension< L, M, T > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:670
Value< Dimension< 0, 0, 0 > > One
Dimensionless value.
Definition DimensionedValues.h:319
constexpr Real _1Im(AnglePerLength a) noexcept
Dimensionated Values conversion functions.
Definition DimensionedValues.h:1347
Value< Dimension< 1, 0, 0 > > Length
Length.
Definition DimensionedValues.h:324
constexpr Real _1Im2(Value< Dimension<-2, 0, 0 > > a) noexcept
Dimensionated Values conversion functions.
Definition DimensionedValues.h:1379
constexpr Real _m(Length l) noexcept
Dimensionated Values conversion functions.
Definition DimensionedValues.h:1210
Value< Dimension<-1, 0, 0 > > AnglePerLength
Angle per length.
Definition DimensionedValues.h:321
float Real
Underlying floating point type to be used with the dim library.
Definition DimensionedValues.h:190
constexpr Real epsilon
Marginal difference in calculations.
Definition DimensionedValues.h:344
constexpr Real _deg(Angle a) noexcept
Dimensionated Values conversion functions.
Definition DimensionedValues.h:1194
Value< Dimension< 0, 0, 0 > > Angle
Angle in radians.
Definition DimensionedValues.h:320
constexpr Value< Dimension< L, M, T > > abs(Value< Dimension< L, M, T > > x) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:680
constexpr Value< Dimension< 0, 0, 0 > > tan(Value< Dimension< 0, 0, 0 > > a) noexcept
Dimensionated Values math function.
Definition DimensionedValues.h:702
constexpr Real _m2(Area a) noexcept
Dimensionated Values conversion functions.
Definition DimensionedValues.h:1299
constexpr auto Determinant(const SquareMatrix< Valtype, nColsAndRows > &m) -> decltype(pow< nColsAndRows >(Valtype{}))
Determinant of the matrix.
Definition Matrix.h:1147
auto Normalize(const Frame< Valtype, ValtypeT > &f) noexcept -> std::pair< Vector< ValtypeT >, Frame< Valtype, decltype(ValtypeT{}/ValtypeT{})> >
Outer normalizing.
Definition Frame.h:1144
constexpr Position< Valtype > Origin3D
Origin of coordinate system.
Definition Position.h:143
Namespace of all the trax track libraries classes and methods.
Definition Collection.h:17
constexpr spat::Vector< One > Up
Vector pointing in the up direction with respect to gravity.
Definition Units.h:144
constexpr AnglePerLength epsilon__curvature
Marginal curvature is earth's curvature.
Definition Units.h:149
An interval describes the area between two numbers. It is understood to contain the near one and exlu...
Definition Interval.h:42
constexpr Valtype Near() const noexcept
Definition Interval.h:381
constexpr Valtype Length() const noexcept
Distance from m_Near to m_Far.
Definition Interval.h:413
constexpr Valtype Far() const noexcept
Definition Interval.h:386
constexpr Valtype Center() const noexcept
gets the value centered in the interval.
Definition Interval.h:431
Type selection for class Value.
Definition DimensionedValues.h:224
A Frame ("TNBFrame") describes a location in 3d space and an orientation using a right handed coordin...
Definition Frame.h:52
Vector< ValtypeT > B
Binormal axis or z-axis.
Definition Frame.h:56
Vector< ValtypeT > N
Normal axis or y-axis.
Definition Frame.h:55
Vector< ValtypeT > T
Tangential axis or x-axis.
Definition Frame.h:54
Implements a 3D - position in cartesian coordinates.
Definition Position.h:46
Implements a tangential space bundle.
Definition VectorBundle2.h:43
Vector< ValtypeT > T
Tangent vector or x-axis.
Definition VectorBundle2.h:45
Vector< ValtypeT > N
Normal axis or y-axis.
Definition VectorBundle2.h:46
Position< Valtype > P
Base space postion.
Definition VectorBundle2.h:44
Implements a Vector bundle.
Definition VectorBundle.h:42
Position< Valtype > P
Base space postion.
Definition VectorBundle.h:43
Vector< ValtypeT > T
Tangent vector or x-axis.
Definition VectorBundle.h:44
Implements a 3D - vector in cartesian coordinates.
Definition Vector.h:48
Valtype dy
cartesian y component.
Definition Vector.h:52
Valtype dx
cartesian x component.
Definition Vector.h:51
Valtype dz
cartesian z component.
Definition Vector.h:53
auto Normalize() noexcept -> decltype(Valtype{}/Valtype{})
Normalizes the vector to length 1.
Definition Vector.h:487
virtual spat::Vector< One > Direction(Length s) const =0
Curves implement this interface that then can get attached to a track to define the tracks geometry.
Definition Curve.h:198