point.h revision d6519bf53baba32bd74436ad9c85f1fa2c6b6ae9
/**
* \file
* \brief Cartesian point / 2D vector and related operations
*//*
* Authors:
* Michael G. Sloan <mgsloan@gmail.com>
* Nathan Hurst <njh@njhurst.com>
* Krzysztof KosiĆski <tweenk.pl@gmail.com>
*
* Copyright (C) 2006-2009 Authors
*
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*/
#ifndef SEEN_Geom_POINT_H
#define SEEN_Geom_POINT_H
#include "config.h"
#include <iostream>
#include <iterator>
#include <boost/operators.hpp>
> > > > > > > > > > // this uses chaining so it looks weird, but works
{
/// @name Create points
/// @{
/** Construct a point on the origin. */
Point()
/** Construct a point from its coordinates. */
}
/** Construct from integer point. */
_pt[X] = p[X];
_pt[Y] = p[Y];
}
for (unsigned i = 0; i < 2; ++i)
}
for (unsigned i = 0; i < 2; ++i)
return *this;
}
/** @brief Construct a point from its polar coordinates.
* The angle is specified in radians, in the mathematical convention (increasing
* counter-clockwise from +X). */
return ret;
}
/** @brief Construct an unit vector from its angle.
* The angle is specified in radians, in the mathematical convention (increasing
* counter-clockwise from +X). */
return ret;
}
/// @}
/// @name Access the coordinates of a point
/// @{
/// @}
/// @name Vector operations
/// @{
/** @brief Compute the distance from origin.
* @return Length of the vector from origin to this point */
void normalize();
/** @brief Return a point like this point but rotated -90 degrees.
* If the y axis grows downwards and the x axis grows to the
* right, then this is 90 degrees counter-clockwise. */
}
/** @brief Return a point like this point but rotated +90 degrees.
* If the y axis grows downwards and the x axis grows to the
* right, then this is 90 degrees clockwise. */
}
/// @}
/// @name Vector-like arithmetic operations
/// @{
}
for ( unsigned i = 0 ; i < 2 ; ++i ) {
}
return *this;
}
for ( unsigned i = 0 ; i < 2 ; ++i ) {
}
return *this;
}
for ( unsigned i = 0 ; i < 2 ; ++i ) _pt[i] *= s;
return *this;
}
//TODO: s == 0?
for ( unsigned i = 0 ; i < 2 ; ++i ) _pt[i] /= s;
return *this;
}
/// @}
/// @name Affine transformations
/// @{
// implemented in transforms.cpp
/// @}
/// @name Conversion to integer points
/// @{
/** @brief Round to nearest integer coordinates. */
return ret;
}
/** @brief Round coordinates downwards. */
return ret;
}
/** @brief Round coordinates upwards. */
return ret;
}
/// @}
/// @name Various utilities
/// @{
/** @brief Check whether both coordinates are finite. */
bool isFinite() const {
for ( unsigned i = 0 ; i < 2 ; ++i ) {
}
return true;
}
/** @brief Check whether both coordinates are zero. */
bool isZero() const {
}
/** @brief Check whether the length of the vector is close to 1. */
}
/** @brief Equality operator.
* This tests for exact identity (as opposed to are_near()). Note that due to numerical
* errors, this test might return false even if the points should be identical. */
}
/** @brief Lexicographical ordering for points.
* Y coordinate is regarded as more significant. When sorting according to this
* ordering, the points will be sorted according to the Y coordinate, and within
* points with the same Y coordinate according to the X coordinate. */
}
/// @}
/** @brief Lexicographical ordering functor. */
/** @brief Lexicographical ordering functor with runtime dimension. */
};
};
/** @brief Output operator for points.
* Prints out the coordinates.
* @relates Point */
return out_file;
}
return a[X] < b[X] || (a[X] == b[X] && a[Y] < b[Y]);
}
};
return a[Y] < b[Y] || (a[Y] == b[Y] && a[X] < b[X]);
}
};
}
/** @brief Compute the second (Euclidean) norm of @a p.
* This corresponds to the length of @a p. The result will not overflow even if
* \f$p_X^2 + p_Y^2\f$ is larger that the maximum value that can be stored
* in a <code>double</code>.
* @return \f$\sqrt{p_X^2 + p_Y^2}\f$
* @relates Point */
{
return p.length();
}
/** @brief Compute the square of the Euclidean norm of @a p.
* Warning: this can overflow where L2 won't.
* @return \f$p_X^2 + p_Y^2\f$
* @relates Point */
{
return p[0]*p[0] + p[1]*p[1];
}
//IMPL: NearConcept
/** @brief Nearness predicate for points.
* True if neither coordinate of @a a is further than @a eps from the corresponding
* coordinate of @a b.
* @relates Point */
{
}
/** @brief Return a point halfway between the specified ones.
* @relates Point */
{
}
/** @brief Returns p * Geom::rotate_degrees(90), but more efficient.
*
* Angle direction in 2Geom: If you use the traditional mathematics convention that y
* increases upwards, then positive angles are anticlockwise as per the mathematics convention. If
* you take the common non-mathematical convention that y increases downwards, then positive angles
* are clockwise, as is common outside of mathematics.
*
* There is no function to rotate by -90 degrees: use -rot90(p) instead.
* @relates Point */
{
return Point(-p[Y], p[X]);
}
/** @brief Linear interpolation between two points.
* @param t Time value
* @param a First point
* @param b Second point
* @return Point on a line between a and b. The ratio of its distance from a
* and the distance between a and b will be equal to t.
* @relates Point */
{
return (a * (1 - t) + b * t);
}
/** @brief Compute the dot product of a and b.
* Dot product can be interpreted as a measure of how parallel the vectors are.
* For perpendicular vectors, it is zero. For parallel ones, its absolute value is highest,
* and the sign depends on whether they point in the same direction (+) or opposite ones (-).
* @return \f$a \cdot b = a_X b_X + a_Y b_Y\f$.
* @relates Point */
{
return a[0] * b[0] + a[1] * b[1];
}
/** @brief Compute the 2D cross product.
* Defined as dot(a, b.cw()). This means it will be zero for parallel vectors,
* and its absolute value highest for perpendicular vectors.
* @relates Point*/
{
}
/** @brief Compute the (Euclidean) distance between points.
* @relates Point */
{
return L2(a - b);
}
/** @brief Compute the square of the distance between points.
* @relates Point */
{
return L2sq(a - b);
}
bool is_unit_vector(Point const &p);
Point constrain_angle(Point const &A, Point const &B, unsigned int n = 4, Geom::Point const &dir = Geom::Point(1,0));
} /* namespace Geom */
// This is required to fix a bug in GCC 4.3.3 (and probably others) that causes the compiler
// to try to instantiate the iterator_traits template and fail. Probably it thinks that Point
// is an iterator and tries to use std::distance instead of Geom::distance.
}
#endif /* !SEEN_Geom_POINT_H */
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :