b7f3d12a1f8ec322d35f8e5481bdb36c11f0a54d
1 /*
2 * Vanishing point for 3D perspectives
3 *
4 * Authors:
5 * Maximilian Albert <Anhalter42@gmx.de>
6 *
7 * Copyright (C) 2007 authors
8 *
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
12 #ifndef SEEN_VANISHING_POINT_H
13 #define SEEN_VANISHING_POINT_H
15 #include "libnr/nr-point.h"
16 #include "line-geometry.h"
18 namespace Box3D {
20 enum VPState {
21 VP_FINITE = 0, // perspective lines meet in the VP
22 VP_INFINITE // perspective lines are parallel
23 };
25 // The X-/Y-/Z-axis corresponds to the first/second/third digit
26 // in binary representation, respectively.
27 enum Axis {
28 X = 1,
29 Y = 2,
30 Z = 4,
31 XY = 3,
32 XZ = 5,
33 YZ = 6,
34 XYZ = 7,
35 NONE = 0
36 };
38 // We use the fourth bit in binary representation
39 // to indicate whether a face is front or rear.
40 enum FrontOrRear { // find a better name
41 FRONT = 0,
42 REAR = 8
43 };
45 extern Axis axes[3];
46 extern Axis planes[3];
47 extern FrontOrRear face_positions [2];
49 // Given a bit sequence that unambiguously specifies the face of a 3D box,
50 // return a number between 0 and 5 corresponding to that particular face
51 // (which is normally used to index an array). Return -1 if the bit sequence
52 // does not specify a face. A face can either be given by its plane (e.g, XY)
53 // or by the axis that is orthogonal to it (e.g., Z).
54 inline gint face_to_int (guint face_id) {
55 switch (face_id) {
56 case 1: return 0;
57 case 2: return 2;
58 case 4: return 4;
59 case 3: return 4;
60 case 5: return 2;
61 case 6: return 0;
63 case 9: return 1;
64 case 10: return 3;
65 case 12: return 5;
66 case 11: return 5;
67 case 13: return 3;
68 case 14: return 1;
70 default: return -1;
71 }
72 }
74 inline bool is_single_axis_direction (Box3D::Axis dir) {
75 // tests whether dir is nonzero and a power of 2
76 return (!(dir & (dir - 1)) && dir);
77 }
79 /**
80 * Given two axis directions out of {X, Y, Z} or the corresponding plane, return the remaining one
81 * We don't check if 'plane' really specifies a plane (i.e., if it consists of precisely two directions).
82 */
83 inline Box3D::Axis third_axis_direction (Box3D::Axis dir1, Box3D::Axis dir2) {
84 return (Box3D::Axis) ((dir1 + dir2) ^ 0x7);
85 }
86 inline Box3D::Axis third_axis_direction (Box3D::Axis plane) {
87 return (Box3D::Axis) (plane ^ 0x7);
88 }
90 /* returns the first/second axis direction occuring in the (possibly compound) expression 'dirs' */
91 inline Box3D::Axis extract_first_axis_direction (Box3D::Axis dirs) {
92 if (dirs & Box3D::X) return Box3D::X;
93 if (dirs & Box3D::Y) return Box3D::Y;
94 if (dirs & Box3D::Z) return Box3D::Z;
95 return Box3D::NONE;
96 }
97 inline Box3D::Axis extract_second_axis_direction (Box3D::Axis dirs) {
98 return extract_first_axis_direction ((Box3D::Axis) (dirs ^ extract_first_axis_direction(dirs)));
99 }
101 inline Box3D::Axis orth_plane (Box3D::Axis axis) {
102 return (Box3D::Axis) (Box3D::XYZ ^ axis);
103 }
105 /* returns an axis direction perpendicular to the ones occuring in the (possibly compound) expression 'dirs' */
106 inline Box3D::Axis get_perpendicular_axis_direction (Box3D::Axis dirs) {
107 if (!(dirs & Box3D::X)) return Box3D::X;
108 if (!(dirs & Box3D::Y)) return Box3D::Y;
109 if (!(dirs & Box3D::Z)) return Box3D::Z;
110 return Box3D::NONE;
111 }
113 inline gchar * string_from_axes (Box3D::Axis axes) {
114 GString *pstring = g_string_new("");
115 if (axes & Box3D::X) g_string_append_printf (pstring, "X");
116 if (axes & Box3D::Y) g_string_append_printf (pstring, "Y");
117 if (axes & Box3D::Z) g_string_append_printf (pstring, "Z");
118 return pstring->str;
119 }
121 // FIXME: Store the Axis of the VP inside the class
122 class VanishingPoint : public NR::Point {
123 public:
124 inline VanishingPoint() : NR::Point() {};
125 /***
126 inline VanishingPoint(NR::Point const &pt, NR::Point const &ref = NR::Point(0,0))
127 : NR::Point (pt),
128 ref_pt (ref),
129 v_dir (pt[NR::X] - ref[NR::X], pt[NR::Y] - ref[NR::Y]) {}
130 inline VanishingPoint(NR::Coord x, NR::Coord y, NR::Point const &ref = NR::Point(0,0))
131 : NR::Point (x, y),
132 ref_pt (ref),
133 v_dir (x - ref[NR::X], y - ref[NR::Y]) {}
134 ***/
135 VanishingPoint(NR::Point const &pt, NR::Point const &inf_dir, VPState st);
136 VanishingPoint(NR::Point const &pt);
137 VanishingPoint(NR::Point const &dir, VPState const state);
138 VanishingPoint(NR::Point const &pt, NR::Point const &direction);
139 VanishingPoint(NR::Coord x, NR::Coord y);
140 VanishingPoint(NR::Coord x, NR::Coord y, VPState const state);
141 VanishingPoint(NR::Coord x, NR::Coord y, NR::Coord dir_x, NR::Coord dir_y);
142 VanishingPoint(VanishingPoint const &rhs);
144 bool is_finite();
145 VPState toggle_parallel();
146 void draw(Box3D::Axis const axis); // Draws a point on the canvas if state == VP_FINITE
147 //inline VPState state() { return state; }
149 VPState state;
150 //NR::Point ref_pt; // point of reference to compute the direction of parallel lines
151 NR::Point v_dir; // direction of perslective lines if the VP has state == VP_INFINITE
153 private:
154 };
157 } // namespace Box3D
160 /** A function to print out the VanishingPoint (prints the coordinates) **/
161 /***
162 inline std::ostream &operator<< (std::ostream &out_file, const VanishingPoint &vp) {
163 out_file << vp;
164 return out_file;
165 }
166 ***/
169 #endif /* !SEEN_VANISHING_POINT_H */
171 /*
172 Local Variables:
173 mode:c++
174 c-file-style:"stroustrup"
175 c-file-offsets:((innamespace . 0)(inline-open . 0))
176 indent-tabs-mode:nil
177 fill-column:99
178 End:
179 */
180 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :