Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotation of 3 points in 3D implemented and covered by tests. #35

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 88 additions & 11 deletions include/cg/operations/orientation.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace cg

struct orientation_d
{
boost::optional<orientation_t> operator() (point_2 const & a, point_2 const & b, point_2 const & c) const
boost::optional<orientation_t> operator()(point_2 const &a, point_2 const &b, point_2 const &c) const
{
double l = (b.x - a.x) * (c.y - a.y);
double r = (b.y - a.y) * (c.x - a.x);
Expand All @@ -45,13 +45,13 @@ namespace cg

struct orientation_i
{
boost::optional<orientation_t> operator() (point_2 const & a, point_2 const & b, point_2 const & c) const
boost::optional<orientation_t> operator()(point_2 const &a, point_2 const &b, point_2 const &c) const
{
typedef boost::numeric::interval_lib::unprotect<boost::numeric::interval<double> >::type interval;

boost::numeric::interval<double>::traits_type::rounding _;
interval res = (interval(b.x) - a.x) * (interval(c.y) - a.y)
- (interval(b.y) - a.y) * (interval(c.x) - a.x);
interval res = (interval(b.x) - a.x) * (interval(c.y) - a.y)
- (interval(b.y) - a.y) * (interval(c.x) - a.x);

if (res.lower() > 0)
return CG_LEFT;
Expand All @@ -68,10 +68,10 @@ namespace cg

struct orientation_r
{
boost::optional<orientation_t> operator() (point_2 const & a, point_2 const & b, point_2 const & c) const
boost::optional<orientation_t> operator()(point_2 const &a, point_2 const &b, point_2 const &c) const
{
mpq_class res = (mpq_class(b.x) - a.x) * (mpq_class(c.y) - a.y)
- (mpq_class(b.y) - a.y) * (mpq_class(c.x) - a.x);
mpq_class res = (mpq_class(b.x) - a.x) * (mpq_class(c.y) - a.y)
- (mpq_class(b.y) - a.y) * (mpq_class(c.x) - a.x);

int cres = cmp(res, 0);

Expand All @@ -85,7 +85,7 @@ namespace cg
}
};

inline orientation_t orientation(point_2 const & a, point_2 const & b, point_2 const & c)
inline orientation_t orientation(point_2 const &a, point_2 const &b, point_2 const &c)
{
if (boost::optional<orientation_t> v = orientation_d()(a, b, c))
return *v;
Expand All @@ -96,7 +96,7 @@ namespace cg
return *orientation_r()(a, b, c);
}

inline bool counterclockwise(contour_2 const & c)
inline bool counterclockwise(contour_2 const &c)
{
if (c.size() < 3) return true;

Expand All @@ -113,9 +113,86 @@ namespace cg
return orientation(prev, min_point, next) == CG_LEFT;
}

template <class Scalar>
bool collinear_are_ordered_along_line(point_2t<Scalar> const & a, point_2t<Scalar> const & b, point_2t<Scalar> const & c)
template<class Scalar>
bool collinear_are_ordered_along_line(point_2t<Scalar> const &a, point_2t<Scalar> const &b, point_2t<Scalar> const &c)
{
return (a <= b && b <= c) || (c <= b && b <= a);
}

struct orientation_3d_vectors_d
{
boost::optional<orientation_t> operator()(point_3 const &a, point_3 const &b, point_3 const &c) const
{
double x23 = a.x * (b.y * c.z - b.z * c.y);
double y13 = a.y * (b.x * c.z - b.z * c.x);
double z12 = a.z * (b.x * c.y - b.y * c.x);
double eps = (fabs(x23) + fabs(y13) + fabs(z12)) * 8 * std::numeric_limits<double>::epsilon();

double res = x23 - y13 + z12;

if (res > eps)
return CG_RIGHT;

if (res < -eps)
return CG_LEFT;

return boost::none;
}
};

struct orientation_3d_vectors_i
{
boost::optional<orientation_t> operator()(point_3 const &a, point_3 const &b, point_3 const &c) const
{
typedef boost::numeric::interval_lib::unprotect<boost::numeric::interval<double> >::type interval;

boost::numeric::interval<double>::traits_type::rounding _;
interval res = (interval(b.y) * c.z - interval(b.z) * c.y) * a.x
- (interval(b.x) * c.z - interval(b.z) * c.x) * a.y
+ (interval(b.x) * c.y - interval(b.y) * c.x) * a.z;

if (res.lower() > 0)
return CG_RIGHT;

if (res.upper() < 0)
return CG_LEFT;

if (res.upper() == res.lower())
return CG_COLLINEAR;

return boost::none;
}
};

struct orientation_3d_vectors_r
{
boost::optional<orientation_t> operator()(point_3 const &a, point_3 const &b, point_3 const &c) const
{
mpq_class res = (mpq_class(b.y) * c.z - mpq_class(b.z) * c.y) * a.x
- (mpq_class(b.x) * c.z - mpq_class(b.z) * c.x) * a.y
+ (mpq_class(b.x) * c.y - mpq_class(b.y) * c.x) * a.z;

int cres = cmp(res, 0);

if (cres > 0)
return CG_RIGHT;

if (cres < 0)
return CG_LEFT;

return CG_COLLINEAR;
}
};

inline orientation_t orientation_3d_vectors(point_3 const &a, point_3 const &b, point_3 const &c)
{
// if (boost::optional<orientation_t> v = orientation_3d_vectors_d()(a, b, c))
// return *v;

if (boost::optional<orientation_t> v = orientation_3d_vectors_i()(a, b, c))
return *v;

return *orientation_3d_vectors_r()(a, b, c);
}

}
129 changes: 96 additions & 33 deletions include/cg/primitives/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,94 +4,157 @@

namespace cg
{
template <class Scalar> struct point_2t;
template<class Scalar>
struct point_2t;

typedef point_2t<double> point_2;
typedef point_2t<float> point_2f;
typedef point_2t<int> point_2i;
typedef point_2t<double> point_2;
typedef point_2t<float> point_2f;
typedef point_2t<int> point_2i;

template <class Scalar>
template<class Scalar>
struct point_2t
{
Scalar x, y;

point_2t(Scalar x, Scalar y)
: x(x)
, y(y)
{}
: x(x), y(y)
{
}

template <class UScalar>
point_2t(point_2t<UScalar> const & o)
: x(o.x)
, y(o.y)
{}
template<class UScalar>
point_2t(point_2t<UScalar> const &o)
: x(o.x), y(o.y)
{
}

point_2t()
: x(0)
, y(0)
{}
: x(0), y(0)
{
}

point_2t<Scalar> & operator += (vector_2t<Scalar> const & delta)
point_2t<Scalar> &operator+=(vector_2t<Scalar> const &delta)
{
x += delta.x;
y += delta.y;
return *this;
}
};

template <class Scalar>
inline bool operator < (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
inline bool operator<(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
if (a.x == b.x)
return a.y < b.y;
else
return a.x < b.x;
}

template <class Scalar>
bool operator > (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
bool operator>(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return b < a;
}

template <class Scalar>
bool operator == (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
bool operator==(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return (a.x == b.x) && (a.y == b.y);
}

template <class Scalar>
bool operator <= (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
bool operator<=(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return !(a > b);
}

template <class Scalar>
bool operator >= (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
bool operator>=(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return !(a < b);
}


template <class Scalar>
bool operator != (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
bool operator!=(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return !(a == b);
}

// в этом месте возможно переполнение!
template <class Scalar>
vector_2t<Scalar> const operator - (point_2t<Scalar> const & a, point_2t<Scalar> const & b)
template<class Scalar>
vector_2t<Scalar> const operator-(point_2t<Scalar> const &a, point_2t<Scalar> const &b)
{
return vector_2t<Scalar>(a.x - b.x, a.y - b.y);
}

// в этом месте возможно переполнение!
template <class Scalar>
point_2t<Scalar> const operator + (point_2t<Scalar> const & pt, vector_2t<Scalar> const & delta)
template<class Scalar>
point_2t<Scalar> const operator+(point_2t<Scalar> const &pt, vector_2t<Scalar> const &delta)
{
point_2t<Scalar> res(pt);
res += delta;
return res;
}

template<class Scalar>
struct point_3t;

typedef point_3t<double> point_3;
typedef point_3t<float> point_3f;
typedef point_3t<int> point_3i;

template<class Scalar>
struct point_3t
{
Scalar x, y, z;

point_3t(Scalar x, Scalar y, Scalar z)
: x(x), y(y), z(z)
{
}

template<class UScalar>
point_3t(point_3t<UScalar> const &o)
: x(o.x), y(o.y), z(o.z)
{
}

point_3t()
: x(0), y(0), z(0)
{
}

point_3t<Scalar> &operator*=(Scalar s)
{
x *= s;
y *= s;
z *= s;
return *this;
}
};

template<class Scalar>
bool operator==(point_3t<Scalar> const &a, point_3t<Scalar> const &b)
{
return (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
}

template<class Scalar>
bool operator!=(point_3t<Scalar> const &a, point_3t<Scalar> const &b)
{
return !(a == b);
}

template<class Scalar>
point_3t<Scalar> operator*(point_3t<Scalar> v, Scalar s)
{
return v *= s;
}

template<class Scalar>
point_3t<Scalar> operator*(Scalar s, point_3t<Scalar> v)
{
return v *= s;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Антон вам еще не рассказал, почему 3 пробела хорошо, а 4 плохо?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нет :)
Предположение - чтобы не было споров?
Или у четырех есть фатальный недостаток?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть. Четыре пробела слишком большой отступ, а два слишком маленький :) Надо поправить на три.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну елки-палки. Это какой-то мрак. Стандарты ведь есть, IDE ведь должны бы быть (а с этого года и для плюсов). Сейчас испорчу на три.

}
Loading