// // $Source: /cvsroot/gambit/gambit/sources/tools/enumpoly/rectangl.imp,v $ // $Date: 2006/08/17 03:05:01 $ // $Revision: 1.6 $ // // DESCRIPTION: // Implementation of rectangle class // // This file is part of Gambit // Copyright (c) 2002, The Gambit Project // // 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #include "rectangl.h" #include "odometer.h" //-------------------------------------------------------------------------- // rectangle -- constructors and destructor //-------------------------------------------------------------------------- template gRectangle::gRectangle(const gRectangle& given) : sides(given.sides) { } template gRectangle::gRectangle(const Gambit::List< gInterval >& given) : sides(given) { } template gRectangle::gRectangle(const Gambit::Vector lower_bd, const Gambit::Vector upper_bd) : sides() { assert (lower_bd.Check(upper_bd)); for (int i = 1; i <= upper_bd.Length(); i++) { gInterval side(lower_bd[i],upper_bd[i]); sides.Append(side); } } template gRectangle::~gRectangle() { } //-------------------------------------------------------------------------- // rectangle -- operators //-------------------------------------------------------------------------- template gRectangle& gRectangle::operator = (const gRectangle& /* rhs */) { // gout << "For const'ness, operator = not allowed for gRectangles\n"; exit (0); return *this; } template bool gRectangle::operator == (const gRectangle& rhs) const { for (int i = 1; i <= Dmnsn(); i++) if (sides[i] != rhs.sides[i]) return false; return true; } template bool gRectangle::operator != (const gRectangle& rhs) const { return !(*this == rhs); } //-------------------------------------------------------------------------- // interval -- information //-------------------------------------------------------------------------- template const int gRectangle::Dmnsn() const { return sides.Length(); } template Gambit::Vector gRectangle::LowerBound(void) const { Gambit::Vector answer(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) answer[i] = sides[i].LowerBound(); return answer; } template Gambit::Vector gRectangle::UpperBound(void) const { Gambit::Vector answer(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) answer[i] = sides[i].UpperBound(); return answer; } template const T gRectangle::LowerBoundOfCoord(const int& i) const { assert (1 <= i && i <= Dmnsn()); return sides[i].LowerBound(); } template const T gRectangle::UpperBoundOfCoord(const int& i) const { assert (1 <= i && i <= Dmnsn()); return sides[i].UpperBound(); } template const T gRectangle::HeightInCoord(const int& i) const { assert (1 <= i && i <= Dmnsn()); return sides[i].Length(); } template const gInterval gRectangle::CartesianFactor(const int& i) const { return sides[i]; } template const gRectangle gRectangle::SameCenterDoubleSideLengths() const { Gambit::List > new_sides; for (int i = 1; i <= Dmnsn(); i++) new_sides.Append(CartesianFactor(i).SameCenterTwiceLength()); return gRectangle(new_sides); } template const gRectangle gRectangle::CubeContainingCrcmscrbngSphere() const { T maxlength((T)0); T sumsquares((T)0); int i; for (i = 1; i <= Dmnsn(); i++) { sumsquares += sides[i].Length() * sides[i].Length(); if (sides[i].Length() > maxlength) maxlength = sides[i].Length(); } T diameter((T)0); while (diameter * diameter < sumsquares) diameter += maxlength; Gambit::List > new_sides; for (i = 1; i <= Dmnsn(); i++) new_sides.Append(CartesianFactor(i).SameCenterWithNewLength(diameter)); return gRectangle(new_sides); } template const gRectangle gRectangle::Orthant(const Gambit::Array& top_or_bot) const { Gambit::List > new_sides; for (int i = 1; i <= Dmnsn(); i++) if (top_or_bot[i] == 0) new_sides.Append(CartesianFactor(i).LeftHalf()); else new_sides.Append(CartesianFactor(i).RightHalf()); return gRectangle(new_sides); } template const Gambit::Vector gRectangle::SideLengths() const { Gambit::Vector answer(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) answer[i] = sides[i].UpperBound() - sides[i].LowerBound(); return answer; } template const T gRectangle::MaximalSideLength() const { T answer((T)0); for (int i = 1; i <= Dmnsn(); i++) if (HeightInCoord(i) > answer) answer = HeightInCoord(i); return answer; } template bool gRectangle::Contains(const Gambit::Vector& point) const { assert (point.Length() == Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) if (point[i] < sides[i].LowerBound() || sides[i].UpperBound() < point[i]) return false; return true; } template bool gRectangle::Contains(const gRectangle& R) const { assert (R.Dmnsn() == Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) if ( !sides[i].Contains(R.sides[i]) ) return false; return true; } template const T gRectangle::Volume() const { T answer = (T)1; for (int i = 1; i <= Dmnsn(); i++) answer *= ( sides[i].UpperBound() - sides[i].LowerBound() ); return answer; } template const Gambit::Vector gRectangle::Center() const { Gambit::Vector answer(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) answer[i] = (sides[i].UpperBound() + sides[i].LowerBound()) / ((T)2); return answer; } template const gRectangle gRectangle::BoundingRectangle() const { return *this; } template const Gambit::List > gRectangle::VertexList() const { Gambit::List > answer; Gambit::Array ListOfTwos(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) ListOfTwos[i] = 2; gIndexOdometer ListOfTopBottoms(ListOfTwos); while (ListOfTopBottoms.Turn()) { Gambit::Vector next(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) if (ListOfTopBottoms[i] == 1) next[i] = LowerBoundOfCoord(i); else next[i] = UpperBoundOfCoord(i); answer.Append(next); } return answer; } template const int gRectangle::NumberOfCellsInSubdivision() const { int answer = 1; for (int i = 1; i <= Dmnsn(); i++) answer *= 2; return answer; } template const gRectangle gRectangle::SubdivisionCell(const int& index) const { int tmp = index; Gambit::Array updowns(Dmnsn()); for (int i = 1; i <= Dmnsn(); i++) { if (tmp % 2 == 1) { updowns[i] = 1; tmp--; } else updowns[i] = 0; tmp /= 2; } return Orthant(updowns); } template const T gRectangle::DiameterSquared() const { T answer((T)0); for (int i = 1; i <= Dmnsn(); i++) answer += HeightInCoord(i) * HeightInCoord(i); return answer; } //---------------------------------- // Conversion //---------------------------------- template gRectangle TogDouble(const gRectangle& given) { Gambit::List > cartesian_factors; for (int i = 1; i <= given.Dmnsn(); i++) cartesian_factors.Append(gInterval((double)given.LowerBound()[i], (double)given.UpperBound()[i])); return gRectangle(cartesian_factors); }