EVOLUTION-MANAGER
Edit File: Vertex.cpp
/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2012 Excensus LLC. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * ********************************************************************** * * Last port: triangulate/Vertex.java r705 * **********************************************************************/ #include <geos/triangulate/quadedge/Vertex.h> #include <geos/triangulate/quadedge/TrianglePredicate.h> #include <geos/triangulate/quadedge/QuadEdge.h> #include <geos/algorithm/NotRepresentableException.h> #include <geos/util.h> namespace geos { namespace triangulate { //geos.triangulate namespace quadedge { //geos.triangulate.quadedge using namespace algorithm; using namespace geom; Vertex::Vertex(double _x, double _y) : p(_x, _y) { } Vertex::Vertex(double _x, double _y, double _z): p(_x, _y, _z) { } Vertex::Vertex(const Coordinate& _p) : p(_p) { } Vertex::Vertex() : p() { } int Vertex::classify(const Vertex& p0, const Vertex& p1) { Vertex& p2 = *this; std::unique_ptr<Vertex> a = p1.sub(p0); std::unique_ptr<Vertex> b = p2.sub(p0); double sa = a->crossProduct(*b); if(sa > 0.0) { return LEFT; } if(sa < 0.0) { return RIGHT; } if((a->getX() * b->getX() < 0.0) || (a->getY() * b->getY() < 0.0)) { return BEHIND; } if(a->magn() < b->magn()) { return BEYOND; } if(p0.equals(p2)) { return ORIGIN; } if(p1.equals(p2)) { return DESTINATION; } else { return BETWEEN; } } bool Vertex::isInCircle(const Vertex& a, const Vertex& b, const Vertex& c) const { return TrianglePredicate::isInCircleRobust(a.p, b.p, c.p, this->p); // non-robust - best to not use //return TrianglePredicate.isInCircle(a.p, b.p, c.p, this->p); } bool Vertex::rightOf(const QuadEdge& e) const { return isCCW(e.dest(), e.orig()); } bool Vertex::leftOf(const QuadEdge& e) const { return isCCW(e.orig(), e.dest()); } std::unique_ptr<HCoordinate> Vertex::bisector(const Vertex& a, const Vertex& b) { // returns the perpendicular bisector of the line segment ab double dx = b.getX() - a.getX(); double dy = b.getY() - a.getY(); HCoordinate l1 = HCoordinate(a.getX() + dx / 2.0, a.getY() + dy / 2.0, 1.0); HCoordinate l2 = HCoordinate(a.getX() - dy + dx / 2.0, a.getY() + dx + dy / 2.0, 1.0); return detail::make_unique<HCoordinate>(l1, l2); } double Vertex::circumRadiusRatio(const Vertex& b, const Vertex& c) { std::unique_ptr<Vertex> x(circleCenter(b, c)); double radius = distance(*x, b); double edgeLength = distance(*this, b); double el = distance(b, c); if(el < edgeLength) { edgeLength = el; } el = distance(c, *this); if(el < edgeLength) { edgeLength = el; } return radius / edgeLength; } std::unique_ptr<Vertex> Vertex::midPoint(const Vertex& a) { double xm = (p.x + a.getX()) / 2.0; double ym = (p.y + a.getY()) / 2.0; double zm = (p.z + a.getZ()) / 2.0; return detail::make_unique<Vertex>(xm, ym, zm); } std::unique_ptr<Vertex> Vertex::circleCenter(const Vertex& b, const Vertex& c) const { auto a = detail::make_unique<Vertex>(getX(), getY()); // compute the perpendicular bisector of cord ab std::unique_ptr<HCoordinate> cab = bisector(*a, b); // compute the perpendicular bisector of cord bc std::unique_ptr<HCoordinate> cbc = bisector(b, c); // compute the intersection of the bisectors (circle radii) std::unique_ptr<HCoordinate> hcc = detail::make_unique<HCoordinate>(*cab, *cbc); std::unique_ptr<Vertex> cc; try { cc.reset(new Vertex(hcc->getX(), hcc->getY())); } catch(NotRepresentableException &) { } return cc; } double Vertex::interpolateZValue(const Vertex& v0, const Vertex& v1, const Vertex& v2) const { double x0 = v0.getX(); double y0 = v0.getY(); double a = v1.getX() - x0; double b = v2.getX() - x0; double c = v1.getY() - y0; double d = v2.getY() - y0; double det = a * d - b * c; double dx = this->getX() - x0; double dy = this->getY() - y0; double t = (d * dx - b * dy) / det; double u = (-c * dx + a * dy) / det; double z = v0.getZ() + t * (v1.getZ() - v0.getZ()) + u * (v2.getZ() - v0.getZ()); return z; } double Vertex::interpolateZ(const Coordinate& p, const Coordinate& v0, const Coordinate& v1, const Coordinate& v2) { double x0 = v0.x; double y0 = v0.y; double a = v1.x - x0; double b = v2.x - x0; double c = v1.y - y0; double d = v2.y - y0; double det = a * d - b * c; double dx = p.x - x0; double dy = p.y - y0; double t = (d * dx - b * dy) / det; double u = (-c * dx + a * dy) / det; double z = v0.z + t * (v1.z - v0.z) + u * (v2.z - v0.z); return z; } double Vertex::interpolateZ(const Coordinate& p, const Coordinate& p0, const Coordinate& p1) { double segLen = p0.distance(p1); double ptLen = p.distance(p0); double dz = p1.z - p0.z; double pz = p0.z + dz * (ptLen / segLen); return pz; } } //namespace geos.triangulate.quadedge } //namespace geos.triangulate } //namespace geos