// GeoElt2d.h
//
// Geometric elements in 2-dim 
// not finite elements, 
// because no shape functions are involved
//
// J.Liu, R.Cali
// ColoState, Jan.-Jun. 2007


#ifndef GeoElt2d_H
#define GeoElt2d_H

#include "PtVec2d.h"

enum GeoElt2d {line2d=1, rect2d, trig, quadri};


// Line2d

class Line2d {
private: 
   PtVec2d P1, P2;
public:
   Line2d(PtVec2d A, PtVec2d B) {P1=A; P2=B;}  // Constructor
   Line2d(const Line2d &L) {P1=L.P1; P2=L.P2;}  // Copy constructor
   Line2d &operator=(const Line2d&);  // Copy assignment
   double length() const {return dist(P1,P2);}
   PtVec2d mapping(double a) const {return (1-a)*P1+a*P2;} 
      // Mapping from [0,1] with natural coordinate a
   PtVec2d mapping1(double a) const {return (1-a)/2*P1+(1+a)/2*P2;}   
      // Mapping from [-1,1] with natural coordinate a
   PtVec2d normal() const;
};


// Rect2d

class Rect2d {
private:
   PtVec2d P1, P2;
public:
   Rect2d(PtVec2d A, PtVec2d B) {P1=A; P2=B;}  // Constructor
   Rect2d(const Rect2d &R) {P1=R.P1; P2=R.P2;}  // Copy constructor
   Rect2d &operator=(const Rect2d&);  // Copy assignment
   void getCrds(double &x1, double &y1, double &x2, double &y2) const;
   void getMaxMinCrds(double &xmax, double &xmin, double &ymax, double &ymin) const;
   void getMaxMinEdges(double &maxEdge, double &minEdge) const;
   PtVec2d mapping(double a, double b) const;  // Mapping from [0,1]^2
   PtVec2d mapping1(double a, double b) const;  // Mapping from [-1,1]^2
   PtVec2d normalLeft() const {return PtVec2d(-1,0);}
   PtVec2d normalRight() const {return PtVec2d(1,0);}
   PtVec2d normalBottom() const {return PtVec2d(0,-1);}
   PtVec2d normalTop() const {return PtVec2d(0,1);}
   bool isInRect2d(PtVec2d) const;
};


// Triangle

class Trig {
private: 
   PtVec2d P1, P2, P3;
public:
   Trig(PtVec2d A, PtVec2d B, PtVec2d C) {P1=A; P2=B; P3=C;}  // Constructor
   Trig(const Trig &T) {P1=T.P1; P2=T.P2; P3=T.P3;}  // Copy constructor
   Trig &operator=(const Trig&);  // Copy assignment
   void getCrds(double &x1, double &y1, double &x2, double &y2, 
      double &x3, double &y3) const;
   void getMaxMinCrds(double &xmax, double &xmin, double &ymax, double &ymin) const;
   void getMaxMinEdges(double &maxEdge, double &minEdge) const;
   double area() const;
   PtVec2d center() const {return (1.0/3)*(P1+P2+P3);}
   PtVec2d mapping(double a, double b) const {return (1-a-b)*P1+a*P2+b*P3;}
      // Mapping from the reference triangle with natural coordinates a,b
   PtVec2d invMapping(PtVec2d P) const;
      // The inverse mapping to the reference triangle
   bool isInTrig(PtVec2d P) const;
   PtVec2d hypInterSxn(const PtVec2d &Pi, const PtVec2d &Po) const;
   PtVec2d normalEdge1() const;
   PtVec2d normalEdge2() const;
   PtVec2d normalEdge3() const;
};

#endif  // GeoElt2d_H
