[geos-commits] r2345 - in trunk/source: geom headers/geos/geom

svn_geos at osgeo.org svn_geos at osgeo.org
Fri Apr 10 08:08:19 EDT 2009


Author: strk
Date: 2009-04-10 08:08:18 -0400 (Fri, 10 Apr 2009)
New Revision: 2345

Modified:
   trunk/source/geom/LineSegment.cpp
   trunk/source/headers/geos/geom/LineSegment.h
   trunk/source/headers/geos/geom/LineSegment.inl
Log:
Sync LineSegment with JTS-1.9


Modified: trunk/source/geom/LineSegment.cpp
===================================================================
--- trunk/source/geom/LineSegment.cpp	2009-04-09 21:46:30 UTC (rev 2344)
+++ trunk/source/geom/LineSegment.cpp	2009-04-10 12:08:18 UTC (rev 2345)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2005-2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
@@ -12,14 +13,22 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: geom/LineSegment.java rev. 1.30 (JTS-1.9)
+ *
  **********************************************************************/
 
 #include <geos/geom/LineSegment.h>
+#include <geos/geom/LineString.h> // for toGeometry
 #include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
+#include <geos/geom/GeometryFactory.h> 
 #include <geos/geom/CoordinateArraySequence.h> // should we really be using this?
 #include <geos/algorithm/CGAlgorithms.h>
 #include <geos/algorithm/LineIntersector.h>
+#include <geos/algorithm/HCoordinate.h>
+#include <geos/algorithm/NotRepresentableException.h>
 #include <geos/profiler.h>
 #include <geos/inline.h>
 
@@ -31,6 +40,10 @@
 #endif
 
 using namespace std;
+//using namespace geos::algorithm;
+using geos::algorithm::HCoordinate;
+using geos::algorithm::NotRepresentableException;
+using geos::algorithm::LineIntersector;
 
 namespace geos {
 namespace geom { // geos::geom
@@ -71,6 +84,18 @@
 }
 
 /*public*/
+double
+LineSegment::segmentFraction(const Coordinate& inputPt) const
+{
+	double segFrac = projectionFactor(inputPt);
+	if (segFrac < 0.0)
+		segFrac = 0.0;
+	else if (segFrac > 1.0)
+		segFrac = 1.0;
+	return segFrac;
+}
+
+/*public*/
 void
 LineSegment::project(const Coordinate& p, Coordinate& ret) const
 {
@@ -227,7 +252,58 @@
 	return false;
 }
 
+bool
+LineSegment::lineIntersection(const LineSegment& line, Coordinate& ret) const
+{
+	try {
+		HCoordinate::intersection(p0, p1, line.p0, line.p1, ret);
+		return true;
+	}
+	catch (const NotRepresentableException& /*ex*/) {
+		// eat this exception, and return null;
+	}
+	return false;
+}
 
+
+/* public */
+void
+LineSegment::pointAlongOffset(double segmentLengthFraction,
+	                      double offsetDistance,
+	                      Coordinate& ret) const
+{
+	// the point on the segment line
+	double segx = p0.x + segmentLengthFraction * (p1.x - p0.x);
+	double segy = p0.y + segmentLengthFraction * (p1.y - p0.y);
+
+	double dx = p1.x - p0.x;
+	double dy = p1.y - p0.y;
+	double len = sqrt(dx * dx + dy * dy);
+	// u is the vector that is the length of the offset,
+	// in the direction of the segment
+	double ux = offsetDistance * dx / len;
+	double uy = offsetDistance * dy / len;
+
+	// the offset point is the seg point plus the offset
+	// vector rotated 90 degrees CCW
+	double offsetx = segx - uy;
+	double offsety = segy + ux;
+
+	ret = Coordinate(offsetx, offsety);
+}
+
+/* public */
+std::auto_ptr<LineString>
+LineSegment::toGeometry(const GeometryFactory& gf) const
+{
+	CoordinateSequence *cl=new CoordinateArraySequence();
+	cl->add(p0);
+	cl->add(p1);
+	return std::auto_ptr<LineString>(
+		gf.createLineString(cl) // ownership transferred
+	);
+}
+
 } // namespace geos::geom
 } // namespace geos
 

Modified: trunk/source/headers/geos/geom/LineSegment.h
===================================================================
--- trunk/source/headers/geos/geom/LineSegment.h	2009-04-09 21:46:30 UTC (rev 2344)
+++ trunk/source/headers/geos/geom/LineSegment.h	2009-04-10 12:08:18 UTC (rev 2345)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2006 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -11,6 +12,10 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: geom/LineSegment.java rev. 1.30 (JTS-1.9)
+ *
  **********************************************************************/
 
 #ifndef GEOS_GEOM_LINESEGMENT_H
@@ -21,11 +26,14 @@
 #include <geos/inline.h>
 
 #include <iostream> // for ostream
+#include <memory> // for auto_ptr
 
 // Forward declarations
 namespace geos {
 	namespace geom {
 		class CoordinateSequence;
+		class GeometryFactory;
+		class LineString;
 	}
 }
 
@@ -61,6 +69,8 @@
 	/// Constructs a LineSegment with the given start and end Coordinates.
 	LineSegment(const Coordinate& c0, const Coordinate& c1);
 
+	LineSegment(double x0, double y0, double x1, double y1);
+
 	virtual ~LineSegment();
 
 	void setCoordinates(const Coordinate& c0, const Coordinate& c1);
@@ -111,8 +121,27 @@
 	 */
 	int orientationIndex(const LineSegment& seg) const;
 
+	// TODO: deprecate this
 	int orientationIndex(const LineSegment* seg) const;
 
+	/** \brief
+	 * Determines the orientation index of a Coordinate
+	 * relative to this segment.
+	 *
+	 * The orientation index is as defined in
+	 * CGAlgorithms::computeOrientation.
+	 *
+	 * @param seg the LineSegment to compare
+	 *
+	 * @return 1 if <code>p</code> is to the left of this segment
+	 * @return -1 if <code>p</code> is to the right of this segment
+	 * @return 0 if <code>p</code> is collinear with this segment
+	 *
+	 * @see CGAlgorithms::computeOrientation(Coordinate, Coordinate,
+	 *                                       Coordinate)
+	 */
+	int orientationIndex(const Coordinate& p) const;
+
 	/// Reverses the direction of the line segment.
 	void reverse();
 
@@ -126,6 +155,12 @@
 	/// @return the angle this segment makes with the x-axis (in radians)
 	double angle() const;
 
+	/// Computes the midpoint of the segment
+	//
+	/// @param ret will be set to the midpoint of the segment
+	///
+	void midPoint(Coordinate& ret) const;
+
 	/// Computes the distance between this line segment and another one.
 	double distance(const LineSegment& ls) const;
 
@@ -138,15 +173,85 @@
 	 */
 	double distancePerpendicular(const Coordinate& p) const;
 
-	/**
+	/** \brief
+	 * Computes the Coordinate that lies a given
+	 * fraction along the line defined by this segment.
+	 *
+	 * A fraction of <code>0.0</code> returns the start point of
+	 * the segment; a fraction of <code>1.0</code> returns the end
+	 * point of the segment.
+	 * If the fraction is < 0.0 or > 1.0 the point returned
+	 * will lie before the start or beyond the end of the segment.
+	 *
+	 * @param segmentLengthFraction the fraction of the segment length
+	 *        along the line
+	 * @param ret will be set to the point at that distance
+	 */
+	void pointAlong(double segmentLengthFraction, Coordinate& ret) const;
+
+	/** \brief
+	 * Computes the {@link Coordinate} that lies a given
+	 * fraction along the line defined by this segment and offset from
+	 * the segment by a given distance.
+	 *
+	 * A fraction of <code>0.0</code> offsets
+	 * from the start point of the segment;
+	 * a fraction of <code>1.0</code> offsets
+	 * from the end point of the segment.
+	 *
+	 * The computed point is offset to the left of the line
+	 * if the offset distance is positive, to the right if negative.
+	 *
+	 * @param segmentLengthFraction the fraction of the segment
+	 *                              length along the line
+	 *
+	 * @param offsetDistance the distance the point is offset
+	 *        from the segment
+	 *         (positive is to the left, negative is to the right)
+	 *
+	 * @param ret will be set to the point at that distance and offset
+	 */
+	void pointAlongOffset(double segmentLengthFraction,
+	                      double offsetDistance,
+	                      Coordinate& ret) const;
+
+	/** \brief
 	 * Compute the projection factor for the projection of the point p
-	 * onto this LineSegment.  The projection factor is the constant k
+	 * onto this LineSegment. 
+	 * 
+	 * The projection factor is the constant r
 	 * by which the vector for this segment must be multiplied to
-	 * equal the vector for the projection of p.
+	 * equal the vector for the projection of p on the line
+	 * defined by this segment.
+	 *
+	 * The projection factor returned will be in the range
+	 * (-inf, +inf)
+	 *
+	 * @param p the point to compute the factor for
+	 *
+	 * @return the projection factor for the point
+	 *
 	 */
 	double projectionFactor(const Coordinate& p) const;
 
 	/** \brief
+	 * Computes the fraction of distance (in <tt>[0.0, 1.0]</tt>)
+	 * that the projection of a point occurs along this line segment.
+	 *
+	 * If the point is beyond either ends of the line segment,
+	 * the closest fractional value (<tt>0.0</tt> or <tt>1.0</tt>)
+	 * is returned.
+	 * 
+	 * Essentially, this is the {@link #projectionFactor} clamped to
+	 * the range <tt>[0.0, 1.0]</tt>.
+	 *
+	 * @param inputPt the point
+	 * @return the fraction along the line segment the projection
+	 *         of the point occurs
+	 */
+	double segmentFraction(const Coordinate& inputPt) const;
+
+	/** \brief
 	 * Compute the projection of a point onto the line determined
 	 * by this line segment.
 	 * 
@@ -231,6 +336,33 @@
 	 */
 	bool intersection(const LineSegment& line, Coordinate& coord) const;
 
