Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef CLOUD_AND_STICK_H
00017 #define CLOUD_AND_STICK_H
00018
00019 #include "point_cloud.h"
00020 #include "auxil.h"
00021 #include <utility>
00022 #include <vector>
00023
00024 typedef std::pair<vector3, vector3> stick_type;
00025
00026
00027 inline
00028 vector3 nearest_point_on_stick (const stick_type &stick, const double alpha)
00029 {
00030 const vector3 p = alpha * stick.second + (1.0 - alpha) * stick.first;
00031 return p;
00032 }
00033
00034 inline
00035 double dist2 (const stick_type &stick, const vector3 &x0, double &alpha)
00036 {
00037 const vector3 x1 = stick.first;
00038 const vector3 x2 = stick.second;
00039 const vector3 d01 = x0 - x1;
00040 const vector3 d21 = x2 - x1;
00041 alpha = (d01 * d21) / (d21 * d21);
00042 alpha = force_in_range (alpha, 0.0, 1.0);
00043
00044 const vector3 p = nearest_point_on_stick (stick, alpha);
00045 const vector3 d = p - x0;
00046 const double retval = d * d;
00047
00048 return retval;
00049 }
00050
00051 inline double dist2 (const stick_type &stick, const vector3 &x0)
00052 {
00053 double alpha;
00054 return dist2 (stick, x0, alpha);
00055 }
00056
00061 template <class cloud_type>
00062 class cloud_and_stick : public cloud_type
00063 {
00064 public:
00065 cloud_and_stick (const options &opts, const calibration &_calib)
00066 : cloud_type (opts, _calib),
00067
00068
00069 sticks_index (opts.data_start_idx ())
00070 {
00071 FILE *fid = fopen (opts.stick_filename ().c_str (), "r");
00072 const bool found = (fid != NULL);
00073 if (!found)
00074 {
00075 std::cerr << "cloud_and_stick::cloud_and_stick: could not open '"
00076 << opts.stick_filename () << "' for reading." << std::endl;
00077 exit (-1);
00078 }
00079 else
00080 {
00081
00082
00083 const int buf_size = 1000;
00084 char line [buf_size];
00085 int num_sticks = 0;
00086 while (fgets (line, buf_size, fid) != NULL)
00087 num_sticks ++;
00088
00089
00090 sticks.resize (num_sticks);
00091 points_on_sticks.resize (num_sticks);
00092
00093
00094 rewind (fid);
00095 const int num_points = 2;
00096 for (int k = 0; k < num_sticks; k++)
00097 {
00098 points_on_sticks [k] = new std::vector<vector3> (num_points);
00099 for (int n = 0; n < num_points; n++)
00100 {
00101 double x, y, z;
00102 const int num_read = fscanf (fid, "%lf %lf %lf", &x, &y, &z);
00103 if (num_read != 3)
00104 {
00105 std::cerr << "cloud_and_stick: invalid stick data" << std::endl;
00106 break;
00107 }
00108 const vector3 v = this->calib.camera_to_world (vector3 (x, y, z));
00109
00110 (*(points_on_sticks [k])) [n] = v;
00111 }
00112 const int num_read = fscanf (fid, "\n");
00113 if (num_read != 0)
00114 {
00115 std::cerr << "cloud_and_stick: invalid line ending in stick data" << std::endl;
00116 }
00117 sticks [k].first = (*(points_on_sticks [k])) [0];
00118 sticks [k].second = (*(points_on_sticks [k])) [num_points-1];
00119 }
00120 fclose (fid);
00121 }
00122 }
00123
00124 ~cloud_and_stick ()
00125 {
00126 for (size_t k = 0; k < points_on_sticks.size (); k++)
00127 delete points_on_sticks [k];
00128 }
00129
00130 bool refresh (bool goto_next = true)
00131 {
00132
00133 bool success = cloud_type::refresh (goto_next);
00134
00135 if (success)
00136 {
00137
00138 if (goto_next)
00139 {
00140 sticks_index ++;
00141 if (sticks_index >= sticks.size ())
00142 success = false;
00143 }
00144
00145
00146 remove_stick_data ();
00147 }
00148 return success;
00149 }
00150
00151 void show () const
00152 {
00153 cloud_type::show ();
00154
00155
00156 const stick_type stick = get_stick ();
00157
00158 OpenTissue::gl::ColorPicker (0.9, 0.1, 0.9, 1.0);
00159 OpenTissue::gl::DrawVector (stick.second, stick.first - stick.second, 1.0, false);
00160 OpenTissue::gl::DrawPoint (stick.first, 0.2);
00161 OpenTissue::gl::ColorPicker (0.9, 0.1, 0.1, 1.0);
00162 OpenTissue::gl::DrawPoint (stick.second, 0.2);
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 }
00173
00178 stick_type get_stick () const
00179 {
00180 return sticks [sticks_index];
00181 }
00182
00183 protected:
00184
00185 std::vector<stick_type> sticks;
00186 std::vector< std::vector<vector3>* > points_on_sticks;
00187 unsigned int sticks_index;
00188
00189 virtual void remove_stick_data () = 0;
00190 };
00191
00192 class point_cloud_and_stick : public cloud_and_stick<point_cloud>
00193 {
00194 public:
00195 point_cloud_and_stick (const options &opts, const calibration &_calib)
00196 : cloud_and_stick<point_cloud> (opts, _calib)
00197 {
00198 }
00199
00200 protected:
00201 void remove_stick_data ()
00202 {
00203 const size_t num_points = points.size ();
00204 size_t num_deletes = 0;
00205 for (size_t k = 0; k < num_points; k++)
00206 {
00207 if (sqrt (dist2 (sticks [sticks_index], points [k])) < 1.0)
00208 num_deletes ++;
00209 else
00210 {
00211 points [k - num_deletes] = points [k];
00212 colours [k - num_deletes] = colours [k];
00213 }
00214 }
00215 points.resize (num_points - num_deletes);
00216 colours.resize (num_points - num_deletes);
00217 }
00218 };
00219
00220 #endif // CLOUD_AND_STICK_H