Trax3 3.1.0
trax track library
Loading...
Searching...
No Matches
RoadwayTwist.h
1// trax track library
2// AD 2014
3//
4// "Twist and Shout!"
5//
6// The Beatles
7//
8// Copyright (c) 2025 Trend Redaktions- und Verlagsgesellschaft mbH
9// Copyright (c) 2019 Marc-Michael Horstmann
10//
11// Permission is hereby granted to any person obtaining a copy of this software
12// and associated source code (the "Software"), to use, view, and study the
13// Software for personal or internal business purposes, subject to the following
14// conditions:
15//
16// 1. Redistribution, modification, sublicensing, or commercial use of the
17// Software is NOT permitted without prior written consent from the copyright
18// holder.
19//
20// 2. The Software is provided "AS IS", without warranty of any kind, express
21// or implied.
22//
23// 3. All copies of the Software must retain this license notice.
24//
25// For further information, please contact: horstmann.marc@trendverlag.de
26
27#pragma once
28
66
67#include "Configuration.h"
68#include "Units.h"
69
70#include "common/Interval.h"
71#include "spat/Vector.h"
72
73#include <memory>
74
75namespace trax
76{
77 struct TrackBuilder;
78
81 struct RoadwayTwist{
82
98
99
101 static dclspc std::unique_ptr<RoadwayTwist> Make( TwistType type ) noexcept;
102
104 static dclspc std::unique_ptr<RoadwayTwist> Make( TwistType type, const RoadwayTwist& fromTwist ) noexcept;
105
106
108 virtual const char* TypeName() const noexcept = 0;
109
110
111 virtual TwistType GetTwistType() const noexcept = 0;
112
113
115 virtual std::unique_ptr<RoadwayTwist> Clone() const = 0;
116
117
123 virtual bool IsValid() const noexcept = 0;
124
125
128 virtual Angle Twist( Length s ) const = 0;
129
130
133 virtual AnglePerLength D1( Length s ) const = 0;
134
135
144 virtual bool ZeroFlip( bool bActive ) noexcept = 0;
145
146
151 virtual void Flip() noexcept = 0;
152
153
158 virtual void Mirror() noexcept = 0;
159
160
168 virtual bool Offset( Angle offset ) noexcept = 0;
169
170
175 virtual bool IsDynamic() const noexcept = 0;
176
177
187 virtual bool IsDirectionalConstant() const noexcept = 0;
188
189
191 virtual bool IsConstant() const noexcept = 0;
192
193
196 virtual void Freeze( bool bFreeze = true ) noexcept = 0;
197
198
200 virtual bool IsFrozen() const noexcept = 0;
201
202
204 virtual bool IsNull() const noexcept = 0;
205
206
213 virtual bool Equals( const RoadwayTwist& toTwist, Angle epsilon_angle = epsilon__angle ) const noexcept = 0;
214
215
218 virtual void OnAttach( const TrackBuilder& track ) noexcept = 0;
219
220
222 virtual void OnDetach() noexcept = 0;
223
224
226 virtual Angle DoTwist( Length ) const = 0;
227
228
230 virtual AnglePerLength DoD1( Length ) const = 0;
231
232
233 virtual ~RoadwayTwist() = default;
234 RoadwayTwist( RoadwayTwist&& ) = delete;
235 RoadwayTwist& operator=( const RoadwayTwist& ) = delete;
236 RoadwayTwist& operator=( RoadwayTwist&& ) = delete;
237 protected:
238 RoadwayTwist() = default;
239 RoadwayTwist( const RoadwayTwist& ) = default;
240 };
241
242
250 bool dclspc Equals(
251 const RoadwayTwist& twistA,
252 const RoadwayTwist& twistB,
253 Angle epsilon_angle = epsilon__angle ) noexcept;
254
255
257 dclspc const char* TypeToName( RoadwayTwist::TwistType type );
258
259
261 dclspc RoadwayTwist::TwistType TwistNameToType( const std::string& name ) noexcept;
262
263
265 struct ConstantTwist : RoadwayTwist{
266
268 static dclspc std::unique_ptr<ConstantTwist> Make() noexcept;
269
271 static dclspc std::unique_ptr<ConstantTwist> Make( const RoadwayTwist& fromTwist ) noexcept;
272
273
275 virtual void TwistValue( Angle twist ) noexcept = 0;
276
277
279 virtual Angle TwistValue() const noexcept = 0;
280
281 using Data = Angle;
282
283 virtual const Data& GetData() const noexcept = 0;
284
285 virtual void Create( const Data& data ) noexcept = 0;
286 };
287
288
290 struct LinearTwist : RoadwayTwist{
291
293 static dclspc std::unique_ptr<LinearTwist> Make( Angle from = 0_deg, Angle to = 0_deg ) noexcept;
294
296 static dclspc std::unique_ptr<LinearTwist> Make( const RoadwayTwist& fromTwist ) noexcept;
297
298
306
307
309 virtual void From( Angle twist ) noexcept = 0;
310
311
313 virtual Angle From() const noexcept = 0;
314
315
317 virtual void To( Angle twist ) noexcept = 0;
318
319
321 virtual Angle To() const noexcept = 0;
322
323
324 virtual const Data& GetData() const noexcept = 0;
325
326 virtual void Create( const Data& data ) noexcept = 0;
327 };
328
329
332 struct PiecewiseTwist : RoadwayTwist
333 {
335 static dclspc std::unique_ptr<PiecewiseTwist> Make( TwistType type = TwistType::Piecewise ) noexcept;
336
338 static dclspc std::unique_ptr<PiecewiseTwist> Make( TwistType type, const RoadwayTwist& fromTwist ) noexcept;
339
340 using SegmentValueType = std::pair<Length, Angle>;
341 using Data = std::vector<SegmentValueType>;
342
344 virtual void Add( Length s, const Angle& twist ) = 0;
345
346
348 virtual void Add( const std::pair<Length,Angle>& pair ) = 0;
349
350
352 virtual int CntTwistValues() const = 0;
353
354
357 virtual std::pair<Length,Angle> Twist( int idx ) const = 0;
358
359 virtual void Create( const Data& data ) = 0;
360
361 virtual const Data& GetData() const noexcept = 0;
362
363 using RoadwayTwist::Twist;
364 };
365
366
372 struct DirectionalTwist : RoadwayTwist{
373
375 static dclspc std::unique_ptr<DirectionalTwist> Make( const spat::Vector<One>& attractor = Up ) noexcept;
376
378 static dclspc std::unique_ptr<DirectionalTwist> Make( const RoadwayTwist& fromTwist ) noexcept;
379
380 using Data = spat::Vector<One>;
381
388 virtual void Attractor( const spat::Vector<One>& attractor ) = 0;
389
393 virtual const spat::Vector<One>& Attractor() const noexcept = 0;
394
395
399 virtual const spat::Vector<One>& Attractor( bool bGlobal ) const noexcept = 0;
400
401
403 virtual std::shared_ptr<const struct Curve> GetCurve() const noexcept = 0;
404
405 virtual const Data& GetData() const noexcept = 0;
406
407
411 virtual void Create( const Data& data ) = 0;
412 };
413
414
419 struct PiecewiseDirectionalTwist : RoadwayTwist{
420
422 static dclspc std::unique_ptr<PiecewiseDirectionalTwist> Make() noexcept;
423
425 static dclspc std::unique_ptr<PiecewiseDirectionalTwist> Make( const RoadwayTwist& fromTwist ) noexcept;
426
427
428 using Data = std::vector<std::pair<Length,spat::Vector<One>>>;
429
430
437 virtual void Add( Length s, const spat::Vector<One>& attractor ) = 0;
438
439 virtual void Add( const std::pair<Length,spat::Vector<One>>& pair ) = 0;
441
442
444 virtual int CntTwistValues() const = 0;
445
449 virtual void Create( const Data& data ) = 0;
450
453 virtual std::pair<Length,spat::Vector<One>> Twist( int idx ) const = 0;
454
455 virtual const Data& GetData() const noexcept = 0;
456
457 using RoadwayTwist::Twist;
458 };
459
460
468 struct CombinedTwist : RoadwayTwist{
469
471 static dclspc std::unique_ptr<CombinedTwist> Make() noexcept;
472
474 static dclspc std::unique_ptr<CombinedTwist> Make( const RoadwayTwist& fromTwist ) noexcept;
475
476
481 virtual void AttachTwist1( std::unique_ptr<RoadwayTwist> pTwist ) = 0;
482
483 virtual RoadwayTwist& Twist1() const noexcept = 0;
484
485 virtual std::unique_ptr<RoadwayTwist> DetachTwist1() = 0;
486
487
492 virtual void AttachTwist2( std::unique_ptr<RoadwayTwist> pTwist ) = 0;
493
494 virtual RoadwayTwist& Twist2() const noexcept = 0;
495
496 virtual std::unique_ptr<RoadwayTwist> DetachTwist2() = 0;
497 };
498
499
506 template<class TwistType>
507 const TwistType* FindTwist( const RoadwayTwist& twist ) noexcept{
508 if( const auto* pTwist = dynamic_cast<const TwistType*>(&twist) )
509 return pTwist;
510
511 if( const auto* pCombinedTwist = dynamic_cast<const CombinedTwist*>(&twist) ){
512 if( const auto* pTwist2 = FindTwist<const TwistType>(pCombinedTwist->Twist2()) )
513 return pTwist2;
514 else if( const auto* pTwist1 = FindTwist<const TwistType>(pCombinedTwist->Twist1()) )
515 return pTwist1;
516 }
517
518 return nullptr;
519 }
520
521 template<class TwistType>
522 TwistType* FindTwist( RoadwayTwist& twist ) noexcept{
523 if( auto pTwist = dynamic_cast<TwistType*>(&twist) )
524 return pTwist;
525
526 if( auto pCombinedTwist = dynamic_cast<const CombinedTwist*>(&twist) ){
527 if( auto pTwist2 = FindTwist<TwistType>(pCombinedTwist->Twist2()) )
528 return pTwist2;
529 else if( auto pTwist1 = FindTwist<TwistType>(pCombinedTwist->Twist1()) )
530 return pTwist1;
531 }
532
533 return nullptr;
534 }
536
537 // for /GR- we export the template instantiations from trax:
538 extern template dclspc const ConstantTwist* FindTwist<ConstantTwist>( const RoadwayTwist& twist ) noexcept;
539 extern template dclspc const LinearTwist* FindTwist<LinearTwist>( const RoadwayTwist& twist ) noexcept;
540 extern template dclspc const PiecewiseTwist* FindTwist<PiecewiseTwist>( const RoadwayTwist& twist ) noexcept;
541 extern template dclspc const DirectionalTwist* FindTwist<DirectionalTwist>( const RoadwayTwist& twist ) noexcept;
542 extern template dclspc const CombinedTwist* FindTwist<CombinedTwist>( const RoadwayTwist& twist ) noexcept;
543
544 extern template dclspc ConstantTwist* FindTwist<ConstantTwist>( RoadwayTwist& twist ) noexcept;
545 extern template dclspc LinearTwist* FindTwist<LinearTwist>( RoadwayTwist& twist ) noexcept;
546 extern template dclspc PiecewiseTwist* FindTwist<PiecewiseTwist>( RoadwayTwist& twist ) noexcept;
547 extern template dclspc DirectionalTwist* FindTwist<DirectionalTwist>( RoadwayTwist& twist ) noexcept;
548 extern template dclspc CombinedTwist* FindTwist<CombinedTwist>( RoadwayTwist& twist ) noexcept;
549
550
551 //std::unique_ptr<RoadwayTwist> dclspc CreateTwistFrom( RoadwayTwist::TwistType type, const RoadwayTwist& twist );
552 //std::unique_ptr<RoadwayTwist> dclspc CreateZeroFrom( const RoadwayTwist& twist );
553 //std::unique_ptr<ConstantTwist> dclspc CreateConstantFrom( const RoadwayTwist& twist );
554 //std::unique_ptr<LinearTwist> dclspc CreateLinearFrom( const RoadwayTwist& twist );
555 //std::unique_ptr<PiecewiseTwist> dclspc CreatePiecewiseFrom( const RoadwayTwist& twist );
556 //std::unique_ptr<PiecewiseTwist> dclspc CreatePiecewiseLinearFrom( const RoadwayTwist& twist );
557 //std::unique_ptr<PiecewiseTwist> dclspc CreatePiecewiseCircularFrom( const RoadwayTwist& twist );
558 //std::unique_ptr<PiecewiseDirectionalTwist> dclspc CreatePiecewiseDirectionalFrom( const RoadwayTwist& twist );
559 //std::unique_ptr<DirectionalTwist> dclspc CreateDirectionalFrom( const RoadwayTwist& twist );
560}
constexpr bool Equals(T a, T b, T epsilon) noexcept
Tests equality in the sense |a-b| < epsilon.
Definition Helpers.h:66
Value< Dimension< 0, 0, 0 > > One
Dimensionless value.
Definition DimensionedValues.h:319
Value< Dimension< 1, 0, 0 > > Length
Length.
Definition DimensionedValues.h:324
Value< Dimension<-1, 0, 0 > > AnglePerLength
Angle per length.
Definition DimensionedValues.h:321
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
The namespace provides classes and methods for spatial computations.
Definition Box.h:32
STL namespace.
Namespace of all the trax track libraries classes and methods.
Definition Collection.h:17
dclspc const char * TypeToName(Curve::CurveType ct)
Gets the type name of a curve from its type enumerator.
constexpr spat::Vector< One > Up
Vector pointing in the up direction with respect to gravity.
Definition Units.h:144
dclspc RoadwayTwist::TwistType TwistNameToType(const std::string &name) noexcept
Gets the type enumerator of a twist from its type name.
An interval describes the area between two numbers. It is understood to contain the near one and exlu...
Definition Interval.h:42
Implements a 3D - vector in cartesian coordinates.
Definition Vector.h:48
Combines the effect of two twists by adding them.
Definition RoadwayTwist.h:468
virtual void AttachTwist1(std::unique_ptr< RoadwayTwist > pTwist)=0
Populates the first slot.
virtual void AttachTwist2(std::unique_ptr< RoadwayTwist > pTwist)=0
Populates the second slot.
static dclspc std::unique_ptr< CombinedTwist > Make() noexcept
Makes a CombinedTwist object.
A twist that stays constant over the whole track range.
Definition RoadwayTwist.h:265
virtual void TwistValue(Angle twist) noexcept=0
Set twist value.
static dclspc std::unique_ptr< ConstantTwist > Make() noexcept
Makes a ConstantTwist object.
Curves implement this interface that then can get attached to a track to define the tracks geometry.
Definition Curve.h:198
A twist that rotates the frame arount T in a way that B is nearest a certain direction.
Definition RoadwayTwist.h:372
virtual const spat::Vector< One > & Attractor() const noexcept=0
virtual void Create(const Data &data)=0
Creates the twist from the data.
virtual std::shared_ptr< const struct Curve > GetCurve() const noexcept=0
static dclspc std::unique_ptr< DirectionalTwist > Make(const RoadwayTwist &fromTwist) noexcept
Makes a DirectionalTwist object from another twist.
static dclspc std::unique_ptr< DirectionalTwist > Make(const spat::Vector< One > &attractor=Up) noexcept
Makes a DirectionalTwist object.
virtual void Attractor(const spat::Vector< One > &attractor)=0
Set the direction for the twist.
A twist that varies linearly between two values.
Definition RoadwayTwist.h:290
virtual void From(Angle twist) noexcept=0
Set starting twist value.
common::Interval< Angle > Data
Data describing the twist.
Definition RoadwayTwist.h:305
static dclspc std::unique_ptr< LinearTwist > Make(const RoadwayTwist &fromTwist) noexcept
Makes a LinearTwist object from another twist.
static dclspc std::unique_ptr< LinearTwist > Make(Angle from=0_deg, Angle to=0_deg) noexcept
Makes a LinearTwist object.
virtual Angle From() const noexcept=0
Get starting twist value.
virtual void To(Angle twist) noexcept=0
Set ending twist value.
A twist that works like a DirectionalTwist but interpolates (linearly) two neighbouring attractors ac...
Definition RoadwayTwist.h:419
virtual void Create(const Data &data)=0
Creates the twist from the data.
virtual int CntTwistValues() const =0
virtual std::pair< Length, spat::Vector< One > > Twist(int idx) const =0
static dclspc std::unique_ptr< PiecewiseDirectionalTwist > Make() noexcept
Makes a PiecewiseDirectionalTwist object.
A twist with values at control points and either none or linear interpolation for the points in betwe...
Definition RoadwayTwist.h:333
virtual std::pair< Length, Angle > Twist(int idx) const =0
static dclspc std::unique_ptr< PiecewiseTwist > Make(TwistType type=TwistType::Piecewise) noexcept
Makes a PiecewiseTwist object.
virtual void Add(Length s, const Angle &twist)=0
Add a control point to the Twist.
virtual void Add(const std::pair< Length, Angle > &pair)=0
Add a control point to the Twist.
virtual int CntTwistValues() const =0
static dclspc std::unique_ptr< PiecewiseTwist > Make(TwistType type, const RoadwayTwist &fromTwist) noexcept
Makes a PiecewiseTwist object from another twist.
A RoadwayTwist is used to define the actual rotating angle around the tangent at a curve to get the c...
Definition RoadwayTwist.h:81
virtual Angle DoTwist(Length) const =0
virtual AnglePerLength DoD1(Length) const =0
virtual bool IsNull() const noexcept=0
virtual void OnAttach(const TrackBuilder &track) noexcept=0
Called on attachment to a track.
virtual bool IsDynamic() const noexcept=0
A twist is dynamic if it relates to geometry global to the track.
TwistType
Definition RoadwayTwist.h:83
@ Linear
A twist that linearly interpolates the twist angle from front to end of a track.
Definition RoadwayTwist.h:88
@ PiecewiseCircular
A twist that interpolates the angles in a 2pi interval and uses the shortest angular distance.
Definition RoadwayTwist.h:91
@ Combined
A twist that combines two twists additively.
Definition RoadwayTwist.h:95
@ PiecewiseDirectional
A twist that interpolates directions (slerp) and uses the result as directional twist.
Definition RoadwayTwist.h:92
@ PiecewiseLinear
A twist that interpolates the angles linearly along the segments.
Definition RoadwayTwist.h:90
@ Directional
A twist that rotates the frame's B closest to some attractor vector.
Definition RoadwayTwist.h:93
@ Positional
A twist that rotates the frame's B to point closest to some point in space.
Definition RoadwayTwist.h:94
@ Constant
A twist that applies a constant twist angle at every point along a track.
Definition RoadwayTwist.h:87
@ Zero
A twist that always applies 0_rad as a twist angle.
Definition RoadwayTwist.h:86
@ Piecewise
A twist that applies different twist angles to segments long the track.
Definition RoadwayTwist.h:89
virtual void OnDetach() noexcept=0
Called on detachment from a track.
static dclspc std::unique_ptr< RoadwayTwist > Make(TwistType type, const RoadwayTwist &fromTwist) noexcept
Makes a RoadwayTwist object from another twist.
virtual bool IsFrozen() const noexcept=0
virtual bool ZeroFlip(bool bActive) noexcept=0
virtual const char * TypeName() const noexcept=0
Name for the object type that implements this interface.
static dclspc std::unique_ptr< RoadwayTwist > Make(TwistType type) noexcept
Makes a RoadwayTwist object.
virtual void Flip() noexcept=0
Flips the effect of the twist along the track. After calling this function, the Twist() and D1() meth...
virtual bool IsValid() const noexcept=0
virtual bool IsDirectionalConstant() const noexcept=0
Find wether the twist is directional only offsetted by a constant.
virtual void Mirror() noexcept=0
Multiplies all twist angle by -1.
virtual bool IsConstant() const noexcept=0
virtual Angle Twist(Length s) const =0
virtual bool Offset(Angle offset) noexcept=0
Adds a global offset angle to the Twist.
virtual bool Equals(const RoadwayTwist &toTwist, Angle epsilon_angle=epsilon__angle) const noexcept=0
Comparison.
virtual AnglePerLength D1(Length s) const =0
virtual void Freeze(bool bFreeze=true) noexcept=0
Freezes the twist, so that dynamic twists like DirectionalTwist don't update anymore.
virtual std::unique_ptr< RoadwayTwist > Clone() const =0
Make a clone from this object.
Interface for making and shaping tracks.
Definition Track.h:831