00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include <algorithm>
00022 #include <math.h>
00023 #include <map>
00024 #include "rect.hxx"
00025 #include "selection.hxx"
00026 #include "particle.hxx"
00027 #include "particle_factory.hxx"
00028 #include "controller.hxx"
00029
00030 Selection::Selection ()
00031 {
00032 world = 0;
00033 }
00034
00035 Vector2d
00036 Selection::get_center ()
00037 {
00038 validate();
00039
00040 Rect<float> rot_box ((*selection.begin ())->pos.x,
00041 (*selection.begin ())->pos.y,
00042 (*selection.begin ())->pos.x,
00043 (*selection.begin ())->pos.y);
00044
00045 for (Selection::iterator i = selection.begin (); i != selection.end (); ++i)
00046 {
00047 rot_box.x1 = Math::min(rot_box.x1, (*i)->pos.x);
00048 rot_box.y1 = Math::min(rot_box.y1, (*i)->pos.y);
00049
00050 rot_box.x2 = Math::max(rot_box.x2, (*i)->pos.x);
00051 rot_box.y2 = Math::max(rot_box.y2, (*i)->pos.y);
00052 }
00053
00054 return rot_box.get_center ();
00055 }
00056
00057 void
00058 Selection::scale (float factor)
00059 {
00060 validate();
00061
00062 if (!selection.empty())
00063 {
00064 Particle& p = **selection.begin();
00065 Rect<float> selection_box (p.pos.x, p.pos.y, p.pos.x, p.pos.y);
00066
00067 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00068 {
00069 selection_box.x1 = Math::min(selection_box.x1, (*i)->pos.x);
00070 selection_box.y1 = Math::min(selection_box.y1, (*i)->pos.y);
00071
00072 selection_box.x2 = Math::max(selection_box.x2, (*i)->pos.x);
00073 selection_box.y2 = Math::max(selection_box.y2, (*i)->pos.y);
00074 }
00075 Vector2d midpoint = selection_box.get_center ();
00076
00077 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00078 {
00079 (*i)->pos = (midpoint - (*i)->pos) * factor;
00080 }
00081 }
00082 }
00083
00084 void
00085 Selection::set_velocity (const Vector2d vel)
00086 {
00087 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00088 (*i)->velocity = vel;
00089 }
00090
00091 void
00092 Selection::flip ()
00093 {
00094 validate();
00095
00096 if (!selection.empty())
00097 {
00098 float midpoint = 0.0f;
00099 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00100 {
00101 midpoint += (*i)->pos.x;
00102 }
00103 midpoint /= selection.size ();
00104
00105 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00106 {
00107 (*i)->pos.x = midpoint - ((*i)->pos.x - midpoint);
00108 }
00109 }
00110 }
00111
00112 void
00113 Selection::select_particles (Vector2d p1, Vector2d p2)
00114 {
00115 world = Controller::instance()->get_world ();
00116
00117 selection = world->get_particles (p1.x, p1.y,
00118 p2.x, p2.y);
00119 }
00120
00121 void
00122 Selection::duplicate ()
00123 {
00124 validate();
00125
00126 Controller::instance()->push_undo();
00127
00128
00129 std::map<Particle*, Particle*> p_trans_table;
00130
00131 SelectionLst new_selection;
00132
00133 std::cout << "Trying to duplicate the selection" << std::endl;
00134 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00135 {
00136 Particle* p = world->get_particle_mgr()->add_particle(**i);
00137 p->pos += Vector2d (50,50);
00138 new_selection.push_back(p);
00139 p_trans_table[*i] = p;
00140
00141
00142 }
00143
00144
00145 std::vector<Spring*> springs = world->get_spring_mgr ();
00146 for (std::vector<Spring*>::iterator i = springs.begin (); i != springs.end (); ++i)
00147 {
00148
00149 if (std::find (selection.begin (), selection.end (), (*i)->particles.first) != selection.end ()
00150 &&
00151 std::find (selection.begin (), selection.end (), (*i)->particles.second) != selection.end ())
00152 {
00153 world->add_spring (p_trans_table[(*i)->particles.first],
00154 p_trans_table[(*i)->particles.second]);
00155 }
00156 }
00157
00158 selection = new_selection;
00159 }
00160
00161 bool
00162 Selection::empty() const
00163 {
00164 return selection.empty();
00165 }
00166
00167 void
00168 Selection::clear()
00169 {
00170 selection.clear();
00171 world = 0;
00172 }
00173
00174 void
00175 Selection::rotate (float rot_angle, Vector2d rotate_center)
00176 {
00177 validate();
00178
00179 for (SelectionLst::iterator i = selection.begin (); i != selection.end (); ++i)
00180 {
00181 Vector2d& pos = (*i)->pos;
00182
00183 pos.x -= rotate_center.x;
00184 pos.y -= rotate_center.y;
00185
00186 float angle = atan2(pos.y, pos.x) + rot_angle;
00187 float length = pos.norm ();
00188
00189 pos.x = (cos (angle)*length) + rotate_center.x;
00190 pos.y = (sin (angle)*length) + rotate_center.y;
00191 }
00192 }
00193
00194 void
00195 Selection::validate()
00196 {
00197 if (world != Controller::instance()->get_world ())
00198 {
00199 std::cout << "World changed; " << world << " " << Controller::instance()->get_world () << std::endl;
00200 clear();
00201 }
00202 }
00203
00204