|
|
|
/**
|
|
|
|
This file is part of Kig, a KDE program for Interactive Geometry...
|
|
|
|
Copyright (C) 2002 Dominique Devriese <devriese@kde.org>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
|
|
USA
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef KIG_MISC_COMMON_H
|
|
|
|
#define KIG_MISC_COMMON_H
|
|
|
|
|
|
|
|
#include "coordinate.h"
|
|
|
|
#include "rect.h"
|
|
|
|
|
|
|
|
#include <tqrect.h>
|
|
|
|
#include <kdeversion.h>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#ifdef KDE_IS_VERSION
|
|
|
|
#if KDE_IS_VERSION( 3, 1, 0 )
|
|
|
|
#define KIG_USE_KDOUBLEVALIDATOR
|
|
|
|
#else
|
|
|
|
#undef KIG_USE_KDOUBLEVALIDATOR
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#undef KIG_USE_KDOUBLEVALIDATOR
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class ObjectImp;
|
|
|
|
class KigWidget;
|
|
|
|
|
|
|
|
extern const double double_inf;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Here, we define some algorithms which we need in
|
|
|
|
* various places...
|
|
|
|
*/
|
|
|
|
|
|
|
|
double getDoubleFromUser( const TQString& caption, const TQString& label, double value,
|
|
|
|
TQWidget* tqparent, bool* ok, double min, double max, int decimals );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Simple class representing a line. Used by various functions in Kig.
|
|
|
|
*/
|
|
|
|
class LineData {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* \ifnot creating-python-scripting-doc
|
|
|
|
* Default constructor. Sets a and b to the origin.
|
|
|
|
* \endif
|
|
|
|
*/
|
|
|
|
LineData() : a(), b() {}
|
|
|
|
/**
|
|
|
|
* Constructor. Sets a and b to the given Coordinates.
|
|
|
|
*/
|
|
|
|
LineData( const Coordinate& na, const Coordinate& nb ) : a( na ), b( nb ) {}
|
|
|
|
/**
|
|
|
|
* One point on the line.
|
|
|
|
*/
|
|
|
|
Coordinate a;
|
|
|
|
/**
|
|
|
|
* Another point on the line.
|
|
|
|
*/
|
|
|
|
Coordinate b;
|
|
|
|
/**
|
|
|
|
* The direction of the line. Equivalent to b - a.
|
|
|
|
*/
|
|
|
|
const Coordinate dir() const { return b - a; }
|
|
|
|
/**
|
|
|
|
* The length from a to b.
|
|
|
|
*/
|
|
|
|
double length() const { return ( b - a ).length(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if this line is parallel to l.
|
|
|
|
*/
|
|
|
|
bool isParallelTo( const LineData& l ) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if this line is orthogonal to l.
|
|
|
|
*/
|
|
|
|
bool isOrthogonalTo( const LineData& l ) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Equality. Tests two LineData's for equality.
|
|
|
|
*/
|
|
|
|
bool operator==( const LineData& l, const LineData& r );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This calcs the rotation of point a around point c by arc arc. Arc
|
|
|
|
* is in radians, in the range 0 < arc < 2*pi ...
|
|
|
|
*/
|
|
|
|
Coordinate calcRotatedPoint( const Coordinate& a, const Coordinate& c, const double arc );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this returns a point, so that the line through point t
|
|
|
|
* and the point returned is perpendicular to the line l.
|
|
|
|
*/
|
|
|
|
Coordinate calcPointOnPerpend( const LineData& l, const Coordinate& t );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this returns a point, so that the line through point t and the
|
|
|
|
* point returned is perpendicular to the direction given in dir...
|
|
|
|
*/
|
|
|
|
Coordinate calcPointOnPerpend( const Coordinate& dir, const Coordinate& t );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this returns a point, so that the line through point t
|
|
|
|
* and the point returned is parallel with the line l
|
|
|
|
*/
|
|
|
|
Coordinate calcPointOnParallel( const LineData& l, const Coordinate& t );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this returns a point, so that the line through point t
|
|
|
|
* and the point returned is parallel with the direction given in dir...
|
|
|
|
*/
|
|
|
|
Coordinate calcPointOnParallel( const Coordinate& dir, const Coordinate& t );
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this calcs the point where the lines l and m intersect...
|
|
|
|
*/
|
|
|
|
Coordinate calcIntersectionPoint( const LineData& l, const LineData& m );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this calcs the intersection points of the circle with center c and
|
|
|
|
* radius sqrt( r ), and the line l. As a circle and a
|
|
|
|
* line have two intersection points, side tells us which one we
|
|
|
|
* need... It should be 1 or -1. If the line and the circle have no
|
|
|
|
* intersection, valid is set to false, otherwise to true...
|
|
|
|
* Note that sqr is the _square_ of the radius. We do this to avoid
|
|
|
|
* rounding errors...
|
|
|
|
*/
|
|
|
|
const Coordinate calcCircleLineIntersect( const Coordinate& c,
|
|
|
|
const double sqr,
|
|
|
|
const LineData& l,
|
|
|
|
int side );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this calcs the intersection points of the arc with center c,
|
|
|
|
* radius sqrt( r ), start angle sa and angle angle, and the line l.
|
|
|
|
* As a arc and a line can have max two intersection points, side
|
|
|
|
* tells us which one we need... It should be 1 or -1. If the line
|
|
|
|
* and the arc have no intersection, valid is set to false, otherwise
|
|
|
|
* to true... Note that sqr is the _square_ of the radius. We do
|
|
|
|
* this to avoid rounding errors...
|
|
|
|
*/
|
|
|
|
const Coordinate calcArcLineIntersect( const Coordinate& c, const double sqr,
|
|
|
|
const double sa, const double angle,
|
|
|
|
const LineData& l, int side );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this calculates the perpendicular projection of point p on line
|
|
|
|
* ab...
|
|
|
|
*/
|
|
|
|
const Coordinate calcPointProjection( const Coordinate& p,
|
|
|
|
const LineData& l );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* calc the distance of point p to the line through a and b...
|
|
|
|
*/
|
|
|
|
double calcDistancePointLine( const Coordinate& p,
|
|
|
|
const LineData& l );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this sets p1 and p2 to p1' and p2' so that p1'p2' is the same line
|
|
|
|
* as p1p2, and so that p1' and p2' are on the border of the Rect...
|
|
|
|
*/
|
|
|
|
void calcBorderPoints( Coordinate& p1, Coordinate& p2, const Rect& r );
|
|
|
|
/**
|
|
|
|
* overload...
|
|
|
|
*/
|
|
|
|
void calcBorderPoints( double& xa, double& xb, double& ya, double& yb, const Rect& r);
|
|
|
|
/**
|
|
|
|
* cleaner overload, intended to replace the above two...
|
|
|
|
*/
|
|
|
|
const LineData calcBorderPoints( const LineData& l, const Rect& r );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* this does the same as the above function, but only for b..
|
|
|
|
*/
|
|
|
|
void calcRayBorderPoints( const Coordinate& a, Coordinate& b, const Rect& r );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function calculates the center of the circle going through the
|
|
|
|
* three given points..
|
|
|
|
*/
|
|
|
|
const Coordinate calcCenter(
|
|
|
|
const Coordinate& a, const Coordinate& b, const Coordinate& c );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* overload...
|
|
|
|
*/
|
|
|
|
void calcRayBorderPoints( const double xa, const double xb, double& ya,
|
|
|
|
double& yb, const Rect& r );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* calc the mirror point of p over the line l
|
|
|
|
*/
|
|
|
|
const Coordinate calcMirrorPoint( const LineData& l,
|
|
|
|
const Coordinate& p );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* test collinearity of three points
|
|
|
|
*/
|
|
|
|
bool areCollinear( const Coordinate& p1, const Coordinate& p2,
|
|
|
|
const Coordinate& p3 );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* test if a 2x2 matrix is singular (relatively to the
|
|
|
|
* norm of the two row vectors)
|
|
|
|
*/
|
|
|
|
bool isSingular( const double& a, const double& b,
|
|
|
|
const double& c, const double& d );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* is o on the line defined by point a and point b ?
|
|
|
|
* fault is the allowed difference...
|
|
|
|
*/
|
|
|
|
bool isOnLine( const Coordinate& o, const Coordinate& a,
|
|
|
|
const Coordinate& b, const double fault );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* is o on the segment defined by point a and point b ?
|
|
|
|
* this calls isOnLine(), but also checks if o is "between" a and b...
|
|
|
|
* fault is the allowed difference...
|
|
|
|
*/
|
|
|
|
bool isOnSegment( const Coordinate& o, const Coordinate& a,
|
|
|
|
const Coordinate& b, const double fault );
|
|
|
|
|
|
|
|
bool isOnRay( const Coordinate& o, const Coordinate& a,
|
|
|
|
const Coordinate& b, const double fault );
|
|
|
|
|
|
|
|
bool isOnArc( const Coordinate& o, const Coordinate& c, const double r,
|
|
|
|
const double sa, const double a, const double fault );
|
|
|
|
|
|
|
|
Coordinate calcCircleRadicalStartPoint( const Coordinate& ca,
|
|
|
|
const Coordinate& cb,
|
|
|
|
double sqra, double sqrb );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is the line, segment, ray or vector inside r ? We need the imp to
|
|
|
|
* distinguish between rays, lines, segments or whatever.. ( we use
|
|
|
|
* their contains functions actually.. )
|
|
|
|
*/
|
|
|
|
bool lineInRect( const Rect& r, const Coordinate& a, const Coordinate& b,
|
|
|
|
const int width, const ObjectImp* imp, const KigWidget& w );
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T kigMin( const T& a, const T& b )
|
|
|
|
{
|
|
|
|
return a < b ? a : b;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T kigMax( const T& a, const T& b )
|
|
|
|
{
|
|
|
|
return a > b ? a : b;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T kigAbs( const T& a )
|
|
|
|
{
|
|
|
|
return a >= 0 ? a : -a;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
int kigSgn( const T& a )
|
|
|
|
{
|
|
|
|
return a == 0 ? 0 : a > 0 ? +1 : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern const double test_threshold;
|
|
|
|
|
|
|
|
#endif
|