From: Fred T. Hamster Date: Fri, 27 Feb 2026 03:14:39 +0000 (-0500) Subject: openssl closer to working but still fubar X-Git-Url: https://feistymeow.org/gitweb/?a=commitdiff_plain;h=0d49d923ed17a81cec957d15906f9700a88133d5;p=feisty_meow.git openssl closer to working but still fubar 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). --- diff --git a/graphiq/applications/makefile b/graphiq/applications/makefile new file mode 100644 index 00000000..54db5eb9 --- /dev/null +++ b/graphiq/applications/makefile @@ -0,0 +1,7 @@ +include variables.def + +PROJECT = graphical_apps +BUILD_BEFORE = + +include rules.def + diff --git a/graphiq/library/geometric/angle.h b/graphiq/library/geometric/angle.h deleted file mode 100644 index 89696850..00000000 --- a/graphiq/library/geometric/angle.h +++ /dev/null @@ -1,240 +0,0 @@ -#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 -#include -#include -#include - -#include - -namespace geometric { - -//! Represents a geometric angle. - -//! angles can be measured in degrees or radians in this class. -enum angular_units { DEGREES, RADIANS }; - -template -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 -{ -public: - double_angle(double init = 0, angular_units unit = RADIANS) - : angle(init, unit) {} - double_angle(const angle &to_copy) : angle(to_copy) {} -}; - -////////////// - -// implementation of larger methods below. - -template -angle::angle(contents a, angular_units unit) { set(a, unit); } - -template -angle angle::operator - (void) const -{ angle to_return(*this); to_return *= -1; return to_return; } - -template -angle angle::operator + (const angle &a) const -{ angle to_return(*this); to_return += a; return to_return; } - -template -angle angle::operator - (const angle &a) const -{ angle to_return(*this); to_return -= a; return to_return; } - -template -angle angle::operator * (contents to_multiply) const -{ - angle to_return(*this); - to_return *= to_multiply; - return to_return; -} - -template -angle angle::operator / (contents to_divide) const -{ angle to_return(*this); to_return /= to_divide; return to_return; } - -template -angle &angle::operator += (const angle &a) -{ _theta += a._theta; return *this; } - -template -angle &angle::operator -= (const angle &a) -{ _theta -= a._theta; return *this; } - -template -angle &angle::operator *= (contents f) -{ _theta *= f; return *this; } - -template -angle &angle::operator /= (contents f) -{ _theta /= f; return *this; } - -template -contents angle::sine() const { return sin(_theta); } - -template -contents angle::cosine() const { return cos(_theta); } - -template -contents angle::tangent() const { return tan(_theta); } - -template -int angle::packed_size() const -{ - basis::byte_array temp; -//hmmm: inefficient! - pack(temp); - return temp.length(); -} - -template -void angle::pack(basis::byte_array &packed_form) const -{ structures::attach(packed_form, _theta); } - -template -bool angle::unpack(basis::byte_array &packed_form) -{ return structures::detach(packed_form, _theta); } - -template -contents angle::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 -contents angle::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 -void angle::set(contents a, angular_units unit) -{ _theta = to_internal(a, unit); } - -template -contents angle::get(angular_units unit) const -{ return from_internal(_theta, unit); } - -template -angle angle::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()); - retval = basis::common::OKAY; - return angle(acos(d), RADIANS); -} - -template -angle angle::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()); - retval = basis::common::OKAY; - return angle(asin(d), RADIANS); -} - -template -angle angle::arctangent(contents opposite, contents adjacent, - basis::outcome &retval) -{ - retval = basis::common::BAD_INPUT; - if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle(); - retval = basis::common::OKAY; - return angle(atan2(opposite, adjacent), RADIANS); -} - -} // namespace. - -#endif - diff --git a/graphiq/library/geometric/cartesian_objects.h b/graphiq/library/geometric/cartesian_objects.h deleted file mode 100644 index e18608e4..00000000 --- a/graphiq/library/geometric/cartesian_objects.h +++ /dev/null @@ -1,74 +0,0 @@ -#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 -{ -public: - cartesian_point(double x = 0, double y = 0) : point(x, y) {} - cartesian_point(double r, double_angle theta) : point(r, theta) {} - cartesian_point(const point &to_copy) : point(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 -{ -public: - cartesian_line(const cartesian_point &endpoint_1, - const cartesian_point &endpoint_2) - : line(endpoint_1, endpoint_2) {} - cartesian_line(double x_1 = 0, double y_1 = 0, - double x_2 = 0, double y_2 = 0) - : line(x_1, y_1, x_2, y_2) {} -}; - -////////////// - -//! Provides a geometric rectangle that use double floating points numbers. - -class cartesian_rectangle : public rectangle -{ -public: - cartesian_rectangle(const cartesian_point &vertex_1, - const cartesian_point &vertex_2) - : rectangle(vertex_1, vertex_2) {} - cartesian_rectangle(double x_1 = 0, double y_1 = 0, - double x_2 = 0, double y_2 = 0) - : rectangle(x_1, y_1, x_2, y_2) {} - cartesian_rectangle(const rectangle &rect) - : rectangle(rect) {} -}; - -} // namespace. - -#endif - diff --git a/graphiq/library/geometric/circle.cpp b/graphiq/library/geometric/circle.cpp deleted file mode 100644 index 8423c488..00000000 --- a/graphiq/library/geometric/circle.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*****************************************************************************\ -* * -* 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 - -#include - -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. - diff --git a/graphiq/library/geometric/circle.h b/graphiq/library/geometric/circle.h deleted file mode 100644 index 4e25286d..00000000 --- a/graphiq/library/geometric/circle.h +++ /dev/null @@ -1,71 +0,0 @@ -#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 - diff --git a/graphiq/library/geometric/ellipse.cpp b/graphiq/library/geometric/ellipse.cpp deleted file mode 100644 index c7be48c9..00000000 --- a/graphiq/library/geometric/ellipse.cpp +++ /dev/null @@ -1,120 +0,0 @@ - - - -/*****************************************************************************\ -* * -* 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 - -#include - -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. - - - - diff --git a/graphiq/library/geometric/ellipse.h b/graphiq/library/geometric/ellipse.h deleted file mode 100644 index 53eb44d9..00000000 --- a/graphiq/library/geometric/ellipse.h +++ /dev/null @@ -1,72 +0,0 @@ -#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 - diff --git a/graphiq/library/geometric/line.h b/graphiq/library/geometric/line.h deleted file mode 100644 index 46f162ee..00000000 --- a/graphiq/library/geometric/line.h +++ /dev/null @@ -1,133 +0,0 @@ -#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 line -{ -public: - line(const point &endpoint1, - const point &endpoint2); - line(numeric_type end1_x = 0, numeric_type end1_y = 0, - numeric_type end2_x = 0, numeric_type end2_y = 0); - - point center() const; - //!< Returns the point at the center of the line segment. - - line operator + (const point &to_add) const; - line operator - (const point &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 &to_add); - line &operator -= (const point &to_subtract); - //!< Adds or subtracts a point from `this' line. - - point endpoint_1() const; - point endpoint_2() const; - - void endpoint_1(const point &to_set); - void endpoint_2(const point &to_set); - - basis::astring text_form() const; - //!< returns a string form of the points defining the line. - -protected: - point _endpoint_1; - point _endpoint_2; -}; - -////////////// - -// implementations below... - -template -line::line(const point &p1, - const point &p2) -: _endpoint_1(p1), _endpoint_2(p2) {} - -template -line::line(numeric_type x1, numeric_type y1, numeric_type x2, - numeric_type y2) -: _endpoint_1(point(x1, y1)), - _endpoint_2(point(x2, y2)) -{} - -template -point line::center() const -{ - return point(_endpoint_1.x() / 2.0 + _endpoint_2.x() / 2.0, - _endpoint_1.y() / 2.0 + _endpoint_2.y() / 2.0); -} - -template -basis::astring line::text_form() const -{ - return basis::astring("<") + _endpoint_1.text_form() + basis::astring(" ") - + _endpoint_2.text_form() + basis::astring(">"); -} - -template -line &line::operator += - (const point &to_add) -{ _endpoint_1 += to_add; _endpoint_2 += to_add; return *this; } - -template -line &line::operator -= - (const point &to_subtract) -{ _endpoint_1 -= to_subtract; _endpoint_2 -= to_subtract; return *this; } - -template -line line::operator + - (const point &to_add) const -{ line to_return(*this); to_return += to_add; return to_return; } - -template -line line::operator - - (const point &to_subtract) const -{ - line to_return(*this); - to_return -= to_subtract; - return to_return; -} - -template -point line::endpoint_1() const -{ return _endpoint_1; } - -template -point line::endpoint_2() const -{ return _endpoint_2; } - -template -void line::endpoint_1(const point &to_set) -{ _endpoint_1 = to_set; } - -template -void line::endpoint_2(const point &to_set) -{ _endpoint_2 = to_set; } - -} // namespace. - -#endif - diff --git a/graphiq/library/geometric/makefile b/graphiq/library/geometric/makefile deleted file mode 100644 index d8c0da6d..00000000 --- a/graphiq/library/geometric/makefile +++ /dev/null @@ -1,9 +0,0 @@ -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 - diff --git a/graphiq/library/geometric/math_bits.cpp b/graphiq/library/geometric/math_bits.cpp deleted file mode 100644 index 442d690a..00000000 --- a/graphiq/library/geometric/math_bits.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/*****************************************************************************\ -* * -* 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 - -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; -} - -} - diff --git a/graphiq/library/geometric/math_bits.h b/graphiq/library/geometric/math_bits.h deleted file mode 100644 index 2df27a2d..00000000 --- a/graphiq/library/geometric/math_bits.h +++ /dev/null @@ -1,85 +0,0 @@ -#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 - -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 -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 -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 -bool is_short(numeric_type) { return sizeof(numeric_type) == 2; } - -//! returns true if the templated type is unsigned. -template -bool is_unsigned(numeric_type t) { t = -1; return t > 0; } -//! returns true if the templated type is signed. -template -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 -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. - diff --git a/graphiq/library/geometric/point.h b/graphiq/library/geometric/point.h deleted file mode 100644 index 00ed75a8..00000000 --- a/graphiq/library/geometric/point.h +++ /dev/null @@ -1,237 +0,0 @@ -#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 -#include -#include -#include - -#include - -//! Contains all of our objects for geometry and avoids name clashes. - -namespace geometric { - -//! Represents a geometric point. - -template -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(-_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 is being used in there, although it's not. -// these lines use a temporary named "sumsquar" to deconfuse the compiler. - -template -point::point(numeric_type x, numeric_type y) { set(x, y); } - -template -point::point(numeric_type r, double_angle theta) -{ set(r, theta); } - -template -basis::astring point::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 -void point::set(numeric_type x, numeric_type y) -{ _x = x; _y = y; } - -template -numeric_type point::r() const -{ - const double sumsquar = basis::square(x()) + basis::square(y()); - return numeric_type(sqrt(sumsquar)); -} - -template -void point::set(numeric_type r, double_angle theta) -{ set(numeric_type(r * theta.cosine()), numeric_type(r * theta.sine())); } - -template -numeric_type point::distance(const point &p2) const -{ - const double sumsquar = basis::square(p2.x() - x()) + basis::square(p2.y() - y()); - return numeric_type(sqrt(sumsquar)); -} - -template -double_angle point::theta() const -{ - basis::outcome retval; - return double_angle::arctangent(y(), x(), retval); -} - -template -int point::packed_size() const -{ - basis::byte_array temp; -//hmmm: inefficient! - pack(temp); - return temp.length(); -} - -template -void point::pack(basis::byte_array &packed_form) const -{ - structures::attach(packed_form, _x); - structures::attach(packed_form, _y); -} - -template -bool point::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 -numeric_type point::magnitude() const -{ - const double sumsquar = basis::square(x()) + basis::square(y()); - return numeric_type(sqrt(sumsquar)); -} - -template -point point::operator + (const point &arg2) const -{ return point(x() + arg2.x(), y() + arg2.y()); } - -template -point point::operator - (const point &arg2) const -{ return point(x() - arg2.x(), y() - arg2.y()); } - -template -point &point::operator += (const point &arg2) -{ _x += arg2.x(); _y += arg2.y(); return *this; } - -template -point &point::operator -= (const point &arg2) -{ _x -= arg2.x(); _y -= arg2.y(); return *this; } - -template -bool point::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 -point point::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(temp1, temp2); -} - -template -bool point::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 - diff --git a/graphiq/library/geometric/polygon.cpp b/graphiq/library/geometric/polygon.cpp deleted file mode 100644 index d1d40056..00000000 --- a/graphiq/library/geometric/polygon.cpp +++ /dev/null @@ -1,50 +0,0 @@ - - - -/*****************************************************************************\ -* * -* 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 - -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); -} - -} - - - - diff --git a/graphiq/library/geometric/polygon.h b/graphiq/library/geometric/polygon.h deleted file mode 100644 index 8553ead1..00000000 --- a/graphiq/library/geometric/polygon.h +++ /dev/null @@ -1,60 +0,0 @@ -#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 - -//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 -{ -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 - diff --git a/graphiq/library/geometric/rectangle.h b/graphiq/library/geometric/rectangle.h deleted file mode 100644 index b63d5ae3..00000000 --- a/graphiq/library/geometric/rectangle.h +++ /dev/null @@ -1,379 +0,0 @@ -#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 - -namespace geometric { - -//! Represents a geometric rectangle. - -template -class rectangle : public basis::packable -{ -public: - rectangle(const point &vertex_1, - const point &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 top_left() const; - point bottom_left() const; - point top_right() const; - point 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 center() const; - //!< Returns the point at the center of the rectangle. - - bool inside(const point &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 &to_add) const; - //!< Returns the rectangle resulting from adding a point to its vertices. - rectangle operator - (const point &to_subtract) const; - //!< Returns the rectangle resulting from subtracting "to_subtract". - - rectangle &operator += (const point &to_add); - //!< Adds the point "to_add" to our vertices. - rectangle &operator -= (const point &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 vertex_1() const; - point vertex_2() const; - - void vertex_1(const point &to_set); - void vertex_2(const point &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 _vertex_1; - point _vertex_2; -}; - -////////////// - -//!< A commonly used rectangle of integers. - -typedef rectangle int_rectangle; - -////////////// - -// implementations below... - -template -rectangle::rectangle(const point &lb, const point &rt) -: _vertex_1(lb), _vertex_2(rt) {} - -template -rectangle::rectangle(numeric_type left, numeric_type bottom, numeric_type right, numeric_type top) -: _vertex_1(point(left, bottom)), - _vertex_2(point(right, top)) {} - -template -point rectangle::vertex_1() const -{ return _vertex_1; } - -template -point rectangle::vertex_2() const -{ return _vertex_2; } - -template -void rectangle::vertex_1(const point &to_set) -{ _vertex_1 = to_set; } - -template -void rectangle::vertex_2(const point &to_set) -{ _vertex_2 = to_set; } - -template -numeric_type rectangle::height() const -{ return absolute_value(_vertex_2.y() - _vertex_1.y()); } - -template -numeric_type rectangle::width() const -{ return absolute_value(_vertex_2.x() - _vertex_1.x()); } - -template -numeric_type rectangle::minimum_x() const -{ return basis::minimum(_vertex_1.x(), _vertex_2.x()); } - -template -numeric_type rectangle::minimum_y() const -{ return basis::minimum(_vertex_1.y(), _vertex_2.y()); } - -template -numeric_type rectangle::maximum_x() const -{ return basis::maximum(_vertex_1.x(), _vertex_2.x()); } - -template -numeric_type rectangle::maximum_y() const -{ return basis::maximum(_vertex_1.y(), _vertex_2.y()); } - -template -rectangle rectangle::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(x1, y1, x2, y2); -} - -template -point rectangle::top_left() const -{ - rectangle temp(order()); - return point(temp.vertex_1().x(), temp.vertex_2().y()); -} - -template -point rectangle::bottom_left() const -{ - rectangle temp(order()); - return point(temp.vertex_1().x(), temp.vertex_1().y()); -} - -template -point rectangle::top_right() const -{ - rectangle temp(order()); - return point(temp.vertex_2().x(), temp.vertex_2().y()); -} - -template -point rectangle::bottom_right() const -{ - rectangle temp(order()); - return point(temp.vertex_2().x(), temp.vertex_1().y()); -} - -template -point rectangle::center() const -{ - return point(numeric_type((_vertex_1.x() - + _vertex_2.x()) / 2.0), numeric_type((_vertex_1.y() - + _vertex_2.y()) / 2.0)); -} - -template -bool rectangle::inside(const point &to_check) const -{ - rectangle 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 -bool rectangle::operator == (const rectangle &to_compare) const -{ - point min1(minimum_x(), minimum_y()); - point max1(maximum_x(), maximum_y()); - point min2(to_compare.minimum_x(), to_compare.minimum_y()); - point max2(to_compare.maximum_x(), to_compare.maximum_y()); - if ( (min1 == min2) && (max1 == max2) ) return true; - else return false; -} - -template -rectangle &rectangle::operator += (const point &p) -{ _vertex_1 += p; _vertex_2 += p; return *this; } - -template -rectangle &rectangle::operator -= (const point &p) -{ _vertex_1 -= p; _vertex_2 -= p; return *this; } - -template -rectangle rectangle::operator + (const point &p) const -{ - rectangle to_return(*this); - to_return += p; - return to_return; -} - -template -int rectangle::packed_size() const -{ - basis::byte_array temp; -//hmmm: inefficient! - pack(temp); - return temp.length(); -} - -template -void rectangle::pack(basis::byte_array &packed_form) const -{ - _vertex_1.pack(packed_form); - _vertex_2.pack(packed_form); -} - -template -bool rectangle::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 -rectangle rectangle::operator - (const point &p) const -{ - rectangle to_return(*this); - to_return -= p; - return to_return; -} - -template -void rectangle::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 -bool rectangle::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 -bool rectangle::intersect(const rectangle &r2) const -{ return bool(!disjoint(r2)); } - -template -bool rectangle::join_intersecting(const rectangle &r2, rectangle &result) -{ - if (disjoint(r2)) return false; - result = *this; - result.encompass(r2); - return true; -} - -template -bool rectangle::intersection(const rectangle &r2, rectangle &result) -{ - if (disjoint(r2)) return false; - result = rectangle(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 -basis::astring rectangle::text_form() const -{ - return basis::astring("[") + _vertex_1.text_form() + basis::astring(" ") - + _vertex_2.text_form() + basis::astring("]"); -} - -template -bool rectangle::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(nums[0], nums[1])); - vertex_2(point(nums[2], nums[3])); - return true; -} - -} // namespace. - -#endif - diff --git a/graphiq/library/geometric/screen_rectangle.cpp b/graphiq/library/geometric/screen_rectangle.cpp deleted file mode 100644 index f8732d33..00000000 --- a/graphiq/library/geometric/screen_rectangle.cpp +++ /dev/null @@ -1,83 +0,0 @@ - - - -/*****************************************************************************\ -* * -* 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 - -#include - -using namespace basis; - -namespace geometric { - -SAFE_STATIC_CONST(screen_point, screen_origin, (0, 0)) - -////////////// - -#ifdef __WIN32__ -screen_point::screen_point(const tagPOINT &original) : point(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 &init) -: rectangle(init) {} - -screen_rectangle::screen_rectangle(const screen_point &vertex_1, - const screen_point &vertex_2) -: rectangle(vertex_1, vertex_2) {} - -screen_rectangle::screen_rectangle(int x_1, int y_1, int x_2, int y_2) -: rectangle(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::bottom_left(); } - -screen_point screen_rectangle::bottom_left() const -{ return rectangle::top_left(); } - -screen_point screen_rectangle::top_right() const -{ return rectangle::bottom_right(); } - -screen_point screen_rectangle::bottom_right() const -{ return rectangle::top_right(); } - -#ifdef __WIN32__ -screen_rectangle::screen_rectangle(const tagRECT &original) -: rectangle(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. - - - diff --git a/graphiq/library/geometric/screen_rectangle.h b/graphiq/library/geometric/screen_rectangle.h deleted file mode 100644 index df6ab72d..00000000 --- a/graphiq/library/geometric/screen_rectangle.h +++ /dev/null @@ -1,95 +0,0 @@ -#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 - -#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 -{ -public: - screen_point(int x = 0, int y = 0) : point(x, y) {} - screen_point(int r, double_angle theta) : point(r, theta) {} - screen_point(const point &original) : point(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 -{ -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 &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 - diff --git a/graphiq/library/geometric/triangle.cpp b/graphiq/library/geometric/triangle.cpp deleted file mode 100644 index 4597d6a6..00000000 --- a/graphiq/library/geometric/triangle.cpp +++ /dev/null @@ -1,112 +0,0 @@ - - - -/*****************************************************************************\ -* * -* 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 triangle::side_1_2() const -{ return line(_vertex_1, _vertex_2); } - -line triangle::side_2_3() const -{ return line(_vertex_2, _vertex_3); } - -line triangle::side_3_1() const -{ return line(_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 chuzzo; -chuzzo beanburp = chuzzo(rectangle(0, 23, 39, 1012), - rectangle(8, 19, 92982, -2), chuzzo::BOTTOM_RIGHT, - chuzzo::TOP_LEFT); -typedef rectangle_warper::horizontal_component horzo; -typedef rectangle_warper::vertical_component verzo; -int frunk() { - horzo peen; - beanburp.separate_horizontal(chuzzo::BOTTOM_RIGHT, peen); - verzo neep; - beanburp.separate_vertical(chuzzo::TOP_RIGHT, neep); -} -*/ - - - - - diff --git a/graphiq/library/geometric/triangle.h b/graphiq/library/geometric/triangle.h deleted file mode 100644 index bf1e5cbb..00000000 --- a/graphiq/library/geometric/triangle.h +++ /dev/null @@ -1,64 +0,0 @@ -#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 side_1_2() const; - line side_2_3() const; - line 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 - diff --git a/graphiq/library/geometric/warper.h b/graphiq/library/geometric/warper.h deleted file mode 100644 index 7110bf06..00000000 --- a/graphiq/library/geometric/warper.h +++ /dev/null @@ -1,291 +0,0 @@ -#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 - -namespace geometric { - -template -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 &system_1, - const rectangle &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 to_system_1(const point &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 to_system_2(const point &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 to_system_1 - (const rectangle &in_system_2) const; - //!< flips a rectangle from the second system into the first. - rectangle to_system_2 - (const rectangle &in_system_1) const; - //!< flips a rectangle from the first system into the second. - - rectangle system_1() const { return _system_1; } - rectangle 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 &to_set, - origin_vertex origin_corner = BOTTOM_LEFT); - void system_2(const rectangle &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 _system_1; - rectangle _system_2; - origin_vertex _vert_1; - origin_vertex _vert_2; - - point scale_point(const rectangle &source, - const rectangle &target, - origin_vertex v1, origin_vertex v2, - const point &old) const; - rectangle scale_rectangle(const rectangle &source, - const rectangle &target, - origin_vertex v1, origin_vertex v2, - const rectangle &old) const; - rectangle flip_accordingly - (const rectangle &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 -rectangle_warper::rectangle_warper - (const rectangle &system_1, - const rectangle &system_2, - origin_vertex v1, origin_vertex v2) -: _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2) -{} - -template -rectangle_warper::~rectangle_warper() {} - -template -void rectangle_warper::system_1 - (const rectangle &to_set, origin_vertex v) -{ _system_1 = to_set; _vert_1 = v; } - -template -void rectangle_warper::system_2 - (const rectangle &to_set, origin_vertex v) -{ _system_2 = to_set; _vert_2 = v; } - -template -point rectangle_warper::to_system_1 - (const point &in_system_2) const -{ return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); } - -template -point rectangle_warper::to_system_2 - (const point &in_system_1) const -{ return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); } - -template -rectangle rectangle_warper::to_system_1 - (const rectangle &in_system_2) const -{ - return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1, - in_system_2); -} - -template -rectangle rectangle_warper::to_system_2 - (const rectangle &in_system_1) const -{ - return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2, - in_system_1); -} - -template -void rectangle_warper::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 -void rectangle_warper::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 -rectangle rectangle_warper::flip_accordingly - (const rectangle &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(x1, y1, x2, y2).text_form()); - return rectangle(x1, y1, x2, y2); -} - -template -rectangle rectangle_warper::scale_rectangle - (const rectangle &source, - const rectangle &target, origin_vertex source_origin, - origin_vertex target_origin, const rectangle &old) const -{ - rectangle s = rectangle - (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 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 o(flip_accordingly(old, source_origin, BOTTOM_LEFT)); - - rectangle to_return = flip_accordingly(rectangle - ((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 -point rectangle_warper::scale_point - (const rectangle &source, const rectangle &target, - origin_vertex source_origin, origin_vertex target_origin, - const point &old) const -{ - // gross but simple. - return scale_rectangle(source, target, source_origin, target_origin, - rectangle(old, old)).vertex_1(); -} - -template -basis::astring rectangle_warper::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 -basis::astring rectangle_warper::text_form() const -{ - return basis::astring(""); -} - -} // namespace. - -#endif - diff --git a/graphiq/library/makefile b/graphiq/library/makefile index 39f2fd14..45a5610a 100644 --- a/graphiq/library/makefile +++ b/graphiq/library/makefile @@ -1,8 +1,9 @@ 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 diff --git a/graphiq/library/tests_geometric/makefile b/graphiq/library/tests_geometric/makefile deleted file mode 100644 index fa54447a..00000000 --- a/graphiq/library/tests_geometric/makefile +++ /dev/null @@ -1,12 +0,0 @@ -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 - diff --git a/graphiq/library/tests_geometric/test_angle.cpp b/graphiq/library/tests_geometric/test_angle.cpp deleted file mode 100644 index b4bbf160..00000000 --- a/graphiq/library/tests_geometric/test_angle.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* -* 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 -#include -#include -#include -#include -#include -#include - -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 a(30.3, DEGREES); - ASSERT_EQUAL(floot(a.get(RADIANS)), floot(.528835), "radian conversion should be right"); - - outcome retval; - angle at = angle::arctangent(28.3, 29.5, retval); - ASSERT_EQUAL(floot(at.get(DEGREES)), floot(43.8106), "atan should be what we expect"); - angle as = angle::arcsine(17.6, 82.3, retval); - ASSERT_EQUAL(floot(as.get(DEGREES)), floot(12.3482), "asin should be what we expect"); - angle ac = angle::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 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 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, ) - diff --git a/graphiq/library/tests_geometric/test_ccri_angle_average.cpp b/graphiq/library/tests_geometric/test_ccri_angle_average.cpp deleted file mode 100644 index f5ac36bb..00000000 --- a/graphiq/library/tests_geometric/test_ccri_angle_average.cpp +++ /dev/null @@ -1,135 +0,0 @@ - -/* - * 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 -#include -#include -#include -#include -#include -#include - -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, ) - diff --git a/graphiq/library/tests_geometric/test_ellipse.cpp b/graphiq/library/tests_geometric/test_ellipse.cpp deleted file mode 100644 index c5062912..00000000 --- a/graphiq/library/tests_geometric/test_ellipse.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* -* 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 -#include -#include -#include -#include -#include -#include -#include -#include - -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 supposed_good_value(const angle &rotation); -}; - -point test_ellipse::supposed_good_value(const angle &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(25.000000, 20.0000); - if (rot == double_plus(35.3)) return point(24.7134, 23.3372); - if (rot == double_plus(70.6)) return point(22.8791, 28.1757); - if (rot == double_plus(105.9)) return point(17.5249, 11.3112); - if (rot == double_plus(141.2)) return point(15.3608, 16.2700); - if (rot == double_plus(176.5)) return point(15.0023, 19.6943); - if (rot == double_plus(211.8)) return point(15.2242, 22.9611); - if (rot == double_plus(247.1)) return point(16.7732, 27.6388); - if (rot == double_plus(282.4)) return point(22.0127, 10.8459); - if (rot == double_plus(317.7)) return point(24.5511, 15.8588); - if (rot == double_plus(353.0)) return point(24.9906, 19.3872); - return point(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 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, ) - diff --git a/graphiq/library/tests_geometric/test_geometry.cpp b/graphiq/library/tests_geometric/test_geometry.cpp deleted file mode 100644 index ef31cda1..00000000 --- a/graphiq/library/tests_geometric/test_geometry.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -* 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 slugmart; - rectangle burger; - rectangle_warper 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, ); - diff --git a/graphiq/library/tests_geometric/test_point.cpp b/graphiq/library/tests_geometric/test_point.cpp deleted file mode 100644 index c96dcf9c..00000000 --- a/graphiq/library/tests_geometric/test_point.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*****************************************************************************\ -* * -* 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 -#include -#include -#include -#include -#include -#include - -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 fred(23, angle(4)); - point bob(399, angle(2.3)); - double dist = bob.distance(fred); -//LOG(astring("fred is ") + fred + " and bob is " + bob); -//LOG(a_sprintf("distance between is ", dist)); - point 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 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, ) - diff --git a/graphiq/library/tests_geometric/test_warper.cpp b/graphiq/library/tests_geometric/test_warper.cpp deleted file mode 100644 index b7fcf393..00000000 --- a/graphiq/library/tests_geometric/test_warper.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*****************************************************************************\ -* * -* 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 -#include -#include -#include -#include -#include -#include - -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 inner(-20, 0, -60, 30); - rectangle outer(20, 30, 0, 0); - rectangle_warper ito(inner, outer, rectangle_warper::TOP_LEFT, - rectangle_warper::BOTTOM_RIGHT); -//LOG(astring("inner to outer warper is: " + ito.text_form())); - - rectangle warped_inner(ito.to_system_2(inner)); -//LOG(astring("warped inner becomes ") + warped_inner.text_form()); - rectangle 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 in_center(inner.center()); - point warp_in_center(ito.to_system_2(in_center)); - point out_center(outer.center()); - point 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, ); - diff --git a/nucleus/library/crypto/blowfish_crypto.cpp b/nucleus/library/crypto/blowfish_crypto.cpp index 532d3392..7703fe20 100644 --- a/nucleus/library/crypto/blowfish_crypto.cpp +++ b/nucleus/library/crypto/blowfish_crypto.cpp @@ -24,6 +24,7 @@ #include #include +#include #include using namespace basis; @@ -41,9 +42,11 @@ const int FUDGE = 128; //#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) @@ -52,6 +55,10 @@ const int FUDGE = 128; #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) \ @@ -101,6 +108,7 @@ blowfish_crypto::blowfish_crypto(const byte_array &key, int 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"); @@ -108,7 +116,6 @@ blowfish_crypto::blowfish_crypto(const byte_array &key, int key_size) 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"); } @@ -163,6 +170,7 @@ bool blowfish_crypto::set_key(const byte_array &new_key, int key_size) 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(); @@ -180,6 +188,7 @@ SAFE_STATIC(mutex, __vector_init_lock, ) 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; @@ -206,9 +215,30 @@ bool blowfish_crypto::encrypt(const byte_array &source, // 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); @@ -219,7 +249,7 @@ bool blowfish_crypto::encrypt(const byte_array &source, 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. @@ -236,7 +266,7 @@ bool blowfish_crypto::encrypt(const byte_array &source, 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)); @@ -260,9 +290,22 @@ bool blowfish_crypto::decrypt(const byte_array &source, 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); @@ -271,7 +314,7 @@ bool blowfish_crypto::decrypt(const byte_array &source, 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)); @@ -287,8 +330,8 @@ bool blowfish_crypto::decrypt(const byte_array &source, 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; diff --git a/nucleus/library/crypto/ssl_init.cpp b/nucleus/library/crypto/ssl_init.cpp index a5c98a28..ea9d45b1 100644 --- a/nucleus/library/crypto/ssl_init.cpp +++ b/nucleus/library/crypto/ssl_init.cpp @@ -35,6 +35,7 @@ namespace crypto { // 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 @@ -51,24 +52,25 @@ const int SEED_SIZE = 100; 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"); @@ -80,6 +82,12 @@ ssl_init::~ssl_init() { 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(); } diff --git a/nucleus/library/crypto/ssl_init.h b/nucleus/library/crypto/ssl_init.h index 27b52d96..fbda4516 100644 --- a/nucleus/library/crypto/ssl_init.h +++ b/nucleus/library/crypto/ssl_init.h @@ -20,6 +20,9 @@ #include +// forward. +struct ossl_provider_st; + namespace crypto { //! provides some initialization for the RSA and blowfish crypto. @@ -52,6 +55,9 @@ public: 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(); diff --git a/nucleus/library/geometric/angle.h b/nucleus/library/geometric/angle.h new file mode 100644 index 00000000..89696850 --- /dev/null +++ b/nucleus/library/geometric/angle.h @@ -0,0 +1,240 @@ +#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 +#include +#include +#include + +#include + +namespace geometric { + +//! Represents a geometric angle. + +//! angles can be measured in degrees or radians in this class. +enum angular_units { DEGREES, RADIANS }; + +template +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 +{ +public: + double_angle(double init = 0, angular_units unit = RADIANS) + : angle(init, unit) {} + double_angle(const angle &to_copy) : angle(to_copy) {} +}; + +////////////// + +// implementation of larger methods below. + +template +angle::angle(contents a, angular_units unit) { set(a, unit); } + +template +angle angle::operator - (void) const +{ angle to_return(*this); to_return *= -1; return to_return; } + +template +angle angle::operator + (const angle &a) const +{ angle to_return(*this); to_return += a; return to_return; } + +template +angle angle::operator - (const angle &a) const +{ angle to_return(*this); to_return -= a; return to_return; } + +template +angle angle::operator * (contents to_multiply) const +{ + angle to_return(*this); + to_return *= to_multiply; + return to_return; +} + +template +angle angle::operator / (contents to_divide) const +{ angle to_return(*this); to_return /= to_divide; return to_return; } + +template +angle &angle::operator += (const angle &a) +{ _theta += a._theta; return *this; } + +template +angle &angle::operator -= (const angle &a) +{ _theta -= a._theta; return *this; } + +template +angle &angle::operator *= (contents f) +{ _theta *= f; return *this; } + +template +angle &angle::operator /= (contents f) +{ _theta /= f; return *this; } + +template +contents angle::sine() const { return sin(_theta); } + +template +contents angle::cosine() const { return cos(_theta); } + +template +contents angle::tangent() const { return tan(_theta); } + +template +int angle::packed_size() const +{ + basis::byte_array temp; +//hmmm: inefficient! + pack(temp); + return temp.length(); +} + +template +void angle::pack(basis::byte_array &packed_form) const +{ structures::attach(packed_form, _theta); } + +template +bool angle::unpack(basis::byte_array &packed_form) +{ return structures::detach(packed_form, _theta); } + +template +contents angle::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 +contents angle::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 +void angle::set(contents a, angular_units unit) +{ _theta = to_internal(a, unit); } + +template +contents angle::get(angular_units unit) const +{ return from_internal(_theta, unit); } + +template +angle angle::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()); + retval = basis::common::OKAY; + return angle(acos(d), RADIANS); +} + +template +angle angle::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()); + retval = basis::common::OKAY; + return angle(asin(d), RADIANS); +} + +template +angle angle::arctangent(contents opposite, contents adjacent, + basis::outcome &retval) +{ + retval = basis::common::BAD_INPUT; + if ( (adjacent == 0.0) && (opposite == 0.0) ) return angle(); + retval = basis::common::OKAY; + return angle(atan2(opposite, adjacent), RADIANS); +} + +} // namespace. + +#endif + diff --git a/nucleus/library/geometric/cartesian_objects.h b/nucleus/library/geometric/cartesian_objects.h new file mode 100644 index 00000000..e18608e4 --- /dev/null +++ b/nucleus/library/geometric/cartesian_objects.h @@ -0,0 +1,74 @@ +#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 +{ +public: + cartesian_point(double x = 0, double y = 0) : point(x, y) {} + cartesian_point(double r, double_angle theta) : point(r, theta) {} + cartesian_point(const point &to_copy) : point(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 +{ +public: + cartesian_line(const cartesian_point &endpoint_1, + const cartesian_point &endpoint_2) + : line(endpoint_1, endpoint_2) {} + cartesian_line(double x_1 = 0, double y_1 = 0, + double x_2 = 0, double y_2 = 0) + : line(x_1, y_1, x_2, y_2) {} +}; + +////////////// + +//! Provides a geometric rectangle that use double floating points numbers. + +class cartesian_rectangle : public rectangle +{ +public: + cartesian_rectangle(const cartesian_point &vertex_1, + const cartesian_point &vertex_2) + : rectangle(vertex_1, vertex_2) {} + cartesian_rectangle(double x_1 = 0, double y_1 = 0, + double x_2 = 0, double y_2 = 0) + : rectangle(x_1, y_1, x_2, y_2) {} + cartesian_rectangle(const rectangle &rect) + : rectangle(rect) {} +}; + +} // namespace. + +#endif + diff --git a/nucleus/library/geometric/circle.cpp b/nucleus/library/geometric/circle.cpp new file mode 100644 index 00000000..8423c488 --- /dev/null +++ b/nucleus/library/geometric/circle.cpp @@ -0,0 +1,77 @@ +/*****************************************************************************\ +* * +* 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 + +#include + +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. + diff --git a/nucleus/library/geometric/circle.h b/nucleus/library/geometric/circle.h new file mode 100644 index 00000000..4e25286d --- /dev/null +++ b/nucleus/library/geometric/circle.h @@ -0,0 +1,71 @@ +#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 + diff --git a/nucleus/library/geometric/ellipse.cpp b/nucleus/library/geometric/ellipse.cpp new file mode 100644 index 00000000..c7be48c9 --- /dev/null +++ b/nucleus/library/geometric/ellipse.cpp @@ -0,0 +1,120 @@ + + + +/*****************************************************************************\ +* * +* 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 + +#include + +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. + + + + diff --git a/nucleus/library/geometric/ellipse.h b/nucleus/library/geometric/ellipse.h new file mode 100644 index 00000000..53eb44d9 --- /dev/null +++ b/nucleus/library/geometric/ellipse.h @@ -0,0 +1,72 @@ +#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 + diff --git a/nucleus/library/geometric/line.h b/nucleus/library/geometric/line.h new file mode 100644 index 00000000..46f162ee --- /dev/null +++ b/nucleus/library/geometric/line.h @@ -0,0 +1,133 @@ +#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 line +{ +public: + line(const point &endpoint1, + const point &endpoint2); + line(numeric_type end1_x = 0, numeric_type end1_y = 0, + numeric_type end2_x = 0, numeric_type end2_y = 0); + + point center() const; + //!< Returns the point at the center of the line segment. + + line operator + (const point &to_add) const; + line operator - (const point &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 &to_add); + line &operator -= (const point &to_subtract); + //!< Adds or subtracts a point from `this' line. + + point endpoint_1() const; + point endpoint_2() const; + + void endpoint_1(const point &to_set); + void endpoint_2(const point &to_set); + + basis::astring text_form() const; + //!< returns a string form of the points defining the line. + +protected: + point _endpoint_1; + point _endpoint_2; +}; + +////////////// + +// implementations below... + +template +line::line(const point &p1, + const point &p2) +: _endpoint_1(p1), _endpoint_2(p2) {} + +template +line::line(numeric_type x1, numeric_type y1, numeric_type x2, + numeric_type y2) +: _endpoint_1(point(x1, y1)), + _endpoint_2(point(x2, y2)) +{} + +template +point line::center() const +{ + return point(_endpoint_1.x() / 2.0 + _endpoint_2.x() / 2.0, + _endpoint_1.y() / 2.0 + _endpoint_2.y() / 2.0); +} + +template +basis::astring line::text_form() const +{ + return basis::astring("<") + _endpoint_1.text_form() + basis::astring(" ") + + _endpoint_2.text_form() + basis::astring(">"); +} + +template +line &line::operator += + (const point &to_add) +{ _endpoint_1 += to_add; _endpoint_2 += to_add; return *this; } + +template +line &line::operator -= + (const point &to_subtract) +{ _endpoint_1 -= to_subtract; _endpoint_2 -= to_subtract; return *this; } + +template +line line::operator + + (const point &to_add) const +{ line to_return(*this); to_return += to_add; return to_return; } + +template +line line::operator - + (const point &to_subtract) const +{ + line to_return(*this); + to_return -= to_subtract; + return to_return; +} + +template +point line::endpoint_1() const +{ return _endpoint_1; } + +template +point line::endpoint_2() const +{ return _endpoint_2; } + +template +void line::endpoint_1(const point &to_set) +{ _endpoint_1 = to_set; } + +template +void line::endpoint_2(const point &to_set) +{ _endpoint_2 = to_set; } + +} // namespace. + +#endif + diff --git a/nucleus/library/geometric/makefile b/nucleus/library/geometric/makefile new file mode 100644 index 00000000..d8c0da6d --- /dev/null +++ b/nucleus/library/geometric/makefile @@ -0,0 +1,9 @@ +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 + diff --git a/nucleus/library/geometric/math_bits.cpp b/nucleus/library/geometric/math_bits.cpp new file mode 100644 index 00000000..442d690a --- /dev/null +++ b/nucleus/library/geometric/math_bits.cpp @@ -0,0 +1,52 @@ +/*****************************************************************************\ +* * +* 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 + +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; +} + +} + diff --git a/nucleus/library/geometric/math_bits.h b/nucleus/library/geometric/math_bits.h new file mode 100644 index 00000000..2df27a2d --- /dev/null +++ b/nucleus/library/geometric/math_bits.h @@ -0,0 +1,85 @@ +#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 + +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 +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 +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 +bool is_short(numeric_type) { return sizeof(numeric_type) == 2; } + +//! returns true if the templated type is unsigned. +template +bool is_unsigned(numeric_type t) { t = -1; return t > 0; } +//! returns true if the templated type is signed. +template +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 +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. + diff --git a/nucleus/library/geometric/point.h b/nucleus/library/geometric/point.h new file mode 100644 index 00000000..00ed75a8 --- /dev/null +++ b/nucleus/library/geometric/point.h @@ -0,0 +1,237 @@ +#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 +#include +#include +#include + +#include + +//! Contains all of our objects for geometry and avoids name clashes. + +namespace geometric { + +//! Represents a geometric point. + +template +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(-_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 is being used in there, although it's not. +// these lines use a temporary named "sumsquar" to deconfuse the compiler. + +template +point::point(numeric_type x, numeric_type y) { set(x, y); } + +template +point::point(numeric_type r, double_angle theta) +{ set(r, theta); } + +template +basis::astring point::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 +void point::set(numeric_type x, numeric_type y) +{ _x = x; _y = y; } + +template +numeric_type point::r() const +{ + const double sumsquar = basis::square(x()) + basis::square(y()); + return numeric_type(sqrt(sumsquar)); +} + +template +void point::set(numeric_type r, double_angle theta) +{ set(numeric_type(r * theta.cosine()), numeric_type(r * theta.sine())); } + +template +numeric_type point::distance(const point &p2) const +{ + const double sumsquar = basis::square(p2.x() - x()) + basis::square(p2.y() - y()); + return numeric_type(sqrt(sumsquar)); +} + +template +double_angle point::theta() const +{ + basis::outcome retval; + return double_angle::arctangent(y(), x(), retval); +} + +template +int point::packed_size() const +{ + basis::byte_array temp; +//hmmm: inefficient! + pack(temp); + return temp.length(); +} + +template +void point::pack(basis::byte_array &packed_form) const +{ + structures::attach(packed_form, _x); + structures::attach(packed_form, _y); +} + +template +bool point::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 +numeric_type point::magnitude() const +{ + const double sumsquar = basis::square(x()) + basis::square(y()); + return numeric_type(sqrt(sumsquar)); +} + +template +point point::operator + (const point &arg2) const +{ return point(x() + arg2.x(), y() + arg2.y()); } + +template +point point::operator - (const point &arg2) const +{ return point(x() - arg2.x(), y() - arg2.y()); } + +template +point &point::operator += (const point &arg2) +{ _x += arg2.x(); _y += arg2.y(); return *this; } + +template +point &point::operator -= (const point &arg2) +{ _x -= arg2.x(); _y -= arg2.y(); return *this; } + +template +bool point::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 +point point::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(temp1, temp2); +} + +template +bool point::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 + diff --git a/nucleus/library/geometric/polygon.cpp b/nucleus/library/geometric/polygon.cpp new file mode 100644 index 00000000..d1d40056 --- /dev/null +++ b/nucleus/library/geometric/polygon.cpp @@ -0,0 +1,50 @@ + + + +/*****************************************************************************\ +* * +* 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 + +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); +} + +} + + + + diff --git a/nucleus/library/geometric/polygon.h b/nucleus/library/geometric/polygon.h new file mode 100644 index 00000000..8553ead1 --- /dev/null +++ b/nucleus/library/geometric/polygon.h @@ -0,0 +1,60 @@ +#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 + +//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 +{ +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 + diff --git a/nucleus/library/geometric/rectangle.h b/nucleus/library/geometric/rectangle.h new file mode 100644 index 00000000..b63d5ae3 --- /dev/null +++ b/nucleus/library/geometric/rectangle.h @@ -0,0 +1,379 @@ +#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 + +namespace geometric { + +//! Represents a geometric rectangle. + +template +class rectangle : public basis::packable +{ +public: + rectangle(const point &vertex_1, + const point &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 top_left() const; + point bottom_left() const; + point top_right() const; + point 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 center() const; + //!< Returns the point at the center of the rectangle. + + bool inside(const point &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 &to_add) const; + //!< Returns the rectangle resulting from adding a point to its vertices. + rectangle operator - (const point &to_subtract) const; + //!< Returns the rectangle resulting from subtracting "to_subtract". + + rectangle &operator += (const point &to_add); + //!< Adds the point "to_add" to our vertices. + rectangle &operator -= (const point &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 vertex_1() const; + point vertex_2() const; + + void vertex_1(const point &to_set); + void vertex_2(const point &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 _vertex_1; + point _vertex_2; +}; + +////////////// + +//!< A commonly used rectangle of integers. + +typedef rectangle int_rectangle; + +////////////// + +// implementations below... + +template +rectangle::rectangle(const point &lb, const point &rt) +: _vertex_1(lb), _vertex_2(rt) {} + +template +rectangle::rectangle(numeric_type left, numeric_type bottom, numeric_type right, numeric_type top) +: _vertex_1(point(left, bottom)), + _vertex_2(point(right, top)) {} + +template +point rectangle::vertex_1() const +{ return _vertex_1; } + +template +point rectangle::vertex_2() const +{ return _vertex_2; } + +template +void rectangle::vertex_1(const point &to_set) +{ _vertex_1 = to_set; } + +template +void rectangle::vertex_2(const point &to_set) +{ _vertex_2 = to_set; } + +template +numeric_type rectangle::height() const +{ return absolute_value(_vertex_2.y() - _vertex_1.y()); } + +template +numeric_type rectangle::width() const +{ return absolute_value(_vertex_2.x() - _vertex_1.x()); } + +template +numeric_type rectangle::minimum_x() const +{ return basis::minimum(_vertex_1.x(), _vertex_2.x()); } + +template +numeric_type rectangle::minimum_y() const +{ return basis::minimum(_vertex_1.y(), _vertex_2.y()); } + +template +numeric_type rectangle::maximum_x() const +{ return basis::maximum(_vertex_1.x(), _vertex_2.x()); } + +template +numeric_type rectangle::maximum_y() const +{ return basis::maximum(_vertex_1.y(), _vertex_2.y()); } + +template +rectangle rectangle::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(x1, y1, x2, y2); +} + +template +point rectangle::top_left() const +{ + rectangle temp(order()); + return point(temp.vertex_1().x(), temp.vertex_2().y()); +} + +template +point rectangle::bottom_left() const +{ + rectangle temp(order()); + return point(temp.vertex_1().x(), temp.vertex_1().y()); +} + +template +point rectangle::top_right() const +{ + rectangle temp(order()); + return point(temp.vertex_2().x(), temp.vertex_2().y()); +} + +template +point rectangle::bottom_right() const +{ + rectangle temp(order()); + return point(temp.vertex_2().x(), temp.vertex_1().y()); +} + +template +point rectangle::center() const +{ + return point(numeric_type((_vertex_1.x() + + _vertex_2.x()) / 2.0), numeric_type((_vertex_1.y() + + _vertex_2.y()) / 2.0)); +} + +template +bool rectangle::inside(const point &to_check) const +{ + rectangle 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 +bool rectangle::operator == (const rectangle &to_compare) const +{ + point min1(minimum_x(), minimum_y()); + point max1(maximum_x(), maximum_y()); + point min2(to_compare.minimum_x(), to_compare.minimum_y()); + point max2(to_compare.maximum_x(), to_compare.maximum_y()); + if ( (min1 == min2) && (max1 == max2) ) return true; + else return false; +} + +template +rectangle &rectangle::operator += (const point &p) +{ _vertex_1 += p; _vertex_2 += p; return *this; } + +template +rectangle &rectangle::operator -= (const point &p) +{ _vertex_1 -= p; _vertex_2 -= p; return *this; } + +template +rectangle rectangle::operator + (const point &p) const +{ + rectangle to_return(*this); + to_return += p; + return to_return; +} + +template +int rectangle::packed_size() const +{ + basis::byte_array temp; +//hmmm: inefficient! + pack(temp); + return temp.length(); +} + +template +void rectangle::pack(basis::byte_array &packed_form) const +{ + _vertex_1.pack(packed_form); + _vertex_2.pack(packed_form); +} + +template +bool rectangle::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 +rectangle rectangle::operator - (const point &p) const +{ + rectangle to_return(*this); + to_return -= p; + return to_return; +} + +template +void rectangle::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 +bool rectangle::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 +bool rectangle::intersect(const rectangle &r2) const +{ return bool(!disjoint(r2)); } + +template +bool rectangle::join_intersecting(const rectangle &r2, rectangle &result) +{ + if (disjoint(r2)) return false; + result = *this; + result.encompass(r2); + return true; +} + +template +bool rectangle::intersection(const rectangle &r2, rectangle &result) +{ + if (disjoint(r2)) return false; + result = rectangle(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 +basis::astring rectangle::text_form() const +{ + return basis::astring("[") + _vertex_1.text_form() + basis::astring(" ") + + _vertex_2.text_form() + basis::astring("]"); +} + +template +bool rectangle::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(nums[0], nums[1])); + vertex_2(point(nums[2], nums[3])); + return true; +} + +} // namespace. + +#endif + diff --git a/nucleus/library/geometric/screen_rectangle.cpp b/nucleus/library/geometric/screen_rectangle.cpp new file mode 100644 index 00000000..f8732d33 --- /dev/null +++ b/nucleus/library/geometric/screen_rectangle.cpp @@ -0,0 +1,83 @@ + + + +/*****************************************************************************\ +* * +* 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 + +#include + +using namespace basis; + +namespace geometric { + +SAFE_STATIC_CONST(screen_point, screen_origin, (0, 0)) + +////////////// + +#ifdef __WIN32__ +screen_point::screen_point(const tagPOINT &original) : point(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 &init) +: rectangle(init) {} + +screen_rectangle::screen_rectangle(const screen_point &vertex_1, + const screen_point &vertex_2) +: rectangle(vertex_1, vertex_2) {} + +screen_rectangle::screen_rectangle(int x_1, int y_1, int x_2, int y_2) +: rectangle(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::bottom_left(); } + +screen_point screen_rectangle::bottom_left() const +{ return rectangle::top_left(); } + +screen_point screen_rectangle::top_right() const +{ return rectangle::bottom_right(); } + +screen_point screen_rectangle::bottom_right() const +{ return rectangle::top_right(); } + +#ifdef __WIN32__ +screen_rectangle::screen_rectangle(const tagRECT &original) +: rectangle(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. + + + diff --git a/nucleus/library/geometric/screen_rectangle.h b/nucleus/library/geometric/screen_rectangle.h new file mode 100644 index 00000000..df6ab72d --- /dev/null +++ b/nucleus/library/geometric/screen_rectangle.h @@ -0,0 +1,95 @@ +#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 + +#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 +{ +public: + screen_point(int x = 0, int y = 0) : point(x, y) {} + screen_point(int r, double_angle theta) : point(r, theta) {} + screen_point(const point &original) : point(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 +{ +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 &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 + diff --git a/nucleus/library/geometric/triangle.cpp b/nucleus/library/geometric/triangle.cpp new file mode 100644 index 00000000..4597d6a6 --- /dev/null +++ b/nucleus/library/geometric/triangle.cpp @@ -0,0 +1,112 @@ + + + +/*****************************************************************************\ +* * +* 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 triangle::side_1_2() const +{ return line(_vertex_1, _vertex_2); } + +line triangle::side_2_3() const +{ return line(_vertex_2, _vertex_3); } + +line triangle::side_3_1() const +{ return line(_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 chuzzo; +chuzzo beanburp = chuzzo(rectangle(0, 23, 39, 1012), + rectangle(8, 19, 92982, -2), chuzzo::BOTTOM_RIGHT, + chuzzo::TOP_LEFT); +typedef rectangle_warper::horizontal_component horzo; +typedef rectangle_warper::vertical_component verzo; +int frunk() { + horzo peen; + beanburp.separate_horizontal(chuzzo::BOTTOM_RIGHT, peen); + verzo neep; + beanburp.separate_vertical(chuzzo::TOP_RIGHT, neep); +} +*/ + + + + + diff --git a/nucleus/library/geometric/triangle.h b/nucleus/library/geometric/triangle.h new file mode 100644 index 00000000..bf1e5cbb --- /dev/null +++ b/nucleus/library/geometric/triangle.h @@ -0,0 +1,64 @@ +#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 side_1_2() const; + line side_2_3() const; + line 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 + diff --git a/nucleus/library/geometric/warper.h b/nucleus/library/geometric/warper.h new file mode 100644 index 00000000..7110bf06 --- /dev/null +++ b/nucleus/library/geometric/warper.h @@ -0,0 +1,291 @@ +#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 + +namespace geometric { + +template +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 &system_1, + const rectangle &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 to_system_1(const point &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 to_system_2(const point &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 to_system_1 + (const rectangle &in_system_2) const; + //!< flips a rectangle from the second system into the first. + rectangle to_system_2 + (const rectangle &in_system_1) const; + //!< flips a rectangle from the first system into the second. + + rectangle system_1() const { return _system_1; } + rectangle 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 &to_set, + origin_vertex origin_corner = BOTTOM_LEFT); + void system_2(const rectangle &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 _system_1; + rectangle _system_2; + origin_vertex _vert_1; + origin_vertex _vert_2; + + point scale_point(const rectangle &source, + const rectangle &target, + origin_vertex v1, origin_vertex v2, + const point &old) const; + rectangle scale_rectangle(const rectangle &source, + const rectangle &target, + origin_vertex v1, origin_vertex v2, + const rectangle &old) const; + rectangle flip_accordingly + (const rectangle &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 +rectangle_warper::rectangle_warper + (const rectangle &system_1, + const rectangle &system_2, + origin_vertex v1, origin_vertex v2) +: _system_1(system_1), _system_2(system_2), _vert_1(v1), _vert_2(v2) +{} + +template +rectangle_warper::~rectangle_warper() {} + +template +void rectangle_warper::system_1 + (const rectangle &to_set, origin_vertex v) +{ _system_1 = to_set; _vert_1 = v; } + +template +void rectangle_warper::system_2 + (const rectangle &to_set, origin_vertex v) +{ _system_2 = to_set; _vert_2 = v; } + +template +point rectangle_warper::to_system_1 + (const point &in_system_2) const +{ return scale_point(_system_2, _system_1, _vert_2, _vert_1, in_system_2); } + +template +point rectangle_warper::to_system_2 + (const point &in_system_1) const +{ return scale_point(_system_1, _system_2, _vert_1, _vert_2, in_system_1); } + +template +rectangle rectangle_warper::to_system_1 + (const rectangle &in_system_2) const +{ + return scale_rectangle(_system_2, _system_1, _vert_2, _vert_1, + in_system_2); +} + +template +rectangle rectangle_warper::to_system_2 + (const rectangle &in_system_1) const +{ + return scale_rectangle(_system_1, _system_2, _vert_1, _vert_2, + in_system_1); +} + +template +void rectangle_warper::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 +void rectangle_warper::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 +rectangle rectangle_warper::flip_accordingly + (const rectangle &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(x1, y1, x2, y2).text_form()); + return rectangle(x1, y1, x2, y2); +} + +template +rectangle rectangle_warper::scale_rectangle + (const rectangle &source, + const rectangle &target, origin_vertex source_origin, + origin_vertex target_origin, const rectangle &old) const +{ + rectangle s = rectangle + (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 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 o(flip_accordingly(old, source_origin, BOTTOM_LEFT)); + + rectangle to_return = flip_accordingly(rectangle + ((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 +point rectangle_warper::scale_point + (const rectangle &source, const rectangle &target, + origin_vertex source_origin, origin_vertex target_origin, + const point &old) const +{ + // gross but simple. + return scale_rectangle(source, target, source_origin, target_origin, + rectangle(old, old)).vertex_1(); +} + +template +basis::astring rectangle_warper::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 +basis::astring rectangle_warper::text_form() const +{ + return basis::astring(""); +} + +} // namespace. + +#endif + diff --git a/nucleus/library/makefile b/nucleus/library/makefile index 6b6045fb..a9a05545 100644 --- a/nucleus/library/makefile +++ b/nucleus/library/makefile @@ -6,6 +6,7 @@ BUILD_BEFORE = algorithms \ structures \ timely \ mathematics \ + geometric \ textual \ nodes \ filesystem \ @@ -19,6 +20,7 @@ BUILD_BEFORE = algorithms \ tests_structures \ tests_filesystem \ tests_mathematics \ + tests_geometric \ tests_processes \ tests_nodes \ tests_textual \ diff --git a/nucleus/library/tests_geometric/makefile b/nucleus/library/tests_geometric/makefile new file mode 100644 index 00000000..fa54447a --- /dev/null +++ b/nucleus/library/tests_geometric/makefile @@ -0,0 +1,12 @@ +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 + diff --git a/nucleus/library/tests_geometric/test_angle.cpp b/nucleus/library/tests_geometric/test_angle.cpp new file mode 100644 index 00000000..b4bbf160 --- /dev/null +++ b/nucleus/library/tests_geometric/test_angle.cpp @@ -0,0 +1,77 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include + +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 a(30.3, DEGREES); + ASSERT_EQUAL(floot(a.get(RADIANS)), floot(.528835), "radian conversion should be right"); + + outcome retval; + angle at = angle::arctangent(28.3, 29.5, retval); + ASSERT_EQUAL(floot(at.get(DEGREES)), floot(43.8106), "atan should be what we expect"); + angle as = angle::arcsine(17.6, 82.3, retval); + ASSERT_EQUAL(floot(as.get(DEGREES)), floot(12.3482), "asin should be what we expect"); + angle ac = angle::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 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 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, ) + diff --git a/nucleus/library/tests_geometric/test_ccri_angle_average.cpp b/nucleus/library/tests_geometric/test_ccri_angle_average.cpp new file mode 100644 index 00000000..f5ac36bb --- /dev/null +++ b/nucleus/library/tests_geometric/test_ccri_angle_average.cpp @@ -0,0 +1,135 @@ + +/* + * 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 +#include +#include +#include +#include +#include +#include + +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, ) + diff --git a/nucleus/library/tests_geometric/test_ellipse.cpp b/nucleus/library/tests_geometric/test_ellipse.cpp new file mode 100644 index 00000000..c5062912 --- /dev/null +++ b/nucleus/library/tests_geometric/test_ellipse.cpp @@ -0,0 +1,83 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 supposed_good_value(const angle &rotation); +}; + +point test_ellipse::supposed_good_value(const angle &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(25.000000, 20.0000); + if (rot == double_plus(35.3)) return point(24.7134, 23.3372); + if (rot == double_plus(70.6)) return point(22.8791, 28.1757); + if (rot == double_plus(105.9)) return point(17.5249, 11.3112); + if (rot == double_plus(141.2)) return point(15.3608, 16.2700); + if (rot == double_plus(176.5)) return point(15.0023, 19.6943); + if (rot == double_plus(211.8)) return point(15.2242, 22.9611); + if (rot == double_plus(247.1)) return point(16.7732, 27.6388); + if (rot == double_plus(282.4)) return point(22.0127, 10.8459); + if (rot == double_plus(317.7)) return point(24.5511, 15.8588); + if (rot == double_plus(353.0)) return point(24.9906, 19.3872); + return point(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 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, ) + diff --git a/nucleus/library/tests_geometric/test_geometry.cpp b/nucleus/library/tests_geometric/test_geometry.cpp new file mode 100644 index 00000000..ef31cda1 --- /dev/null +++ b/nucleus/library/tests_geometric/test_geometry.cpp @@ -0,0 +1,95 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 slugmart; + rectangle burger; + rectangle_warper 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, ); + diff --git a/nucleus/library/tests_geometric/test_point.cpp b/nucleus/library/tests_geometric/test_point.cpp new file mode 100644 index 00000000..c96dcf9c --- /dev/null +++ b/nucleus/library/tests_geometric/test_point.cpp @@ -0,0 +1,74 @@ +/*****************************************************************************\ +* * +* 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 +#include +#include +#include +#include +#include +#include + +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 fred(23, angle(4)); + point bob(399, angle(2.3)); + double dist = bob.distance(fred); +//LOG(astring("fred is ") + fred + " and bob is " + bob); +//LOG(a_sprintf("distance between is ", dist)); + point 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 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, ) + diff --git a/nucleus/library/tests_geometric/test_warper.cpp b/nucleus/library/tests_geometric/test_warper.cpp new file mode 100644 index 00000000..b7fcf393 --- /dev/null +++ b/nucleus/library/tests_geometric/test_warper.cpp @@ -0,0 +1,69 @@ +/*****************************************************************************\ +* * +* 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 +#include +#include +#include +#include +#include +#include + +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 inner(-20, 0, -60, 30); + rectangle outer(20, 30, 0, 0); + rectangle_warper ito(inner, outer, rectangle_warper::TOP_LEFT, + rectangle_warper::BOTTOM_RIGHT); +//LOG(astring("inner to outer warper is: " + ito.text_form())); + + rectangle warped_inner(ito.to_system_2(inner)); +//LOG(astring("warped inner becomes ") + warped_inner.text_form()); + rectangle 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 in_center(inner.center()); + point warp_in_center(ito.to_system_2(in_center)); + point out_center(outer.center()); + point 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, ); +