Code

b7f3d12a1f8ec322d35f8e5481bdb36c11f0a54d
[inkscape.git] / src / vanishing-point.h
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);
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;
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;
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; }
148         
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;
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 :