got it to actually do *some* encryptions and decryptions, after finding that they've really broken the new version in terms of how
you have to set up the encryption process.
but it's failing a bunch still too! at this point, i wonder if my padding code is incorrect, except that the code NEVER failed before
this set of recent releases (where they hid blowfish in the legacy provider, and now with ubuntu 24.04 where they've made it a dance
across razor blades to get *anything* to work properly, even with the legacy provider loaded).
--- /dev/null
+include variables.def
+
+PROJECT = graphical_apps
+BUILD_BEFORE =
+
+include rules.def
+
+++ /dev/null
-#ifndef ANGLE_CLASS
-#define ANGLE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : angle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include <basis/byte_array.h>
-#include <basis/common_outcomes.h>
-#include <basis/contracts.h>
-#include <structures/object_packers.h>
-
-#include <math.h>
-
-namespace geometric {
-
-//! Represents a geometric angle.
-
-//! angles can be measured in degrees or radians in this class.
-enum angular_units { DEGREES, RADIANS };
-
-template <class contents>
-class angle : public basis::packable
-{
-public:
- DEFINE_CLASS_NAME("angle");
-
- angle(contents inital_rotation = 0, angular_units unit = RADIANS);
- //!< constructs a new angle with "initial_rotation" in the "unit".
-
- void set(contents a, angular_units unit);
- //!< sets the angle to a new rotation "a" in the "unit".
- contents get(angular_units unit) const;
- //!< retrieves the current angular measure.
-
- angle operator - (void) const;
- //!< returns the negation of this angle.
-
- angle operator + (const angle &to_add) const;
- angle operator - (const angle &to_subtract) const;
- angle operator * (contents to_multiply) const;
- angle operator / (contents to_divide) const;
- angle &operator += (const angle &to_add);
- angle &operator -= (const angle &to_subtract);
- angle &operator *= (contents to_multiply);
- angle &operator /= (contents to_divide);
-
- contents sine() const;
- //!< returns the sin function of this angle.
- contents cosine() const;
- //!< returns the cos function of this angle.
- contents tangent() const;
- //!< returns the tan function of this angle.
-
- static angle arctangent(contents opposite, contents adjacent,
- basis::outcome &retval);
- //!< returns the atan of the angle.
- /*!< the outcome will be set to OKAY if the function operated successfully.
- otherwise it will be set to BAD_INPUT. */
- static angle arccosine(contents adjacent, contents hypotenuse,
- basis::outcome &retval);
- //!< returns the acos of the angle.
- static angle arcsine(contents opposite, contents hypotenuse,
- basis::outcome &retval);
- //!< returns the asin of the angle.
-
- virtual int packed_size() const;
- virtual void pack(basis::byte_array &packed_form) const;
- //!< packs the angle for shipping in bytes.
- virtual bool unpack(basis::byte_array &packed_form);
- //!< unpacks the angle from the "packed_form".
-
-private:
- contents _theta; //!< the held angular measure.
-
- contents to_internal(contents initial, angular_units unit) const;
- //!< converts the angle into the units we use inside the class.
- contents from_internal(contents initial, angular_units unit) const;
- //!< converts the angle from our internal measure into "unit" measure.
-};
-
-//////////////
-
-//! double_angle provides a non-templated class for forward declarations.
-
-class double_angle : public angle<double>
-{
-public:
- double_angle(double init = 0, angular_units unit = RADIANS)
- : angle<double>(init, unit) {}
- double_angle(const angle<double> &to_copy) : angle<double>(to_copy) {}
-};
-
-//////////////
-
-// implementation of larger methods below.
-
-template <class contents>
-angle<contents>::angle(contents a, angular_units unit) { set(a, unit); }
-
-template <class contents>
-angle<contents> angle<contents>::operator - (void) const
-{ angle<contents> to_return(*this); to_return *= -1; return to_return; }
-
-template <class contents>
-angle<contents> angle<contents>::operator + (const angle<contents> &a) const
-{ angle<contents> to_return(*this); to_return += a; return to_return; }
-
-template <class contents>
-angle<contents> angle<contents>::operator - (const angle<contents> &a) const
-{ angle<contents> to_return(*this); to_return -= a; return to_return; }
-
-template <class contents>
-angle<contents> angle<contents>::operator * (contents to_multiply) const
-{
- angle<contents> to_return(*this);
- to_return *= to_multiply;
- return to_return;
-}
-
-template <class contents>
-angle<contents> angle<contents>::operator / (contents to_divide) const
-{ angle<contents> to_return(*this); to_return /= to_divide; return to_return; }
-
-template <class contents>
-angle<contents> &angle<contents>::operator += (const angle<contents> &a)
-{ _theta += a._theta; return *this; }
-
-template <class contents>
-angle<contents> &angle<contents>::operator -= (const angle<contents> &a)
-{ _theta -= a._theta; return *this; }
-
-template <class contents>
-angle<contents> &angle<contents>::operator *= (contents f)
-{ _theta *= f; return *this; }
-
-template <class contents>
-angle<contents> &angle<contents>::operator /= (contents f)
-{ _theta /= f; return *this; }
-
-template <class contents>
-contents angle<contents>::sine() const { return sin(_theta); }
-
-template <class contents>
-contents angle<contents>::cosine() const { return cos(_theta); }
-
-template <class contents>
-contents angle<contents>::tangent() const { return tan(_theta); }
-
-template <class contents>
-int angle<contents>::packed_size() const
-{
- basis::byte_array temp;
-//hmmm: inefficient!
- pack(temp);
- return temp.length();
-}
-
-template <class contents>
-void angle<contents>::pack(basis::byte_array &packed_form) const
-{ structures::attach(packed_form, _theta); }
-
-template <class contents>
-bool angle<contents>::unpack(basis::byte_array &packed_form)
-{ return structures::detach(packed_form, _theta); }
-
-template <class contents>
-contents angle<contents>::to_internal(contents a, angular_units unit) const
-{
- switch(unit) {
- case RADIANS: return a;
- case DEGREES: return a * PI_APPROX / 180.0;
- default: return 0;
- }
-}
-
-template <class contents>
-contents angle<contents>::from_internal(contents a, angular_units unit) const
-{
- switch(unit) {
- case RADIANS: return a;
- case DEGREES: return a * 180.0 / PI_APPROX;
- default: return 0;
- }
-}
-
-template <class contents>
-void angle<contents>::set(contents a, angular_units unit)
-{ _theta = to_internal(a, unit); }
-
-template <class contents>
-contents angle<contents>::get(angular_units unit) const
-{ return from_internal(_theta, unit); }
-
-template <class contents>
-angle<contents> angle<contents>::arccosine(contents adjacent,
- contents hypotenuse, basis::outcome &retval)
-{
- contents d = adjacent / hypotenuse;
- retval = basis::common::BAD_INPUT;
- bounds_return(d, -1.0, 1.0, angle<contents>());
- retval = basis::common::OKAY;
- return angle<contents>(acos(d), RADIANS);
-}
-
-template <class contents>
-angle<contents> angle<contents>::arcsine(contents opposite, contents hypotenuse,
- basis::outcome &retval)
-{
- contents d = opposite / hypotenuse;
- retval = basis::common::BAD_INPUT;
- bounds_return(d, -1.0, 1.0, angle<contents>());
- retval = basis::common::OKAY;
- return angle<contents>(asin(d), RADIANS);
-}
-
-template <class contents>
-angle<contents> angle<contents>::arctangent(contents opposite, contents adjacent,
- basis::outcome &retval)
-{
- retval = basis::common::BAD_INPUT;
- if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle<contents>();
- retval = basis::common::OKAY;
- return angle<contents>(atan2(opposite, adjacent), RADIANS);
-}
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-#ifndef CARTESIAN_OBJECTS_GROUP
-#define CARTESIAN_OBJECTS_GROUP
-
-/*****************************************************************************\
-* *
-* Name : cartesian objects *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "angle.h"
-#include "line.h"
-#include "point.h"
-#include "rectangle.h"
-
-namespace geometric {
-
-//! Provides a geometric point that use double floating points numbers.
-
-class cartesian_point : public point<double>
-{
-public:
- cartesian_point(double x = 0, double y = 0) : point<double>(x, y) {}
- cartesian_point(double r, double_angle theta) : point<double>(r, theta) {}
- cartesian_point(const point<double> &to_copy) : point<double>(to_copy) {}
- DEFINE_CLASS_NAME("cartesian_point");
-
- static cartesian_point origin() { return cartesian_point(0.0, 0.0); }
- //!< the origin of the two-dimensional system.
-};
-
-//////////////
-
-//! Provides a geometric line that use double floating points numbers.
-
-class cartesian_line : public line<double>
-{
-public:
- cartesian_line(const cartesian_point &endpoint_1,
- const cartesian_point &endpoint_2)
- : line<double>(endpoint_1, endpoint_2) {}
- cartesian_line(double x_1 = 0, double y_1 = 0,
- double x_2 = 0, double y_2 = 0)
- : line<double>(x_1, y_1, x_2, y_2) {}
-};
-
-//////////////
-
-//! Provides a geometric rectangle that use double floating points numbers.
-
-class cartesian_rectangle : public rectangle<double>
-{
-public:
- cartesian_rectangle(const cartesian_point &vertex_1,
- const cartesian_point &vertex_2)
- : rectangle<double>(vertex_1, vertex_2) {}
- cartesian_rectangle(double x_1 = 0, double y_1 = 0,
- double x_2 = 0, double y_2 = 0)
- : rectangle<double>(x_1, y_1, x_2, y_2) {}
- cartesian_rectangle(const rectangle<double> &rect)
- : rectangle<double>(rect) {}
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-/*****************************************************************************\
-* *
-* Name : circle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "circle.h"
-#include "cartesian_objects.h"
-#include "line.h"
-#include "rectangle.h"
-
-#include <basis/functions.h>
-
-#include <math.h>
-
-using namespace basis;
-
-namespace geometric {
-
-circle::circle() : _radius(1), _center(cartesian_point::origin()) {}
-
-circle::circle(double a_radius, const cartesian_point &a_center)
-: _radius(a_radius), _center(a_center) {}
-
-circle::~circle() {}
-
-double circle::area() const { return PI_APPROX * square(_radius); }
-
-double circle::diameter() const { return 2.0 * _radius; }
-
-double circle::circumference() const { return 2.0 * PI_APPROX * _radius; }
-
-cartesian_point circle::location(const double_angle &where) const
-{
- double rotation = where.get(RADIANS);
- cartesian_point second(cos(rotation) * _radius, sin(rotation) * _radius);
- return _center + second;
-}
-
-bool circle::inside(const cartesian_point &where) const
-{
- double dist = where.distance(_center);
- return dist <= _radius? true : false;
-}
-
-cartesian_rectangle circle::dimensions() const
-{
- const double deg0 = 0;
- const double deg90 = 0.5 * PI_APPROX;
- const double deg180 = PI_APPROX;
- const double deg270 = 1.5 * PI_APPROX;
-
- cartesian_point right(location(deg0));
- cartesian_point top(location(deg90));
- cartesian_point left(location(deg180));
- cartesian_point bottom(location(deg270));
- return cartesian_rectangle(left.x(), bottom.y(), right.x(), top.y());
-}
-
-double circle::radius() const { return _radius; }
-
-void circle::radius(double to_set) { _radius = to_set; }
-
-cartesian_point circle::center() const { return _center; }
-
-void circle::center(const cartesian_point &to_set) { _center = to_set; }
-
-} // namespace.
-
+++ /dev/null
-#ifndef CIRCLE_CLASS
-#define CIRCLE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : circle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "cartesian_objects.h"
-
-namespace geometric {
-
-//! Represents a geometric circle.
-/*!
- A circle is specified by its center and its radius. The angles are
- measured in radians.
-*/
-
-class circle
-{
-public:
- circle();
- circle(double radius, const cartesian_point ¢er);
- ~circle();
-
- double area() const;
- //!< Returns the area occupied by the circle.
-
- double circumference() const;
- //!< Returns the perimeter for the circle.
- /*!< The circumference is the length of a virtual string around the
- circle. */
-
- double diameter() const;
- //!< Returns the length of the circle's bisecting line.
- /*!< This is the length of a line segment that is circumscribed by the
- circle and which passes through the center of the circle. */
-
- bool inside(const cartesian_point &where) const;
- //!< Returns true if the point is inside the circle.
-
- cartesian_point location(const double_angle &where) const;
- //!< Returns the point on the circle that is at the angle "where".
-
- cartesian_rectangle dimensions() const;
- //!< Returns a bounding box around the circle.
-
- double radius() const; //!< Half of the circle's diameter.
- void radius(double to_set); //!< Sets the radius of the circle.
-
- cartesian_point center() const; //!< The point at the center of the circle.
- void center(const cartesian_point &to_set); //!< Resets the circle's center.
-
-private:
- double _radius; //!< Records the current radius.
- cartesian_point _center; //!< Records the current center.
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-
-
-
-/*****************************************************************************\
-* *
-* Name : ellipse *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "cartesian_objects.h"
-#include "ellipse.h"
-#include "line.h"
-#include "rectangle.h"
-
-#include <basis/functions.h>
-
-#include <math.h>
-
-using namespace basis;
-
-namespace geometric {
-
-ellipse::ellipse()
-: _center(cartesian_point::origin()),
- _width_from_center(1),
- _height_from_center(1)
-{}
-
-ellipse::ellipse(const cartesian_point &a_center, double a_width_from_center,
- double a_height_from_center)
-: _center(a_center),
- _width_from_center(a_width_from_center),
- _height_from_center(a_height_from_center)
-{}
-
-ellipse::ellipse(const ellipse &to_copy)
-: _center(),
- _width_from_center(0),
- _height_from_center(0)
-{ *this = to_copy; }
-
-ellipse::~ellipse() {}
-
-ellipse &ellipse::operator = (const ellipse &to_copy)
-{
- if (this == &to_copy) return *this;
- _center = to_copy._center;
- _width_from_center = to_copy._width_from_center;
- _height_from_center = to_copy._height_from_center;
- return *this;
-}
-
-double ellipse::area() const
-{ return absolute_value(PI_APPROX * _width_from_center * _height_from_center); }
-
-double ellipse::perimeter() const
-{
- double w = _width_from_center;
- double h = _height_from_center;
- double perim_temp = sqrt(square(h) + square(w)) / 2;
- return 2.0 * PI_APPROX * perim_temp;
-}
-
-cartesian_point ellipse::location(const double_angle &where) const
-{
- double a = _width_from_center;
- double b = _height_from_center;
- double a_multiplier = square(where.tangent());
- double denom = sqrt(square(b) + square(a) * a_multiplier);
- double ab = a * b;
- double tango = where.tangent();
- cartesian_point to_return(ab / denom, ab * tango / denom);
-
- // the following negates the x component if the angle is in the appropriate
- // part of the ellipse.
- int ang = int(where.get(DEGREES));
- double adjustment = where.get(DEGREES) - double(ang);
- ang %= 360;
- double adjusted_ang = ang + adjustment;
- if ( (adjusted_ang < 270.0) && (adjusted_ang > 90.0) )
- to_return.set(to_return.x() * -1.0, to_return.y());
- to_return += _center;
- return to_return;
-}
-
-bool ellipse::inside(const cartesian_point &where) const
-{
- double dist = where.distance(_center);
- double_angle to_point = double_angle(asin(where.y() / dist), RADIANS);
- cartesian_point intersector = location(to_point);
- return dist <= intersector.distance(_center)? true : false;
-}
-
-cartesian_point ellipse::center() const { return _center; }
-
-double ellipse::width_from_center() const { return _width_from_center; }
-
-double ellipse::height_from_center() const { return _height_from_center; }
-
-void ellipse::center(const cartesian_point &to_set) { _center = to_set; }
-
-void ellipse::width_from_center(double to_set)
-{ _width_from_center = to_set; }
-
-void ellipse::height_from_center(double to_set)
-{ _height_from_center = to_set; }
-
-} // namespace.
-
-
-
-
+++ /dev/null
-#ifndef ELLIPSE_CLASS
-#define ELLIPSE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : ellipse *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-namespace geometric {
-
-// forward.
-class cartesian_point;
-class double_angle;
-
-//! Represents a geometric ellipse.
-/*! An ellipse is specified by its height, width and center. */
-
-class ellipse
-{
-public:
- ellipse();
- ellipse(const cartesian_point ¢er, double width_from_center,
- double height_from_center);
- ellipse(const ellipse &to_copy);
-
- ~ellipse();
-
- ellipse &operator = (const ellipse &to_copy);
-
- double area() const;
- //!< Returns the area occupied by the ellipse.
-
- double perimeter() const;
- //!< Returns the perimeter for the ellipse.
- /*!< This is the length of the virtual string around the ellipse. The
- returned value is an approximation. */
-
- bool inside(const cartesian_point &where) const;
- //!< Returns true if the point is inside the ellipse.
-
- cartesian_point location(const double_angle &where) const;
- //!< Describes the locus of the ellipse (basically, where it lives).
- /*!< Returns the point on the ellipse that lies on a ray from the center
- of the ellipse directed at an angle "where". */
-
- cartesian_point center() const;
- double width_from_center() const;
- double height_from_center() const;
-
- void center(const cartesian_point &to_set);
- void width_from_center(double to_set);
- void height_from_center(double to_set);
-
-protected:
- cartesian_point _center;
- double _width_from_center;
- double _height_from_center;
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-#ifndef LINE_CLASS
-#define LINE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : line *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "point.h"
-
-namespace geometric {
-
-//! Represents a geometric line segment.
-
-template <class numeric_type>
-class line
-{
-public:
- line(const point<numeric_type> &endpoint1,
- const point<numeric_type> &endpoint2);
- line(numeric_type end1_x = 0, numeric_type end1_y = 0,
- numeric_type end2_x = 0, numeric_type end2_y = 0);
-
- point<numeric_type> center() const;
- //!< Returns the point at the center of the line segment.
-
- line operator + (const point<numeric_type> &to_add) const;
- line operator - (const point<numeric_type> &to_subtract) const;
- //!< Returns this line with "to_add" added to it.
- /*!< This returns a line that is the result of adding or subtracting a
- point to the endpoints of this line. */
-
- line &operator += (const point<numeric_type> &to_add);
- line &operator -= (const point<numeric_type> &to_subtract);
- //!< Adds or subtracts a point from `this' line.
-
- point<numeric_type> endpoint_1() const;
- point<numeric_type> endpoint_2() const;
-
- void endpoint_1(const point<numeric_type> &to_set);
- void endpoint_2(const point<numeric_type> &to_set);
-
- basis::astring text_form() const;
- //!< returns a string form of the points defining the line.
-
-protected:
- point<numeric_type> _endpoint_1;
- point<numeric_type> _endpoint_2;
-};
-
-//////////////
-
-// implementations below...
-
-template <class numeric_type>
-line<numeric_type>::line(const point<numeric_type> &p1,
- const point<numeric_type> &p2)
-: _endpoint_1(p1), _endpoint_2(p2) {}
-
-template <class numeric_type>
-line<numeric_type>::line(numeric_type x1, numeric_type y1, numeric_type x2,
- numeric_type y2)
-: _endpoint_1(point<numeric_type>(x1, y1)),
- _endpoint_2(point<numeric_type>(x2, y2))
-{}
-
-template <class numeric_type>
-point<numeric_type> line<numeric_type>::center() const
-{
- return point<numeric_type>(_endpoint_1.x() / 2.0 + _endpoint_2.x() / 2.0,
- _endpoint_1.y() / 2.0 + _endpoint_2.y() / 2.0);
-}
-
-template <class numeric_type>
-basis::astring line<numeric_type>::text_form() const
-{
- return basis::astring("<") + _endpoint_1.text_form() + basis::astring(" ")
- + _endpoint_2.text_form() + basis::astring(">");
-}
-
-template <class numeric_type>
-line<numeric_type> &line<numeric_type>::operator +=
- (const point<numeric_type> &to_add)
-{ _endpoint_1 += to_add; _endpoint_2 += to_add; return *this; }
-
-template <class numeric_type>
-line<numeric_type> &line<numeric_type>::operator -=
- (const point<numeric_type> &to_subtract)
-{ _endpoint_1 -= to_subtract; _endpoint_2 -= to_subtract; return *this; }
-
-template <class numeric_type>
-line<numeric_type> line<numeric_type>::operator +
- (const point<numeric_type> &to_add) const
-{ line<numeric_type> to_return(*this); to_return += to_add; return to_return; }
-
-template <class numeric_type>
-line<numeric_type> line<numeric_type>::operator -
- (const point<numeric_type> &to_subtract) const
-{
- line<numeric_type> to_return(*this);
- to_return -= to_subtract;
- return to_return;
-}
-
-template <class numeric_type>
-point<numeric_type> line<numeric_type>::endpoint_1() const
-{ return _endpoint_1; }
-
-template <class numeric_type>
-point<numeric_type> line<numeric_type>::endpoint_2() const
-{ return _endpoint_2; }
-
-template <class numeric_type>
-void line<numeric_type>::endpoint_1(const point<numeric_type> &to_set)
-{ _endpoint_1 = to_set; }
-
-template <class numeric_type>
-void line<numeric_type>::endpoint_2(const point<numeric_type> &to_set)
-{ _endpoint_2 = to_set; }
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-include cpp/variables.def
-
-PROJECT = geometric
-TYPE = library
-SOURCE = circle.cpp ellipse.cpp math_bits.cpp polygon.cpp screen_rectangle.cpp triangle.cpp
-TARGETS = geometric.lib
-
-include cpp/rules.def
-
+++ /dev/null
-/*****************************************************************************\
-* *
-* Name : mathematical operations group *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1996-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "math_bits.h"
-
-#include <basis/astring.h>
-
-using namespace basis;
-
-namespace geometric {
-
-astring crop_numeric(const astring &input)
-{
- astring to_return(input);
- for (int i = 0; i < to_return.length(); i++)
- if ( ( (to_return[i] >= '0') && (to_return[i] <= '9') )
- || (to_return[i] == '.')
- || (to_return[i] == '+') || (to_return[i] == '-')
- || (to_return[i] == 'E') || (to_return[i] == 'e') ) {
- to_return.zap(i, i); // remove non-useful character.
- i--; // move backwards in loop.
- } else break;
- return to_return;
-}
-
-astring crop_non_numeric(const astring &input)
-{
- astring to_return(input);
- for (int i = 0; i < to_return.length(); i++)
- if ( ! ((to_return[i] >= '0') && (to_return[i] <= '9'))
- && (to_return[i] != '.')
- && (to_return[i] != '+') && (to_return[i] != '-')
- && (to_return[i] != 'E') && (to_return[i] != 'e') ) {
- to_return.zap(i, i); // remove non-useful character.
- i--; // move backwards in loop.
- } else break;
- return to_return;
-}
-
-}
-
+++ /dev/null
-#ifndef MATHEMATICAL_OPERATIONS_GROUP
-#define MATHEMATICAL_OPERATIONS_GROUP
-
-/*****************************************************************************\
-* *
-* Name : mathematical operations group *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1996-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-/*! @file math_bits.h
- @brief Provides some fairly low-level math support.
-*/
-
-#include <basis/astring.h>
-
-namespace geometric {
-
-basis::astring crop_numeric(const basis::astring &input);
- //!< Eats the numeric characters from the front of "input".
- /*!< This and crop_non_numeric() return a string that is constructed from
- "input" by chopping the numerical (or non-numerical) characters off of the
- beginning. The types of numbers supported are floating point, but it will
- generally work for integers also (problems arise when mixing in
- the period, e, E, +, and - characters with integer numbers). */
-basis::astring crop_non_numeric(const basis::astring &input);
- //!< Eats the non-numeric characters from the front of "input".
-
-// type identification functions:
-
-//! returns true if the specified numeric_type is a floating_point type.
-/*! this is useful in templates where one wants to know about the templated
-type. */
-template <class numeric_type>
-bool is_floating_point(numeric_type t)
- { t = numeric_type(5.1); t = numeric_type(t * 3.0);
- return 0.001 < float(basis::absolute_value(numeric_type(t - 15.0))); }
-
-//! returns true if the instantiation type is an integer.
-template <class numeric_type>
-bool is_integral(numeric_type t) { return !is_floating_point(t); }
-
-// the following functions (is_short, is_signed and is_unsigned) are only
-// useful for integral types.
-
-//! returns true if the specified type is short on the PC.
-template <class numeric_type>
-bool is_short(numeric_type) { return sizeof(numeric_type) == 2; }
-
-//! returns true if the templated type is unsigned.
-template <class numeric_type>
-bool is_unsigned(numeric_type t) { t = -1; return t > 0; }
-//! returns true if the templated type is signed.
-template <class numeric_type>
-bool is_signed(numeric_type t) { return !is_unsigned(t); }
-
-//! Guesses the formatting string needed for the type provided.
-/*! Returns a string that is appropriate as the format specifier of a printf
-(or the astring constructor) given the template type. templates can rely
-on this to print numerical types correctly. */
-template <class numeric_type>
-basis::astring numeric_specifier(numeric_type t) {
- basis::astring to_return("%d");
- if (is_floating_point(t))
- to_return = basis::astring("%f");
- else { // integral.
- if (is_unsigned(t))
- to_return = basis::astring("%u");
- if (is_short(t))
- to_return.insert(1, "h");
- }
- return to_return;
-}
-
-}
-
-#endif // outer guard.
-
+++ /dev/null
-#ifndef POINT_CLASS
-#define POINT_CLASS
-
-/*****************************************************************************\
-* *
-* Name : point *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "angle.h"
-#include "math_bits.h"
-#include "point.h"
-
-#include <basis/astring.h>
-#include <basis/contracts.h>
-#include <basis/functions.h>
-#include <structures/object_packers.h>
-
-#include <math.h>
-
-//! Contains all of our objects for geometry and avoids name clashes.
-
-namespace geometric {
-
-//! Represents a geometric point.
-
-template <class numeric_type>
-class point : public basis::packable, public virtual basis::root_object
-{
-public:
- point(numeric_type x = 0, numeric_type y = 0);
- point(numeric_type r, double_angle theta);
-
- DEFINE_CLASS_NAME("point");
-
- void set(numeric_type x, numeric_type y);
- void set(numeric_type r, double_angle theta);
-
- numeric_type x() const { return _x; }
- numeric_type y() const { return _y; }
-
- numeric_type r() const;
- double_angle theta() const;
-
- point rotate(const double_angle &theta) const;
- //!< Rotates the point by the angle "theta".
- /*!< This rotates the position of the point around the origin in the
- trigonometric standard manner; zero degrees is at the right, increasing
- degree angles are counterclockwise from the x axis to the y to the
- -x to the -y .... */
-
- numeric_type distance(const point &p2) const;
- //!< Returns the distance between `this' and the second point `p2'.
-
- point operator - () const { return point<numeric_type>(-_x, -_y); }
- //!< return the additive inverse of the vector
-
- numeric_type magnitude() const;
- //!< return the distance from the origin to this point.
-
- point operator + (const point &arg2) const;
- point operator - (const point &arg2) const;
- point &operator += (const point &arg2);
- point &operator -= (const point &arg2);
- bool operator == (const point &arg2) const;
-
- basis::astring text_form() const;
- //!< Prints out the two values (x and y) held in the point.
-
- bool from_text(const basis::astring &text);
- //!< returns true if the "text" is successfully pulled into this point.
-
- virtual void pack(basis::byte_array &packed_form) const;
- virtual bool unpack(basis::byte_array &packed_form);
- int packed_size() const;
-
-private:
- numeric_type _x;
- numeric_type _y;
-};
-
-//////////////
-
-// implementations below...
-
-// notes:
-//
-// - there is an odd breaking up of the expressions where we're taking a
-// square root because ms visual studio 7 has a bug of some sort that
-// convinces it that angle<int> is being used in there, although it's not.
-// these lines use a temporary named "sumsquar" to deconfuse the compiler.
-
-template <class numeric_type>
-point<numeric_type>::point(numeric_type x, numeric_type y) { set(x, y); }
-
-template <class numeric_type>
-point<numeric_type>::point(numeric_type r, double_angle theta)
-{ set(r, theta); }
-
-template <class numeric_type>
-basis::astring point<numeric_type>::text_form() const
-{
- numeric_type temp = 0;
- basis::astring specifier(numeric_specifier(temp));
- basis::astring sprintf_template(basis::astring::SPRINTF, "(%s, %s)", specifier.s(), specifier.s());
- return basis::astring(basis::astring::SPRINTF, sprintf_template.s(), x(), y());
-}
-
-template <class numeric_type>
-void point<numeric_type>::set(numeric_type x, numeric_type y)
-{ _x = x; _y = y; }
-
-template <class numeric_type>
-numeric_type point<numeric_type>::r() const
-{
- const double sumsquar = basis::square(x()) + basis::square(y());
- return numeric_type(sqrt(sumsquar));
-}
-
-template <class numeric_type>
-void point<numeric_type>::set(numeric_type r, double_angle theta)
-{ set(numeric_type(r * theta.cosine()), numeric_type(r * theta.sine())); }
-
-template <class numeric_type>
-numeric_type point<numeric_type>::distance(const point &p2) const
-{
- const double sumsquar = basis::square(p2.x() - x()) + basis::square(p2.y() - y());
- return numeric_type(sqrt(sumsquar));
-}
-
-template <class numeric_type>
-double_angle point<numeric_type>::theta() const
-{
- basis::outcome retval;
- return double_angle::arctangent(y(), x(), retval);
-}
-
-template <class contents>
-int point<contents>::packed_size() const
-{
- basis::byte_array temp;
-//hmmm: inefficient!
- pack(temp);
- return temp.length();
-}
-
-template <class contents>
-void point<contents>::pack(basis::byte_array &packed_form) const
-{
- structures::attach(packed_form, _x);
- structures::attach(packed_form, _y);
-}
-
-template <class contents>
-bool point<contents>::unpack(basis::byte_array &packed_form)
-{
- if (!structures::detach(packed_form, _x)) return false;
- if (!structures::detach(packed_form, _y)) return false;
- return true;
-}
-
-template <class numeric_type>
-numeric_type point<numeric_type>::magnitude() const
-{
- const double sumsquar = basis::square(x()) + basis::square(y());
- return numeric_type(sqrt(sumsquar));
-}
-
-template <class numeric_type>
-point<numeric_type> point<numeric_type>::operator + (const point &arg2) const
-{ return point<numeric_type>(x() + arg2.x(), y() + arg2.y()); }
-
-template <class numeric_type>
-point<numeric_type> point<numeric_type>::operator - (const point &arg2) const
-{ return point<numeric_type>(x() - arg2.x(), y() - arg2.y()); }
-
-template <class numeric_type>
-point<numeric_type> &point<numeric_type>::operator += (const point &arg2)
-{ _x += arg2.x(); _y += arg2.y(); return *this; }
-
-template <class numeric_type>
-point<numeric_type> &point<numeric_type>::operator -= (const point &arg2)
-{ _x -= arg2.x(); _y -= arg2.y(); return *this; }
-
-template <class numeric_type>
-bool point<numeric_type>::operator == (const point &arg2) const
-{
-// this bit should be part of the floating point stuff...
- double epsilon = 1e-10;
- return (basis::absolute_value(x() - arg2.x()) <= epsilon)
- && (basis::absolute_value(y() - arg2.y()) <= epsilon);
-}
-
-template <class numeric_type>
-point<numeric_type> point<numeric_type>::rotate
- (const double_angle &theta) const
-{
- numeric_type tempX = x();
- numeric_type tempY = y();
- numeric_type temp1 = numeric_type(tempX * theta.cosine()
- - tempY * theta.sine());
- numeric_type temp2 = numeric_type(tempX * theta.sine()
- + tempY * theta.cosine());
- return point<numeric_type>(temp1, temp2);
-}
-
-template <class numeric_type>
-bool point<numeric_type>::from_text(const basis::astring &_text)
-{
- numeric_type x = 0, y = 0;
- basis::astring text(_text);
- // chop junk off the front.
- text = crop_non_numeric(text);
- // scan the string for values.
- x = text.convert(x);
- // remove the number.
- text = crop_numeric(text);
- // chop off more junk.
- text = crop_non_numeric(text);
- // get the next number.
- y = text.convert(y);
- set(x, y);
- return true;
-}
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-
-
-
-/*****************************************************************************\
-* *
-* Name : polygon *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "polygon.h"
-
-#include <basis/array.h>
-
-using namespace basis;
-
-namespace geometric {
-
-bool polygon::inside(const cartesian_point &to_check)
-{
- int right_intersect_count = 0;
- for (int i = 0; i < length(); i++) {
- cartesian_point vert_1 = get(i);
- cartesian_point vert_2 = get( (i + 1) % length() );
- if ( (to_check.y() < minimum(vert_1.y(), vert_2.y()))
- || (to_check.y() > maximum(vert_1.y(), vert_2.y())) ) continue;
- double x_intersect;
- if (vert_2.x() == vert_1.x()) {
- x_intersect = vert_2.x();
- } else {
- double m = (vert_2.y() - vert_1.y()) / (vert_2.x() - vert_1.x());
- x_intersect = 1.0 / m * (to_check.y() - vert_1.y() + m * vert_1.x());
- }
- if (x_intersect > to_check.x()) right_intersect_count++;
- }
- return !!(right_intersect_count % 2);
-}
-
-}
-
-
-
-
+++ /dev/null
-#ifndef POLYGON_CLASS
-#define POLYGON_CLASS
-
-/*****************************************************************************\
-* *
-* Name : polygon *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-//! Represents a multi-sided geometric figure made of line segments.
-/*!
- The polygon is a list of points that are assumed to be connected. It will
- have as many sides as its point count minus one. Thus there is no valid
- polygon with less than three points. A function that tests whether a point
- is inside or outside the polygon is provided.
-*/
-
-#include "cartesian_objects.h"
-
-#include <basis/array.h>
-
-//hmmm: it might be nice to structuralize this.
-//hmmm: also deriving from an array of points is not so great.
-
-namespace geometric {
-
-class polygon : public basis::array<geometric::cartesian_point>
-{
-public:
- polygon() {}
- ~polygon() {}
-
- void add(const cartesian_point &to_add);
- //!< adds a new point to the list that represents the polygon's sides.
-
- int points() const { return length(); }
- int sides() const { return points() - 1; }
-
- cartesian_point &operator [] (int index);
- //!< retrieves the index-th point in the list.
- /*!< this is valid for indices between zero and points() - 1. */
-
- bool inside(const cartesian_point &to_check);
- //!< Returns true if the point "to_check" is inside of this polygon.
- /*!< This function assumes that the polygon is closed when performing
- the check. */
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-#ifndef RECTANGLE_CLASS
-#define RECTANGLE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : rectangle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "point.h"
-
-#include <basis/functions.h>
-
-namespace geometric {
-
-//! Represents a geometric rectangle.
-
-template <class numeric_type>
-class rectangle : public basis::packable
-{
-public:
- rectangle(const point<numeric_type> &vertex_1,
- const point<numeric_type> &vertex_2);
- rectangle(numeric_type x_1 = 0, numeric_type y_1 = 0,
- numeric_type x_2 = 0, numeric_type y_2 = 0);
-
- numeric_type height() const;
- numeric_type width() const;
-
- rectangle order() const;
- //!< Re-orders the vertices of the line to be increasing.
- /*!< Orients the vertices such that the x and y coordinates of the first
- vertex are respectively closer to the origin than the x and y
- coordinates of the second vertex (or they are equidistant). */
-
- point<numeric_type> top_left() const;
- point<numeric_type> bottom_left() const;
- point<numeric_type> top_right() const;
- point<numeric_type> bottom_right() const;
- //!< returns the appropriate point as represented by our rectangle.
- /*!< note that these are with respect to a normal cartesian coordinate
- system. if you want points for a screen based coordinate system (with
- the origin in the top left), then bottom_left and top_right return the
- appropriate bounding points for that rectangle. */
-
- numeric_type minimum_x() const;
- //!< Return the smallest x from the points in the rectangle.
- numeric_type minimum_y() const;
- //!< Return the smallest y from the points in the rectangle.
- numeric_type maximum_x() const;
- //!< Return the largest x from the points in the rectangle.
- numeric_type maximum_y() const;
- //!< Return the largest y from the points in the rectangle.
-
- point<numeric_type> center() const;
- //!< Returns the point at the center of the rectangle.
-
- bool inside(const point<numeric_type> &to_check) const;
- //!< Returns true if `to_check' is inside `this' rectangle.
-
- bool operator == (const rectangle &to_compare) const;
- //!< Returns true if `to_compare' has vertices equal to `this'.
-
- rectangle operator + (const point<numeric_type> &to_add) const;
- //!< Returns the rectangle resulting from adding a point to its vertices.
- rectangle operator - (const point<numeric_type> &to_subtract) const;
- //!< Returns the rectangle resulting from subtracting "to_subtract".
-
- rectangle &operator += (const point<numeric_type> &to_add);
- //!< Adds the point "to_add" to our vertices.
- rectangle &operator -= (const point<numeric_type> &to_subtract);
- //!< Subtracts the point "to_add" to our vertices.
-
- void encompass(const rectangle &to_adjust_to);
- //!< Finds the largest dimension needed to contain all rectangles passed in.
- /*!< The original dimension of `this' rectangle is compared with
- all subsequent rectangles passed to adjust_dimension, and it is
- modified (joined with `to_adjust_to') if the extent of `to_adjust_to'
- is greater or lesser than the current extent of `this' rectangle. */
-
- bool intersect(const rectangle &r2) const;
- //!< Returns true if `this' & `r2' cover any common points.
-
- bool disjoint(const rectangle &r2) const;
- //!< Returns true if `this' & `r2' have mutually exclusive extents.
-
- bool join_intersecting(const rectangle &r2, rectangle &result);
- //!< Sets "result" to encompass this and "r2" if they intersect.
- /*!< If `this' and `r2' intersect, `result' is adjusted to their dimension
- and true is returned. If not, false is returned and `result' is
- undefined. */
-
- bool intersection(const rectangle &r2, rectangle &result);
- //!< Sets "result" to the intersection of this and "r2".
- /*!< If `this' and `r2' intersect, then `result' is set to their
- intersecting extent and true is returned. If not, then false is returned
- and `result' is undefined. */
-
- basis::astring text_form() const;
- //!< Prints out the contents of the rectangle.
-
- bool from_text(const basis::astring &text);
- //!< Returns true if the "text" is parsed into this rectangle.
-
- point<numeric_type> vertex_1() const;
- point<numeric_type> vertex_2() const;
-
- void vertex_1(const point<numeric_type> &to_set);
- void vertex_2(const point<numeric_type> &to_set);
-
- virtual int packed_size() const;
- virtual void pack(basis::byte_array &packed_form) const;
- virtual bool unpack(basis::byte_array &packed_form);
-
-protected:
- point<numeric_type> _vertex_1;
- point<numeric_type> _vertex_2;
-};
-
-//////////////
-
-//!< A commonly used rectangle of integers.
-
-typedef rectangle<int> int_rectangle;
-
-//////////////
-
-// implementations below...
-
-template <class numeric_type>
-rectangle<numeric_type>::rectangle(const point<numeric_type> &lb, const point<numeric_type> &rt)
-: _vertex_1(lb), _vertex_2(rt) {}
-
-template <class numeric_type>
-rectangle<numeric_type>::rectangle(numeric_type left, numeric_type bottom, numeric_type right, numeric_type top)
-: _vertex_1(point<numeric_type>(left, bottom)),
- _vertex_2(point<numeric_type>(right, top)) {}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::vertex_1() const
-{ return _vertex_1; }
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::vertex_2() const
-{ return _vertex_2; }
-
-template <class numeric_type>
-void rectangle<numeric_type>::vertex_1(const point<numeric_type> &to_set)
-{ _vertex_1 = to_set; }
-
-template <class numeric_type>
-void rectangle<numeric_type>::vertex_2(const point<numeric_type> &to_set)
-{ _vertex_2 = to_set; }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::height() const
-{ return absolute_value(_vertex_2.y() - _vertex_1.y()); }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::width() const
-{ return absolute_value(_vertex_2.x() - _vertex_1.x()); }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::minimum_x() const
-{ return basis::minimum(_vertex_1.x(), _vertex_2.x()); }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::minimum_y() const
-{ return basis::minimum(_vertex_1.y(), _vertex_2.y()); }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::maximum_x() const
-{ return basis::maximum(_vertex_1.x(), _vertex_2.x()); }
-
-template <class numeric_type>
-numeric_type rectangle<numeric_type>::maximum_y() const
-{ return basis::maximum(_vertex_1.y(), _vertex_2.y()); }
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle<numeric_type>::order() const
-{
- numeric_type x1 = _vertex_1.x();
- numeric_type x2 = _vertex_2.x();
- numeric_type y1 = _vertex_1.y();
- numeric_type y2 = _vertex_2.y();
- basis::flip_increasing(x1, x2);
- basis::flip_increasing(y1, y2);
- return rectangle<numeric_type>(x1, y1, x2, y2);
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::top_left() const
-{
- rectangle temp(order());
- return point<numeric_type>(temp.vertex_1().x(), temp.vertex_2().y());
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::bottom_left() const
-{
- rectangle temp(order());
- return point<numeric_type>(temp.vertex_1().x(), temp.vertex_1().y());
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::top_right() const
-{
- rectangle temp(order());
- return point<numeric_type>(temp.vertex_2().x(), temp.vertex_2().y());
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::bottom_right() const
-{
- rectangle temp(order());
- return point<numeric_type>(temp.vertex_2().x(), temp.vertex_1().y());
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle<numeric_type>::center() const
-{
- return point<numeric_type>(numeric_type((_vertex_1.x()
- + _vertex_2.x()) / 2.0), numeric_type((_vertex_1.y()
- + _vertex_2.y()) / 2.0));
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::inside(const point<numeric_type> &to_check) const
-{
- rectangle<numeric_type> ordered_me = this->order();
- return bool( (to_check.x() >= ordered_me._vertex_1.x())
- && (to_check.x() <= ordered_me._vertex_2.x())
- && (to_check.y() >= ordered_me._vertex_1.y())
- && (to_check.y() <= ordered_me._vertex_2.y()) );
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::operator == (const rectangle &to_compare) const
-{
- point<numeric_type> min1(minimum_x(), minimum_y());
- point<numeric_type> max1(maximum_x(), maximum_y());
- point<numeric_type> min2(to_compare.minimum_x(), to_compare.minimum_y());
- point<numeric_type> max2(to_compare.maximum_x(), to_compare.maximum_y());
- if ( (min1 == min2) && (max1 == max2) ) return true;
- else return false;
-}
-
-template <class numeric_type>
-rectangle<numeric_type> &rectangle<numeric_type>::operator += (const point<numeric_type> &p)
-{ _vertex_1 += p; _vertex_2 += p; return *this; }
-
-template <class numeric_type>
-rectangle<numeric_type> &rectangle<numeric_type>::operator -= (const point<numeric_type> &p)
-{ _vertex_1 -= p; _vertex_2 -= p; return *this; }
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle<numeric_type>::operator + (const point<numeric_type> &p) const
-{
- rectangle to_return(*this);
- to_return += p;
- return to_return;
-}
-
-template <class contents>
-int rectangle<contents>::packed_size() const
-{
- basis::byte_array temp;
-//hmmm: inefficient!
- pack(temp);
- return temp.length();
-}
-
-template <class contents>
-void rectangle<contents>::pack(basis::byte_array &packed_form) const
-{
- _vertex_1.pack(packed_form);
- _vertex_2.pack(packed_form);
-}
-
-template <class contents>
-bool rectangle<contents>::unpack(basis::byte_array &packed_form)
-{
- if (!_vertex_1.unpack(packed_form)) return false;
- if (!_vertex_2.unpack(packed_form)) return false;
- return true;
-}
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle<numeric_type>::operator - (const point<numeric_type> &p) const
-{
- rectangle to_return(*this);
- to_return -= p;
- return to_return;
-}
-
-template <class numeric_type>
-void rectangle<numeric_type>::encompass(const rectangle &to_adjust_to)
-{
- if (to_adjust_to._vertex_1.x() < _vertex_1.x())
- _vertex_1.set(to_adjust_to._vertex_1.x(), _vertex_1.y());
- if (to_adjust_to._vertex_1.y() < _vertex_1.y())
- _vertex_1.set(_vertex_1.x(), to_adjust_to._vertex_1.y());
- if (to_adjust_to._vertex_2.x() > _vertex_2.x())
- _vertex_2.set(to_adjust_to._vertex_2.x(), _vertex_2.y());
- if (to_adjust_to._vertex_2.y() > _vertex_2.y())
- _vertex_2.set(_vertex_2.x(), to_adjust_to._vertex_2.y());
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::disjoint(const rectangle &r2) const
-{
- if ( (maximum_x() < r2.minimum_x())
- || (minimum_x() > r2.maximum_x())
- || (maximum_y() < r2.minimum_y())
- || (minimum_y() > r2.maximum_y()) ) return true;
- else return false;
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::intersect(const rectangle &r2) const
-{ return bool(!disjoint(r2)); }
-
-template <class numeric_type>
-bool rectangle<numeric_type>::join_intersecting(const rectangle &r2, rectangle &result)
-{
- if (disjoint(r2)) return false;
- result = *this;
- result.encompass(r2);
- return true;
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::intersection(const rectangle &r2, rectangle &result)
-{
- if (disjoint(r2)) return false;
- result = rectangle<numeric_type>(basis::maximum(minimum_x(), r2.minimum_x()),
- basis::maximum(minimum_y(), r2.minimum_y()),
- basis::minimum(maximum_x(), r2.maximum_x()),
- basis::minimum(maximum_y(), r2.maximum_y()));
- return true;
-}
-
-template <class numeric_type>
-basis::astring rectangle<numeric_type>::text_form() const
-{
- return basis::astring("[") + _vertex_1.text_form() + basis::astring(" ")
- + _vertex_2.text_form() + basis::astring("]");
-}
-
-template <class numeric_type>
-bool rectangle<numeric_type>::from_text(const basis::astring &_text)
-{
- numeric_type nums[4] = { 0, 0, 0, 0 };
- // setup the scanning specifier.
- basis::astring spec(numeric_specifier(nums[0]));
- // scan the string for values.
- basis::astring text(_text);
- for (int i = 0; i < 4; i++) {
- text = crop_non_numeric(text);
- nums[i] = text.convert(nums[i]);
- text = crop_numeric(text);
- }
- vertex_1(point<numeric_type>(nums[0], nums[1]));
- vertex_2(point<numeric_type>(nums[2], nums[3]));
- return true;
-}
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-
-
-
-/*****************************************************************************\
-* *
-* Name : screen_rectangle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "rectangle.h"
-#include "screen_rectangle.h"
-
-#include <basis/mutex.h>
-
-#include <structures/static_memory_gremlin.h>
-
-using namespace basis;
-
-namespace geometric {
-
-SAFE_STATIC_CONST(screen_point, screen_origin, (0, 0))
-
-//////////////
-
-#ifdef __WIN32__
-screen_point::screen_point(const tagPOINT &original) : point<int>(original.x, original.y) {}
-
-screen_point::operator tagPOINT()
-{ POINT to_return; to_return.x = x(); to_return.y = y(); return to_return; }
-#endif
-
-//////////////
-
-screen_rectangle::screen_rectangle(const rectangle<int> &init)
-: rectangle<int>(init) {}
-
-screen_rectangle::screen_rectangle(const screen_point &vertex_1,
- const screen_point &vertex_2)
-: rectangle<int>(vertex_1, vertex_2) {}
-
-screen_rectangle::screen_rectangle(int x_1, int y_1, int x_2, int y_2)
-: rectangle<int>(x_1, y_1, x_2, y_2) {}
-
-screen_rectangle screen_rectangle::order() const
-{ return screen_rectangle(top_left(), bottom_right()); }
-
-screen_point screen_rectangle::top_left() const
-{ return rectangle<int>::bottom_left(); }
-
-screen_point screen_rectangle::bottom_left() const
-{ return rectangle<int>::top_left(); }
-
-screen_point screen_rectangle::top_right() const
-{ return rectangle<int>::bottom_right(); }
-
-screen_point screen_rectangle::bottom_right() const
-{ return rectangle<int>::top_right(); }
-
-#ifdef __WIN32__
-screen_rectangle::screen_rectangle(const tagRECT &original)
-: rectangle<int>(original.left, original.top, original.right, original.bottom)
-{}
-
-screen_rectangle::operator tagRECT() const
-{
- RECT to_return; to_return.left = left();
- to_return.top = top(); to_return.right = right();
- to_return.bottom = bottom(); return to_return;
-}
-#endif
-
-} // namespace.
-
-
-
+++ /dev/null
-#ifndef SCREEN_RECTANGLE_CLASS
-#define SCREEN_RECTANGLE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : screen_rectangle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include <application/windoze_helper.h>
-
-#include "rectangle.h"
-
-#ifdef __WIN32__
- // forward.
- struct tagPOINT; struct tagRECT;
-#endif
-
-namespace geometric {
-
-// forward.
-class double_angle;
-
-//! a simple class used to describe points on a graphics screen.
-
-class screen_point : public point<int>
-{
-public:
- screen_point(int x = 0, int y = 0) : point<int>(x, y) {}
- screen_point(int r, double_angle theta) : point<int>(r, theta) {}
- screen_point(const point<int> &original) : point<int>(original) {}
- DEFINE_CLASS_NAME("screen_point");
-
-#ifdef __WIN32__
- screen_point(const tagPOINT &original);
- //!< helpful conversions from basic ms-windows type.
- operator tagPOINT();
- //!< helpful conversions to basic ms-windows type.
-#endif
-};
-
-const screen_point &screen_origin();
- //!< the origin of the screen coordinate system (which is top-left here).
-
-//////////////
-
-//! Represents a rectangle as interpreted on display screens.
-/*!
- The origin is the top-left corner of the rectangle and the y coordinate
- gets larger as one goes downwards. This class is primarily useful in
- conjunction with a windowing environment.
-*/
-
-class screen_rectangle : public rectangle<int>
-{
-public:
- screen_rectangle(const screen_point &vertex_1, const screen_point &vertex_2);
- screen_rectangle(int x_1 = 0, int y_1 = 0, int x_2 = 0, int y_2 = 0);
- screen_rectangle(const rectangle<int> &init);
-
- screen_rectangle order() const;
- //!< Re-orders the vertices to match expectations.
- /*!< This is just like rectangle::order() except that the first vertex
- will be closest to the top-left of the screen. */
-
- screen_point top_left() const;
- screen_point bottom_left() const;
- screen_point top_right() const;
- screen_point bottom_right() const;
-
- int left() const { return top_left().x(); }
- int top() const { return top_left().y(); }
- int right() const { return bottom_right().x(); }
- int bottom() const { return bottom_right().y(); }
-
-#ifdef __WIN32__
- screen_rectangle(const tagRECT &original);
- //!< helpful conversion from basic ms-windows type.
- operator tagRECT() const;
- //!< helpful conversion to basic ms-windows type.
-#endif
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-
-
-
-/*****************************************************************************\
-* *
-* Name : triangle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include "cartesian_objects.h"
-#include "line.h"
-#include "rectangle.h"
-#include "triangle.h"
-
-namespace geometric {
-
-triangle::triangle()
-: _vertex_1(cartesian_point::origin()),
- _vertex_2(cartesian_point::origin()),
- _vertex_3(cartesian_point::origin())
-{}
-
-triangle::triangle(const cartesian_point &vertex_1,
- const cartesian_point &vertex_2, const cartesian_point &vertex_3)
-: _vertex_1(vertex_1),
- _vertex_2(vertex_2),
- _vertex_3(vertex_3)
-{}
-
-triangle::triangle(const triangle &to_copy)
-: _vertex_1(to_copy._vertex_1),
- _vertex_2(to_copy._vertex_2),
- _vertex_3(to_copy._vertex_3)
-{}
-
-triangle::~triangle() {}
-
-triangle &triangle::operator =(const triangle &to_copy)
-{
- if (this == &to_copy) return *this;
- _vertex_1 = to_copy._vertex_1;
- _vertex_2 = to_copy._vertex_2;
- _vertex_3 = to_copy._vertex_3;
- return *this;
-}
-
-line<double> triangle::side_1_2() const
-{ return line<double>(_vertex_1, _vertex_2); }
-
-line<double> triangle::side_2_3() const
-{ return line<double>(_vertex_2, _vertex_3); }
-
-line<double> triangle::side_3_1() const
-{ return line<double>(_vertex_3, _vertex_1); }
-
-cartesian_point triangle::vertex_1() const { return _vertex_1; }
-
-cartesian_point triangle::vertex_2() const { return _vertex_2; }
-
-cartesian_point triangle::vertex_3() const { return _vertex_3; }
-
-void triangle::vertex_1(const cartesian_point &to_set) { _vertex_1 = to_set; }
-
-void triangle::vertex_2(const cartesian_point &to_set) { _vertex_2 = to_set; }
-
-void triangle::vertex_3(const cartesian_point &to_set) { _vertex_3 = to_set; }
-
-bool triangle::inside(const cartesian_point &where) const
-{
-//cerr << "triangle::inside: not implemented" << endl << flush;
-if (where.x()) where.y(); // bogus.
- return false;
-}
-
-double triangle::area() const
-{
-//cerr << "triangle::area: not implemented" << endl << flush;
- return 5;
-}
-
-} // namespace.
-
-/*
-//temp
-#include "warper.h"
-using namespace geometric;
-typedef rectangle_warper<double> chuzzo;
-chuzzo beanburp = chuzzo(rectangle<double>(0, 23, 39, 1012),
- rectangle<double>(8, 19, 92982, -2), chuzzo::BOTTOM_RIGHT,
- chuzzo::TOP_LEFT);
-typedef rectangle_warper<double>::horizontal_component horzo;
-typedef rectangle_warper<double>::vertical_component verzo;
-int frunk() {
- horzo peen;
- beanburp.separate_horizontal(chuzzo::BOTTOM_RIGHT, peen);
- verzo neep;
- beanburp.separate_vertical(chuzzo::TOP_RIGHT, neep);
-}
-*/
-
-
-
-
-
+++ /dev/null
-#ifndef TRIANGLE_CLASS
-#define TRIANGLE_CLASS
-
-/*****************************************************************************\
-* *
-* Name : triangle *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-
-
-// forward.
-class cartesian_line;
-class cartesian_point;
-
-namespace geometric {
-
-//! Represents a geometric triangle.
-
-class triangle
-{
-public:
- triangle();
- triangle(const cartesian_point &vertex1, const cartesian_point &vertex2,
- const cartesian_point &vertex3);
- triangle(const triangle &to_copy);
- ~triangle();
-
- triangle &operator =(const triangle &to_copy);
-
- bool inside(const cartesian_point &where) const;
-
- double area() const;
-
- line<double> side_1_2() const;
- line<double> side_2_3() const;
- line<double> side_3_1() const;
-
- cartesian_point vertex_1() const;
- cartesian_point vertex_2() const;
- cartesian_point vertex_3() const;
-
- void vertex_1(const cartesian_point &to_set);
- void vertex_2(const cartesian_point &to_set);
- void vertex_3(const cartesian_point &to_set);
-
-protected:
- cartesian_point _vertex_1;
- cartesian_point _vertex_2;
- cartesian_point _vertex_3;
-};
-
-} // namespace.
-
-#endif
-
+++ /dev/null
-#ifndef RECTANGLE_WARPER_CLASS
-#define RECTANGLE_WARPER_CLASS
-
-/*****************************************************************************\
-* *
-* Name : rectangle_warper *
-* Author : Chris Koeritz *
-* *
-*******************************************************************************
-* Copyright (c) 1992-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-//! Warps points in one frame of reference to a different one.
-/*!
- This class encapsulates the notion of a rectangular region that is
- referred to from two different points of view. This relates two
- two-dimensional frames of reference to each other. Each frame of reference
- is specified by two rectangles. A point that is measured in one frame of
- reference can be transformed into a point that is measured in the other,
- and vice-versa.
-*/
-
-#include "rectangle.h"
-
-#include <basis/astring.h>
-
-namespace geometric {
-
-template <class numeric_type>
-class rectangle_warper
-{
-public:
- //! describes where a rectangle's origin is located on the rectangle.
- /*! our model is to consider the first vertex point of the rectangle as its
- origin and the second vertex point (diagonally opposite the first point) as
- its extent. since it may make sense for that first vertex point to be
- located at any one of the vertices of the rectangle (as in windowing
- coordinate system conversions), the enumeration below allows any one of the
- rectangle's vertices to be chosen as its origin. */
- enum origin_vertex { BOTTOM_LEFT, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT };
-
- rectangle_warper(const rectangle<numeric_type> &system_1,
- const rectangle<numeric_type> &system_2,
- origin_vertex system_1_origin = BOTTOM_LEFT,
- origin_vertex system_2_origin = BOTTOM_LEFT);
- //!< constructs a warper given the two reference systems.
- /*!< constructs a warper where the first rectangular system is in
- "system_1", the second system is in "system_2" and the respective origins
- for these systems are in "system_1_origin" and "system_2_origin". */
-
- ~rectangle_warper();
-
- point<numeric_type> to_system_1(const point<numeric_type> &in_system_2) const;
- //!< Converts from the second system into the first.
- /*!< This returns a point that is measured in the first frame of reference
- when given a point "in_system_2" that is measured in the second frame of
- reference. */
-
- point<numeric_type> to_system_2(const point<numeric_type> &in_system_1) const;
- //!< Converts from the first system into the second.
- /*!< This returns a point that is measured in the second frame of reference
- when given a point "in_system_1" that is measured in the first frame of
- reference. */
-
- rectangle<numeric_type> to_system_1
- (const rectangle<numeric_type> &in_system_2) const;
- //!< flips a rectangle from the second system into the first.
- rectangle<numeric_type> to_system_2
- (const rectangle<numeric_type> &in_system_1) const;
- //!< flips a rectangle from the first system into the second.
-
- rectangle<numeric_type> system_1() const { return _system_1; }
- rectangle<numeric_type> system_2() const { return _system_2; }
- origin_vertex origin_1() const { return _vert_1; }
- origin_vertex origin_2() const { return _vert_2; }
-
- void system_1(const rectangle<numeric_type> &to_set,
- origin_vertex origin_corner = BOTTOM_LEFT);
- void system_2(const rectangle<numeric_type> &to_set,
- origin_vertex origin_corner = BOTTOM_LEFT);
-
- basis::astring text_form() const;
- //!< Prints out the two systems held in the rectangle_warper.
-
- basis::astring vertex_name(origin_vertex v) const;
- //!< Prints out the name of the vertex location.
-
- enum vertical_component { RW_BOTTOM, RW_TOP };
- enum horizontal_component { RW_LEFT, RW_RIGHT };
-
- void separate_vertical(origin_vertex v, vertical_component &to_set) const;
- void separate_horizontal(origin_vertex v, horizontal_component &to_set) const;
- //!< separates out a component of the placement of the vertex.
-
-private:
- rectangle<numeric_type> _system_1;
- rectangle<numeric_type> _system_2;
- origin_vertex _vert_1;
- origin_vertex _vert_2;
-
- point<numeric_type> scale_point(const rectangle<numeric_type> &source,
- const rectangle<numeric_type> &target,
- origin_vertex v1, origin_vertex v2,
- const point<numeric_type> &old) const;
- rectangle<numeric_type> scale_rectangle(const rectangle<numeric_type> &source,
- const rectangle<numeric_type> &target,
- origin_vertex v1, origin_vertex v2,
- const rectangle<numeric_type> &old) const;
- rectangle<numeric_type> flip_accordingly
- (const rectangle<numeric_type> &to_flip, origin_vertex to_flip_origin,
- origin_vertex target_origin) const;
- //!< Flips the points in "to_flip" to match the "target_origin".
- /*!< swaps the points contained in a rectangle that uses a particular point
- as the vertex ("to_flip_origin") so that the points are arranged
- according to a second choice of vertex ("target_origin"). */
-};
-
-//////////////
-
-// implementations for longer methods below...
-
-template <class numeric_type>
-rectangle_warper<numeric_type>::rectangle_warper
- (const rectangle<numeric_type> &system_1,
- const rectangle<numeric_type> &system_2,
- origin_vertex v1, origin_vertex v2)
-: _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2)
-{}
-
-template <class numeric_type>
-rectangle_warper<numeric_type>::~rectangle_warper() {}
-
-template <class numeric_type>
-void rectangle_warper<numeric_type>::system_1
- (const rectangle<numeric_type> &to_set, origin_vertex v)
-{ _system_1 = to_set; _vert_1 = v; }
-
-template <class numeric_type>
-void rectangle_warper<numeric_type>::system_2
- (const rectangle<numeric_type> &to_set, origin_vertex v)
-{ _system_2 = to_set; _vert_2 = v; }
-
-template <class numeric_type>
-point<numeric_type> rectangle_warper<numeric_type>::to_system_1
- (const point<numeric_type> &in_system_2) const
-{ return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); }
-
-template <class numeric_type>
-point<numeric_type> rectangle_warper<numeric_type>::to_system_2
- (const point<numeric_type> &in_system_1) const
-{ return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); }
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_1
- (const rectangle<numeric_type> &in_system_2) const
-{
- return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1,
- in_system_2);
-}
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_2
- (const rectangle<numeric_type> &in_system_1) const
-{
- return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2,
- in_system_1);
-}
-
-template <class numeric_type>
-void rectangle_warper<numeric_type>::separate_vertical
- (origin_vertex v, vertical_component &to_set) const
-{
- if ( (v == BOTTOM_LEFT) || (v == BOTTOM_RIGHT) ) to_set = RW_BOTTOM;
- to_set = RW_TOP;
-}
-
-template <class numeric_type>
-void rectangle_warper<numeric_type>::separate_horizontal
- (origin_vertex v, horizontal_component &to_set) const
-{
- if ( (v == BOTTOM_LEFT) || (v == TOP_LEFT) ) to_set = RW_LEFT;
- to_set = RW_RIGHT;
-}
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle_warper<numeric_type>::flip_accordingly
- (const rectangle<numeric_type> &to_flip, origin_vertex flipo,
- origin_vertex targo) const
-{
-//LOG(basis::astring("flipping ") + to_flip.text_form() + " from " + flipo.text_form() + " to " + targo.text_form());
- if (flipo == targo) return to_flip;
- numeric_type x1(to_flip.vertex_1().x());
- numeric_type y1(to_flip.vertex_1().y());
- numeric_type x2(to_flip.vertex_2().x());
- numeric_type y2(to_flip.vertex_2().y());
- horizontal_component horiz1;
- separate_horizontal(flipo, horiz1);
- horizontal_component horiz2;
- separate_horizontal(targo, horiz2);
- bool flip_x = bool(horiz1 != horiz2);
- vertical_component vert1;
- separate_vertical(flipo, vert1);
- vertical_component vert2;
- separate_vertical(targo, vert2);
- bool flip_y = bool(vert1 != vert2);
- if (flip_x) basis::swap_values(x1, x2);
- if (flip_y) basis::swap_values(y1, y2);
-//LOG(basis::astring("it becomes ") + rectangle<numeric_type>(x1, y1, x2, y2).text_form());
- return rectangle<numeric_type>(x1, y1, x2, y2);
-}
-
-template <class numeric_type>
-rectangle<numeric_type> rectangle_warper<numeric_type>::scale_rectangle
- (const rectangle<numeric_type> &source,
- const rectangle<numeric_type> &target, origin_vertex source_origin,
- origin_vertex target_origin, const rectangle<numeric_type> &old) const
-{
- rectangle<numeric_type> s = rectangle<numeric_type>
- (flip_accordingly(source, source_origin, BOTTOM_LEFT));
- numeric_type width_source = s.vertex_2().x() - s.vertex_1().x();
- numeric_type height_source = s.vertex_2().y() - s.vertex_1().y();
- if ( !width_source || !height_source ) {
-// cerr << "degenerate rectangle in rectangle_warper::scaler: " << s
-// << endl << flush;
- return old;
- }
- rectangle<numeric_type> t(flip_accordingly(target, target_origin, BOTTOM_LEFT));
- numeric_type width_target = t.vertex_2().x() - t.vertex_1().x();
- numeric_type height_target = t.vertex_2().y() - t.vertex_1().y();
- numeric_type x_scale = width_target / width_source;
- numeric_type y_scale = height_target / height_source;
-
-//LOG(basis::astring("scaler: source ") + source.text_form() + " with vert " + source_origin.text_form() + " becomes " + s + " target " + target + " with vert " + target_origin + " becomes " + t + ".");
-
- rectangle<numeric_type> o(flip_accordingly(old, source_origin, BOTTOM_LEFT));
-
- rectangle<numeric_type> to_return = flip_accordingly(rectangle<numeric_type>
- ((o.vertex_1().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
- (o.vertex_1().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y(),
- (o.vertex_2().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
- (o.vertex_2().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y()),
- BOTTOM_LEFT, target_origin);
-
-// LOG(basis::astring("old ") + old.text_form() + " with source vert becomes " + o.text_form() + " and then is moved into " + to_return.text_form());
-
- return to_return;
-}
-
-template <class numeric_type>
-point<numeric_type> rectangle_warper<numeric_type>::scale_point
- (const rectangle<numeric_type> &source, const rectangle<numeric_type> &target,
- origin_vertex source_origin, origin_vertex target_origin,
- const point<numeric_type> &old) const
-{
- // gross but simple.
- return scale_rectangle(source, target, source_origin, target_origin,
- rectangle<numeric_type>(old, old)).vertex_1();
-}
-
-template <class numeric_type>
-basis::astring rectangle_warper<numeric_type>::vertex_name(origin_vertex v) const
-{
- basis::astring name("unknown");
- switch (v) {
- case BOTTOM_LEFT: name = "bottom-left"; break;
- case BOTTOM_RIGHT: name = "bottom-right"; break;
- case TOP_LEFT: name = "top-left"; break;
- case TOP_RIGHT: name = "top-right"; break;
- }
- return name;
-}
-
-template <class numeric_type>
-basis::astring rectangle_warper<numeric_type>::text_form() const
-{
- return basis::astring("<warps from: ") + _system_1.text_form()
- + basis::astring(" with vertex at ") + vertex_name(_vert_1)
- + basis::astring(" into ") + _system_2.text_form()
- + basis::astring(" with vertex at ") + vertex_name(_vert_2)
- + basis::astring(">");
-}
-
-} // namespace.
-
-#endif
-
include variables.def
PROJECT = graphical_libraries
-BUILD_BEFORE = geometric \
- user_interface \
+BUILD_BEFORE = user_interface
+#wrong hierarchical considerations having geometric here.
+#geometric \
tests_geometric
include rules.def
+++ /dev/null
-include cpp/variables.def
-
-PROJECT = test_geometric
-TYPE = test
-TARGETS = test_angle.exe test_ellipse.exe test_geometry.exe test_point.exe test_warper.exe \
- test_ccri_angle_average.exe
-LOCAL_LIBS_USED = unit_test application filesystem timely loggers configuration textual \
- structures geometric basis
-RUN_TARGETS = $(ACTUAL_TARGETS)
-
-include cpp/rules.def
-
+++ /dev/null
-/*
-* Name : test_angle *
-* Author : Chris Koeritz *
-* Purpose: *
-* Tests the angle class. *
-**
-* Copyright (c) 2001-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-*/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <geometric/angle.h>
-#include <loggers/program_wide_logger.h>
-#include <mathematics/double_plus.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace mathematics;
-using namespace structures;
-using namespace unit_test;
-
-typedef double_plus floot;
-
-class test_angle : public virtual unit_base, public virtual application_shell
-{
-public:
- test_angle() : application_shell() {}
- DEFINE_CLASS_NAME("test_angle");
- virtual int execute();
-};
-
-int test_angle::execute()
-{
- FUNCDEF("execute");
- {
- // first test group: double angle inverse trigonometrics.
- angle<double> a(30.3, DEGREES);
- ASSERT_EQUAL(floot(a.get(RADIANS)), floot(.528835), "radian conversion should be right");
-
- outcome retval;
- angle<double> at = angle<double>::arctangent(28.3, 29.5, retval);
- ASSERT_EQUAL(floot(at.get(DEGREES)), floot(43.8106), "atan should be what we expect");
- angle<double> as = angle<double>::arcsine(17.6, 82.3, retval);
- ASSERT_EQUAL(floot(as.get(DEGREES)), floot(12.3482), "asin should be what we expect");
- angle<double> ac = angle<double>::arccosine(17.2, 42.0, retval);
- ASSERT_EQUAL(floot(ac.get(DEGREES)), floot(65.8251), "acos should be what we expect");
- }
- {
- // second test: packing an angle.
- angle<double> q(128, DEGREES);
- byte_array pacd;
- int siz = q.packed_size();
- q.pack(pacd);
- ASSERT_EQUAL(siz, pacd.length(), "packed size should report proper length");
- angle<double> x;
- x.unpack(pacd);
- ASSERT_EQUAL(floot(q.get(RADIANS)), floot(x.get(RADIANS)),
- "unpacking should return original value");
- ASSERT_FALSE(pacd.length(), "unpacking should consume entire array");
- }
-
- return final_report();
-}
-
-//////////////
-
-HOOPLE_MAIN(test_angle, )
-
+++ /dev/null
-
-/*
- * Name : test_ccri_angle_average
- * Author : Chris Koeritz
- * Purpose:
- * Tests the angle averaging method (for angles in degrees)
- *
- * Copyright (c) 2001-$now By Author. 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 is online at:
- * http://www.fsf.org/copyleft/gpl.html
- * Please send any updates to: fred@gruntose.com
-*/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <geometric/angle.h>
-#include <loggers/program_wide_logger.h>
-#include <mathematics/double_plus.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace mathematics;
-using namespace structures;
-using namespace unit_test;
-
-typedef double_plus floot;
-
-class test_ccri_angle_average : public virtual unit_base, public virtual application_shell
-{
-public:
- test_ccri_angle_average() : application_shell() {}
- DEFINE_CLASS_NAME("test_ccri_angle_average");
- virtual int execute();
-
- // returns average of angles a1 and a2, in degrees.
- double angleAverage(double a1, double a2) {
- a1 = fmod(a1, 360.0);
- a2 = fmod(a2, 360.0);
- if (absolute_value(a1 - a2) > 180.0) {
- if (a1 < 180.0) a1 += 360.0;
- else a2 += 360.0;
- }
- return fmod( (a1 + a2) / 2.0, 360.0);
- }
-
-};
-
-int test_ccri_angle_average::execute()
-{
- FUNCDEF("execute");
-
- outcome retval;
- double a1, a2, avg;
-
- // there could be two right answers for angles 180 degrees apart, but we only test for one.
- a1 = 23; a2 = 203;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(113), a_sprintf("%f and %f 180 degrees apart", a1, a2));
- a1 = 359; a2 = 179;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(269), a_sprintf("%f and %f 180 degrees apart", a1, a2));
- a1 = 90; a2 = 270;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(180), a_sprintf("%f and %f 180 degrees apart", a1, a2));
-
- // more cases.
- a1 = 89; a2 = 274;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(1.5), a_sprintf("%f and %f", a1, a2));
- a1 = 89.9; a2 = 270.1;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
- a1 = 0; a2 = 0;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
- a1 = 0; a2 = 359;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(359.5), a_sprintf("%f and %f", a1, a2));
- a1 = 358; a2 = 359;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(358.5), a_sprintf("%f and %f", a1, a2));
- a1 = 1; a2 = 357;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(359), a_sprintf("%f and %f", a1, a2));
- a1 = 23; a2 = 160;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(91.5), a_sprintf("%f and %f", a1, a2));
- a1 = 47; a2 = 221;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(134), a_sprintf("%f and %f", a1, a2));
- a1 = 113; a2 = 114;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(113.5), a_sprintf("%f and %f", a1, a2));
- a1 = 113; a2 = 270;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(191.5), a_sprintf("%f and %f", a1, a2));
- a1 = 190; a2 = 230;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(210), a_sprintf("%f and %f", a1, a2));
- a1 = 12; a2 = 273;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(322.5), a_sprintf("%f and %f", a1, a2));
- a1 = 181; a2 = 179;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(180), a_sprintf("%f and %f", a1, a2));
- a1 = 89; a2 = 271;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
-
- a1 = 359; a2 = 120;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(59.5), a_sprintf("%f and %f", a1, a2));
- a1 = 220; a2 = 359;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(289.5), a_sprintf("%f and %f", a1, a2));
- a1 = 3; a2 = 189;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(276), a_sprintf("%f and %f", a1, a2));
- a1 = 93; a2 = 275;
- avg = angleAverage(a1, a2);
- ASSERT_EQUAL(floot(avg), floot(4), a_sprintf("%f and %f", a1, a2));
-
- return final_report();
-}
-
-//////////////
-
-HOOPLE_MAIN(test_ccri_angle_average, )
-
+++ /dev/null
-/*
-* Name : test_ellipse *
-* Author : Chris Koeritz *
-* Purpose: *
-* Tests the ellipse class. *
-**
-* Copyright (c) 1993-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-*/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <basis/guards.h>
-#include <geometric/cartesian_objects.h>
-#include <geometric/ellipse.h>
-#include <geometric/point.h>
-#include <mathematics/double_plus.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace mathematics;
-using namespace structures;
-using namespace unit_test;
-
-typedef cartesian_point e_point;
-
-class test_ellipse : virtual public unit_base, virtual public application_shell
-{
-public:
- test_ellipse() : application_shell() {}
- DEFINE_CLASS_NAME("test_ellipse");
- int execute();
- point<double> supposed_good_value(const angle<double> &rotation);
-};
-
-point<double> test_ellipse::supposed_good_value(const angle<double> &rotation)
-{
- double_plus rot(rotation.get(DEGREES));
-//log(a_sprintf("rotation coming in is %f", rot.value()));
- if (rot == double_plus(0.0)) return point<double>(25.000000, 20.0000);
- if (rot == double_plus(35.3)) return point<double>(24.7134, 23.3372);
- if (rot == double_plus(70.6)) return point<double>(22.8791, 28.1757);
- if (rot == double_plus(105.9)) return point<double>(17.5249, 11.3112);
- if (rot == double_plus(141.2)) return point<double>(15.3608, 16.2700);
- if (rot == double_plus(176.5)) return point<double>(15.0023, 19.6943);
- if (rot == double_plus(211.8)) return point<double>(15.2242, 22.9611);
- if (rot == double_plus(247.1)) return point<double>(16.7732, 27.6388);
- if (rot == double_plus(282.4)) return point<double>(22.0127, 10.8459);
- if (rot == double_plus(317.7)) return point<double>(24.5511, 15.8588);
- if (rot == double_plus(353.0)) return point<double>(24.9906, 19.3872);
- return point<double>(0, 0); // unknown angle.
-}
-
-int test_ellipse::execute()
-{
- FUNCDEF("execute");
- ellipse fred(e_point(20, 20), 5, 10);
- for (double i = 0; i < 360.0; i += 35.3) {
- e_point where(fred.location(double_angle(i, DEGREES)));
- a_sprintf test_name("%.2f", double_angle(i, DEGREES).get(DEGREES));
-// log(astring(astring::SPRINTF, "at angle %f ellipse is at ", i) + where.text_form());
- point<double> compare = supposed_good_value(double_angle(i, DEGREES));
- // right now point is not orderable, so we compare x and y but use the same test name.
- ASSERT_EQUAL(double_plus(where.x()), double_plus(compare.x()),
- test_name + " rotation should have proper position");
- ASSERT_EQUAL(double_plus(where.y()), double_plus(compare.y()),
- test_name + " rotation should have proper position");
- }
- return final_report();
-}
-
-//////////////
-
-HOOPLE_MAIN(test_ellipse, )
-
+++ /dev/null
-/*
-* Name : test_geometry *
-* Author : Chris Koeritz *
-* Purpose: *
-* Exercises some of the classes in the geometry library. *
-**
-* Copyright (c) 2001-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-*/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <basis/guards.h>
-#include <geometric/cartesian_objects.h>
-#include <geometric/circle.h>
-#include <geometric/ellipse.h>
-#include <geometric/line.h>
-#include <geometric/screen_rectangle.h>
-#include <geometric/rectangle.h>
-#include <geometric/warper.h>
-#include <geometric/triangle.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace structures;
-using namespace unit_test;
-using namespace geometric;
-
-class test_geometric : public virtual unit_base, public virtual application_shell
-{
-public:
- test_geometric() {}
- DEFINE_CLASS_NAME("test_geometric");
- virtual int execute();
-};
-
-int test_geometric::execute()
-{
- FUNCDEF("execute");
- // test constructors
- circle fred;
- ellipse tobias;
- line<double> slugmart;
- rectangle<double> burger;
- rectangle_warper<double> space_warp(burger, burger);
- triangle euclid;
-
- burger = cartesian_rectangle(23, 19, 82, 745);
- ASSERT_TRUE(burger.from_text(astring("84.0 290.0 10.0 912.0")),
- "cartesian from_text test should not return failure");
- ASSERT_FALSE(burger != cartesian_rectangle(84.0, 290.0, 10.0, 912.0),
- "cartesian from_text test should compare with expected value");
-
- screen_rectangle xingu(23, 19, 82, 745);
- ASSERT_TRUE(xingu == screen_rectangle(screen_point(23, 19), screen_point(82, 745)),
- "xingu screen test construction should agree with expectations");
- ASSERT_TRUE(xingu.from_text(astring("84 290 10 912")),
- "xingu screen from_text test should not return failure");
- ASSERT_TRUE(xingu == screen_rectangle(84, 290, 10, 912),
- "xingu screen from_text test should compare with expected value");
-
- screen_rectangle guinness(-223, 19, 82, -745);
- ASSERT_TRUE(guinness == screen_rectangle(screen_point(-223, 19), screen_point(82, -745)),
- "guinness screen test construction should agree with expectations");
- ASSERT_TRUE(guinness.from_text(astring("-84 290 -10 912")),
- "guinness screen from_text test should not return failure");
- ASSERT_TRUE(guinness == screen_rectangle(-84, 290, -10, 912),
- "screen from_text test should compare with expected value");
-
-//log(astring(astring::SPRINTF, "the string form is %s.", guinness.text_form().s()));
-
- // test non-mainstream constructors
- // test non-mainstream constructors
-
- // test operators
-
- // test conversions
-
- // test class specific functions
-
- // test other things?
-
- return final_report();
-}
-
-HOOPLE_MAIN(test_geometric, );
-
+++ /dev/null
-/*****************************************************************************\
-* *
-* Name : test_point *
-* Author : Chris Koeritz *
-* *
-* Purpose: *
-* *
-* Tests out the point class. *
-* *
-*******************************************************************************
-* Copyright (c) 2002-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <basis/guards.h>
-#include <geometric/point.h>
-#include <loggers/console_logger.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace structures;
-using namespace unit_test;
-
-class test_point : virtual public unit_base, virtual public application_shell
-{
-public:
- test_point() : application_shell() {}
- DEFINE_CLASS_NAME("test_point");
- virtual int execute();
-};
-
-int test_point::execute()
-{
- FUNCDEF("execute");
- {
- // first test just instantiates some things.
- point<double> fred(23, angle<double>(4));
- point<double> bob(399, angle<double>(2.3));
- double dist = bob.distance(fred);
-//LOG(astring("fred is ") + fred + " and bob is " + bob);
-//LOG(a_sprintf("distance between is ", dist));
- point<double> borg(fred - bob);
-//LOG(astring("borg is fred-bob, which is ") + borg);
- ASSERT_FALSE(borg.magnitude() - dist > 0.001,
- "difference must be small between distance and magnitude");
- }
-
- {
- astring pt1 = "12,38";
- point<double> to_scan;
- to_scan.from_text(pt1);
- ASSERT_FALSE( (to_scan.x() != 12) || (to_scan.y() != 38),
- "second test: first from_text should work");
- astring pt2 = "{14.3,16.2989}";
- to_scan.from_text(pt2);
- ASSERT_FALSE( (to_scan.x() != 14.3) || (to_scan.y() != 16.2989),
- "second test: second from_text should work too");
- }
-
- return final_report();
-}
-
-HOOPLE_MAIN(test_point, )
-
+++ /dev/null
-/*****************************************************************************\
-* *
-* Name : test_rectangle_warper *
-* Author : Chris Koeritz *
-* *
-* Purpose: *
-* *
-* Tests the rectangle warper class. *
-* *
-*******************************************************************************
-* Copyright (c) 1993-$now By Author. 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 is online at: *
-* http://www.fsf.org/copyleft/gpl.html *
-* Please send any updates to: fred@gruntose.com *
-\*****************************************************************************/
-
-#include <application/hoople_main.h>
-#include <basis/astring.h>
-#include <basis/functions.h>
-#include <basis/guards.h>
-#include <geometric/warper.h>
-#include <structures/static_memory_gremlin.h>
-#include <unit_test/unit_base.h>
-
-using namespace application;
-using namespace basis;
-using namespace geometric;
-using namespace loggers;
-using namespace structures;
-using namespace unit_test;
-using namespace geometric;
-
-class test_rectangle_warper : public virtual unit_base, virtual public application_shell
-{
-public:
- test_rectangle_warper() {}
- DEFINE_CLASS_NAME("test_rectangle_warper");
- virtual int execute();
-};
-
-int test_rectangle_warper::execute()
-{
- FUNCDEF("execute");
- rectangle<double> inner(-20, 0, -60, 30);
- rectangle<double> outer(20, 30, 0, 0);
- rectangle_warper<double> ito(inner, outer, rectangle_warper<double>::TOP_LEFT,
- rectangle_warper<double>::BOTTOM_RIGHT);
-//LOG(astring("inner to outer warper is: " + ito.text_form()));
-
- rectangle<double> warped_inner(ito.to_system_2(inner));
-//LOG(astring("warped inner becomes ") + warped_inner.text_form());
- rectangle<double> warped_outer(ito.to_system_1(outer));
-//LOG(astring(" and outer becomes ") + warped_outer.text_form());
- ASSERT_FALSE( (warped_inner != outer) || (warped_outer != inner),
- "systems should warp to each other correctly");
-
- point<double> in_center(inner.center());
- point<double> warp_in_center(ito.to_system_2(in_center));
- point<double> out_center(outer.center());
- point<double> warp_out_center(ito.to_system_1(out_center));
- ASSERT_FALSE( (warp_out_center != inner.center()) || (warp_in_center != outer.center()),
- "centers should warp to each other");
- return final_report();
-}
-
-HOOPLE_MAIN(test_rectangle_warper, );
-
#include <structures/static_memory_gremlin.h>
#include <openssl/blowfish.h>
+#include <openssl/err.h>
#include <openssl/evp.h>
using namespace basis;
//#undef set_key
// get rid of a macro we don't want.
-//#define DEBUG_BLOWFISH
+#define DEBUG_BLOWFISH
// uncomment for noisier version.
+#undef ALWAYS_LOG
+#define ALWAYS_LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
#ifdef DEBUG_BLOWFISH
#undef LOG
#define LOG(t) CLASS_EMERGENCY_LOG(program_wide_logger::get(), t)
#define LOG(t)
#endif
+// helpful macro for the error string of last failure.
+#define GET_SSL_ERROR() \
+ ERR_error_string(ERR_get_error(), NULL_POINTER)
+
#ifdef DEBUG_BLOWFISH
// this macro checks on the validity of the key sizes (in bits).
#define DISCUSS_KEY_SIZE(key_size) \
_key(new byte_array(key))
{
FUNCDEF("ctor(byte_array,int)");
+ static_ssl_initializer();
// any problems with the key provided are horrid. they will yield a
// non-working blowfish object.
LOG("prior to key size discuss");
LOG("prior to provided key discuss");
DISCUSS_PROVIDED_KEY(key_size, key);
LOG("prior to ssl static init");
- static_ssl_initializer();
LOG("after ssl static init");
}
void blowfish_crypto::generate_key(int size, byte_array &new_key)
{
FUNCDEF("generate_key");
+ static_ssl_initializer();
DISCUSS_KEY_SIZE(size);
if (size < minimum_key_size())
size = minimum_key_size();
const byte_array &blowfish_crypto::init_vector()
{
FUNCDEF("init_vector");
+ static_ssl_initializer();
auto_synchronizer locking(__vector_init_lock());
static byte_array to_return(EVP_MAX_IV_LENGTH);
static bool initted = false;
// initialize an encoding session.
EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(session);
- EVP_EncryptInit_ex(session, EVP_bf_cbc(), NULL_POINTER, _key->observe(), init_vector().observe());
+
+//new rules!
+//EVP_EncryptInit to set the cipher, but leave key and IV null and unset
+//EVP_CIPHER_CTX_set_key_length and EVP_CTRL_AEAD_SET_IVLEN
+//EVP_EncryptInit again. This time leave cipher null, because you've already set it, and set the key and IV.
+
+ int initret = EVP_EncryptInit_ex(session, EVP_bf_cbc(), NULL_POINTER, NULL_POINTER, NULL_POINTER);
+ if (!initret) {
+ // zero means a failure of the initialization.
+ ALWAYS_LOG(a_sprintf("failure in calling EVP_EncryptInit_ex, with error %s", GET_SSL_ERROR()));
+ exit(1);
+ }
LOG(a_sprintf("calling set key len with key size of %d", _key_size));
+ // new fancy footwork needed to keep openssl from blowing up and claiming we didn't set the key.
+//hmmm: check returns on these setters?
EVP_CIPHER_CTX_set_key_length(session, _key_size);
+ EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN, init_vector().length(), NULL);
+ // and round and round we go...
+ initret = EVP_EncryptInit_ex(session, NULL_POINTER, NULL_POINTER, _key->observe(), init_vector().observe());
+ if (!initret) {
+ // zero means a failure of the initialization.
+ ALWAYS_LOG(a_sprintf("second phase failure in calling EVP_EncryptInit_ex, with error %s", GET_SSL_ERROR()));
+ exit(1);
+ }
// allocate temporary space for encrypted data.
byte_array encoded(source.length() + FUDGE);
source.observe(), source.length());
if (enc_ret != 1) {
continuable_error(class_name(), func, a_sprintf("encryption failed, "
- "result=%d.", enc_ret));
+ "result=%d with error=%s.", enc_ret, GET_SSL_ERROR()));
to_return = false;
} else {
// chop any extra space off.
enc_ret = EVP_EncryptFinal_ex(session, encoded.access(), &pad_len);
if (enc_ret != 1) {
continuable_error(class_name(), func, a_sprintf("finalizing encryption "
- "failed, result=%d.", enc_ret));
+ "failed, result=%d with error=%s.", enc_ret, GET_SSL_ERROR()));
to_return = false;
} else {
LOG(a_sprintf("padding added %d bytes.\n", pad_len));
EVP_CIPHER_CTX *session = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(session);
LOG(a_sprintf("key size %d bits.\n", BITS_PER_BYTE * _key->length()));
- EVP_DecryptInit_ex(session, EVP_bf_cbc(), NULL_POINTER, _key->observe(),
- init_vector().observe());
+ int initret = EVP_DecryptInit_ex(session, EVP_bf_cbc(), NULL_POINTER, NULL_POINTER, NULL_POINTER);
+ if (!initret) {
+ // zero means a failure of the initialization.
+ ALWAYS_LOG(a_sprintf("failure in calling EVP_DecryptInit_ex, with error %s", GET_SSL_ERROR()));
+ exit(1);
+ }
+ // more fancy fupwork.
+//hmmm: check returns on these setters?
EVP_CIPHER_CTX_set_key_length(session, _key_size);
+ EVP_CIPHER_CTX_ctrl(session, EVP_CTRL_AEAD_SET_IVLEN, init_vector().length(), NULL);
+ initret = EVP_DecryptInit_ex(session, NULL_POINTER, NULL_POINTER, _key->observe(), init_vector().observe());
+ if (!initret) {
+ // zero means a failure of the initialization.
+ ALWAYS_LOG(a_sprintf("second phase failure in calling EVP_DecryptInit_ex, with error %s", GET_SSL_ERROR()));
+ exit(1);
+ }
// allocate enough space for decoded bytes.
byte_array decoded(source.length() + FUDGE);
int dec_ret = EVP_DecryptUpdate(session, decoded.access(), &decoded_len,
source.observe(), source.length());
if (dec_ret != 1) {
- continuable_error(class_name(), func, "decryption failed.");
+ continuable_error(class_name(), func, a_sprintf("decryption failed with error=%s", GET_SSL_ERROR()));
to_return = false;
} else {
LOG(a_sprintf(" decrypted size in bytes is %d.\n", decoded_len));
LOG(a_sprintf("padding added %d bytes.\n", pad_len));
if (dec_ret != 1) {
continuable_error(class_name(), func, a_sprintf("finalizing decryption "
- "failed, result=%d, padlen=%d, target had %d bytes.", dec_ret,
- pad_len, target.length()));
+ "failed, result=%d, padlen=%d, target had %d bytes, error=%s.", dec_ret,
+ pad_len, target.length(), GET_SSL_ERROR()));
to_return = false;
} else {
int dec_size = pad_len;
// uncomment to cause more debugging information to be generated, plus
// more checking to be performed in the SSL support.
+#undef ALWAYS_LOG
#define ALWAYS_LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
#ifdef DEBUG_SSL
#undef LOG
SAFE_STATIC_CONST(ssl_init, static_ssl_initializer, )
ssl_init::ssl_init()
-: c_rando()
+: c_rando(),
+ c_default_provider(NULL_POINTER),
+ c_legacy_provider(NULL_POINTER)
{
FUNCDEF("ctor");
LOG("prior to provider setup");
- // also load the default provider or the standard, still accepted, algorithms will not be available.
- OSSL_PROVIDER *default_provider = OSSL_PROVIDER_load(NULL_POINTER, "default");
- if (!default_provider) {
- ALWAYS_LOG("failed to load default openssl provider! mega flopsweat fail!");
- exit(1);
- }
// new code needed because blowfish is considered legacy code now. ugh.
- OSSL_PROVIDER *legacy_provider = OSSL_PROVIDER_load(NULL_POINTER, "legacy");
- if (!legacy_provider) {
+ c_legacy_provider = OSSL_PROVIDER_load(NULL_POINTER, "legacy");
+ if (!c_legacy_provider) {
ALWAYS_LOG("failed to load legacy openssl provider! mega boofer fail!");
exit(1);
}
-//hmmm: do we need to clean up those providers?
+ // also load the default provider or the standard, still accepted, algorithms will not be available.
+ c_default_provider = OSSL_PROVIDER_load(NULL_POINTER, "default");
+ if (!c_default_provider) {
+ ALWAYS_LOG("failed to load default openssl provider! mega flopsweat fail!");
+ exit(1);
+ }
LOG("after provider setup");
LOG("prior to rand seed");
{
FUNCDEF("destructor");
LOG("prior to crypto cleanup");
+
+ // clean up the providers again. not super necessary since the program will
+ // exit shortly, but it's good to be tidy.
+ if (c_default_provider) OSSL_PROVIDER_unload(c_default_provider);
+ if (c_legacy_provider) OSSL_PROVIDER_unload(c_legacy_provider);
+
CRYPTO_cleanup_all_ex_data();
}
#include <openssl/opensslv.h>
+// forward.
+struct ossl_provider_st;
+
namespace crypto {
//! provides some initialization for the RSA and blowfish crypto.
private:
mathematics::chaos c_rando; //!< used for generating random numbers.
+ // we hang onto our providers so we can clean them up on exit.
+ ossl_provider_st *c_default_provider;
+ ossl_provider_st *c_legacy_provider;
};
extern const ssl_init &static_ssl_initializer();
--- /dev/null
+#ifndef ANGLE_CLASS
+#define ANGLE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : angle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include <basis/byte_array.h>
+#include <basis/common_outcomes.h>
+#include <basis/contracts.h>
+#include <structures/object_packers.h>
+
+#include <math.h>
+
+namespace geometric {
+
+//! Represents a geometric angle.
+
+//! angles can be measured in degrees or radians in this class.
+enum angular_units { DEGREES, RADIANS };
+
+template <class contents>
+class angle : public basis::packable
+{
+public:
+ DEFINE_CLASS_NAME("angle");
+
+ angle(contents inital_rotation = 0, angular_units unit = RADIANS);
+ //!< constructs a new angle with "initial_rotation" in the "unit".
+
+ void set(contents a, angular_units unit);
+ //!< sets the angle to a new rotation "a" in the "unit".
+ contents get(angular_units unit) const;
+ //!< retrieves the current angular measure.
+
+ angle operator - (void) const;
+ //!< returns the negation of this angle.
+
+ angle operator + (const angle &to_add) const;
+ angle operator - (const angle &to_subtract) const;
+ angle operator * (contents to_multiply) const;
+ angle operator / (contents to_divide) const;
+ angle &operator += (const angle &to_add);
+ angle &operator -= (const angle &to_subtract);
+ angle &operator *= (contents to_multiply);
+ angle &operator /= (contents to_divide);
+
+ contents sine() const;
+ //!< returns the sin function of this angle.
+ contents cosine() const;
+ //!< returns the cos function of this angle.
+ contents tangent() const;
+ //!< returns the tan function of this angle.
+
+ static angle arctangent(contents opposite, contents adjacent,
+ basis::outcome &retval);
+ //!< returns the atan of the angle.
+ /*!< the outcome will be set to OKAY if the function operated successfully.
+ otherwise it will be set to BAD_INPUT. */
+ static angle arccosine(contents adjacent, contents hypotenuse,
+ basis::outcome &retval);
+ //!< returns the acos of the angle.
+ static angle arcsine(contents opposite, contents hypotenuse,
+ basis::outcome &retval);
+ //!< returns the asin of the angle.
+
+ virtual int packed_size() const;
+ virtual void pack(basis::byte_array &packed_form) const;
+ //!< packs the angle for shipping in bytes.
+ virtual bool unpack(basis::byte_array &packed_form);
+ //!< unpacks the angle from the "packed_form".
+
+private:
+ contents _theta; //!< the held angular measure.
+
+ contents to_internal(contents initial, angular_units unit) const;
+ //!< converts the angle into the units we use inside the class.
+ contents from_internal(contents initial, angular_units unit) const;
+ //!< converts the angle from our internal measure into "unit" measure.
+};
+
+//////////////
+
+//! double_angle provides a non-templated class for forward declarations.
+
+class double_angle : public angle<double>
+{
+public:
+ double_angle(double init = 0, angular_units unit = RADIANS)
+ : angle<double>(init, unit) {}
+ double_angle(const angle<double> &to_copy) : angle<double>(to_copy) {}
+};
+
+//////////////
+
+// implementation of larger methods below.
+
+template <class contents>
+angle<contents>::angle(contents a, angular_units unit) { set(a, unit); }
+
+template <class contents>
+angle<contents> angle<contents>::operator - (void) const
+{ angle<contents> to_return(*this); to_return *= -1; return to_return; }
+
+template <class contents>
+angle<contents> angle<contents>::operator + (const angle<contents> &a) const
+{ angle<contents> to_return(*this); to_return += a; return to_return; }
+
+template <class contents>
+angle<contents> angle<contents>::operator - (const angle<contents> &a) const
+{ angle<contents> to_return(*this); to_return -= a; return to_return; }
+
+template <class contents>
+angle<contents> angle<contents>::operator * (contents to_multiply) const
+{
+ angle<contents> to_return(*this);
+ to_return *= to_multiply;
+ return to_return;
+}
+
+template <class contents>
+angle<contents> angle<contents>::operator / (contents to_divide) const
+{ angle<contents> to_return(*this); to_return /= to_divide; return to_return; }
+
+template <class contents>
+angle<contents> &angle<contents>::operator += (const angle<contents> &a)
+{ _theta += a._theta; return *this; }
+
+template <class contents>
+angle<contents> &angle<contents>::operator -= (const angle<contents> &a)
+{ _theta -= a._theta; return *this; }
+
+template <class contents>
+angle<contents> &angle<contents>::operator *= (contents f)
+{ _theta *= f; return *this; }
+
+template <class contents>
+angle<contents> &angle<contents>::operator /= (contents f)
+{ _theta /= f; return *this; }
+
+template <class contents>
+contents angle<contents>::sine() const { return sin(_theta); }
+
+template <class contents>
+contents angle<contents>::cosine() const { return cos(_theta); }
+
+template <class contents>
+contents angle<contents>::tangent() const { return tan(_theta); }
+
+template <class contents>
+int angle<contents>::packed_size() const
+{
+ basis::byte_array temp;
+//hmmm: inefficient!
+ pack(temp);
+ return temp.length();
+}
+
+template <class contents>
+void angle<contents>::pack(basis::byte_array &packed_form) const
+{ structures::attach(packed_form, _theta); }
+
+template <class contents>
+bool angle<contents>::unpack(basis::byte_array &packed_form)
+{ return structures::detach(packed_form, _theta); }
+
+template <class contents>
+contents angle<contents>::to_internal(contents a, angular_units unit) const
+{
+ switch(unit) {
+ case RADIANS: return a;
+ case DEGREES: return a * PI_APPROX / 180.0;
+ default: return 0;
+ }
+}
+
+template <class contents>
+contents angle<contents>::from_internal(contents a, angular_units unit) const
+{
+ switch(unit) {
+ case RADIANS: return a;
+ case DEGREES: return a * 180.0 / PI_APPROX;
+ default: return 0;
+ }
+}
+
+template <class contents>
+void angle<contents>::set(contents a, angular_units unit)
+{ _theta = to_internal(a, unit); }
+
+template <class contents>
+contents angle<contents>::get(angular_units unit) const
+{ return from_internal(_theta, unit); }
+
+template <class contents>
+angle<contents> angle<contents>::arccosine(contents adjacent,
+ contents hypotenuse, basis::outcome &retval)
+{
+ contents d = adjacent / hypotenuse;
+ retval = basis::common::BAD_INPUT;
+ bounds_return(d, -1.0, 1.0, angle<contents>());
+ retval = basis::common::OKAY;
+ return angle<contents>(acos(d), RADIANS);
+}
+
+template <class contents>
+angle<contents> angle<contents>::arcsine(contents opposite, contents hypotenuse,
+ basis::outcome &retval)
+{
+ contents d = opposite / hypotenuse;
+ retval = basis::common::BAD_INPUT;
+ bounds_return(d, -1.0, 1.0, angle<contents>());
+ retval = basis::common::OKAY;
+ return angle<contents>(asin(d), RADIANS);
+}
+
+template <class contents>
+angle<contents> angle<contents>::arctangent(contents opposite, contents adjacent,
+ basis::outcome &retval)
+{
+ retval = basis::common::BAD_INPUT;
+ if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle<contents>();
+ retval = basis::common::OKAY;
+ return angle<contents>(atan2(opposite, adjacent), RADIANS);
+}
+
+} // namespace.
+
+#endif
+
--- /dev/null
+#ifndef CARTESIAN_OBJECTS_GROUP
+#define CARTESIAN_OBJECTS_GROUP
+
+/*****************************************************************************\
+* *
+* Name : cartesian objects *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "angle.h"
+#include "line.h"
+#include "point.h"
+#include "rectangle.h"
+
+namespace geometric {
+
+//! Provides a geometric point that use double floating points numbers.
+
+class cartesian_point : public point<double>
+{
+public:
+ cartesian_point(double x = 0, double y = 0) : point<double>(x, y) {}
+ cartesian_point(double r, double_angle theta) : point<double>(r, theta) {}
+ cartesian_point(const point<double> &to_copy) : point<double>(to_copy) {}
+ DEFINE_CLASS_NAME("cartesian_point");
+
+ static cartesian_point origin() { return cartesian_point(0.0, 0.0); }
+ //!< the origin of the two-dimensional system.
+};
+
+//////////////
+
+//! Provides a geometric line that use double floating points numbers.
+
+class cartesian_line : public line<double>
+{
+public:
+ cartesian_line(const cartesian_point &endpoint_1,
+ const cartesian_point &endpoint_2)
+ : line<double>(endpoint_1, endpoint_2) {}
+ cartesian_line(double x_1 = 0, double y_1 = 0,
+ double x_2 = 0, double y_2 = 0)
+ : line<double>(x_1, y_1, x_2, y_2) {}
+};
+
+//////////////
+
+//! Provides a geometric rectangle that use double floating points numbers.
+
+class cartesian_rectangle : public rectangle<double>
+{
+public:
+ cartesian_rectangle(const cartesian_point &vertex_1,
+ const cartesian_point &vertex_2)
+ : rectangle<double>(vertex_1, vertex_2) {}
+ cartesian_rectangle(double x_1 = 0, double y_1 = 0,
+ double x_2 = 0, double y_2 = 0)
+ : rectangle<double>(x_1, y_1, x_2, y_2) {}
+ cartesian_rectangle(const rectangle<double> &rect)
+ : rectangle<double>(rect) {}
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : circle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "circle.h"
+#include "cartesian_objects.h"
+#include "line.h"
+#include "rectangle.h"
+
+#include <basis/functions.h>
+
+#include <math.h>
+
+using namespace basis;
+
+namespace geometric {
+
+circle::circle() : _radius(1), _center(cartesian_point::origin()) {}
+
+circle::circle(double a_radius, const cartesian_point &a_center)
+: _radius(a_radius), _center(a_center) {}
+
+circle::~circle() {}
+
+double circle::area() const { return PI_APPROX * square(_radius); }
+
+double circle::diameter() const { return 2.0 * _radius; }
+
+double circle::circumference() const { return 2.0 * PI_APPROX * _radius; }
+
+cartesian_point circle::location(const double_angle &where) const
+{
+ double rotation = where.get(RADIANS);
+ cartesian_point second(cos(rotation) * _radius, sin(rotation) * _radius);
+ return _center + second;
+}
+
+bool circle::inside(const cartesian_point &where) const
+{
+ double dist = where.distance(_center);
+ return dist <= _radius? true : false;
+}
+
+cartesian_rectangle circle::dimensions() const
+{
+ const double deg0 = 0;
+ const double deg90 = 0.5 * PI_APPROX;
+ const double deg180 = PI_APPROX;
+ const double deg270 = 1.5 * PI_APPROX;
+
+ cartesian_point right(location(deg0));
+ cartesian_point top(location(deg90));
+ cartesian_point left(location(deg180));
+ cartesian_point bottom(location(deg270));
+ return cartesian_rectangle(left.x(), bottom.y(), right.x(), top.y());
+}
+
+double circle::radius() const { return _radius; }
+
+void circle::radius(double to_set) { _radius = to_set; }
+
+cartesian_point circle::center() const { return _center; }
+
+void circle::center(const cartesian_point &to_set) { _center = to_set; }
+
+} // namespace.
+
--- /dev/null
+#ifndef CIRCLE_CLASS
+#define CIRCLE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : circle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "cartesian_objects.h"
+
+namespace geometric {
+
+//! Represents a geometric circle.
+/*!
+ A circle is specified by its center and its radius. The angles are
+ measured in radians.
+*/
+
+class circle
+{
+public:
+ circle();
+ circle(double radius, const cartesian_point ¢er);
+ ~circle();
+
+ double area() const;
+ //!< Returns the area occupied by the circle.
+
+ double circumference() const;
+ //!< Returns the perimeter for the circle.
+ /*!< The circumference is the length of a virtual string around the
+ circle. */
+
+ double diameter() const;
+ //!< Returns the length of the circle's bisecting line.
+ /*!< This is the length of a line segment that is circumscribed by the
+ circle and which passes through the center of the circle. */
+
+ bool inside(const cartesian_point &where) const;
+ //!< Returns true if the point is inside the circle.
+
+ cartesian_point location(const double_angle &where) const;
+ //!< Returns the point on the circle that is at the angle "where".
+
+ cartesian_rectangle dimensions() const;
+ //!< Returns a bounding box around the circle.
+
+ double radius() const; //!< Half of the circle's diameter.
+ void radius(double to_set); //!< Sets the radius of the circle.
+
+ cartesian_point center() const; //!< The point at the center of the circle.
+ void center(const cartesian_point &to_set); //!< Resets the circle's center.
+
+private:
+ double _radius; //!< Records the current radius.
+ cartesian_point _center; //!< Records the current center.
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : ellipse *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "cartesian_objects.h"
+#include "ellipse.h"
+#include "line.h"
+#include "rectangle.h"
+
+#include <basis/functions.h>
+
+#include <math.h>
+
+using namespace basis;
+
+namespace geometric {
+
+ellipse::ellipse()
+: _center(cartesian_point::origin()),
+ _width_from_center(1),
+ _height_from_center(1)
+{}
+
+ellipse::ellipse(const cartesian_point &a_center, double a_width_from_center,
+ double a_height_from_center)
+: _center(a_center),
+ _width_from_center(a_width_from_center),
+ _height_from_center(a_height_from_center)
+{}
+
+ellipse::ellipse(const ellipse &to_copy)
+: _center(),
+ _width_from_center(0),
+ _height_from_center(0)
+{ *this = to_copy; }
+
+ellipse::~ellipse() {}
+
+ellipse &ellipse::operator = (const ellipse &to_copy)
+{
+ if (this == &to_copy) return *this;
+ _center = to_copy._center;
+ _width_from_center = to_copy._width_from_center;
+ _height_from_center = to_copy._height_from_center;
+ return *this;
+}
+
+double ellipse::area() const
+{ return absolute_value(PI_APPROX * _width_from_center * _height_from_center); }
+
+double ellipse::perimeter() const
+{
+ double w = _width_from_center;
+ double h = _height_from_center;
+ double perim_temp = sqrt(square(h) + square(w)) / 2;
+ return 2.0 * PI_APPROX * perim_temp;
+}
+
+cartesian_point ellipse::location(const double_angle &where) const
+{
+ double a = _width_from_center;
+ double b = _height_from_center;
+ double a_multiplier = square(where.tangent());
+ double denom = sqrt(square(b) + square(a) * a_multiplier);
+ double ab = a * b;
+ double tango = where.tangent();
+ cartesian_point to_return(ab / denom, ab * tango / denom);
+
+ // the following negates the x component if the angle is in the appropriate
+ // part of the ellipse.
+ int ang = int(where.get(DEGREES));
+ double adjustment = where.get(DEGREES) - double(ang);
+ ang %= 360;
+ double adjusted_ang = ang + adjustment;
+ if ( (adjusted_ang < 270.0) && (adjusted_ang > 90.0) )
+ to_return.set(to_return.x() * -1.0, to_return.y());
+ to_return += _center;
+ return to_return;
+}
+
+bool ellipse::inside(const cartesian_point &where) const
+{
+ double dist = where.distance(_center);
+ double_angle to_point = double_angle(asin(where.y() / dist), RADIANS);
+ cartesian_point intersector = location(to_point);
+ return dist <= intersector.distance(_center)? true : false;
+}
+
+cartesian_point ellipse::center() const { return _center; }
+
+double ellipse::width_from_center() const { return _width_from_center; }
+
+double ellipse::height_from_center() const { return _height_from_center; }
+
+void ellipse::center(const cartesian_point &to_set) { _center = to_set; }
+
+void ellipse::width_from_center(double to_set)
+{ _width_from_center = to_set; }
+
+void ellipse::height_from_center(double to_set)
+{ _height_from_center = to_set; }
+
+} // namespace.
+
+
+
+
--- /dev/null
+#ifndef ELLIPSE_CLASS
+#define ELLIPSE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : ellipse *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+namespace geometric {
+
+// forward.
+class cartesian_point;
+class double_angle;
+
+//! Represents a geometric ellipse.
+/*! An ellipse is specified by its height, width and center. */
+
+class ellipse
+{
+public:
+ ellipse();
+ ellipse(const cartesian_point ¢er, double width_from_center,
+ double height_from_center);
+ ellipse(const ellipse &to_copy);
+
+ ~ellipse();
+
+ ellipse &operator = (const ellipse &to_copy);
+
+ double area() const;
+ //!< Returns the area occupied by the ellipse.
+
+ double perimeter() const;
+ //!< Returns the perimeter for the ellipse.
+ /*!< This is the length of the virtual string around the ellipse. The
+ returned value is an approximation. */
+
+ bool inside(const cartesian_point &where) const;
+ //!< Returns true if the point is inside the ellipse.
+
+ cartesian_point location(const double_angle &where) const;
+ //!< Describes the locus of the ellipse (basically, where it lives).
+ /*!< Returns the point on the ellipse that lies on a ray from the center
+ of the ellipse directed at an angle "where". */
+
+ cartesian_point center() const;
+ double width_from_center() const;
+ double height_from_center() const;
+
+ void center(const cartesian_point &to_set);
+ void width_from_center(double to_set);
+ void height_from_center(double to_set);
+
+protected:
+ cartesian_point _center;
+ double _width_from_center;
+ double _height_from_center;
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+#ifndef LINE_CLASS
+#define LINE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : line *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "point.h"
+
+namespace geometric {
+
+//! Represents a geometric line segment.
+
+template <class numeric_type>
+class line
+{
+public:
+ line(const point<numeric_type> &endpoint1,
+ const point<numeric_type> &endpoint2);
+ line(numeric_type end1_x = 0, numeric_type end1_y = 0,
+ numeric_type end2_x = 0, numeric_type end2_y = 0);
+
+ point<numeric_type> center() const;
+ //!< Returns the point at the center of the line segment.
+
+ line operator + (const point<numeric_type> &to_add) const;
+ line operator - (const point<numeric_type> &to_subtract) const;
+ //!< Returns this line with "to_add" added to it.
+ /*!< This returns a line that is the result of adding or subtracting a
+ point to the endpoints of this line. */
+
+ line &operator += (const point<numeric_type> &to_add);
+ line &operator -= (const point<numeric_type> &to_subtract);
+ //!< Adds or subtracts a point from `this' line.
+
+ point<numeric_type> endpoint_1() const;
+ point<numeric_type> endpoint_2() const;
+
+ void endpoint_1(const point<numeric_type> &to_set);
+ void endpoint_2(const point<numeric_type> &to_set);
+
+ basis::astring text_form() const;
+ //!< returns a string form of the points defining the line.
+
+protected:
+ point<numeric_type> _endpoint_1;
+ point<numeric_type> _endpoint_2;
+};
+
+//////////////
+
+// implementations below...
+
+template <class numeric_type>
+line<numeric_type>::line(const point<numeric_type> &p1,
+ const point<numeric_type> &p2)
+: _endpoint_1(p1), _endpoint_2(p2) {}
+
+template <class numeric_type>
+line<numeric_type>::line(numeric_type x1, numeric_type y1, numeric_type x2,
+ numeric_type y2)
+: _endpoint_1(point<numeric_type>(x1, y1)),
+ _endpoint_2(point<numeric_type>(x2, y2))
+{}
+
+template <class numeric_type>
+point<numeric_type> line<numeric_type>::center() const
+{
+ return point<numeric_type>(_endpoint_1.x() / 2.0 + _endpoint_2.x() / 2.0,
+ _endpoint_1.y() / 2.0 + _endpoint_2.y() / 2.0);
+}
+
+template <class numeric_type>
+basis::astring line<numeric_type>::text_form() const
+{
+ return basis::astring("<") + _endpoint_1.text_form() + basis::astring(" ")
+ + _endpoint_2.text_form() + basis::astring(">");
+}
+
+template <class numeric_type>
+line<numeric_type> &line<numeric_type>::operator +=
+ (const point<numeric_type> &to_add)
+{ _endpoint_1 += to_add; _endpoint_2 += to_add; return *this; }
+
+template <class numeric_type>
+line<numeric_type> &line<numeric_type>::operator -=
+ (const point<numeric_type> &to_subtract)
+{ _endpoint_1 -= to_subtract; _endpoint_2 -= to_subtract; return *this; }
+
+template <class numeric_type>
+line<numeric_type> line<numeric_type>::operator +
+ (const point<numeric_type> &to_add) const
+{ line<numeric_type> to_return(*this); to_return += to_add; return to_return; }
+
+template <class numeric_type>
+line<numeric_type> line<numeric_type>::operator -
+ (const point<numeric_type> &to_subtract) const
+{
+ line<numeric_type> to_return(*this);
+ to_return -= to_subtract;
+ return to_return;
+}
+
+template <class numeric_type>
+point<numeric_type> line<numeric_type>::endpoint_1() const
+{ return _endpoint_1; }
+
+template <class numeric_type>
+point<numeric_type> line<numeric_type>::endpoint_2() const
+{ return _endpoint_2; }
+
+template <class numeric_type>
+void line<numeric_type>::endpoint_1(const point<numeric_type> &to_set)
+{ _endpoint_1 = to_set; }
+
+template <class numeric_type>
+void line<numeric_type>::endpoint_2(const point<numeric_type> &to_set)
+{ _endpoint_2 = to_set; }
+
+} // namespace.
+
+#endif
+
--- /dev/null
+include cpp/variables.def
+
+PROJECT = geometric
+TYPE = library
+SOURCE = circle.cpp ellipse.cpp math_bits.cpp polygon.cpp screen_rectangle.cpp triangle.cpp
+TARGETS = geometric.lib
+
+include cpp/rules.def
+
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : mathematical operations group *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1996-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "math_bits.h"
+
+#include <basis/astring.h>
+
+using namespace basis;
+
+namespace geometric {
+
+astring crop_numeric(const astring &input)
+{
+ astring to_return(input);
+ for (int i = 0; i < to_return.length(); i++)
+ if ( ( (to_return[i] >= '0') && (to_return[i] <= '9') )
+ || (to_return[i] == '.')
+ || (to_return[i] == '+') || (to_return[i] == '-')
+ || (to_return[i] == 'E') || (to_return[i] == 'e') ) {
+ to_return.zap(i, i); // remove non-useful character.
+ i--; // move backwards in loop.
+ } else break;
+ return to_return;
+}
+
+astring crop_non_numeric(const astring &input)
+{
+ astring to_return(input);
+ for (int i = 0; i < to_return.length(); i++)
+ if ( ! ((to_return[i] >= '0') && (to_return[i] <= '9'))
+ && (to_return[i] != '.')
+ && (to_return[i] != '+') && (to_return[i] != '-')
+ && (to_return[i] != 'E') && (to_return[i] != 'e') ) {
+ to_return.zap(i, i); // remove non-useful character.
+ i--; // move backwards in loop.
+ } else break;
+ return to_return;
+}
+
+}
+
--- /dev/null
+#ifndef MATHEMATICAL_OPERATIONS_GROUP
+#define MATHEMATICAL_OPERATIONS_GROUP
+
+/*****************************************************************************\
+* *
+* Name : mathematical operations group *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1996-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+/*! @file math_bits.h
+ @brief Provides some fairly low-level math support.
+*/
+
+#include <basis/astring.h>
+
+namespace geometric {
+
+basis::astring crop_numeric(const basis::astring &input);
+ //!< Eats the numeric characters from the front of "input".
+ /*!< This and crop_non_numeric() return a string that is constructed from
+ "input" by chopping the numerical (or non-numerical) characters off of the
+ beginning. The types of numbers supported are floating point, but it will
+ generally work for integers also (problems arise when mixing in
+ the period, e, E, +, and - characters with integer numbers). */
+basis::astring crop_non_numeric(const basis::astring &input);
+ //!< Eats the non-numeric characters from the front of "input".
+
+// type identification functions:
+
+//! returns true if the specified numeric_type is a floating_point type.
+/*! this is useful in templates where one wants to know about the templated
+type. */
+template <class numeric_type>
+bool is_floating_point(numeric_type t)
+ { t = numeric_type(5.1); t = numeric_type(t * 3.0);
+ return 0.001 < float(basis::absolute_value(numeric_type(t - 15.0))); }
+
+//! returns true if the instantiation type is an integer.
+template <class numeric_type>
+bool is_integral(numeric_type t) { return !is_floating_point(t); }
+
+// the following functions (is_short, is_signed and is_unsigned) are only
+// useful for integral types.
+
+//! returns true if the specified type is short on the PC.
+template <class numeric_type>
+bool is_short(numeric_type) { return sizeof(numeric_type) == 2; }
+
+//! returns true if the templated type is unsigned.
+template <class numeric_type>
+bool is_unsigned(numeric_type t) { t = -1; return t > 0; }
+//! returns true if the templated type is signed.
+template <class numeric_type>
+bool is_signed(numeric_type t) { return !is_unsigned(t); }
+
+//! Guesses the formatting string needed for the type provided.
+/*! Returns a string that is appropriate as the format specifier of a printf
+(or the astring constructor) given the template type. templates can rely
+on this to print numerical types correctly. */
+template <class numeric_type>
+basis::astring numeric_specifier(numeric_type t) {
+ basis::astring to_return("%d");
+ if (is_floating_point(t))
+ to_return = basis::astring("%f");
+ else { // integral.
+ if (is_unsigned(t))
+ to_return = basis::astring("%u");
+ if (is_short(t))
+ to_return.insert(1, "h");
+ }
+ return to_return;
+}
+
+}
+
+#endif // outer guard.
+
--- /dev/null
+#ifndef POINT_CLASS
+#define POINT_CLASS
+
+/*****************************************************************************\
+* *
+* Name : point *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "angle.h"
+#include "math_bits.h"
+#include "point.h"
+
+#include <basis/astring.h>
+#include <basis/contracts.h>
+#include <basis/functions.h>
+#include <structures/object_packers.h>
+
+#include <math.h>
+
+//! Contains all of our objects for geometry and avoids name clashes.
+
+namespace geometric {
+
+//! Represents a geometric point.
+
+template <class numeric_type>
+class point : public basis::packable, public virtual basis::root_object
+{
+public:
+ point(numeric_type x = 0, numeric_type y = 0);
+ point(numeric_type r, double_angle theta);
+
+ DEFINE_CLASS_NAME("point");
+
+ void set(numeric_type x, numeric_type y);
+ void set(numeric_type r, double_angle theta);
+
+ numeric_type x() const { return _x; }
+ numeric_type y() const { return _y; }
+
+ numeric_type r() const;
+ double_angle theta() const;
+
+ point rotate(const double_angle &theta) const;
+ //!< Rotates the point by the angle "theta".
+ /*!< This rotates the position of the point around the origin in the
+ trigonometric standard manner; zero degrees is at the right, increasing
+ degree angles are counterclockwise from the x axis to the y to the
+ -x to the -y .... */
+
+ numeric_type distance(const point &p2) const;
+ //!< Returns the distance between `this' and the second point `p2'.
+
+ point operator - () const { return point<numeric_type>(-_x, -_y); }
+ //!< return the additive inverse of the vector
+
+ numeric_type magnitude() const;
+ //!< return the distance from the origin to this point.
+
+ point operator + (const point &arg2) const;
+ point operator - (const point &arg2) const;
+ point &operator += (const point &arg2);
+ point &operator -= (const point &arg2);
+ bool operator == (const point &arg2) const;
+
+ basis::astring text_form() const;
+ //!< Prints out the two values (x and y) held in the point.
+
+ bool from_text(const basis::astring &text);
+ //!< returns true if the "text" is successfully pulled into this point.
+
+ virtual void pack(basis::byte_array &packed_form) const;
+ virtual bool unpack(basis::byte_array &packed_form);
+ int packed_size() const;
+
+private:
+ numeric_type _x;
+ numeric_type _y;
+};
+
+//////////////
+
+// implementations below...
+
+// notes:
+//
+// - there is an odd breaking up of the expressions where we're taking a
+// square root because ms visual studio 7 has a bug of some sort that
+// convinces it that angle<int> is being used in there, although it's not.
+// these lines use a temporary named "sumsquar" to deconfuse the compiler.
+
+template <class numeric_type>
+point<numeric_type>::point(numeric_type x, numeric_type y) { set(x, y); }
+
+template <class numeric_type>
+point<numeric_type>::point(numeric_type r, double_angle theta)
+{ set(r, theta); }
+
+template <class numeric_type>
+basis::astring point<numeric_type>::text_form() const
+{
+ numeric_type temp = 0;
+ basis::astring specifier(numeric_specifier(temp));
+ basis::astring sprintf_template(basis::astring::SPRINTF, "(%s, %s)", specifier.s(), specifier.s());
+ return basis::astring(basis::astring::SPRINTF, sprintf_template.s(), x(), y());
+}
+
+template <class numeric_type>
+void point<numeric_type>::set(numeric_type x, numeric_type y)
+{ _x = x; _y = y; }
+
+template <class numeric_type>
+numeric_type point<numeric_type>::r() const
+{
+ const double sumsquar = basis::square(x()) + basis::square(y());
+ return numeric_type(sqrt(sumsquar));
+}
+
+template <class numeric_type>
+void point<numeric_type>::set(numeric_type r, double_angle theta)
+{ set(numeric_type(r * theta.cosine()), numeric_type(r * theta.sine())); }
+
+template <class numeric_type>
+numeric_type point<numeric_type>::distance(const point &p2) const
+{
+ const double sumsquar = basis::square(p2.x() - x()) + basis::square(p2.y() - y());
+ return numeric_type(sqrt(sumsquar));
+}
+
+template <class numeric_type>
+double_angle point<numeric_type>::theta() const
+{
+ basis::outcome retval;
+ return double_angle::arctangent(y(), x(), retval);
+}
+
+template <class contents>
+int point<contents>::packed_size() const
+{
+ basis::byte_array temp;
+//hmmm: inefficient!
+ pack(temp);
+ return temp.length();
+}
+
+template <class contents>
+void point<contents>::pack(basis::byte_array &packed_form) const
+{
+ structures::attach(packed_form, _x);
+ structures::attach(packed_form, _y);
+}
+
+template <class contents>
+bool point<contents>::unpack(basis::byte_array &packed_form)
+{
+ if (!structures::detach(packed_form, _x)) return false;
+ if (!structures::detach(packed_form, _y)) return false;
+ return true;
+}
+
+template <class numeric_type>
+numeric_type point<numeric_type>::magnitude() const
+{
+ const double sumsquar = basis::square(x()) + basis::square(y());
+ return numeric_type(sqrt(sumsquar));
+}
+
+template <class numeric_type>
+point<numeric_type> point<numeric_type>::operator + (const point &arg2) const
+{ return point<numeric_type>(x() + arg2.x(), y() + arg2.y()); }
+
+template <class numeric_type>
+point<numeric_type> point<numeric_type>::operator - (const point &arg2) const
+{ return point<numeric_type>(x() - arg2.x(), y() - arg2.y()); }
+
+template <class numeric_type>
+point<numeric_type> &point<numeric_type>::operator += (const point &arg2)
+{ _x += arg2.x(); _y += arg2.y(); return *this; }
+
+template <class numeric_type>
+point<numeric_type> &point<numeric_type>::operator -= (const point &arg2)
+{ _x -= arg2.x(); _y -= arg2.y(); return *this; }
+
+template <class numeric_type>
+bool point<numeric_type>::operator == (const point &arg2) const
+{
+// this bit should be part of the floating point stuff...
+ double epsilon = 1e-10;
+ return (basis::absolute_value(x() - arg2.x()) <= epsilon)
+ && (basis::absolute_value(y() - arg2.y()) <= epsilon);
+}
+
+template <class numeric_type>
+point<numeric_type> point<numeric_type>::rotate
+ (const double_angle &theta) const
+{
+ numeric_type tempX = x();
+ numeric_type tempY = y();
+ numeric_type temp1 = numeric_type(tempX * theta.cosine()
+ - tempY * theta.sine());
+ numeric_type temp2 = numeric_type(tempX * theta.sine()
+ + tempY * theta.cosine());
+ return point<numeric_type>(temp1, temp2);
+}
+
+template <class numeric_type>
+bool point<numeric_type>::from_text(const basis::astring &_text)
+{
+ numeric_type x = 0, y = 0;
+ basis::astring text(_text);
+ // chop junk off the front.
+ text = crop_non_numeric(text);
+ // scan the string for values.
+ x = text.convert(x);
+ // remove the number.
+ text = crop_numeric(text);
+ // chop off more junk.
+ text = crop_non_numeric(text);
+ // get the next number.
+ y = text.convert(y);
+ set(x, y);
+ return true;
+}
+
+} // namespace.
+
+#endif
+
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : polygon *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "polygon.h"
+
+#include <basis/array.h>
+
+using namespace basis;
+
+namespace geometric {
+
+bool polygon::inside(const cartesian_point &to_check)
+{
+ int right_intersect_count = 0;
+ for (int i = 0; i < length(); i++) {
+ cartesian_point vert_1 = get(i);
+ cartesian_point vert_2 = get( (i + 1) % length() );
+ if ( (to_check.y() < minimum(vert_1.y(), vert_2.y()))
+ || (to_check.y() > maximum(vert_1.y(), vert_2.y())) ) continue;
+ double x_intersect;
+ if (vert_2.x() == vert_1.x()) {
+ x_intersect = vert_2.x();
+ } else {
+ double m = (vert_2.y() - vert_1.y()) / (vert_2.x() - vert_1.x());
+ x_intersect = 1.0 / m * (to_check.y() - vert_1.y() + m * vert_1.x());
+ }
+ if (x_intersect > to_check.x()) right_intersect_count++;
+ }
+ return !!(right_intersect_count % 2);
+}
+
+}
+
+
+
+
--- /dev/null
+#ifndef POLYGON_CLASS
+#define POLYGON_CLASS
+
+/*****************************************************************************\
+* *
+* Name : polygon *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+//! Represents a multi-sided geometric figure made of line segments.
+/*!
+ The polygon is a list of points that are assumed to be connected. It will
+ have as many sides as its point count minus one. Thus there is no valid
+ polygon with less than three points. A function that tests whether a point
+ is inside or outside the polygon is provided.
+*/
+
+#include "cartesian_objects.h"
+
+#include <basis/array.h>
+
+//hmmm: it might be nice to structuralize this.
+//hmmm: also deriving from an array of points is not so great.
+
+namespace geometric {
+
+class polygon : public basis::array<geometric::cartesian_point>
+{
+public:
+ polygon() {}
+ ~polygon() {}
+
+ void add(const cartesian_point &to_add);
+ //!< adds a new point to the list that represents the polygon's sides.
+
+ int points() const { return length(); }
+ int sides() const { return points() - 1; }
+
+ cartesian_point &operator [] (int index);
+ //!< retrieves the index-th point in the list.
+ /*!< this is valid for indices between zero and points() - 1. */
+
+ bool inside(const cartesian_point &to_check);
+ //!< Returns true if the point "to_check" is inside of this polygon.
+ /*!< This function assumes that the polygon is closed when performing
+ the check. */
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+#ifndef RECTANGLE_CLASS
+#define RECTANGLE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : rectangle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "point.h"
+
+#include <basis/functions.h>
+
+namespace geometric {
+
+//! Represents a geometric rectangle.
+
+template <class numeric_type>
+class rectangle : public basis::packable
+{
+public:
+ rectangle(const point<numeric_type> &vertex_1,
+ const point<numeric_type> &vertex_2);
+ rectangle(numeric_type x_1 = 0, numeric_type y_1 = 0,
+ numeric_type x_2 = 0, numeric_type y_2 = 0);
+
+ numeric_type height() const;
+ numeric_type width() const;
+
+ rectangle order() const;
+ //!< Re-orders the vertices of the line to be increasing.
+ /*!< Orients the vertices such that the x and y coordinates of the first
+ vertex are respectively closer to the origin than the x and y
+ coordinates of the second vertex (or they are equidistant). */
+
+ point<numeric_type> top_left() const;
+ point<numeric_type> bottom_left() const;
+ point<numeric_type> top_right() const;
+ point<numeric_type> bottom_right() const;
+ //!< returns the appropriate point as represented by our rectangle.
+ /*!< note that these are with respect to a normal cartesian coordinate
+ system. if you want points for a screen based coordinate system (with
+ the origin in the top left), then bottom_left and top_right return the
+ appropriate bounding points for that rectangle. */
+
+ numeric_type minimum_x() const;
+ //!< Return the smallest x from the points in the rectangle.
+ numeric_type minimum_y() const;
+ //!< Return the smallest y from the points in the rectangle.
+ numeric_type maximum_x() const;
+ //!< Return the largest x from the points in the rectangle.
+ numeric_type maximum_y() const;
+ //!< Return the largest y from the points in the rectangle.
+
+ point<numeric_type> center() const;
+ //!< Returns the point at the center of the rectangle.
+
+ bool inside(const point<numeric_type> &to_check) const;
+ //!< Returns true if `to_check' is inside `this' rectangle.
+
+ bool operator == (const rectangle &to_compare) const;
+ //!< Returns true if `to_compare' has vertices equal to `this'.
+
+ rectangle operator + (const point<numeric_type> &to_add) const;
+ //!< Returns the rectangle resulting from adding a point to its vertices.
+ rectangle operator - (const point<numeric_type> &to_subtract) const;
+ //!< Returns the rectangle resulting from subtracting "to_subtract".
+
+ rectangle &operator += (const point<numeric_type> &to_add);
+ //!< Adds the point "to_add" to our vertices.
+ rectangle &operator -= (const point<numeric_type> &to_subtract);
+ //!< Subtracts the point "to_add" to our vertices.
+
+ void encompass(const rectangle &to_adjust_to);
+ //!< Finds the largest dimension needed to contain all rectangles passed in.
+ /*!< The original dimension of `this' rectangle is compared with
+ all subsequent rectangles passed to adjust_dimension, and it is
+ modified (joined with `to_adjust_to') if the extent of `to_adjust_to'
+ is greater or lesser than the current extent of `this' rectangle. */
+
+ bool intersect(const rectangle &r2) const;
+ //!< Returns true if `this' & `r2' cover any common points.
+
+ bool disjoint(const rectangle &r2) const;
+ //!< Returns true if `this' & `r2' have mutually exclusive extents.
+
+ bool join_intersecting(const rectangle &r2, rectangle &result);
+ //!< Sets "result" to encompass this and "r2" if they intersect.
+ /*!< If `this' and `r2' intersect, `result' is adjusted to their dimension
+ and true is returned. If not, false is returned and `result' is
+ undefined. */
+
+ bool intersection(const rectangle &r2, rectangle &result);
+ //!< Sets "result" to the intersection of this and "r2".
+ /*!< If `this' and `r2' intersect, then `result' is set to their
+ intersecting extent and true is returned. If not, then false is returned
+ and `result' is undefined. */
+
+ basis::astring text_form() const;
+ //!< Prints out the contents of the rectangle.
+
+ bool from_text(const basis::astring &text);
+ //!< Returns true if the "text" is parsed into this rectangle.
+
+ point<numeric_type> vertex_1() const;
+ point<numeric_type> vertex_2() const;
+
+ void vertex_1(const point<numeric_type> &to_set);
+ void vertex_2(const point<numeric_type> &to_set);
+
+ virtual int packed_size() const;
+ virtual void pack(basis::byte_array &packed_form) const;
+ virtual bool unpack(basis::byte_array &packed_form);
+
+protected:
+ point<numeric_type> _vertex_1;
+ point<numeric_type> _vertex_2;
+};
+
+//////////////
+
+//!< A commonly used rectangle of integers.
+
+typedef rectangle<int> int_rectangle;
+
+//////////////
+
+// implementations below...
+
+template <class numeric_type>
+rectangle<numeric_type>::rectangle(const point<numeric_type> &lb, const point<numeric_type> &rt)
+: _vertex_1(lb), _vertex_2(rt) {}
+
+template <class numeric_type>
+rectangle<numeric_type>::rectangle(numeric_type left, numeric_type bottom, numeric_type right, numeric_type top)
+: _vertex_1(point<numeric_type>(left, bottom)),
+ _vertex_2(point<numeric_type>(right, top)) {}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::vertex_1() const
+{ return _vertex_1; }
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::vertex_2() const
+{ return _vertex_2; }
+
+template <class numeric_type>
+void rectangle<numeric_type>::vertex_1(const point<numeric_type> &to_set)
+{ _vertex_1 = to_set; }
+
+template <class numeric_type>
+void rectangle<numeric_type>::vertex_2(const point<numeric_type> &to_set)
+{ _vertex_2 = to_set; }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::height() const
+{ return absolute_value(_vertex_2.y() - _vertex_1.y()); }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::width() const
+{ return absolute_value(_vertex_2.x() - _vertex_1.x()); }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::minimum_x() const
+{ return basis::minimum(_vertex_1.x(), _vertex_2.x()); }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::minimum_y() const
+{ return basis::minimum(_vertex_1.y(), _vertex_2.y()); }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::maximum_x() const
+{ return basis::maximum(_vertex_1.x(), _vertex_2.x()); }
+
+template <class numeric_type>
+numeric_type rectangle<numeric_type>::maximum_y() const
+{ return basis::maximum(_vertex_1.y(), _vertex_2.y()); }
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle<numeric_type>::order() const
+{
+ numeric_type x1 = _vertex_1.x();
+ numeric_type x2 = _vertex_2.x();
+ numeric_type y1 = _vertex_1.y();
+ numeric_type y2 = _vertex_2.y();
+ basis::flip_increasing(x1, x2);
+ basis::flip_increasing(y1, y2);
+ return rectangle<numeric_type>(x1, y1, x2, y2);
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::top_left() const
+{
+ rectangle temp(order());
+ return point<numeric_type>(temp.vertex_1().x(), temp.vertex_2().y());
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::bottom_left() const
+{
+ rectangle temp(order());
+ return point<numeric_type>(temp.vertex_1().x(), temp.vertex_1().y());
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::top_right() const
+{
+ rectangle temp(order());
+ return point<numeric_type>(temp.vertex_2().x(), temp.vertex_2().y());
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::bottom_right() const
+{
+ rectangle temp(order());
+ return point<numeric_type>(temp.vertex_2().x(), temp.vertex_1().y());
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle<numeric_type>::center() const
+{
+ return point<numeric_type>(numeric_type((_vertex_1.x()
+ + _vertex_2.x()) / 2.0), numeric_type((_vertex_1.y()
+ + _vertex_2.y()) / 2.0));
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::inside(const point<numeric_type> &to_check) const
+{
+ rectangle<numeric_type> ordered_me = this->order();
+ return bool( (to_check.x() >= ordered_me._vertex_1.x())
+ && (to_check.x() <= ordered_me._vertex_2.x())
+ && (to_check.y() >= ordered_me._vertex_1.y())
+ && (to_check.y() <= ordered_me._vertex_2.y()) );
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::operator == (const rectangle &to_compare) const
+{
+ point<numeric_type> min1(minimum_x(), minimum_y());
+ point<numeric_type> max1(maximum_x(), maximum_y());
+ point<numeric_type> min2(to_compare.minimum_x(), to_compare.minimum_y());
+ point<numeric_type> max2(to_compare.maximum_x(), to_compare.maximum_y());
+ if ( (min1 == min2) && (max1 == max2) ) return true;
+ else return false;
+}
+
+template <class numeric_type>
+rectangle<numeric_type> &rectangle<numeric_type>::operator += (const point<numeric_type> &p)
+{ _vertex_1 += p; _vertex_2 += p; return *this; }
+
+template <class numeric_type>
+rectangle<numeric_type> &rectangle<numeric_type>::operator -= (const point<numeric_type> &p)
+{ _vertex_1 -= p; _vertex_2 -= p; return *this; }
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle<numeric_type>::operator + (const point<numeric_type> &p) const
+{
+ rectangle to_return(*this);
+ to_return += p;
+ return to_return;
+}
+
+template <class contents>
+int rectangle<contents>::packed_size() const
+{
+ basis::byte_array temp;
+//hmmm: inefficient!
+ pack(temp);
+ return temp.length();
+}
+
+template <class contents>
+void rectangle<contents>::pack(basis::byte_array &packed_form) const
+{
+ _vertex_1.pack(packed_form);
+ _vertex_2.pack(packed_form);
+}
+
+template <class contents>
+bool rectangle<contents>::unpack(basis::byte_array &packed_form)
+{
+ if (!_vertex_1.unpack(packed_form)) return false;
+ if (!_vertex_2.unpack(packed_form)) return false;
+ return true;
+}
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle<numeric_type>::operator - (const point<numeric_type> &p) const
+{
+ rectangle to_return(*this);
+ to_return -= p;
+ return to_return;
+}
+
+template <class numeric_type>
+void rectangle<numeric_type>::encompass(const rectangle &to_adjust_to)
+{
+ if (to_adjust_to._vertex_1.x() < _vertex_1.x())
+ _vertex_1.set(to_adjust_to._vertex_1.x(), _vertex_1.y());
+ if (to_adjust_to._vertex_1.y() < _vertex_1.y())
+ _vertex_1.set(_vertex_1.x(), to_adjust_to._vertex_1.y());
+ if (to_adjust_to._vertex_2.x() > _vertex_2.x())
+ _vertex_2.set(to_adjust_to._vertex_2.x(), _vertex_2.y());
+ if (to_adjust_to._vertex_2.y() > _vertex_2.y())
+ _vertex_2.set(_vertex_2.x(), to_adjust_to._vertex_2.y());
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::disjoint(const rectangle &r2) const
+{
+ if ( (maximum_x() < r2.minimum_x())
+ || (minimum_x() > r2.maximum_x())
+ || (maximum_y() < r2.minimum_y())
+ || (minimum_y() > r2.maximum_y()) ) return true;
+ else return false;
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::intersect(const rectangle &r2) const
+{ return bool(!disjoint(r2)); }
+
+template <class numeric_type>
+bool rectangle<numeric_type>::join_intersecting(const rectangle &r2, rectangle &result)
+{
+ if (disjoint(r2)) return false;
+ result = *this;
+ result.encompass(r2);
+ return true;
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::intersection(const rectangle &r2, rectangle &result)
+{
+ if (disjoint(r2)) return false;
+ result = rectangle<numeric_type>(basis::maximum(minimum_x(), r2.minimum_x()),
+ basis::maximum(minimum_y(), r2.minimum_y()),
+ basis::minimum(maximum_x(), r2.maximum_x()),
+ basis::minimum(maximum_y(), r2.maximum_y()));
+ return true;
+}
+
+template <class numeric_type>
+basis::astring rectangle<numeric_type>::text_form() const
+{
+ return basis::astring("[") + _vertex_1.text_form() + basis::astring(" ")
+ + _vertex_2.text_form() + basis::astring("]");
+}
+
+template <class numeric_type>
+bool rectangle<numeric_type>::from_text(const basis::astring &_text)
+{
+ numeric_type nums[4] = { 0, 0, 0, 0 };
+ // setup the scanning specifier.
+ basis::astring spec(numeric_specifier(nums[0]));
+ // scan the string for values.
+ basis::astring text(_text);
+ for (int i = 0; i < 4; i++) {
+ text = crop_non_numeric(text);
+ nums[i] = text.convert(nums[i]);
+ text = crop_numeric(text);
+ }
+ vertex_1(point<numeric_type>(nums[0], nums[1]));
+ vertex_2(point<numeric_type>(nums[2], nums[3]));
+ return true;
+}
+
+} // namespace.
+
+#endif
+
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : screen_rectangle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "rectangle.h"
+#include "screen_rectangle.h"
+
+#include <basis/mutex.h>
+
+#include <structures/static_memory_gremlin.h>
+
+using namespace basis;
+
+namespace geometric {
+
+SAFE_STATIC_CONST(screen_point, screen_origin, (0, 0))
+
+//////////////
+
+#ifdef __WIN32__
+screen_point::screen_point(const tagPOINT &original) : point<int>(original.x, original.y) {}
+
+screen_point::operator tagPOINT()
+{ POINT to_return; to_return.x = x(); to_return.y = y(); return to_return; }
+#endif
+
+//////////////
+
+screen_rectangle::screen_rectangle(const rectangle<int> &init)
+: rectangle<int>(init) {}
+
+screen_rectangle::screen_rectangle(const screen_point &vertex_1,
+ const screen_point &vertex_2)
+: rectangle<int>(vertex_1, vertex_2) {}
+
+screen_rectangle::screen_rectangle(int x_1, int y_1, int x_2, int y_2)
+: rectangle<int>(x_1, y_1, x_2, y_2) {}
+
+screen_rectangle screen_rectangle::order() const
+{ return screen_rectangle(top_left(), bottom_right()); }
+
+screen_point screen_rectangle::top_left() const
+{ return rectangle<int>::bottom_left(); }
+
+screen_point screen_rectangle::bottom_left() const
+{ return rectangle<int>::top_left(); }
+
+screen_point screen_rectangle::top_right() const
+{ return rectangle<int>::bottom_right(); }
+
+screen_point screen_rectangle::bottom_right() const
+{ return rectangle<int>::top_right(); }
+
+#ifdef __WIN32__
+screen_rectangle::screen_rectangle(const tagRECT &original)
+: rectangle<int>(original.left, original.top, original.right, original.bottom)
+{}
+
+screen_rectangle::operator tagRECT() const
+{
+ RECT to_return; to_return.left = left();
+ to_return.top = top(); to_return.right = right();
+ to_return.bottom = bottom(); return to_return;
+}
+#endif
+
+} // namespace.
+
+
+
--- /dev/null
+#ifndef SCREEN_RECTANGLE_CLASS
+#define SCREEN_RECTANGLE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : screen_rectangle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include <application/windoze_helper.h>
+
+#include "rectangle.h"
+
+#ifdef __WIN32__
+ // forward.
+ struct tagPOINT; struct tagRECT;
+#endif
+
+namespace geometric {
+
+// forward.
+class double_angle;
+
+//! a simple class used to describe points on a graphics screen.
+
+class screen_point : public point<int>
+{
+public:
+ screen_point(int x = 0, int y = 0) : point<int>(x, y) {}
+ screen_point(int r, double_angle theta) : point<int>(r, theta) {}
+ screen_point(const point<int> &original) : point<int>(original) {}
+ DEFINE_CLASS_NAME("screen_point");
+
+#ifdef __WIN32__
+ screen_point(const tagPOINT &original);
+ //!< helpful conversions from basic ms-windows type.
+ operator tagPOINT();
+ //!< helpful conversions to basic ms-windows type.
+#endif
+};
+
+const screen_point &screen_origin();
+ //!< the origin of the screen coordinate system (which is top-left here).
+
+//////////////
+
+//! Represents a rectangle as interpreted on display screens.
+/*!
+ The origin is the top-left corner of the rectangle and the y coordinate
+ gets larger as one goes downwards. This class is primarily useful in
+ conjunction with a windowing environment.
+*/
+
+class screen_rectangle : public rectangle<int>
+{
+public:
+ screen_rectangle(const screen_point &vertex_1, const screen_point &vertex_2);
+ screen_rectangle(int x_1 = 0, int y_1 = 0, int x_2 = 0, int y_2 = 0);
+ screen_rectangle(const rectangle<int> &init);
+
+ screen_rectangle order() const;
+ //!< Re-orders the vertices to match expectations.
+ /*!< This is just like rectangle::order() except that the first vertex
+ will be closest to the top-left of the screen. */
+
+ screen_point top_left() const;
+ screen_point bottom_left() const;
+ screen_point top_right() const;
+ screen_point bottom_right() const;
+
+ int left() const { return top_left().x(); }
+ int top() const { return top_left().y(); }
+ int right() const { return bottom_right().x(); }
+ int bottom() const { return bottom_right().y(); }
+
+#ifdef __WIN32__
+ screen_rectangle(const tagRECT &original);
+ //!< helpful conversion from basic ms-windows type.
+ operator tagRECT() const;
+ //!< helpful conversion to basic ms-windows type.
+#endif
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : triangle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "cartesian_objects.h"
+#include "line.h"
+#include "rectangle.h"
+#include "triangle.h"
+
+namespace geometric {
+
+triangle::triangle()
+: _vertex_1(cartesian_point::origin()),
+ _vertex_2(cartesian_point::origin()),
+ _vertex_3(cartesian_point::origin())
+{}
+
+triangle::triangle(const cartesian_point &vertex_1,
+ const cartesian_point &vertex_2, const cartesian_point &vertex_3)
+: _vertex_1(vertex_1),
+ _vertex_2(vertex_2),
+ _vertex_3(vertex_3)
+{}
+
+triangle::triangle(const triangle &to_copy)
+: _vertex_1(to_copy._vertex_1),
+ _vertex_2(to_copy._vertex_2),
+ _vertex_3(to_copy._vertex_3)
+{}
+
+triangle::~triangle() {}
+
+triangle &triangle::operator =(const triangle &to_copy)
+{
+ if (this == &to_copy) return *this;
+ _vertex_1 = to_copy._vertex_1;
+ _vertex_2 = to_copy._vertex_2;
+ _vertex_3 = to_copy._vertex_3;
+ return *this;
+}
+
+line<double> triangle::side_1_2() const
+{ return line<double>(_vertex_1, _vertex_2); }
+
+line<double> triangle::side_2_3() const
+{ return line<double>(_vertex_2, _vertex_3); }
+
+line<double> triangle::side_3_1() const
+{ return line<double>(_vertex_3, _vertex_1); }
+
+cartesian_point triangle::vertex_1() const { return _vertex_1; }
+
+cartesian_point triangle::vertex_2() const { return _vertex_2; }
+
+cartesian_point triangle::vertex_3() const { return _vertex_3; }
+
+void triangle::vertex_1(const cartesian_point &to_set) { _vertex_1 = to_set; }
+
+void triangle::vertex_2(const cartesian_point &to_set) { _vertex_2 = to_set; }
+
+void triangle::vertex_3(const cartesian_point &to_set) { _vertex_3 = to_set; }
+
+bool triangle::inside(const cartesian_point &where) const
+{
+//cerr << "triangle::inside: not implemented" << endl << flush;
+if (where.x()) where.y(); // bogus.
+ return false;
+}
+
+double triangle::area() const
+{
+//cerr << "triangle::area: not implemented" << endl << flush;
+ return 5;
+}
+
+} // namespace.
+
+/*
+//temp
+#include "warper.h"
+using namespace geometric;
+typedef rectangle_warper<double> chuzzo;
+chuzzo beanburp = chuzzo(rectangle<double>(0, 23, 39, 1012),
+ rectangle<double>(8, 19, 92982, -2), chuzzo::BOTTOM_RIGHT,
+ chuzzo::TOP_LEFT);
+typedef rectangle_warper<double>::horizontal_component horzo;
+typedef rectangle_warper<double>::vertical_component verzo;
+int frunk() {
+ horzo peen;
+ beanburp.separate_horizontal(chuzzo::BOTTOM_RIGHT, peen);
+ verzo neep;
+ beanburp.separate_vertical(chuzzo::TOP_RIGHT, neep);
+}
+*/
+
+
+
+
+
--- /dev/null
+#ifndef TRIANGLE_CLASS
+#define TRIANGLE_CLASS
+
+/*****************************************************************************\
+* *
+* Name : triangle *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+
+
+// forward.
+class cartesian_line;
+class cartesian_point;
+
+namespace geometric {
+
+//! Represents a geometric triangle.
+
+class triangle
+{
+public:
+ triangle();
+ triangle(const cartesian_point &vertex1, const cartesian_point &vertex2,
+ const cartesian_point &vertex3);
+ triangle(const triangle &to_copy);
+ ~triangle();
+
+ triangle &operator =(const triangle &to_copy);
+
+ bool inside(const cartesian_point &where) const;
+
+ double area() const;
+
+ line<double> side_1_2() const;
+ line<double> side_2_3() const;
+ line<double> side_3_1() const;
+
+ cartesian_point vertex_1() const;
+ cartesian_point vertex_2() const;
+ cartesian_point vertex_3() const;
+
+ void vertex_1(const cartesian_point &to_set);
+ void vertex_2(const cartesian_point &to_set);
+ void vertex_3(const cartesian_point &to_set);
+
+protected:
+ cartesian_point _vertex_1;
+ cartesian_point _vertex_2;
+ cartesian_point _vertex_3;
+};
+
+} // namespace.
+
+#endif
+
--- /dev/null
+#ifndef RECTANGLE_WARPER_CLASS
+#define RECTANGLE_WARPER_CLASS
+
+/*****************************************************************************\
+* *
+* Name : rectangle_warper *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1992-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+//! Warps points in one frame of reference to a different one.
+/*!
+ This class encapsulates the notion of a rectangular region that is
+ referred to from two different points of view. This relates two
+ two-dimensional frames of reference to each other. Each frame of reference
+ is specified by two rectangles. A point that is measured in one frame of
+ reference can be transformed into a point that is measured in the other,
+ and vice-versa.
+*/
+
+#include "rectangle.h"
+
+#include <basis/astring.h>
+
+namespace geometric {
+
+template <class numeric_type>
+class rectangle_warper
+{
+public:
+ //! describes where a rectangle's origin is located on the rectangle.
+ /*! our model is to consider the first vertex point of the rectangle as its
+ origin and the second vertex point (diagonally opposite the first point) as
+ its extent. since it may make sense for that first vertex point to be
+ located at any one of the vertices of the rectangle (as in windowing
+ coordinate system conversions), the enumeration below allows any one of the
+ rectangle's vertices to be chosen as its origin. */
+ enum origin_vertex { BOTTOM_LEFT, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT };
+
+ rectangle_warper(const rectangle<numeric_type> &system_1,
+ const rectangle<numeric_type> &system_2,
+ origin_vertex system_1_origin = BOTTOM_LEFT,
+ origin_vertex system_2_origin = BOTTOM_LEFT);
+ //!< constructs a warper given the two reference systems.
+ /*!< constructs a warper where the first rectangular system is in
+ "system_1", the second system is in "system_2" and the respective origins
+ for these systems are in "system_1_origin" and "system_2_origin". */
+
+ ~rectangle_warper();
+
+ point<numeric_type> to_system_1(const point<numeric_type> &in_system_2) const;
+ //!< Converts from the second system into the first.
+ /*!< This returns a point that is measured in the first frame of reference
+ when given a point "in_system_2" that is measured in the second frame of
+ reference. */
+
+ point<numeric_type> to_system_2(const point<numeric_type> &in_system_1) const;
+ //!< Converts from the first system into the second.
+ /*!< This returns a point that is measured in the second frame of reference
+ when given a point "in_system_1" that is measured in the first frame of
+ reference. */
+
+ rectangle<numeric_type> to_system_1
+ (const rectangle<numeric_type> &in_system_2) const;
+ //!< flips a rectangle from the second system into the first.
+ rectangle<numeric_type> to_system_2
+ (const rectangle<numeric_type> &in_system_1) const;
+ //!< flips a rectangle from the first system into the second.
+
+ rectangle<numeric_type> system_1() const { return _system_1; }
+ rectangle<numeric_type> system_2() const { return _system_2; }
+ origin_vertex origin_1() const { return _vert_1; }
+ origin_vertex origin_2() const { return _vert_2; }
+
+ void system_1(const rectangle<numeric_type> &to_set,
+ origin_vertex origin_corner = BOTTOM_LEFT);
+ void system_2(const rectangle<numeric_type> &to_set,
+ origin_vertex origin_corner = BOTTOM_LEFT);
+
+ basis::astring text_form() const;
+ //!< Prints out the two systems held in the rectangle_warper.
+
+ basis::astring vertex_name(origin_vertex v) const;
+ //!< Prints out the name of the vertex location.
+
+ enum vertical_component { RW_BOTTOM, RW_TOP };
+ enum horizontal_component { RW_LEFT, RW_RIGHT };
+
+ void separate_vertical(origin_vertex v, vertical_component &to_set) const;
+ void separate_horizontal(origin_vertex v, horizontal_component &to_set) const;
+ //!< separates out a component of the placement of the vertex.
+
+private:
+ rectangle<numeric_type> _system_1;
+ rectangle<numeric_type> _system_2;
+ origin_vertex _vert_1;
+ origin_vertex _vert_2;
+
+ point<numeric_type> scale_point(const rectangle<numeric_type> &source,
+ const rectangle<numeric_type> &target,
+ origin_vertex v1, origin_vertex v2,
+ const point<numeric_type> &old) const;
+ rectangle<numeric_type> scale_rectangle(const rectangle<numeric_type> &source,
+ const rectangle<numeric_type> &target,
+ origin_vertex v1, origin_vertex v2,
+ const rectangle<numeric_type> &old) const;
+ rectangle<numeric_type> flip_accordingly
+ (const rectangle<numeric_type> &to_flip, origin_vertex to_flip_origin,
+ origin_vertex target_origin) const;
+ //!< Flips the points in "to_flip" to match the "target_origin".
+ /*!< swaps the points contained in a rectangle that uses a particular point
+ as the vertex ("to_flip_origin") so that the points are arranged
+ according to a second choice of vertex ("target_origin"). */
+};
+
+//////////////
+
+// implementations for longer methods below...
+
+template <class numeric_type>
+rectangle_warper<numeric_type>::rectangle_warper
+ (const rectangle<numeric_type> &system_1,
+ const rectangle<numeric_type> &system_2,
+ origin_vertex v1, origin_vertex v2)
+: _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2)
+{}
+
+template <class numeric_type>
+rectangle_warper<numeric_type>::~rectangle_warper() {}
+
+template <class numeric_type>
+void rectangle_warper<numeric_type>::system_1
+ (const rectangle<numeric_type> &to_set, origin_vertex v)
+{ _system_1 = to_set; _vert_1 = v; }
+
+template <class numeric_type>
+void rectangle_warper<numeric_type>::system_2
+ (const rectangle<numeric_type> &to_set, origin_vertex v)
+{ _system_2 = to_set; _vert_2 = v; }
+
+template <class numeric_type>
+point<numeric_type> rectangle_warper<numeric_type>::to_system_1
+ (const point<numeric_type> &in_system_2) const
+{ return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); }
+
+template <class numeric_type>
+point<numeric_type> rectangle_warper<numeric_type>::to_system_2
+ (const point<numeric_type> &in_system_1) const
+{ return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); }
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_1
+ (const rectangle<numeric_type> &in_system_2) const
+{
+ return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1,
+ in_system_2);
+}
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle_warper<numeric_type>::to_system_2
+ (const rectangle<numeric_type> &in_system_1) const
+{
+ return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2,
+ in_system_1);
+}
+
+template <class numeric_type>
+void rectangle_warper<numeric_type>::separate_vertical
+ (origin_vertex v, vertical_component &to_set) const
+{
+ if ( (v == BOTTOM_LEFT) || (v == BOTTOM_RIGHT) ) to_set = RW_BOTTOM;
+ to_set = RW_TOP;
+}
+
+template <class numeric_type>
+void rectangle_warper<numeric_type>::separate_horizontal
+ (origin_vertex v, horizontal_component &to_set) const
+{
+ if ( (v == BOTTOM_LEFT) || (v == TOP_LEFT) ) to_set = RW_LEFT;
+ to_set = RW_RIGHT;
+}
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle_warper<numeric_type>::flip_accordingly
+ (const rectangle<numeric_type> &to_flip, origin_vertex flipo,
+ origin_vertex targo) const
+{
+//LOG(basis::astring("flipping ") + to_flip.text_form() + " from " + flipo.text_form() + " to " + targo.text_form());
+ if (flipo == targo) return to_flip;
+ numeric_type x1(to_flip.vertex_1().x());
+ numeric_type y1(to_flip.vertex_1().y());
+ numeric_type x2(to_flip.vertex_2().x());
+ numeric_type y2(to_flip.vertex_2().y());
+ horizontal_component horiz1;
+ separate_horizontal(flipo, horiz1);
+ horizontal_component horiz2;
+ separate_horizontal(targo, horiz2);
+ bool flip_x = bool(horiz1 != horiz2);
+ vertical_component vert1;
+ separate_vertical(flipo, vert1);
+ vertical_component vert2;
+ separate_vertical(targo, vert2);
+ bool flip_y = bool(vert1 != vert2);
+ if (flip_x) basis::swap_values(x1, x2);
+ if (flip_y) basis::swap_values(y1, y2);
+//LOG(basis::astring("it becomes ") + rectangle<numeric_type>(x1, y1, x2, y2).text_form());
+ return rectangle<numeric_type>(x1, y1, x2, y2);
+}
+
+template <class numeric_type>
+rectangle<numeric_type> rectangle_warper<numeric_type>::scale_rectangle
+ (const rectangle<numeric_type> &source,
+ const rectangle<numeric_type> &target, origin_vertex source_origin,
+ origin_vertex target_origin, const rectangle<numeric_type> &old) const
+{
+ rectangle<numeric_type> s = rectangle<numeric_type>
+ (flip_accordingly(source, source_origin, BOTTOM_LEFT));
+ numeric_type width_source = s.vertex_2().x() - s.vertex_1().x();
+ numeric_type height_source = s.vertex_2().y() - s.vertex_1().y();
+ if ( !width_source || !height_source ) {
+// cerr << "degenerate rectangle in rectangle_warper::scaler: " << s
+// << endl << flush;
+ return old;
+ }
+ rectangle<numeric_type> t(flip_accordingly(target, target_origin, BOTTOM_LEFT));
+ numeric_type width_target = t.vertex_2().x() - t.vertex_1().x();
+ numeric_type height_target = t.vertex_2().y() - t.vertex_1().y();
+ numeric_type x_scale = width_target / width_source;
+ numeric_type y_scale = height_target / height_source;
+
+//LOG(basis::astring("scaler: source ") + source.text_form() + " with vert " + source_origin.text_form() + " becomes " + s + " target " + target + " with vert " + target_origin + " becomes " + t + ".");
+
+ rectangle<numeric_type> o(flip_accordingly(old, source_origin, BOTTOM_LEFT));
+
+ rectangle<numeric_type> to_return = flip_accordingly(rectangle<numeric_type>
+ ((o.vertex_1().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
+ (o.vertex_1().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y(),
+ (o.vertex_2().x() - s.vertex_1().x()) * x_scale + t.vertex_1().x(),
+ (o.vertex_2().y() - s.vertex_1().y()) * y_scale + t.vertex_1().y()),
+ BOTTOM_LEFT, target_origin);
+
+// LOG(basis::astring("old ") + old.text_form() + " with source vert becomes " + o.text_form() + " and then is moved into " + to_return.text_form());
+
+ return to_return;
+}
+
+template <class numeric_type>
+point<numeric_type> rectangle_warper<numeric_type>::scale_point
+ (const rectangle<numeric_type> &source, const rectangle<numeric_type> &target,
+ origin_vertex source_origin, origin_vertex target_origin,
+ const point<numeric_type> &old) const
+{
+ // gross but simple.
+ return scale_rectangle(source, target, source_origin, target_origin,
+ rectangle<numeric_type>(old, old)).vertex_1();
+}
+
+template <class numeric_type>
+basis::astring rectangle_warper<numeric_type>::vertex_name(origin_vertex v) const
+{
+ basis::astring name("unknown");
+ switch (v) {
+ case BOTTOM_LEFT: name = "bottom-left"; break;
+ case BOTTOM_RIGHT: name = "bottom-right"; break;
+ case TOP_LEFT: name = "top-left"; break;
+ case TOP_RIGHT: name = "top-right"; break;
+ }
+ return name;
+}
+
+template <class numeric_type>
+basis::astring rectangle_warper<numeric_type>::text_form() const
+{
+ return basis::astring("<warps from: ") + _system_1.text_form()
+ + basis::astring(" with vertex at ") + vertex_name(_vert_1)
+ + basis::astring(" into ") + _system_2.text_form()
+ + basis::astring(" with vertex at ") + vertex_name(_vert_2)
+ + basis::astring(">");
+}
+
+} // namespace.
+
+#endif
+
structures \
timely \
mathematics \
+ geometric \
textual \
nodes \
filesystem \
tests_structures \
tests_filesystem \
tests_mathematics \
+ tests_geometric \
tests_processes \
tests_nodes \
tests_textual \
--- /dev/null
+include cpp/variables.def
+
+PROJECT = test_geometric
+TYPE = test
+TARGETS = test_angle.exe test_ellipse.exe test_geometry.exe test_point.exe test_warper.exe \
+ test_ccri_angle_average.exe
+LOCAL_LIBS_USED = unit_test application filesystem timely loggers configuration textual \
+ structures geometric basis
+RUN_TARGETS = $(ACTUAL_TARGETS)
+
+include cpp/rules.def
+
--- /dev/null
+/*
+* Name : test_angle *
+* Author : Chris Koeritz *
+* Purpose: *
+* Tests the angle class. *
+**
+* Copyright (c) 2001-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+*/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <geometric/angle.h>
+#include <loggers/program_wide_logger.h>
+#include <mathematics/double_plus.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace mathematics;
+using namespace structures;
+using namespace unit_test;
+
+typedef double_plus floot;
+
+class test_angle : public virtual unit_base, public virtual application_shell
+{
+public:
+ test_angle() : application_shell() {}
+ DEFINE_CLASS_NAME("test_angle");
+ virtual int execute();
+};
+
+int test_angle::execute()
+{
+ FUNCDEF("execute");
+ {
+ // first test group: double angle inverse trigonometrics.
+ angle<double> a(30.3, DEGREES);
+ ASSERT_EQUAL(floot(a.get(RADIANS)), floot(.528835), "radian conversion should be right");
+
+ outcome retval;
+ angle<double> at = angle<double>::arctangent(28.3, 29.5, retval);
+ ASSERT_EQUAL(floot(at.get(DEGREES)), floot(43.8106), "atan should be what we expect");
+ angle<double> as = angle<double>::arcsine(17.6, 82.3, retval);
+ ASSERT_EQUAL(floot(as.get(DEGREES)), floot(12.3482), "asin should be what we expect");
+ angle<double> ac = angle<double>::arccosine(17.2, 42.0, retval);
+ ASSERT_EQUAL(floot(ac.get(DEGREES)), floot(65.8251), "acos should be what we expect");
+ }
+ {
+ // second test: packing an angle.
+ angle<double> q(128, DEGREES);
+ byte_array pacd;
+ int siz = q.packed_size();
+ q.pack(pacd);
+ ASSERT_EQUAL(siz, pacd.length(), "packed size should report proper length");
+ angle<double> x;
+ x.unpack(pacd);
+ ASSERT_EQUAL(floot(q.get(RADIANS)), floot(x.get(RADIANS)),
+ "unpacking should return original value");
+ ASSERT_FALSE(pacd.length(), "unpacking should consume entire array");
+ }
+
+ return final_report();
+}
+
+//////////////
+
+HOOPLE_MAIN(test_angle, )
+
--- /dev/null
+
+/*
+ * Name : test_ccri_angle_average
+ * Author : Chris Koeritz
+ * Purpose:
+ * Tests the angle averaging method (for angles in degrees)
+ *
+ * Copyright (c) 2001-$now By Author. 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 is online at:
+ * http://www.fsf.org/copyleft/gpl.html
+ * Please send any updates to: fred@gruntose.com
+*/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <geometric/angle.h>
+#include <loggers/program_wide_logger.h>
+#include <mathematics/double_plus.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace mathematics;
+using namespace structures;
+using namespace unit_test;
+
+typedef double_plus floot;
+
+class test_ccri_angle_average : public virtual unit_base, public virtual application_shell
+{
+public:
+ test_ccri_angle_average() : application_shell() {}
+ DEFINE_CLASS_NAME("test_ccri_angle_average");
+ virtual int execute();
+
+ // returns average of angles a1 and a2, in degrees.
+ double angleAverage(double a1, double a2) {
+ a1 = fmod(a1, 360.0);
+ a2 = fmod(a2, 360.0);
+ if (absolute_value(a1 - a2) > 180.0) {
+ if (a1 < 180.0) a1 += 360.0;
+ else a2 += 360.0;
+ }
+ return fmod( (a1 + a2) / 2.0, 360.0);
+ }
+
+};
+
+int test_ccri_angle_average::execute()
+{
+ FUNCDEF("execute");
+
+ outcome retval;
+ double a1, a2, avg;
+
+ // there could be two right answers for angles 180 degrees apart, but we only test for one.
+ a1 = 23; a2 = 203;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(113), a_sprintf("%f and %f 180 degrees apart", a1, a2));
+ a1 = 359; a2 = 179;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(269), a_sprintf("%f and %f 180 degrees apart", a1, a2));
+ a1 = 90; a2 = 270;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(180), a_sprintf("%f and %f 180 degrees apart", a1, a2));
+
+ // more cases.
+ a1 = 89; a2 = 274;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(1.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 89.9; a2 = 270.1;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
+ a1 = 0; a2 = 0;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
+ a1 = 0; a2 = 359;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(359.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 358; a2 = 359;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(358.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 1; a2 = 357;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(359), a_sprintf("%f and %f", a1, a2));
+ a1 = 23; a2 = 160;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(91.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 47; a2 = 221;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(134), a_sprintf("%f and %f", a1, a2));
+ a1 = 113; a2 = 114;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(113.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 113; a2 = 270;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(191.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 190; a2 = 230;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(210), a_sprintf("%f and %f", a1, a2));
+ a1 = 12; a2 = 273;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(322.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 181; a2 = 179;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(180), a_sprintf("%f and %f", a1, a2));
+ a1 = 89; a2 = 271;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(0), a_sprintf("%f and %f", a1, a2));
+
+ a1 = 359; a2 = 120;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(59.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 220; a2 = 359;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(289.5), a_sprintf("%f and %f", a1, a2));
+ a1 = 3; a2 = 189;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(276), a_sprintf("%f and %f", a1, a2));
+ a1 = 93; a2 = 275;
+ avg = angleAverage(a1, a2);
+ ASSERT_EQUAL(floot(avg), floot(4), a_sprintf("%f and %f", a1, a2));
+
+ return final_report();
+}
+
+//////////////
+
+HOOPLE_MAIN(test_ccri_angle_average, )
+
--- /dev/null
+/*
+* Name : test_ellipse *
+* Author : Chris Koeritz *
+* Purpose: *
+* Tests the ellipse class. *
+**
+* Copyright (c) 1993-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+*/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/guards.h>
+#include <geometric/cartesian_objects.h>
+#include <geometric/ellipse.h>
+#include <geometric/point.h>
+#include <mathematics/double_plus.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace mathematics;
+using namespace structures;
+using namespace unit_test;
+
+typedef cartesian_point e_point;
+
+class test_ellipse : virtual public unit_base, virtual public application_shell
+{
+public:
+ test_ellipse() : application_shell() {}
+ DEFINE_CLASS_NAME("test_ellipse");
+ int execute();
+ point<double> supposed_good_value(const angle<double> &rotation);
+};
+
+point<double> test_ellipse::supposed_good_value(const angle<double> &rotation)
+{
+ double_plus rot(rotation.get(DEGREES));
+//log(a_sprintf("rotation coming in is %f", rot.value()));
+ if (rot == double_plus(0.0)) return point<double>(25.000000, 20.0000);
+ if (rot == double_plus(35.3)) return point<double>(24.7134, 23.3372);
+ if (rot == double_plus(70.6)) return point<double>(22.8791, 28.1757);
+ if (rot == double_plus(105.9)) return point<double>(17.5249, 11.3112);
+ if (rot == double_plus(141.2)) return point<double>(15.3608, 16.2700);
+ if (rot == double_plus(176.5)) return point<double>(15.0023, 19.6943);
+ if (rot == double_plus(211.8)) return point<double>(15.2242, 22.9611);
+ if (rot == double_plus(247.1)) return point<double>(16.7732, 27.6388);
+ if (rot == double_plus(282.4)) return point<double>(22.0127, 10.8459);
+ if (rot == double_plus(317.7)) return point<double>(24.5511, 15.8588);
+ if (rot == double_plus(353.0)) return point<double>(24.9906, 19.3872);
+ return point<double>(0, 0); // unknown angle.
+}
+
+int test_ellipse::execute()
+{
+ FUNCDEF("execute");
+ ellipse fred(e_point(20, 20), 5, 10);
+ for (double i = 0; i < 360.0; i += 35.3) {
+ e_point where(fred.location(double_angle(i, DEGREES)));
+ a_sprintf test_name("%.2f", double_angle(i, DEGREES).get(DEGREES));
+// log(astring(astring::SPRINTF, "at angle %f ellipse is at ", i) + where.text_form());
+ point<double> compare = supposed_good_value(double_angle(i, DEGREES));
+ // right now point is not orderable, so we compare x and y but use the same test name.
+ ASSERT_EQUAL(double_plus(where.x()), double_plus(compare.x()),
+ test_name + " rotation should have proper position");
+ ASSERT_EQUAL(double_plus(where.y()), double_plus(compare.y()),
+ test_name + " rotation should have proper position");
+ }
+ return final_report();
+}
+
+//////////////
+
+HOOPLE_MAIN(test_ellipse, )
+
--- /dev/null
+/*
+* Name : test_geometry *
+* Author : Chris Koeritz *
+* Purpose: *
+* Exercises some of the classes in the geometry library. *
+**
+* Copyright (c) 2001-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+*/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/guards.h>
+#include <geometric/cartesian_objects.h>
+#include <geometric/circle.h>
+#include <geometric/ellipse.h>
+#include <geometric/line.h>
+#include <geometric/screen_rectangle.h>
+#include <geometric/rectangle.h>
+#include <geometric/warper.h>
+#include <geometric/triangle.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace structures;
+using namespace unit_test;
+using namespace geometric;
+
+class test_geometric : public virtual unit_base, public virtual application_shell
+{
+public:
+ test_geometric() {}
+ DEFINE_CLASS_NAME("test_geometric");
+ virtual int execute();
+};
+
+int test_geometric::execute()
+{
+ FUNCDEF("execute");
+ // test constructors
+ circle fred;
+ ellipse tobias;
+ line<double> slugmart;
+ rectangle<double> burger;
+ rectangle_warper<double> space_warp(burger, burger);
+ triangle euclid;
+
+ burger = cartesian_rectangle(23, 19, 82, 745);
+ ASSERT_TRUE(burger.from_text(astring("84.0 290.0 10.0 912.0")),
+ "cartesian from_text test should not return failure");
+ ASSERT_FALSE(burger != cartesian_rectangle(84.0, 290.0, 10.0, 912.0),
+ "cartesian from_text test should compare with expected value");
+
+ screen_rectangle xingu(23, 19, 82, 745);
+ ASSERT_TRUE(xingu == screen_rectangle(screen_point(23, 19), screen_point(82, 745)),
+ "xingu screen test construction should agree with expectations");
+ ASSERT_TRUE(xingu.from_text(astring("84 290 10 912")),
+ "xingu screen from_text test should not return failure");
+ ASSERT_TRUE(xingu == screen_rectangle(84, 290, 10, 912),
+ "xingu screen from_text test should compare with expected value");
+
+ screen_rectangle guinness(-223, 19, 82, -745);
+ ASSERT_TRUE(guinness == screen_rectangle(screen_point(-223, 19), screen_point(82, -745)),
+ "guinness screen test construction should agree with expectations");
+ ASSERT_TRUE(guinness.from_text(astring("-84 290 -10 912")),
+ "guinness screen from_text test should not return failure");
+ ASSERT_TRUE(guinness == screen_rectangle(-84, 290, -10, 912),
+ "screen from_text test should compare with expected value");
+
+//log(astring(astring::SPRINTF, "the string form is %s.", guinness.text_form().s()));
+
+ // test non-mainstream constructors
+ // test non-mainstream constructors
+
+ // test operators
+
+ // test conversions
+
+ // test class specific functions
+
+ // test other things?
+
+ return final_report();
+}
+
+HOOPLE_MAIN(test_geometric, );
+
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : test_point *
+* Author : Chris Koeritz *
+* *
+* Purpose: *
+* *
+* Tests out the point class. *
+* *
+*******************************************************************************
+* Copyright (c) 2002-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/guards.h>
+#include <geometric/point.h>
+#include <loggers/console_logger.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace structures;
+using namespace unit_test;
+
+class test_point : virtual public unit_base, virtual public application_shell
+{
+public:
+ test_point() : application_shell() {}
+ DEFINE_CLASS_NAME("test_point");
+ virtual int execute();
+};
+
+int test_point::execute()
+{
+ FUNCDEF("execute");
+ {
+ // first test just instantiates some things.
+ point<double> fred(23, angle<double>(4));
+ point<double> bob(399, angle<double>(2.3));
+ double dist = bob.distance(fred);
+//LOG(astring("fred is ") + fred + " and bob is " + bob);
+//LOG(a_sprintf("distance between is ", dist));
+ point<double> borg(fred - bob);
+//LOG(astring("borg is fred-bob, which is ") + borg);
+ ASSERT_FALSE(borg.magnitude() - dist > 0.001,
+ "difference must be small between distance and magnitude");
+ }
+
+ {
+ astring pt1 = "12,38";
+ point<double> to_scan;
+ to_scan.from_text(pt1);
+ ASSERT_FALSE( (to_scan.x() != 12) || (to_scan.y() != 38),
+ "second test: first from_text should work");
+ astring pt2 = "{14.3,16.2989}";
+ to_scan.from_text(pt2);
+ ASSERT_FALSE( (to_scan.x() != 14.3) || (to_scan.y() != 16.2989),
+ "second test: second from_text should work too");
+ }
+
+ return final_report();
+}
+
+HOOPLE_MAIN(test_point, )
+
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : test_rectangle_warper *
+* Author : Chris Koeritz *
+* *
+* Purpose: *
+* *
+* Tests the rectangle warper class. *
+* *
+*******************************************************************************
+* Copyright (c) 1993-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include <application/hoople_main.h>
+#include <basis/astring.h>
+#include <basis/functions.h>
+#include <basis/guards.h>
+#include <geometric/warper.h>
+#include <structures/static_memory_gremlin.h>
+#include <unit_test/unit_base.h>
+
+using namespace application;
+using namespace basis;
+using namespace geometric;
+using namespace loggers;
+using namespace structures;
+using namespace unit_test;
+using namespace geometric;
+
+class test_rectangle_warper : public virtual unit_base, virtual public application_shell
+{
+public:
+ test_rectangle_warper() {}
+ DEFINE_CLASS_NAME("test_rectangle_warper");
+ virtual int execute();
+};
+
+int test_rectangle_warper::execute()
+{
+ FUNCDEF("execute");
+ rectangle<double> inner(-20, 0, -60, 30);
+ rectangle<double> outer(20, 30, 0, 0);
+ rectangle_warper<double> ito(inner, outer, rectangle_warper<double>::TOP_LEFT,
+ rectangle_warper<double>::BOTTOM_RIGHT);
+//LOG(astring("inner to outer warper is: " + ito.text_form()));
+
+ rectangle<double> warped_inner(ito.to_system_2(inner));
+//LOG(astring("warped inner becomes ") + warped_inner.text_form());
+ rectangle<double> warped_outer(ito.to_system_1(outer));
+//LOG(astring(" and outer becomes ") + warped_outer.text_form());
+ ASSERT_FALSE( (warped_inner != outer) || (warped_outer != inner),
+ "systems should warp to each other correctly");
+
+ point<double> in_center(inner.center());
+ point<double> warp_in_center(ito.to_system_2(in_center));
+ point<double> out_center(outer.center());
+ point<double> warp_out_center(ito.to_system_1(out_center));
+ ASSERT_FALSE( (warp_out_center != inner.center()) || (warp_in_center != outer.center()),
+ "centers should warp to each other");
+ return final_report();
+}
+
+HOOPLE_MAIN(test_rectangle_warper, );
+