// Path: poly2tri-core/src/main/java/org/poly2tri/triangulation/TriangulationPoint.java
// public abstract class TriangulationPoint extends Point
// {
//     // List of edges this point constitutes an upper ending point (CDT)
//     private ArrayList<DTSweepConstraint> edges; 
//     
//     @Override
//     public String toString()
//     {
//         return "[" + getX() + "," + getY() + "]";
//     }
//     
//     public abstract double getX();
//     public abstract double getY();
//     public abstract double getZ();
// 
//     public abstract float getXf();
//     public abstract float getYf();
//     public abstract float getZf();
//     
//     public abstract void set( double x, double y, double z );
//     
//     public ArrayList<DTSweepConstraint> getEdges()
//     {
//         return edges;
//     }
// 
//     public void addEdge( DTSweepConstraint e )
//     {
//         if( edges == null )
//         {
//             edges = new ArrayList<DTSweepConstraint>();
//         }
//         edges.add( e );
//     }
// 
//     public boolean hasEdges()
//     {
//         return edges != null;
//     }
// 
//     /**
//      * @param p - edge destination point
//      * @return the edge from this point to given point
//      */
//     public DTSweepConstraint getEdge( TriangulationPoint p )
//     {
//         for( DTSweepConstraint c : edges )
//         {
//             if( c.p == p )
//             {
//                 return c;
//             }
//         }
//         return null;
//     }
//     
//     public boolean equals(Object obj) 
//     {
//         if( obj instanceof TriangulationPoint ) 
//         {
//             TriangulationPoint p = (TriangulationPoint)obj;
//             return getX() == p.getX() && getY() == p.getY();
//         }
//         return super.equals( obj );
//     }
// 
//     public int hashCode()
//     {
//         long bits = java.lang.Double.doubleToLongBits(getX());
//         bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
//         return (((int) bits) ^ ((int) (bits >> 32)));
//     }
// 
// 
//     /**
//      * Replace points in ptList for all equals object in uniquePts.
//      * @param uniquePts Map of triangulation points
//      * @param ptList Point list, updated, but always the same size.
//      */
//     public static void mergeInstances(Map<TriangulationPoint, TriangulationPoint> uniquePts, List<TriangulationPoint> ptList) {
//         for(int idPoint = 0; idPoint < ptList.size(); idPoint++) {
//             TriangulationPoint pt = ptList.get(idPoint);
//             TriangulationPoint uniquePt = uniquePts.get(pt);
//             if(uniquePt == null) {
//                 uniquePts.put(pt, pt);
//             } else {
//                 // Duplicate point
//                 ptList.set(idPoint, uniquePt);
//             }
//         }
//     }
// }


import java.util.List;
import org.poly2tri.geometry.primitives.Point;
import org.poly2tri.transform.coordinate.CoordinateTransform;
import org.poly2tri.triangulation.TriangulationPoint;

package org.poly2tri.examples.geotools;



/**
 * Converts a Point with Longitude,Latitude,Altitude representation to cartesian coordinates 
 * 
 * TODO:
 * 
 * WGS-84
 * The relation between Cartesian coordinates (X,Y,Z) and the curvilinear ones (lat,lon,h) is:
 
        X = (N+h) * cos(lat) * cos(lon)
        Y = (N+h) * cos(lat) * sin(lon)
        Z = (N*(1-e2)+h) * sin(lat)
 
        where
        
        N = prime vertical radius of curvature = a/sqrt(1-e2*sin(lat)^2)
        e2 = first eccentricity of the reference ellipsoid = 1 -b^2/a^2
        a = major semi-axis of reference ellipsoid = 6378137.000 m for WGS-84
        b = minor semi-axis of reference ellipsoid = 6356752.314 m for WGS-84
        
 * http://www.colorado.edu/geography/gcraft/notes/datum/gif/llhxyz.gif
 * @author Thomas Åhlén, thahlen@gmail.com
 */
public class WGS84GeodeticTransform implements CoordinateTransform
{
    private final static double PI_div180 = Math.PI/180;
    private double _radius = 1;
    
