// -*- C++ -*-
// $RCSfile: shape.C,v $
// $Revision: 1.6 $
// $Author: langer $
// $Date: 2000/09/06 20:11:48 $
/* This software was produced by NIST, an agency of the U.S. government,
* and by statute is not subject to copyright in the United States.
* Recipients of this software assume all responsibilities associated
* with its operation, modification and maintenance. However, to
* facilitate maintenance we ask that before distributing modifed
* versions of this software, you first contact the authors at
* oof_manager@ctcms.nist.gov.
*/
// Shapes with integer coordinates (shapes defined on an image)
#include "cell_coordinate.h"
#include "ishape.h"
#include "meshcoord.h"
#include "shape.h"
#include <math.h>
Rectangle::Rectangle(const MeshCoord &c1, const MeshCoord &c2) {
if(c1.x < c2.x) {
ll.x = c1.x;
ur.x = c2.x;
}
else {
ll.x = c2.x;
ur.x = c1.x;
}
if(c1.y < c2.y) {
ll.y = c1.y;
ur.y = c2.y;
}
else {
ll.y = c2.y;
ur.y = c1.y;
}
}
Shape *Rectangle::clone() const {
return new Rectangle(*this);
}
ImageRect Rectangle::containing_rectangle() const {
return ImageRect(mesh2cell_dn(ll), mesh2cell_up(ur));
}
int Rectangle::contains(const MeshCoord &c) const {
return (c.x >= ll.x && c.x < ur.x && c.y >= ll.y && c.y < ur.y);
}
double Rectangle::width() const {
return ur.x - ll.x;
}
double Rectangle::height() const {
return ur.y - ll.y;
}
//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//
Circle::Circle(const MeshCoord &c1, const MeshCoord &c2)
: xcenter(c1.x), ycenter(c1.y)
{
double dx = c1.x - c2.x;
double dy = c1.y - c2.y;
rsquare = dx*dx + dy*dy;
r = sqrt(rsquare);
MeshCoord diag(M_SQRT2*r, M_SQRT2*r); // diagonal of containing box
container = ImageRect(mesh2cell_dn(c1-diag), mesh2cell_up(c1+diag));
}
int Circle::contains(const MeshCoord &c) const {
double dx = c.x - xcenter;
double dy = c.y - ycenter;
return dx*dx + dy*dy < rsquare;
}
Shape *Circle::clone() const {
return new Circle(*this);
}
//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//
Ellipse::Ellipse(const MeshCoord &c1, const MeshCoord &c2)
: container(mesh2cell_dn(c1), mesh2cell_up(c2)), null(0)
{
double dx = c2.x - c1.x;
double dy = c2.y - c1.y;
if(dx == 0.0 || dy == 0.0) {
null = 1;
return;
}
invxaxis = 4./(dx*dx); // 1/semi-axis^2
invyaxis = 4./(dy*dy);
xcenter = 0.5*(c1.x + c2.x);
ycenter = 0.5*(c1.y + c2.y);
}
int Ellipse::contains(const MeshCoord &c) const {
if(null) return 0;
double dx = c.x - xcenter;
double dy = c.y - ycenter;
return dx*dx*invxaxis + dy*dy*invyaxis < 1.0;
}
Shape *Ellipse::clone() const {
return new Ellipse(*this);
}
//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//
Intersection::Intersection(const Shape &s1, const Shape &s2)
: shape1(s1.clone()), shape2(s2.clone())
{
ImageRect r1 = shape1->containing_rectangle();
ImageRect r2 = shape2->containing_rectangle();
container = r1 && r2;
}
Intersection::~Intersection() {
delete shape1;
delete shape2;
}
Shape *Intersection::clone() const {
return new Intersection(*shape1, *shape2);
}
int Intersection::contains(const MeshCoord &c) const {
return shape1->contains(c) && shape2->contains(c);
}
ImageRect Intersection::containing_rectangle() const {
return container;
}
Intersection operator&&(const Shape &s1, const Shape &s2) {
return Intersection(s1, s2);
}
//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//
int ShapeIterator::operator()(Cell_coordinate &pixel) {
while(iter(pixel))
if(shape->contains(cell2mesh(pixel)))
return 1;
return 0;
}
ShapeIterator::~ShapeIterator() {
delete shape;
}
int ShapeIterator::upperbound() const {
ImageRect boundingbox = shape->containing_rectangle();
return boundingbox.height()*boundingbox.width();
}
syntax highlighted by Code2HTML, v. 0.9.1