/
spivag
/
command_occ
Обзор
Документация
Войти
/
spivag
/
command_occ
Код
Запросы
1
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
initial
commands/geometry_types.cpp
1 064 строки
25 KB
spivag
Запрос на слияние 'c3d_sdk_removal' (
#2
) из c3d_sdk_removal в initial
16 апр 2026, 15:34
Верифицирован
16 апр 2026, 15:34
e04e876
Код
Авторство
О чём код?
// geometry_types.cpp #include "geometry_types.h" #include <cmath> #include <limits> #define M_PI 3.141592653589793238462643383279502884 R1::Angle::Angle() { } R1::Angle::Angle( double angle ) : m_angle{ angle } { } double R1::Angle::Epsilon() { return 1e-9; } R1::Angle::Degrees::Degrees() { } R1::Angle::Degrees::Degrees( double degrees ) : m_degrees{ degrees } { } R1::Angle::Angle( Degrees degrees ) : m_angle{ degrees.m_degrees * M_PI / 180. } { } R1::Distance::Distance( double distance ) : m_distance{ distance } { } bool R1::Distance::IsValid() const { return !std::isnan( m_distance ) && m_distance >= 0.; } void R1::Distance::SetValid() { if ( !IsValid() ) { if ( !std::isnan( m_distance ) ) m_distance = ::fabs( m_distance ); } } double R1::Distance::Epsilon() { return 1e-7; } R1::Angle02pi::Angle02pi( double angle ) : m_angle{ angle } { } R1::Angle02pi::Angle02pi( R1::Angle::Degrees degrees ) : m_angle{ degrees } { } bool R1::Angle02pi::IsValid() const { return m_angle.m_angle >= 0. && m_angle.m_angle <= 2. * M_PI; } static void FinInto2Pi( double& angle ) { while ( angle < -M_PI ) { angle += 2. * M_PI; } while ( angle > M_PI ) { angle -= 2. * M_PI; } } void R1::Angle02pi::SetValid() { ::FinInto2Pi( m_angle.m_angle ); } R1::AngleModPi::AngleModPi( double angle ) : m_angle{ angle } { } R1::AngleModPi::AngleModPi( R1::Angle::Degrees degrees ) : m_angle{ degrees } { } bool R1::AngleModPi::IsValid() const { return m_angle.m_angle >= -M_PI && m_angle.m_angle <= M_PI; } void R1::AngleModPi::SetValid() { ::FinInto2Pi( m_angle.m_angle ); } R1::Angle0Pi2::Angle0Pi2( R1::Angle::Degrees degrees ) : m_angle{ degrees } { } R1::Angle0Pi2::Angle0Pi2( double angle ) : m_angle{ angle } { } bool R1::Angle0Pi2::IsValid() const { return m_angle.m_angle >= 0. && m_angle.m_angle <= M_PI * 0.5; } bool R1::Angle0Pi2::SetValid() { double tmpAngle = m_angle.m_angle; ::FinInto2Pi( tmpAngle ); const bool result = ( tmpAngle <= M_PI * 0.5 ) && ( tmpAngle >= 0. ); if ( result ) { m_angle.m_angle = tmpAngle; } return result; } R1::AngleModPi2::AngleModPi2( R1::Angle::Degrees degrees ) : m_angle{ degrees } { } R1::AngleModPi2::AngleModPi2( double angle ) : m_angle{ angle } { } bool R1::AngleModPi2::IsValid() const { return m_angle.m_angle >= -M_PI * 0.5 && m_angle.m_angle <= M_PI * 0.5; } bool R1::AngleModPi2::SetValid() { double tmpAngle = m_angle.m_angle; ::FinInto2Pi( tmpAngle ); const bool result = ( tmpAngle <= M_PI * 0.5 ) && ( tmpAngle >= -0.5 * M_PI ); if ( result ) { m_angle.m_angle = tmpAngle; } return result; } R1::Angle0Pi::Angle0Pi( R1::Angle::Degrees degrees ) : m_angle{ degrees } { } R1::Angle0Pi::Angle0Pi( double angle ) : m_angle{ angle } { } bool R1::Angle0Pi::IsValid() const { return ( m_angle.m_angle >= 0. ) && ( m_angle.m_angle <= M_PI ); } bool R1::Angle0Pi::SetValid() { double tmpAngle = m_angle.m_angle; ::FinInto2Pi( tmpAngle ); const bool result{ ( tmpAngle >= 0. ) && ( tmpAngle <= M_PI ) }; if ( result ) { m_angle.m_angle = tmpAngle; } return result; } R1::Range::Range() : m_min( 1. ) , m_max( -1. ) { } R1::Range::Range( double initialValue ) : m_min{ initialValue } , m_max{ initialValue } { } R1::Range::Range( double oneValue, double otherValue ) : m_min( std::min( oneValue, otherValue ) ) , m_max( std::max( oneValue, otherValue ) ) { if ( IsEmpty() ) SetEmpty(); } R1::Range R1::Range::Infinite() { return Range{ std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max() }; } bool R1::Range::Contains( double value ) const { return value >= m_min && value <= m_max; } bool R1::Range::IsEmpty() const { return m_min > m_max; } double R1::Range::Upper() const { return m_max; } double R1::Range::Lower() const { return m_min; } double R1::Range::Width() const { return m_max - m_min; } void R1::Range::Append( double value ) { if ( IsEmpty() ) { m_min = m_max = value; } else { m_min = std::min( m_min, value ); m_max = std::max( m_max, value ); } } void R1::Range::SetEmpty() { m_min = 1.; m_max = -1.; } Interposition R1::Range::InterpositionWith( const Range& other ) const { if ( IsEmpty() || other.IsEmpty() ) return Interposition::notAppliable; if ( m_min == other.m_min && m_max == other.m_max ) return Interposition::same; if ( m_min >= other.m_min && m_max <= other.m_max ) return Interposition::included; if ( m_min <= other.m_min && m_max >= other.m_max ) return Interposition::contains; if ( ( Contains( other.m_min ) && !Contains( other.m_max ) ) || ( Contains( other.m_max ) && !Contains( other.m_min ) ) ) return Interposition::intersected; return Interposition::isolated; } R1::ForwardDistance::ForwardDistance( double distance ) : m_distance{ distance } { } bool R1::ForwardDistance::IsValid() const { return m_distance.IsValid(); } void R1::ForwardDistance::SetValid() { m_distance.SetValid(); } R1::BackwardDistance::BackwardDistance( double distance ) : m_distance{ distance } { } bool R1::BackwardDistance::IsValid() const { return m_distance.IsValid(); } void R1::BackwardDistance::SetValid() { m_distance.SetValid(); } R2::Point::Point( double x, double y ) : m_xy{ x, y } { } R2::Point::Point( R2::Point::Polar const& polarValues ) { auto distance = polarValues.m_radius; distance.SetValid(); auto angle = polarValues.m_angle; angle.SetValid(); m_xy = { distance.m_distance * cos( angle.m_angle.m_angle ), distance.m_distance * sin( angle.m_angle.m_angle ) }; } double R2::Point::x() const { return m_xy[0]; } double R2::Point::y() const { return m_xy[1]; } constexpr size_t R2::Point::size() { return 2; } double R2::Point::operator[]( size_t index ) const { return m_xy.at( index ); } R2::Point R2::Point::operator+( R2::Vector const& to ) const { return R2::Point{ x() + to.x(), y() + to.y() }; } void R2::Point::operator+=( R2::Vector const& to ) { for ( size_t i = 0; i < R2::Point::size(); ++i ) m_xy[i] += to[i]; } void R2::Point::RotateCcw( R2::Point const& rotationCenter, R1::Angle angle ) { R2::Vector vecRotate{ R2::StartPoint{ rotationCenter }, R2::EndPoint{ *this } }; vecRotate.RotateCcw( angle ); *this = rotationCenter + vecRotate; } R2::StartPoint::StartPoint( double x, double y ) : m_point( x, y ) { } R2::StartPoint::StartPoint( Point const& point ) : m_point( point ) { } R2::StartPoint::StartPoint( R2::Point::Polar const& polarValues ) : m_point( polarValues ) { } R2::EndPoint::EndPoint( double x, double y ) : m_point( x, y ) { } R2::EndPoint::EndPoint( Point const& point ) : m_point( point ) { } R2::EndPoint::EndPoint( R2::Point::Polar const& polarValues ) : m_point( polarValues ) { } R2::AnyMidPoint::AnyMidPoint( double x, double y ) : m_point{ x, y } { } R2::AnyMidPoint::AnyMidPoint( Point const& point ) : m_point{ point } { } R2::AnyMidPoint::AnyMidPoint( R2::Point::Polar const& polarValues ) : m_point{ polarValues } { } R2::Vector::Vector( double x, double y ) : m_xy( { x, y } ) { } R2::Vector::Vector( R2::Point::Polar const& polarValues ) { auto distance = polarValues.m_radius; distance.SetValid(); auto angle = polarValues.m_angle; angle.SetValid(); m_xy = { distance.m_distance * cos( angle.m_angle.m_angle ), distance.m_distance * sin( angle.m_angle.m_angle ) }; } R2::Vector::Vector( R1::Angle const& angle ) : m_xy( { cos( angle.m_angle ), sin( angle.m_angle ) } ) { } R2::Vector::Vector( StartPoint const& startPoint, EndPoint const& endPoint ) : m_xy( { endPoint.m_point.x() - startPoint.m_point.x(), endPoint.m_point.y() - startPoint.m_point.y() } ) { } R2::Vector::Vector( R2::EndPoint const& endPoint, R2::StartPoint const& startPoint ) : m_xy( { endPoint.m_point.x() - startPoint.m_point.x(), endPoint.m_point.y() - startPoint.m_point.y() } ) { } double R2::Vector::x() const { return m_xy[0]; } double R2::Vector::y() const { return m_xy[1]; } double R2::Vector::operator[]( size_t i ) const { return m_xy.at( i ); } constexpr size_t R2::Vector::size() { return 2; } R2::Vector R2::Vector::ox() { return R2::Vector( 1, 0 ); } R2::Vector R2::Vector::oy() { return R2::Vector( 0, 1 ); } double R2::Vector::LengthSquare() const { return m_xy[0] * m_xy[0] + m_xy[1] * m_xy[1]; } double R2::Vector::Length() const { return sqrt( LengthSquare() ); } R2::Vector R2::Vector::operator+( R2::Vector const& with ) const { R2::Vector result{ *this }; for ( size_t i = 0; i < Vector::size(); ++i ) result.m_xy[i] += with[i]; return result; } void R2::Vector::operator+=( R2::Vector const& with ) { for ( size_t i = 0; i < Vector::size(); ++i ) m_xy[i] += with[i]; } void R2::Vector::RotateCcw( R1::Angle angle ) { const double cosA = cos( angle.m_angle ); const double sinA = sin( angle.m_angle ); const double prevX = m_xy[0]; const double& prevY = m_xy[1]; m_xy[0] = prevX * cosA - m_xy[1] * sinA; m_xy[1] = prevX * sinA + m_xy[1] * cosA; } R2::Placement::Placement() : m_origin{} , m_ox{ R2::Vector::ox() } { } R2::Placement::Placement( R2::Point const& origin ) : m_origin( origin ) , m_ox( R2::Vector::ox() ) { } R2::Placement::Placement( R2::Point const& origin, R1::Angle rotation ) : m_origin( origin ) , m_ox{ R1::Angle{ rotation } } { } R2::Placement R2::Placement::World() { return Placement{}; } R2::Point R2::Placement::Origin() const { return m_origin; } R2::Vector R2::Placement::Axis() const { return m_ox; } void R2::Placement::operator+=( R2::Vector to ) { m_origin += to; } void R2::Placement::RotateCcw( R2::Point rotationCenter, R1::Angle angle ) { m_origin.RotateCcw( rotationCenter, angle ); m_ox.RotateCcw( angle ); } R2::Gabarit::Gabarit( R2::Point const& initial ) : m_ranges{ { R1::Range( initial.x() ), R1::Range( initial.y() ) } } { } R2::Gabarit::Gabarit( R2::Point const& onePoint, R2::Point const& otherPoint ) : m_ranges{ { R1::Range( onePoint.x(), otherPoint.x() ), R1::Range( onePoint.y(), otherPoint.y() ) } } { } bool R2::Gabarit::PointIn( R2::Point const& point ) const { return m_ranges[0].Contains( point.x() ) && m_ranges[1].Contains( point.y() ); } bool R2::Gabarit::IsEmpty() const { return m_ranges[0].IsEmpty() || m_ranges[1].IsEmpty(); } static bool OneOf( Interposition value, Interposition oneValue, Interposition otherValue ) { return ( value == oneValue ) || ( value == otherValue ); } Interposition R2::Gabarit::InterpositionWith( Gabarit const& other ) const { const auto rangeXInt = m_ranges[0].InterpositionWith( other.m_ranges[0] ); const auto rangeYInt = m_ranges[1].InterpositionWith( other.m_ranges[1] ); if ( rangeXInt == Interposition::notAppliable || rangeYInt == Interposition::notAppliable ) return Interposition::notAppliable; if ( ( rangeXInt == Interposition::isolated ) || ( rangeYInt == Interposition::isolated ) ) return Interposition::isolated; if ( ( rangeXInt == Interposition::same ) && ( rangeYInt == Interposition::same ) ) return Interposition::same; if ( ( ::OneOf( rangeXInt, Interposition::contains, Interposition::same ) ) && ( ::OneOf( rangeYInt, Interposition::contains, Interposition::same ) ) ) return Interposition::contains; if ( ( ::OneOf( rangeXInt, Interposition::included, Interposition::same ) ) && ( ::OneOf( rangeYInt, Interposition::included, Interposition::same ) ) ) return Interposition::included; return Interposition::intersected; } void R2::Gabarit::SetEmpty() { for ( auto& range : m_ranges ) range.SetEmpty(); } void R2::Gabarit::Append( Point const& point ) { m_ranges[0].Append( point.x() ); m_ranges[1].Append( point.y() ); } R2::Transform::Transform() : m_origin{} , m_ox{ R2::Vector::ox() } , m_oy{ R2::Vector::oy() } { } R2::Transform::Transform( R2::Point const& origin ) : m_origin{ origin } , m_ox{ R2::Vector::ox() } , m_oy{ R2::Vector::oy() } { } R2::Transform::Transform( R2::Point const& origin, R2::Vector const& ox, R2::Vector const& oy ) : m_origin{ origin } , m_ox{ ox } , m_oy{ oy } { } R2::Transform R2::Transform::World() { return R2::Transform{}; } R2::Transform R2::Transform::operator*( R2::Transform const& other ) const { // Применение двух последовательных преобразований // Если this = T1 и other = T2, результат эквивалентен применению сначала T2, затем T1. // Используем методы Apply для трансформирования компонентов other через this return R2::Transform{ Apply( other.m_origin ), // Трансформируем начало координат Apply( other.m_ox ), // Трансформируем первый базисный вектор Apply( other.m_oy ) // Трансформируем второй базисный вектор }; } R2::Point R2::Transform::Apply( R2::Point const& point ) const { // Преобразуем точку из локальной системы в базовую: // P_base = origin + ox * x_local + oy * y_local return m_origin + R2::Vector{ m_ox.x() * point.x() + m_oy.x() * point.y(), m_ox.y() * point.x() + m_oy.y() * point.y() }; } R2::Vector R2::Transform::Apply( R2::Vector const& r2ver ) const { // Преобразуем вектор (без учёта смещения начала координат): // V_base = ox * x_local + oy * y_local return R2::Vector{ m_ox.x() * r2ver.x() + m_oy.x() * r2ver.y(), m_ox.y() * r2ver.x() + m_oy.y() * r2ver.y() }; } R3::Point::Point() { } R3::Point::Point( double x, double y, double z ) : m_xyz{ x, y, z } { } R3::Point::Point( R3::Point::Cylindrical const& cylindricalValues ) : m_xyz{ cylindricalValues.m_radius.m_distance * cos( cylindricalValues.m_angle.m_angle ), cylindricalValues.m_radius.m_distance * sin( cylindricalValues.m_angle.m_angle ), cylindricalValues.m_z } { } R3::Point::Point( R3::Point::Polar const& polarValues ) : m_xyz{ polarValues.m_radius.m_distance * cos( polarValues.m_south_north.m_angle.m_angle ) * cos( polarValues.m_east_west.m_angle ), polarValues.m_radius.m_distance * cos( polarValues.m_south_north.m_angle.m_angle ) * sin( polarValues.m_east_west.m_angle ), polarValues.m_radius.m_distance * sin( polarValues.m_south_north.m_angle.m_angle ) } { } double R3::Point::x() const { return m_xyz[0]; } double R3::Point::y() const { return m_xyz[1]; } double R3::Point::z() const { return m_xyz[2]; } constexpr size_t R3::Point::size() { return 3; } double R3::Point::operator[]( size_t index ) const { return m_xyz[index]; } R3::Point R3::Point::operator+( R3::Vector const& to ) const { return R3::Point{ x() + to.x(), y() + to.y(), z() + to.z() }; } void R3::Point::operator+=( R3::Vector const& to ) { for ( size_t i = 0; i < R2::Point::size(); ++i ) m_xyz[i] += to[i]; } R3::StartPoint::StartPoint( double x, double y, double z ) : m_point{ x, y, z } { } R3::StartPoint::StartPoint( Point const& point ) : m_point{ point } { } R3::EndPoint::EndPoint( double x, double y, double z ) : m_point{ x, y, z } { } R3::EndPoint::EndPoint( Point const& point ) : m_point{ point } { } R3::AnyMidPoint::AnyMidPoint( double x, double y, double z ) : m_point{ x, y, z } { } R3::AnyMidPoint::AnyMidPoint( Point const& point ) : m_point{ point } { } R3::Vector::Vector( double x, double y, double z ) : m_xyz( { x, y, z } ) { } R3::Vector::Vector( R3::Point const& point ) : m_xyz( { point.x(), point.y(), point.z() } ) { } R3::Vector::Vector( R1::Angle const& theta, R1::AngleModPi const& phi ) : m_xyz{ { cos( theta.m_angle ) * sin( phi.m_angle.m_angle ), sin( theta.m_angle ) * sin( phi.m_angle.m_angle ), cos( phi.m_angle.m_angle ) } } { } R3::Vector::Vector( R3::StartPoint const& startPoint, R3::EndPoint const& endPoint ) : m_xyz( { endPoint.m_point.x() - startPoint.m_point.x(), endPoint.m_point.y() - startPoint.m_point.y(), endPoint.m_point.z() - startPoint.m_point.z() } ) { } R3::Vector::Vector( R3::EndPoint const& startPoint, R3::StartPoint const& endPoint ) : m_xyz( { endPoint.m_point.x() - startPoint.m_point.x(), endPoint.m_point.y() - startPoint.m_point.y(), endPoint.m_point.z() - startPoint.m_point.z() } ) { } double R3::Vector::x() const { return m_xyz[0]; } double R3::Vector::y() const { return m_xyz[1]; } double R3::Vector::z() const { return m_xyz[2]; } void R3::Vector::operator+=( R3::Vector const& to ) { for ( size_t i = 0; i < size(); ++i ) m_xyz[i] += to[i]; } R3::Vector R3::Vector::operator+( R3::Vector const& to ) const { R3::Vector result{ *this }; result += to; return result; } double R3::Vector::LengthSquare() const { return m_xyz[0] * m_xyz[0] + m_xyz[1] * m_xyz[1] + m_xyz[2] * m_xyz[2]; } double R3::Vector::Length() const { return sqrt( LengthSquare() ); } double R3::Vector::operator[]( size_t index ) const { return m_xyz.at( index ); } constexpr size_t R3::Vector::size() { return 3; } R3::Vector R3::Vector::ox() { return Vector( 1, 0, 0 ); } R3::Vector R3::Vector::oy() { return Vector( 0, 1, 0 ); } R3::Vector R3::Vector::oz() { return Vector( 0, 0, 1 ); } R3::Axis::Axis( R3::Point const& origin, R3::Vector const& direction ) : m_origin( origin ) , m_direction( direction ) { } bool R3::Axis::AreParametersValid() const { return m_direction.LengthSquare() > R1::Distance::Epsilon() * R1::Distance::Epsilon(); } R3::Placement::Placement() : m_origin{} , m_ox{ R3::Vector::ox() } , m_oy{ R3::Vector::oy() } { } R3::Placement::Placement( Point const& origin ) : m_origin( origin ) , m_ox{ R3::Vector::ox() } , m_oy{ R3::Vector::oy() } { } static void RotateWorldOx( R3::Vector& baseVector, R1::Angle const& angle ) { const double cosAngle = cos( angle.m_angle ); const double sinAngle = sin( angle.m_angle ); baseVector = R3::Vector{ baseVector.x(), baseVector.y() * cosAngle + baseVector.z() * sinAngle, -baseVector.y() * sinAngle + baseVector.z() * cosAngle }; } static void RotateWorldOy( R3::Vector& baseVector, R1::Angle const& angle ) { const double cosAngle = cos( angle.m_angle ); const double sinAngle = sin( angle.m_angle ); baseVector = R3::Vector{ baseVector.x() * cosAngle + baseVector.z() * sinAngle, baseVector.y(), baseVector.x() * sinAngle + baseVector.z() * cosAngle }; } static void RotateWorldOz( R3::Vector& baseVector, R1::Angle const& angle ) { const double cosAngle = cos( angle.m_angle ); const double sinAngle = sin( angle.m_angle ); baseVector = R3::Vector{ baseVector.x() * cosAngle + baseVector.y() * sinAngle, -baseVector.x() * sinAngle + baseVector.y() * cosAngle, baseVector.z() }; } R3::Placement::Placement( Point const& origin, R1::Angle rotateLocalOx, R1::Angle rotateWorldPolarEastWest, R1::AngleModPi rotateWorldPolarSouthNorth ) : m_origin( origin ) , m_ox{ R3::Vector::ox() } , m_oy{ R3::Vector::oy() } { ::RotateWorldOx( m_ox, rotateLocalOx ); ::RotateWorldOx( m_oy, rotateLocalOx ); ::RotateWorldOy( m_ox, rotateWorldPolarSouthNorth.m_angle ); ::RotateWorldOy( m_oy, rotateWorldPolarSouthNorth.m_angle ); ::RotateWorldOz( m_ox, rotateWorldPolarEastWest ); ::RotateWorldOz( m_oy, rotateWorldPolarEastWest ); } R3::Placement R3::Placement::World() { return R3::Placement( R3::Point() ); } R3::Transform::Transform() : m_origin{} , m_ox{ R3::Vector::ox() } , m_oy{ R3::Vector::oy() } , m_oz{ R3::Vector::oz() } { } R3::Transform::Transform( Point const& origin ) : m_origin{ origin } , m_ox{ R3::Vector::ox() } , m_oy{ R3::Vector::oy() } , m_oz{ R3::Vector::oz() } { } R3::Transform::Transform( Point const& origin, Vector const& ox, Vector const& oy, Vector const& oz ) : m_origin{ origin } , m_ox{ ox } , m_oy{ oy } , m_oz{ oz } { } R3::Transform R3::Transform::World() { return R3::Transform{}; } R3::Transform R3::Transform::operator*( R3::Transform const& other ) const { // Применение двух последовательных преобразований // Если this = T1 и other = T2, результат эквивалентен применению сначала T2, затем T1. // Используем методы Apply для трансформирования компонентов other через this return R3::Transform{ Apply( other.m_origin ), // Трансформируем начало координат Apply( other.m_ox ), // Трансформируем первый базисный вектор Apply( other.m_oy ), // Трансформируем второй базисный вектор Apply( other.m_oz ) // Трансформируем третий базисный вектор }; } R3::Point R3::Transform::Apply( R3::Point const& point ) const { // Преобразуем точку из локальной системы в базовую: // P_base = origin + ox * x_local + oy * y_local + oz * z_local return m_origin + R3::Vector{ m_ox.x() * point.x() + m_oy.x() * point.y() + m_oz.x() * point.z(), m_ox.y() * point.x() + m_oy.y() * point.y() + m_oz.y() * point.z(), m_ox.z() * point.x() + m_oy.z() * point.y() + m_oz.z() * point.z() }; } R3::Vector R3::Transform::Apply( R3::Vector const& r3ver ) const { // Преобразуем вектор (без учёта смещения начала координат): // V_base = ox * x_local + oy * y_local + oz * z_local return R3::Vector{ m_ox.x() * r3ver.x() + m_oy.x() * r3ver.y() + m_oz.x() * r3ver.z(), m_ox.y() * r3ver.x() + m_oy.y() * r3ver.y() + m_oz.y() * r3ver.z(), m_ox.z() * r3ver.x() + m_oy.z() * r3ver.y() + m_oz.z() * r3ver.z() }; } R3::Gabarit::Gabarit( Point const& point ) : m_ranges{ { R1::Range( point.x() ), R1::Range( point.y() ), R1::Range( point.z() ) } } { } R3::Gabarit::Gabarit( Point const& onePoint, Point const& otherPoint ) : m_ranges{ { R1::Range( onePoint.x(), otherPoint.x() ), R1::Range( onePoint.y(), otherPoint.y() ), R1::Range( onePoint.z(), otherPoint.z() ) } } { } bool R3::Gabarit::PoinIn( Point const& point ) const { return m_ranges[0].Contains( point.x() ) && m_ranges[1].Contains( point.y() ) && m_ranges[2].Contains( point.z() ); } bool R3::Gabarit::IsEmpty() const { return m_ranges[0].IsEmpty() || m_ranges[1].IsEmpty() || m_ranges[2].IsEmpty(); } R3::Point R3::Gabarit::Lowers() const { return R3::Point{ m_ranges[0].Lower(), m_ranges[1].Lower(), m_ranges[2].Lower() }; } R3::Point R3::Gabarit::Uppers() const { return R3::Point{ m_ranges[0].Upper(), m_ranges[1].Upper(), m_ranges[2].Upper() }; } double R3::Gabarit::SizeX() const { return m_ranges[0].Width(); } double R3::Gabarit::SizeY() const { return m_ranges[1].Width(); } double R3::Gabarit::SizeZ() const { return m_ranges[2].Width(); } Interposition R3::Gabarit::InterpositionWith( R3::Gabarit const& other ) const { const auto rangeXInt = m_ranges[0].InterpositionWith( other.m_ranges[0] ); const auto rangeYInt = m_ranges[1].InterpositionWith( other.m_ranges[1] ); const auto rangeZInt = m_ranges[2].InterpositionWith( other.m_ranges[2] ); if ( rangeXInt == Interposition::notAppliable || rangeYInt == Interposition::notAppliable || rangeZInt == Interposition::notAppliable ) return Interposition::notAppliable; if ( ( rangeXInt == Interposition::isolated ) || ( rangeYInt == Interposition::isolated ) || ( rangeZInt == Interposition::isolated ) ) return Interposition::isolated; if ( ( rangeXInt == Interposition::same ) && ( rangeYInt == Interposition::same ) || ( rangeZInt == Interposition::same ) ) return Interposition::same; if ( ( ::OneOf( rangeXInt, Interposition::contains, Interposition::same ) ) && ( ::OneOf( rangeYInt, Interposition::contains, Interposition::same ) ) && ( ::OneOf( rangeZInt, Interposition::contains, Interposition::same ) ) ) return Interposition::contains; if ( ( ::OneOf( rangeXInt, Interposition::included, Interposition::same ) ) && ( ::OneOf( rangeYInt, Interposition::included, Interposition::same ) ) && ( ::OneOf( rangeZInt, Interposition::included, Interposition::same ) ) ) return Interposition::included; return Interposition::intersected; } void R3::Gabarit::SetEmpty() { for ( auto& range : m_ranges ) range.SetEmpty(); } void R3::Gabarit::Append( R3::Point const& point ) { m_ranges[0].Append( point.x() ); m_ranges[1].Append( point.y() ); m_ranges[2].Append( point.z() ); }