+	/** \brief
+	 * Computes the intersection point of the lines defined
+	 * by two segments, if there is one.
+	 *
+	 * There may be 0, 1 or an infinite number of intersection points
+	 * between two lines.
+	 * If there is a unique intersection point, it is returned.
+	 * Otherwise, <tt>null</tt> is returned.
+	 * If more information is required about the details of the
+	 * intersection, the algorithms::LineIntersector class should
+	 * be used.
+	 *
+	 * @param line a line segment defining a straight line
+	 * @param ret will be set to the intersection point (if any)
+	 * @return true if an intersection was found, false otherwise
+	 *
+	 */
+	bool lineIntersection(const LineSegment& line, Coordinate& coord) const;
+
+	/**
+	 * Creates a LineString with the same coordinates as this segment
+	 *
+	 * @param gf the geometery factory to use
+	 * @return a LineString with the same geometry as this segment
+	 */
+	std::auto_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
+
 };
 
 std::ostream& operator<< (std::ostream& o, const LineSegment& l);

Modified: trunk/source/headers/geos/geom/LineSegment.inl
===================================================================
--- trunk/source/headers/geos/geom/LineSegment.inl	2009-04-09 21:46:30 UTC (rev 2344)
+++ trunk/source/headers/geos/geom/LineSegment.inl	2009-04-10 12:08:18 UTC (rev 2345)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2009  Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2005-2006 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -11,6 +12,10 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: geom/LineSegment.java rev. 1.30 (JTS-1.9)
+ *
  **********************************************************************/
 
 #ifndef GEOS_LINESEGMENT_INL
@@ -42,6 +47,14 @@
 }
 
 INLINE
+LineSegment::LineSegment(double x0, double y0, double x1, double y1)
+	:
+	p0(x0, y0),
+	p1(x1, y1)
+{
+}
+
+INLINE
 LineSegment::LineSegment()
 {
 }
@@ -57,6 +70,14 @@
 	return algorithm::CGAlgorithms::distancePointLinePerpendicular(p, p0, p1);
 }
 
+INLINE void
+LineSegment::pointAlong(double segmentLengthFraction, Coordinate& ret) const
+{
+    ret = Coordinate(
+	p0.x + segmentLengthFraction * (p1.x - p0.x),
+	p0.y + segmentLengthFraction * (p1.y - p0.y));
+}
+
 INLINE double
 LineSegment::distance(const LineSegment& ls) const
 {
@@ -130,6 +151,12 @@
 	return orientationIndex(*seg);
 }
 
+INLINE int
+LineSegment::orientationIndex(const Coordinate& p) const
+{
+	return algorithm::CGAlgorithms::orientationIndex(p0, p1, p);
+}
+
 INLINE CoordinateSequence*
 LineSegment::closestPoints(const LineSegment* line)
 {
@@ -143,6 +170,13 @@
 	return std::atan2(p1.y-p0.y,p1.x-p0.x);
 }
 
+INLINE void
+LineSegment::midPoint(Coordinate& ret) const
+{
+	ret = Coordinate( (p0.x + p1.x) / 2,
+	                  (p0.y + p1.y) / 2 );
+}
+
 INLINE std::ostream&
 operator<< (std::ostream& o, const LineSegment& l)
 {



More information about the geos-commits mailing list