1 #include "libr2c2/track.h"
8 SlopeTool::SlopeTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, const set<Object *> &objects):
12 for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
13 if(!dynamic_cast<Track *>(*i) || (*i)->get_n_link_slots()!=2)
15 set_status("Must have linear tracks only");
21 for(set<Object *>::const_iterator i=objects.begin(); (!track && i!=objects.end()); ++i)
22 if(Track *t = dynamic_cast<Track *>(*i))
24 unsigned nls = t->get_n_link_slots();
25 for(unsigned j=0; (!track && j<nls); ++j)
26 if(!objects.count((*i)->get_link(j)))
27 track = TrackIter(t, j);
31 while(track && objects.count(track.track()))
33 tracks.push_back(track);
34 total_length += track->get_type().get_path_length(0);
39 void SlopeTool::even_slope(bool smooth)
44 float start_z = tracks.front()->get_snap_node(tracks.front().entry()).position.z;
45 float end_z = tracks.back()->get_snap_node(tracks.back().reverse().entry()).position.z;
47 float length = total_length;
50 float dir = (end_z>start_z)?1:-1;
52 while((end_z-start_z)*dir/length>cur_slope+0.025 && tracks.size()>2)
55 Angle tilt = Geometry::atan(cur_slope);
57 set_slope(tracks.front(), start_z, tilt);
58 start_z += tracks.front()->get_type().get_path_length(0)*dir*cur_slope;
59 length -= tracks.front()->get_type().get_path_length(0);
62 end_z -= tracks.back()->get_type().get_path_length(0)*dir*cur_slope;
63 set_slope(tracks.back(), end_z, tilt);
64 length -= tracks.back()->get_type().get_path_length(0);
69 float cur_z = start_z;
70 Angle tilt = Geometry::atan((end_z-start_z)/length);
71 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
73 set_slope(*i, cur_z, tilt);
74 cur_z += (*i)->get_type().get_path_length(0)*(end_z-start_z)/length;
80 void SlopeTool::flatten()
86 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
88 unsigned nsn = (*i)->get_n_snap_nodes();
89 for(unsigned j=0; j<nsn; ++j)
90 z += (*i)->get_snap_node(j).position.z/nsn;
92 z /= static_cast<int>(tracks.size());
94 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
96 Vector p = (*i)->get_position();
97 (*i)->set_position(Vector(p.x, p.y, z));
98 (*i)->set_tilt(Angle::zero());
104 void SlopeTool::set_slope(const TrackIter &track, float z, const Angle &tilt)
106 const Vector &p = track->get_position();
107 float dz = tan(tilt)*track->get_type().get_path_length(0);
110 track->set_position(Vector(p.x, p.y, z+dz));
111 track->set_tilt(-tilt);
115 track->set_position(Vector(p.x, p.y, z));
116 track->set_tilt(tilt);