    public WGS84GeodeticTransform( double radius )
    {
        _radius = radius;
    }
    
//    @Override
//    public double toX( TriangulationPoint p )
//    {
//        return _radius*Math.cos( PI_div180*p.getY() )*Math.cos( PI_div180*p.getX() );
//    }
//
//    @Override
//    public double toY( TriangulationPoint p )
//    {
//        return _radius*Math.sin( PI_div180*p.getY() );
//    }
//
//    @Override
//    public double toZ( TriangulationPoint p )
//    {
//        return -_radius*Math.cos( PI_div180*p.getY() )*Math.sin( PI_div180*p.getX() );
//    }
//
//    @Override
//    public float toXf( TriangulationPoint p )
//    {
//        return (float)toX(p);
//    }
//
//    @Override
//    public float toYf( TriangulationPoint p )
//    {
//        return (float)toY(p);
//    }
//
//    @Override
//    public float toZf( TriangulationPoint p )
//    {
//        return (float)toZ(p);
//    }


// Path: poly2tri-core/src/main/java/org/poly2tri/triangulation/TriangulationPoint.java
// public abstract class TriangulationPoint extends Point
// {
//     // List of edges this point constitutes an upper ending point (CDT)
//     private ArrayList<DTSweepConstraint> edges; 
//     
//     @Override
//     public String toString()
//     {
//         return "[" + getX() + "," + getY() + "]";
//     }
//     
//     public abstract double getX();
//     public abstract double getY();
//     public abstract double getZ();
// 
//     public abstract float getXf();
//     public abstract float getYf();
//     public abstract float getZf();
//     
//     public abstract void set( double x, double y, double z );
//     
//     public ArrayList<DTSweepConstraint> getEdges()
//     {
//         return edges;
//     }
// 
//     public void addEdge( DTSweepConstraint e )
//     {
//         if( edges == null )
//         {
//             edges = new ArrayList<DTSweepConstraint>();
//         }
//         edges.add( e );
//     }
// 
//     public boolean hasEdges()
//     {
//         return edges != null;
//     }
// 
//     /**
//      * @param p - edge destination point
//      * @return the edge from this point to given point
//      */
//     public DTSweepConstraint getEdge( TriangulationPoint p )
//     {
//         for( DTSweepConstraint c : edges )
//         {
//             if( c.p == p )
//             {
//                 return c;
//             }
//         }
//         return null;
//     }
//     
//     public boolean equals(Object obj) 
//     {
//         if( obj instanceof TriangulationPoint ) 
//         {
//             TriangulationPoint p = (TriangulationPoint)obj;
//             return getX() == p.getX() && getY() == p.getY();
//         }
//         return super.equals( obj );
//     }
// 
//     public int hashCode()
//     {
//         long bits = java.lang.Double.doubleToLongBits(getX());
//         bits ^= java.lang.Double.doubleToLongBits(getY()) * 31;
//         return (((int) bits) ^ ((int) (bits >> 32)));
//     }
// 
// 
//     /**
//      * Replace points in ptList for all equals object in uniquePts.
//      * @param uniquePts Map of triangulation points
//      * @param ptList Point list, updated, but always the same size.
//      */
//     public static void mergeInstances(Map<TriangulationPoint, TriangulationPoint> uniquePts, List<TriangulationPoint> ptList) {
//         for(int idPoint = 0; idPoint < ptList.size(); idPoint++) {
//             TriangulationPoint pt = ptList.get(idPoint);
//             TriangulationPoint uniquePt = uniquePts.get(pt);
//             if(uniquePt == null) {
//                 uniquePts.put(pt, pt);
//             } else {
//                 // Duplicate point
//                 ptList.set(idPoint, uniquePt);
//             }
//         }
//     }
// }


// Path: poly2tri-examples-geotools/src/main/java/org/poly2tri/examples/geotools/WGS84GeodeticTransform.java
import java.util.List;
import org.poly2tri.geometry.primitives.Point;
import org.poly2tri.transform.coordinate.CoordinateTransform;
import org.poly2tri.triangulation.TriangulationPoint;

package org.poly2tri.examples.geotools;



/**
 * Converts a Point with Longitude,Latitude,Altitude representation to cartesian coordinates 
 * 
 * TODO:
 * 
 * WGS-84
 * The relation between Cartesian coordinates (X,Y,Z) and the curvilinear ones (lat,lon,h) is:
 
        X = (N+h) * cos(lat) * cos(lon)
        Y = (N+h) * cos(lat) * sin(lon)
        Z = (N*(1-e2)+h) * sin(lat)
 
        where
        
        N = prime vertical radius of curvature = a/sqrt(1-e2*sin(lat)^2)
        e2 = first eccentricity of the reference ellipsoid = 1 -b^2/a^2
        a = major semi-axis of reference ellipsoid = 6378137.000 m for WGS-84
        b = minor semi-axis of reference ellipsoid = 6356752.314 m for WGS-84
        
 * http://www.colorado.edu/geography/gcraft/notes/datum/gif/llhxyz.gif
 * @author Thomas Åhlén, thahlen@gmail.com
 */
public class WGS84GeodeticTransform implements CoordinateTransform
{
    private final static double PI_div180 = Math.PI/180;
    private double _radius = 1;
    
    public WGS84GeodeticTransform( double radius )
    {
        _radius = radius;
    }
    
//    @Override
//    public double toX( TriangulationPoint p )
//    {
//        return _radius*Math.cos( PI_div180*p.getY() )*Math.cos( PI_div180*p.getX() );
//    }
//
//    @Override
//    public double toY( TriangulationPoint p )
//    {
//        return _radius*Math.sin( PI_div180*p.getY() );
//    }
//
//    @Override
//    public double toZ( TriangulationPoint p )
//    {
//        return -_radius*Math.cos( PI_div180*p.getY() )*Math.sin( PI_div180*p.getX() );
//    }
//
//    @Override
//    public float toXf( TriangulationPoint p )
//    {
//        return (float)toX(p);
//    }
//
//    @Override
//    public float toYf( TriangulationPoint p )
//    {
//        return (float)toY(p);
//    }
//
//    @Override
//    public float toZf( TriangulationPoint p )
//    {
//        return (float)toZ(p);
//    }


    public void transform( TriangulationPoint p, TriangulationPoint store )
