1 #include "libr2c2/track.h"
8 SlopeTool::SlopeTool(Designer &d, Input::Keyboard &k, Input::Mouse &m, const set<Object *> &objects):
14 set_status("Nothing selected");
19 for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
20 if(!dynamic_cast<Track *>(*i) || (*i)->get_n_link_slots()!=2)
22 set_status("Must have linear tracks only");
28 for(set<Object *>::const_iterator i=objects.begin(); (!track && i!=objects.end()); ++i)
29 if(Track *t = dynamic_cast<Track *>(*i))
31 unsigned nls = t->get_n_link_slots();
32 for(unsigned j=0; (!track && j<nls); ++j)
33 if(!objects.count((*i)->get_link(j)))
34 track = TrackIter(t, j);
38 while(track && objects.count(track.track()))
40 tracks.push_back(track);
41 total_length += track->get_type().get_path_length(0);
46 void SlopeTool::even_slope(bool smooth)
51 float start_z = tracks.front()->get_snap_node(tracks.front().entry()).position.z;
52 float end_z = tracks.back()->get_snap_node(tracks.back().reverse().entry()).position.z;
54 float length = total_length;
57 float dir = (end_z>start_z)?1:-1;
59 while((end_z-start_z)*dir/length>cur_slope+0.025 && tracks.size()>2)
62 Angle tilt = Geometry::atan(cur_slope);
64 set_slope(tracks.front(), start_z, tilt);
65 start_z += tracks.front()->get_type().get_path_length(0)*dir*cur_slope;
66 length -= tracks.front()->get_type().get_path_length(0);
69 end_z -= tracks.back()->get_type().get_path_length(0)*dir*cur_slope;
70 set_slope(tracks.back(), end_z, tilt);
71 length -= tracks.back()->get_type().get_path_length(0);
76 float cur_z = start_z;
77 Angle tilt = Geometry::atan((end_z-start_z)/length);
78 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
80 set_slope(*i, cur_z, tilt);
81 cur_z += (*i)->get_type().get_path_length(0)*(end_z-start_z)/length;
87 void SlopeTool::flatten()
93 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
95 unsigned nsn = (*i)->get_n_snap_nodes();
96 for(unsigned j=0; j<nsn; ++j)
97 z += (*i)->get_snap_node(j).position.z/nsn;
99 z /= static_cast<int>(tracks.size());
101 for(list<TrackIter>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
103 Vector p = (*i)->get_position();
104 (*i)->set_position(Vector(p.x, p.y, z));
105 (*i)->set_tilt(Angle::zero());
111 void SlopeTool::set_slope(const TrackIter &track, float z, const Angle &tilt)
113 const Vector &p = track->get_position();
114 float dz = tan(tilt)*track->get_type().get_path_length(0);
117 track->set_position(Vector(p.x, p.y, z+dz));
118 track->set_tilt(-tilt);
122 track->set_position(Vector(p.x, p.y, z));
123 track->set_tilt(tilt);