1 #ifndef __PROJ_PT_H__
2 #define __PROJ_PT_H__
4 /*
5 * 3x4 transformation matrix to map points from projective 3-space into the projective plane
6 *
7 * Authors:
8 * Maximilian Albert <Anhalter42@gmx.de>
9 *
10 * Copyright (C) 2007 Authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #include <2geom/point.h>
16 #include "libnr/nr-point.h"
17 #include "libnr/nr-values.h"
18 #include <gtk/gtk.h>
20 namespace Proj {
22 const double epsilon = 1E-6;
24 // TODO: Catch the case when the constructors are called with only zeros
25 class Pt2 {
26 public:
27 Pt2 () { pt[0] = 0; pt[1] = 0; pt[2] = 1.0; } // we default to (0 : 0 : 1)
28 Pt2 (double x, double y, double w) { pt[0] = x; pt[1] = y; pt[2] = w; }
29 Pt2 (NR::Point const &point) { pt[0] = point[NR::X]; pt[1] = point[NR::Y]; pt[2] = 1; }
30 Pt2 (Geom::Point const &point) { pt[0] = point[Geom::X]; pt[1] = point[Geom::Y]; pt[2] = 1; }
31 Pt2 (const gchar *coord_str);
33 inline double operator[] (unsigned int index) const {
34 if (index > 2) { return NR_HUGE; }
35 return pt[index];
36 }
37 inline double &operator[] (unsigned int index) {
38 // FIXME: How should we handle wrong indices?
39 //if (index > 2) { return NR_HUGE; }
40 return pt[index];
41 }
42 inline bool operator== (Pt2 &rhs) {
43 normalize();
44 rhs.normalize();
45 return (fabs(pt[0] - rhs.pt[0]) < epsilon &&
46 fabs(pt[1] - rhs.pt[1]) < epsilon &&
47 fabs(pt[2] - rhs.pt[2]) < epsilon);
48 }
49 inline bool operator!= (Pt2 &rhs) {
50 return !((*this) == rhs);
51 }
53 /*** For convenience, we define addition/subtraction etc. as "affine" operators (i.e.,
54 the result for finite points is the same as if the affine points were addes ***/
55 inline Pt2 &operator+(Pt2 &rhs) const {
56 Pt2 *result = new Pt2 (*this);
57 result->normalize();
58 rhs.normalize();
59 for ( unsigned i = 0 ; i < 2 ; ++i ) {
60 result->pt[i] += rhs.pt[i];
61 }
62 return *result;
63 }
65 inline Pt2 &operator-(Pt2 &rhs) const {
66 Pt2 *result = new Pt2 (*this);
67 result->normalize();
68 rhs.normalize();
69 for ( unsigned i = 0 ; i < 2 ; ++i ) {
70 result->pt[i] -= rhs.pt[i];
71 }
72 return *result;
73 }
75 inline Pt2 &operator*(double const s) const {
76 Pt2 *result = new Pt2 (*this);
77 result->normalize();
78 for ( unsigned i = 0 ; i < 2 ; ++i ) {
79 result->pt[i] *= s;
80 }
81 return *result;
82 }
84 void normalize();
85 NR::Point affine();
86 inline bool is_finite() { return pt[2] != 0; } // FIXME: Should we allow for some tolerance?
87 gchar *coord_string();
88 inline void print(gchar const *s) const { g_print ("%s(%8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2]); }
90 private:
91 double pt[3];
92 };
95 class Pt3 {
96 public:
97 Pt3 () { pt[0] = 0; pt[1] = 0; pt[2] = 0; pt[3] = 1.0; } // we default to (0 : 0 : 0 : 1)
98 Pt3 (double x, double y, double z, double w) { pt[0] = x; pt[1] = y; pt[2] = z; pt[3] = w; }
99 Pt3 (const gchar *coord_str);
101 inline bool operator== (Pt3 &rhs) {
102 normalize();
103 rhs.normalize();
104 return (fabs(pt[0] - rhs.pt[0]) < epsilon &&
105 fabs(pt[1] - rhs.pt[1]) < epsilon &&
106 fabs(pt[2] - rhs.pt[2]) < epsilon &&
107 fabs(pt[3] - rhs.pt[3]) < epsilon);
108 }
110 /*** For convenience, we define addition/subtraction etc. as "affine" operators (i.e.,
111 the result for finite points is the same as if the affine points were addes ***/
112 inline Pt3 &operator+(Pt3 &rhs) const {
113 Pt3 *result = new Pt3 (*this);
114 result->normalize();
115 rhs.normalize();
116 for ( unsigned i = 0 ; i < 3 ; ++i ) {
117 result->pt[i] += rhs.pt[i];
118 }
119 return *result;
120 }
122 inline Pt3 &operator-(Pt3 &rhs) const {
123 Pt3 *result = new Pt3 (*this);
124 result->normalize();
125 rhs.normalize();
126 for ( unsigned i = 0 ; i < 3 ; ++i ) {
127 result->pt[i] -= rhs.pt[i];
128 }
129 return *result;
130 }
132 inline Pt3 &operator*(double const s) const {
133 Pt3 *result = new Pt3 (*this);
134 result->normalize();
135 for ( unsigned i = 0 ; i < 3 ; ++i ) {
136 result->pt[i] *= s;
137 }
138 return *result;
139 }
141 inline double operator[] (unsigned int index) const {
142 if (index > 3) { return NR_HUGE; }
143 return pt[index];
144 }
145 inline double &operator[] (unsigned int index) {
146 // FIXME: How should we handle wrong indices?
147 //if (index > 3) { return NR_HUGE; }
148 return pt[index];
149 }
150 void normalize();
151 inline bool is_finite() { return pt[3] != 0; } // FIXME: Should we allow for some tolerance?
152 gchar *coord_string();
153 inline void print(gchar const *s) const {
154 g_print ("%s(%8.2f : %8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2], pt[3]);
155 }
157 private:
158 double pt[4];
159 };
161 } // namespace Proj
163 #endif /* __PROJ_PT_H__ */
165 /*
166 Local Variables:
167 mode:c++
168 c-file-style:"stroustrup"
169 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
170 indent-tabs-mode:nil
171 fill-column:99
172 End:
173 */
174 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :