// ====================================================================== // // Copyright (c) 1999 The CGAL Consortium // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------- // release : // release_date : 2000, August 16 // // source : webS2/S2.lw // file : include/CGAL/SimpleCartesian/SegmentS2.h // package : S2 (1.7) // maintainer : Stefan Schirra // revision : 1.6 // revision_date : 27 Jun 2000 // author(s) : Stefan Schirra // based on code by // Andreas Fabri and // Herve Brönnimann // // coordinator : MPI, Saarbrücken // ====================================================================== #ifndef CGAL_SEGMENTS2_H #define CGAL_SEGMENTS2_H #include CGAL_BEGIN_NAMESPACE template < class FT > class SegmentS2 { public: SegmentS2(); SegmentS2(const PointS2& sp, const PointS2& ep); bool is_horizontal() const; bool is_vertical() const; bool has_on(const PointS2& p) const; bool collinear_has_on(const PointS2& p) const; bool operator==(const SegmentS2& s) const; bool operator!=(const SegmentS2& s) const; int id() const; const PointS2& start() const; const PointS2& end() const; const PointS2& source() const; const PointS2& target() const; PointS2 min() const; PointS2 max() const; PointS2 vertex(int i) const; PointS2 point(int i) const; PointS2 operator[](int i) const; FT squared_length() const; DirectionS2 direction() const; LineS2 supporting_line() const; SegmentS2 opposite() const; SegmentS2 transform(const Aff_transformationS2& t) const; bool is_degenerate() const; Bbox_2 bbox() const; // private: PointS2 s; PointS2 t; }; template < class FT > CGAL_KERNEL_CTOR_INLINE SegmentS2::SegmentS2() {} template < class FT > CGAL_KERNEL_CTOR_INLINE SegmentS2::SegmentS2(const PointS2& sp, const PointS2& ep) : s(sp), t(ep) {} template < class FT > inline bool SegmentS2::operator==(const SegmentS2& s) const { return ( (source() == s.source()) && (target() == s.target()) ); } template < class FT > inline bool SegmentS2::operator!=(const SegmentS2& s) const { return !(*this == s); } template < class FT > inline const PointS2& SegmentS2::start() const { return s; } template < class FT > inline const PointS2& SegmentS2::end() const { return t; } template < class FT > inline const PointS2& SegmentS2::source() const { return s; } template < class FT > inline const PointS2& SegmentS2::target() const { return t; } template < class FT > CGAL_KERNEL_INLINE PointS2 SegmentS2::min() const { return (lexicographically_xy_smaller(source(),target())) ? source() : target(); } template < class FT > CGAL_KERNEL_INLINE PointS2 SegmentS2::max() const { return (lexicographically_xy_smaller(source(),target())) ? target() : source(); } template < class FT > CGAL_KERNEL_INLINE PointS2 SegmentS2::vertex(int i) const { return (i%2 ==0) ? source() : target(); } template < class FT > CGAL_KERNEL_INLINE PointS2 SegmentS2::point(int i) const { return (i%2 ==0) ? source() : target(); } template < class FT > inline PointS2 SegmentS2::operator[](int i) const { return vertex(i); } template < class FT > CGAL_KERNEL_INLINE FT SegmentS2::squared_length() const { return squared_distance(source(), target()); } template < class FT > CGAL_KERNEL_INLINE DirectionS2 SegmentS2::direction() const { return DirectionS2( target() - source() ); } template < class FT > inline LineS2 SegmentS2::supporting_line() const { return LineS2(*this); } template < class FT > inline SegmentS2 SegmentS2::opposite() const { return SegmentS2(target(), source()); } template < class FT > inline SegmentS2 SegmentS2::transform( const Aff_transformationS2& t) const { return SegmentS2(t.transform(source()), t.transform(target())); } template < class FT > CGAL_KERNEL_INLINE Bbox_2 SegmentS2::bbox() const { return source().bbox() + target().bbox(); } template < class FT > inline bool SegmentS2::is_degenerate() const { return (source() == target()); } #ifndef CGAL_NO_OSTREAM_INSERT_SEGMENTS2 template < class FT > std::ostream& operator<<(std::ostream &os, const SegmentS2 &s) { switch(os.iword(IO::mode)) { case IO::ASCII : return os << s.source() << ' ' << s.target(); case IO::BINARY : return os << s.source() << s.target(); default: return os << "SegmentS2(" << s.source() << ", " << s.target() << ")"; } } #endif // CGAL_NO_OSTREAM_INSERT_SEGMENTS2 #ifndef CGAL_NO_ISTREAM_EXTRACT_SEGMENTS2 template < class FT > std::istream& operator>>(std::istream &is, SegmentS2 &s) { PointS2 p, q; is >> p >> q; s = SegmentS2(p, q); return is; } #endif // CGAL_NO_ISTREAM_EXTRACT_SEGMENTS2 template < class FT > CGAL_KERNEL_INLINE bool SegmentS2::is_horizontal() const { return source().y() == target().y(); } template < class FT > CGAL_KERNEL_INLINE bool SegmentS2::is_vertical() const { return source().x() == target().x(); } template < class FT > CGAL_KERNEL_INLINE bool SegmentS2::has_on(const PointS2& p) const { return(( p == source() ) || ( p == target() ) || ( collinear(source(), p, target()) && ( DirectionS2(p - source()) != DirectionS2(p - target())) ) ); } template < class FT > CGAL_KERNEL_MEDIUM_INLINE bool SegmentS2::collinear_has_on(const PointS2& p) const { CGAL_kernel_exactness_precondition( collinear(source(), p, target()) ); if (CGAL_NTS abs(target().x()-source().x()) > CGAL_NTS abs(target().y()-source().y())) { if (p.x() < source().x()) return (p.x() >= target().x()); if (p.x() <= target().x()) return true; return (p.x() == source().x()); } else { if (p.y() < source().y()) return (p.y() >= target().y()); if (p.y() <= target().y()) return true; return (p.y() == source().y()); } } CGAL_END_NAMESPACE #endif