home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
freedraft.tar.gz
/
freedraft.tar
/
FREEdraft-050298
/
GEOMLIB2D
/
circle.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-19
|
4KB
|
144 lines
// circle.cpp
// Copyright (C) 1997 Cliff Johnson //
// //
// 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 software 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 software (see COPYING.LIB); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
#include "circle.h"
#include "geom_enum.h"
#include "math.h"
#include "geomexception.h"
// unit circle - default constructor
Circle::Circle():Geom(CIRCLE) // default is unit radius circle at origin -
{
center = Point();
origin = Point(1,0);
}
// Circle by center and origin
Circle::Circle(const Point& c, const Point& o) throw (GeomException) :Geom(CIRCLE)
{
if( c == o )
throw GeomException("Circle::Circle(c,o) : points are coincident");
center = c;
origin = o;
}
// circle by center and radius
Circle::Circle(const Point& c, double r) throw (GeomException) :Geom(CIRCLE)
{
if(fabs(r) < Point::NullDist)
throw GeomException("Circle::Circle(c,r) : r is zero");
center = c;
origin = c + Point(r,0);
}
Circle::Circle(const Circle& c):Geom(CIRCLE)
{
center = c.center;
origin = c.origin;
}
Circle& Circle::operator=(const Circle& c)
{
center = c.center;
origin = c.origin;
return *this;
}
double Circle::Radius() const
{
return center.Distance(origin);
}
Point Circle::U(double u) const
{
if(center == origin) return center; // check for zero radius;
Point v = origin - center;
double sine = sin(u * 2 * M_PI);
double cosine = cos(u * 2 * M_PI);
return center + Point( v[0]*cosine - v[1]*sine, v[0]*sine + v[1]*cosine);
}
ostream& operator<<(ostream& os, const Circle& c)
{
os << "Circle: center= " << c.center << " origin= " << c.origin;
return os;
}
Point Circle::Project(const Point& p ) const throw (GeomException)
{
// if(center == origin) return center; // Null circles ( not allowed anymore )
if(p == center) throw GeomException("Circle::Project : Point is at Circle center");
// vector from center to point
Point v = p - center;
return center + ( v.Normal() * Radius() ) ; // the exception above should be
//thrown instead of this one
}
double Circle::Distance(const Point& p ) const
{
// if(center == origin) return center.Distance(p);
if(p == center) return Radius();
// vector from center to point
Vector v = p - center;
Point px = center + ( v.Normal() * Radius() ) ; // ~should~ not be null :)
return p.Distance(px);
}
double Circle::UProject(const Point& p ) const throw (GeomException)
{
//if(center == origin) return 0; // Null circle
if(p == center) throw GeomException("Circle::UProject() : Point at Circle center");
// vector from center to origin
Point v0 = origin - center;
// vector from center to point
Point v1 = p - center;
//get angle
double theta = Angle(v0, v1); // both vectors should not be null
// here, so no worry about raising exception :)
// get cross product
Point px = Cross(v0,v1);
// if left hand rotation, theta is between PI and 2*PI
if(px[2]<0)theta = 2 * M_PI - theta;
return (theta / (2 * M_PI));
}