/***************************************************************** * File: Segment.h * Synopsis: * Basic 2-dimensional geometry * * $Id: Segment2d.j,v 1.1 2003/02/12 17:57:36 yap Exp $ *****************************************************************/ /************************************************************ * Class Segment: * * An instance s of Segment is a finite or infinite line segment * in the two dimensional plane, defined by a start point * s.startPt() and a stop point s.stopPt(). It can be regarded * as an open or a closed segment (default: open), and directed * or not (default: directed). * * We do not necessarily assume that startPt() != stopPt(). ************************************************************/ class Segment : public GeomObj { private: Point2d p0; Point2d p1; bool directed; // segments can be directed or not (default is directed) bool open; // segments can be open or closed (default is open) public: /************************************************************ * Constructors ************************************************************/ Segment(Segment ); Segment(Point2d p, Point2d q); //finite segment with endpoints p and q Segment(Point2d p, Vector v); //ray segment Segment(); //unit segment from (0,0) to (1,0) virtual ~Segment() {} /************************************************************* * member functions *************************************************************/ Point2d startPt() { return p0; } Point2d stopPt() { return p1; } void reverse() { Point2d pTmp = p0; p0=p1; p1=pTmp; } // reverses the direction of the segment Line2d toLine() { return Line2d(p0,p1); } double length() { return p0.distance(p1); } //length of segment double distance( Point2d p ) ; // returns the Euclidean distance between this segment and point q Point2d nearPt( Point2d p ) ; // returns the point on segment closest to q; void setDirected( bool _directed ) { directed = _directed; } void setOpen( bool _open ) { directed = open; } // orientation of p0, p1 and p int orientation( Point2d p ) { return toLine().orientation(p); } /************************************************************* * predicates *************************************************************/ bool isOpen() {return open; } bool isDirected() {return directed; } bool isTrivial() {return p0 == p1; } bool isVertical() { return p0.X() == p1.X(); } bool isHorizontal() { return p0.Y() == p1.Y(); } bool isCollinear( Point2d p ) { return toLine().contains(p); } bool isCoincident( Segment s) ; bool isParallel( Segment s ) { return toLine().isParallel( s.toLine() ); } bool contains( Point2d p ) ; bool contains( Segment s ) { return contains(s.startPt()) contains(s.stopPt()); } bool isEqual(Segment s) { return isCoincident(s); } /************************************************************* * intersection *************************************************************/ int intersects( Line2d l ) ; //decides whether *this and t intersect in one point // return dim of intersetion int intersects( Segment s ) ; //decides whether *this and t intersect in one point // return dim of intersetion GeomObj* intersection( Line2d l ) ; // return intersection point if this segment and l intersect at a single point // the intersection point is returned GeomObj* intersection( Segment s ) ; // return intersection point if this segment and s intersect at a single point // the intersection point is returned /************************************************************* * angles *************************************************************/ // the sine/cosine of the angle made with positive x-direction double sine() { return (p1.Y() - p0.Y()) / length() ; } double cosine() { return (p1.X() - p0.X()) / length() ; } Line2d rotate90(Point2d q) { return Line2d(startPt().rotate90(q), stopPt().rotate90(q)); } // computes the orientation (a, b, p), where a!=b and a and b appear // in this order on segment l int orientation2d( Segment s, Point2d p) { return orientation2d( s.toLine(), p ); } int cmp_slopes( Segment s1, Segment s2) //l1.slope > l2.slope: +1; equal: 0; otherwise: -1 { Line2d l1 = s1.toLine(); Line2d l2 = s2.toLine(); if (l1.slope() == l2.slope()) return 0; else return (l1.slope() > l2.slope()) ? +1 : -1; } /************************************************************* * I/O *************************************************************/ std::istream dump(std::istream in, Segment l); std::ostream read(std::ostream out, Segment l); // syntax: {[} p {===} q {]} }; //class Segment // Extra Line2d p_bisector(Point2d p, Point2d q);