DxLibEx
point3d.hpp
Go to the documentation of this file.
1 /*=============================================================================
2  Copyright (C) 2015-2017 DxLibEx project
3  https://github.com/Nagarei/DxLibEx/
4 
5  Distributed under the Boost Software License, Version 1.0.
6  (See http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #ifndef DXLE_INC_BASIC_TYPES_point3d3D_HPP_
9 #define DXLE_INC_BASIC_TYPES_point3d3D_HPP_
19 #include "dxlibex/math.hpp"
20 #include "dxlibex/cstdlib.hpp"
22 //#include "dxlibex/basic_types.hpp"//DO NOT REMOVE COMMENT-OUT to avoid redefine
23 #include <iostream>
24 #include <tuple>
25 #include <type_traits>
26 #include <algorithm>
27 #include <cmath>
28 #include <limits>
29 #include "dxlibex/config/defines.h"
30 
31 namespace dxle {
97  template<typename T, enable_if_t<std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value, nullptr_t> = nullptr>
98  class point3d_c final
99  {
100  public:
101  typedef T value_type;
102  value_type x, y, z;
103  DXLE_CONSTEXPR point3d_c() DXLE_NOEXCEPT_IF(std::is_nothrow_constructible<value_type>::value) : x(), y(), z() {}
104  DXLE_CONSTEXPR point3d_c(const value_type& x_, const value_type& y_, const value_type& z_) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : x(x_), y(y_), z(z_) {}
105  DXLE_CONSTEXPR point3d_c(value_type&& x_, value_type&& y_, value_type&& z_) DXLE_NOEXCEPT_OR_NOTHROW : x(std::move(x_)), y(std::move(y_)), z(std::move(z_)) {}
106 
107  //copy constructor
108  DXLE_CONSTEXPR point3d_c(const point3d_c<value_type>& o) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_constructible<value_type>::value)) : x(o.x), y(o.y), z(o.z) {}
109  //move constructor
110  DXLE_CONSTEXPR point3d_c(point3d_c<value_type>&& o) DXLE_NOEXCEPT_OR_NOTHROW : x(std::move(o.x)), y(std::move(o.y)), z(std::move(o.z)) {}
111  //copy assignment operator
112  point3d_c& operator=(const point3d_c<value_type>& r) DXLE_NOEXCEPT_IF((std::is_nothrow_copy_assignable<value_type>::value))
113  {
114  this->x = r.x;
115  this->y = r.y;
116  this->z = r.z;
117  return *this;
118  }
119  //move assignment operator
121  {
122  this->x = std::move(r.x);
123  this->y = std::move(r.y);
124  this->z = std::move(r.z);
125  return *this;
126  }
131  DXLE_CONSTEXPR explicit operator bool()
132  const DXLE_NOEXCEPT_IF_EXPR((dxle::detail::operator_bool_helper(std::declval<value_type>(), std::declval<value_type>(), std::declval<value_type>())))
133  {
134  return dxle::detail::operator_bool_helper(this->x, this->y, this->z);
135  }
138  template<typename Tp2_> DXLE_CONSTEXPR explicit operator point3d_c<Tp2_>() const DXLE_NOEXCEPT_OR_NOTHROW
139  {
140  return{ static_cast<Tp2_>(this->x), static_cast<Tp2_>(this->y), static_cast<Tp2_>(this->z) };
141  }
144  template<typename Tp2_> explicit operator std::tuple<Tp2_, Tp2_, Tp2_>() const DXLE_NOEXCEPT_IF_EXPR(static_cast<Tp2_>(std::declval<value_type>()))
145  {
146  return std::forward_as_tuple(static_cast<Tp2_>(this->x), static_cast<Tp2_>(this->y), static_cast<Tp2_>(this->z));
147  }
148  };
149  //convert from std::tuple
150 
160  template<typename T> point3d_c<T> make_point3d_c(const std::tuple<T, T, T>& p) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value)
161  {
162  return { std::get<0>(p), std::get<1>(p), std::get<2>(p) };
163  }
173  template<typename T> point3d_c<T> make_point3d_c(std::tuple<T, T, T>&& p) DXLE_NOEXCEPT_OR_NOTHROW
174  {
175  return point3d_c<T>(std::move(std::get<0>(p)), std::move(std::get<1>(p)), std::move(std::get<2>(p)));
176  }
177 
178  //ostream operator
179  namespace detail {
180  template<typename CharType, typename point3dType>
181  void ostream_operator_helper(std::basic_ostream<CharType>& os, const CharType* str, const point3d_c<point3dType>& p)
182  {
183  using use_big_type_when_one_byte_p = use_big_type_when_one_byte_t<point3dType>;
184  os << static_cast<use_big_type_when_one_byte_p>(p.x) << str << static_cast<use_big_type_when_one_byte_p>(p.y) << str << static_cast<use_big_type_when_one_byte_p>(p.z);
185  }
186  template<typename CharType, typename point3dType>
187  void istream_operator_helper(std::basic_istream<CharType>& is, point3d_c<point3dType>& p)
188  {
190  is >> x;
191  is.ignore((std::numeric_limits<std::streamsize>::max)(), dxle::char_constant::comma<CharType>());
192  is >> y;
193  is.ignore((std::numeric_limits<std::streamsize>::max)(), dxle::char_constant::comma<CharType>());
194  is >> z;
195  p.x = static_cast<point3dType>(x); p.y = static_cast<point3dType>(y); p.z = static_cast<point3dType>(z);
196  }
197  }
209  template<typename T> std::ostream& operator<<(std::ostream& os, const point3d_c<T>& p)
210  {
211  dxle::detail::ostream_operator_helper<char, T>(os, ", ", p);
212  return os;
213  }
225  template<typename T> std::wostream& operator<<(std::wostream& os, const point3d_c<T>& p)
226  {
227  dxle::detail::ostream_operator_helper<wchar_t, T>(os, L", ", p);
228  return os;
229  }
241  template<typename T> std::istream& operator>>(std::istream& is, point3d_c<T>& p)
242  {
243  dxle::detail::istream_operator_helper<char, T>(is, p);
244  return is;
245  }
257  template<typename T> std::wistream& operator>>(std::wistream& is, point3d_c<T>& p)
258  {
259  dxle::detail::istream_operator_helper<wchar_t, T>(is, p);
260  return is;
261  }
262 
272  template <typename T>
274  {
275  return { -r.x, -r.y, -r.z };
276  }
277 
287  template <typename T>
288  DXLE_CONSTEXPR inline const point3d_c<T>& operator +(const point3d_c<T>& r) DXLE_NOEXCEPT_IF(std::is_nothrow_copy_constructible<T>::value) { return r; }
289 
299  template <typename T>
301 
313  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
315  {
316  l.x += r.x;
317  l.y += r.y;
318  l.z += r.z;
319  return l;
320  }
321 
333  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
334  point3d_c<T1>& operator -=(point3d_c<T1>& l, const point3d_c<T2>& r) DXLE_NOEXCEPT_IF_EXPR(l.x -= r.x)
335  {
336  l.x -= r.x;
337  l.y -= r.y;
338  l.z -= r.z;
339  return l;
340  }
341 
353  template <typename T1, typename T2>
355  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() + std::declval<std::remove_cv_t<T2>>())>
356  {
357  return { l.x + r.x, l.y + r.y, l.z + r.z };
358  }
359 
371  template <typename T1, typename T2>
373  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() - std::declval<std::remove_cv_t<T2>>())>
374  {
375  return { l.x - r.x, l.y - r.y, l.z - r.z };
376  }
377 
389  template <typename T1, typename T2>
391  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
392  {
393  return { l.x * r, l.y * r, l.z * r };
394  }
395 
407  template <typename T1, typename T2>
409  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
410  {
411  return { l * r.x, l * r.y, l * r.z };
412  }
413 
425  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
427  {
428  l.x *= r;
429  l.y *= r;
430  l.z *= r;
431  return l;
432  }
433 
445  template <typename T1, typename T2>
447  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() - std::declval<std::remove_cv_t<T2>>())>
448  {
449  return { l.x / r, l.y / r, l.z / r};
450  }
451 
463  template <typename T1, typename T2, enable_if_t<is_representable<T2, T1>::value, nullptr_t> = nullptr>
465  {
466  l.x /= r;
467  l.y /= r;
468  l.z /= r;
469  return l;
470  }
471 
483  template <typename T>
484  DXLE_CONSTEXPR bool operator !=(const point3d_c<T>& l, const point3d_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l.x != r.x)
485  {
486  return (l.x != r.x) || (l.y != r.y) || (l.z != r.z);
487  }
488 
502  template <typename T>
503  DXLE_CONSTEXPR bool operator !=(const point3d_c<T>& p, nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
504  {
505  return !static_cast<bool>(p);
506  }
507 
521  template <typename T>
522  DXLE_CONSTEXPR bool operator !=(nullptr_t, const point3d_c<T>& p) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
523  {
524  return !static_cast<bool>(p);
525  }
526 
538  template <typename T, enable_if_t<std::is_arithmetic<T>::value, nullptr_t> = nullptr>
539  DXLE_CONSTEXPR bool operator ==(const point3d_c<T>& l, const point3d_c<T>& r) DXLE_NOEXCEPT_IF_EXPR(l.x != r.x) { return !(l != r); }
540 
554  template <typename T>
555  DXLE_CONSTEXPR bool operator ==(const point3d_c<T>& p, nullptr_t) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
556  {
557  return !static_cast<bool>(p);
558  }
559 
573  template <typename T>
574  DXLE_CONSTEXPR bool operator ==(nullptr_t, const point3d_c<T>& p) DXLE_NOEXCEPT_IF_EXPR(static_cast<bool>(p))
575  {
576  return !static_cast<bool>(p);
577  }
578 
592  template<typename T>
593  DXLE_CONSTEXPR point3d_c<T> abs(const point3d_c<T>& o) DXLE_NOEXCEPT_IF_EXPR(abs(o.x)) { return{ abs(o.x), abs(o.y), abs(o.z) }; }
594 
606  template<typename T1, typename T2>
607  DXLE_CONSTEXPR auto dot(const point3d_c<T1>& p1, const point3d_c<T2>& p2) DXLE_NOEXCEPT_IF_EXPR(p1.x * p2.x + p1.y * p2.y + p1.z * p2.z)
608  -> decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())
609  {
610  return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
611  }
612 
624  template<typename T1, typename T2>
625  DXLE_CONSTEXPR auto cross(const point3d_c<T1>& p1, const point3d_c<T2>& p2) DXLE_NOEXCEPT_IF_EXPR(std::declval<T1>() * std::declval<T2>() - std::declval<T1>() * std::declval<T2>())
626  ->point3d_c<decltype(std::declval<std::remove_cv_t<T1>>() * std::declval<std::remove_cv_t<T2>>())>
627  {
628  //a=(a1,a2,a3)、 b=(b1,b2,b3)としたとき、(a2b3-a3b2, a3b1-a1b3, a1b2-a2b1)
629  return { p1.y * p2.z - p1.z * p2.y, p1.z * p2.x - p1.x * p2.z, p1.x * p2.y - p1.y * p2.x };
630  }
631 
643  template<typename T1, typename T2>
645  DXLE_NOEXCEPT_IF_EXPR(hypot(safe_dist(std::declval<T1>(), std::declval<T2>()), safe_dist(std::declval<T1>(), std::declval<T2>())))
646  {
647  return hypot(safe_dist(p1.x, p2.x), hypot(safe_dist(p1.y, p2.y), safe_dist(p1.z, p2.z)));
648  }
654 };
655 #endif //DXLE_INC_BASIC_TYPES_point3d3D_HPP_
point3d_c< std::uint8_t > point3du8i
Definition: point3d.hpp:650
value_type y
Definition: point3d.hpp:102
void ostream_operator_helper(std::basic_ostream< CharType > &os, const CharType *str, const point3d_c< point3dType > &p)
Definition: point3d.hpp:181
DXLE_CONSTEXPR point3d_c(const point3d_c< value_type > &o) DXLE_NOEXCEPT_IF((std
Definition: point3d.hpp:108
#define DXLE_CONSTEXPR
Definition: suffix.hpp:21
DXLE_CONSTEXPR point3d_c(const value_type &x_, const value_type &y_, const value_type &z_) DXLE_NOEXCEPT_IF((std
Definition: point3d.hpp:104
point_c< T1 > T2 DXLE_CONSTEXPR auto dot(const point_c< T1 > &p1, const point_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR(p1.x *p2.x+p1.y *p2.y) -> decltype(std::declval< std::remove_cv_t< T1 >>() *std::declval< std::remove_cv_t< T2 >>())
Definition: point2d.hpp:622
DXLE_CONSTEXPR point3d_c() DXLE_NOEXCEPT_IF(std
Definition: point3d.hpp:103
point3d_c< double > point3dd
Definition: point3d.hpp:652
DXLE_CONSTEXPR const point3d_c< T > & operator+(const point3d_c< T > &r) DXLE_NOEXCEPT_IF(std
Overload of unary operator +.
Definition: point3d.hpp:288
DXLE_CONSTEXPR int abs(int j) DXLE_NOEXCEPT_OR_NOTHROW
Definition: abs.hpp:22
DXLE_CONSTEXPR bool operator_bool_helper(const T &first, const T &second) DXLE_NOEXCEPT_IF_EXPR(dxle
point_c< T1 > T2 DXLE_CONSTEXPR auto operator/(const point_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x/r) -> point_c< decltype(std::declval< std::remove_cv_t< T1 >>()/std::declval< std::remove_cv_t< T2 >>())>
Definition: point2d.hpp:464
point3d_c & operator=(point3d_c< value_type > &&r) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point3d.hpp:120
DXLE_CONSTEXPR auto cross(const point3d_c< T1 > &p1, const point3d_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR(std
Computes a cross-product of two point3d_c value as vectors.
Definition: point3d.hpp:625
typename use_big_type_when_one_byte< T >::type use_big_type_when_one_byte_t
for int8_t/uint8_t
DXLE_CONSTEXPR point3d_c(value_type &&x_, value_type &&y_, value_type &&z_) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point3d.hpp:105
distance_result_type_t< T1, T2 > distance(const point3d_c< T1 > &p1, const point3d_c< T2 > &p2) DXLE_NOEXCEPT_IF_EXPR(hypot(safe_dist(std
Calculate the distance of the two point3d_c class object based on the Pythagorean theorem(std::hypot)...
Definition: point3d.hpp:644
Definition: point2d.hpp:672
point3d_c< int > point3di
Definition: point3d.hpp:649
point_c< T1 > T2
Definition: point2d.hpp:353
Definition: cast_if.hpp:12
point3d_c & operator=(const point3d_c< value_type > &r) DXLE_NOEXCEPT_IF((std
Definition: point3d.hpp:112
point3d_c< T1 > & operator/=(point3d_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x/
Overload of binary operator /=.
value_type z
Definition: point3d.hpp:102
#define DXLE_NOEXCEPT_IF_EXPR(EXPR)
Definition: suffix.hpp:110
Template class for 3D points specified by its coordinates x and y.
Definition: point3d.hpp:98
DXLE_CONSTEXPR point3d_c< T > operator-(const point3d_c< T > &r) DXLE_NOEXCEPT_IF_EXPR(-std
Overload of unary operator -.
Definition: point3d.hpp:273
DXLE_CONSTEXPR auto safe_dist(const T1 &n1, const T2 &n2) DXLE_NOEXCEPT_IF_EXPR((n1 - n2)) -> decltype(n1 - n2)
Definition: safe_dist.hpp:14
DXLE_CONSTEXPR point3d_c(point3d_c< value_type > &&o) DXLE_NOEXCEPT_OR_NOTHROW
Definition: point3d.hpp:110
value_type x
Definition: point3d.hpp:102
void istream_operator_helper(std::basic_istream< CharType > &is, point3d_c< point3dType > &p)
Definition: point3d.hpp:187
point3d_c< T > make_point3d_c(const std::tuple< T, T, T > &p) DXLE_NOEXCEPT_IF(std
conversion from std::tuple
Definition: point3d.hpp:160
#define DXLE_NOEXCEPT_IF(COND)
Definition: suffix.hpp:107
point3d_c< T > make_point3d_c(std::tuple< T, T, T > &&p) DXLE_NOEXCEPT_OR_NOTHROW
conversion from std::tuple
Definition: point3d.hpp:173
point3d_c< float > point3df
Definition: point3d.hpp:653
#define DXLE_NOEXCEPT_OR_NOTHROW
Definition: suffix.hpp:94
DXLE_CONSTEXPR auto operator*(const point3d_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x *r) -> point3d_c< decltype(std::declval< std::remove_cv_t< T1 >>() *std::declval< std::remove_cv_t< T2 >>())>
Overload of binary operator *.
Definition: point3d.hpp:390
std::wistream & operator>>(std::wistream &is, point3d_c< T > &p)
istream operator
Definition: point3d.hpp:257
typename distance_result_type< T1, T2 >::type distance_result_type_t
std::istream & operator>>(std::istream &is, point3d_c< T > &p)
istream operator
Definition: point3d.hpp:241
point3d_c< T1 > & operator+=(point3d_c< T1 > &l, const point3d_c< T2 > &r) DXLE_NOEXCEPT_IF_EXPR(l.x+
Overload of binary operator +=.
point3d_c< std::int8_t > point3d8i
Definition: point3d.hpp:651
point3d_c< T1 > & operator*=(point3d_c< T1 > &l, T2 r) DXLE_NOEXCEPT_IF_EXPR(l.x *
Overload of binary operator *=.