7 SlopeTool::SlopeTool(Designer &d, Input::Mouse &m, const set<Object *> &objects):
11 for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
13 unsigned nls = (*i)->get_n_link_slots();
14 if(nls!=2 || !dynamic_cast<Track *>(*i))
16 set_status("Must have linear tracks only");
21 for(set<Object *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
23 unsigned nls = (*i)->get_n_link_slots();
24 for(unsigned j=0; j<nls; ++j)
25 if(Track *link = dynamic_cast<Track *>((*i)->get_link(j)))
26 if(!objects.count(link))
27 neighbors.push_back(link);
30 list<Track *> tmp_tracks;
31 for(set<Object *>::iterator i=objects.begin(); i!=objects.end(); ++i)
32 if(Track *track = dynamic_cast<Track *>(*i))
33 tmp_tracks.push_back(track);
35 Track *cur = neighbors.front();
36 while(!tmp_tracks.empty())
39 for(list<Track *>::iterator i=tmp_tracks.begin(); i!=tmp_tracks.end(); ++i)
41 const vector<Track *> &links = (*i)->get_links();
48 else if(links[1]==cur)
56 tracks.push_back(TrackOrder(cur, rev));
57 total_length += cur->get_type().get_total_length();
61 void SlopeTool::even_slope(bool smooth)
63 list<Track *>::iterator nb = neighbors.begin();
64 int epi = (*nb)->get_link_slot(*tracks.front().track);
65 float start_z = (*nb)->get_snap_node(epi).position.z;
67 epi = (*nb)->get_link_slot(*tracks.back().track);
68 float end_z = (*nb)->get_snap_node(epi).position.z;
70 float length = total_length;
73 float dir = (end_z>start_z)?1:-1;
75 while((end_z-start_z)*dir/length>cur_slope+0.025 && tracks.size()>2)
78 Angle tilt = Geometry::atan(cur_slope);
80 set_slope(tracks.front(), start_z, tilt);
81 start_z += tracks.front().track->get_type().get_path_length(0)*dir*cur_slope;
82 length -= tracks.front().track->get_type().get_path_length(0);
85 end_z -= tracks.back().track->get_type().get_path_length(0)*dir*cur_slope;
86 set_slope(tracks.back(), end_z, tilt);
87 length -= tracks.back().track->get_type().get_path_length(0);
92 float cur_z = start_z;
93 Angle tilt = Geometry::atan((end_z-start_z)/length);
94 for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
96 set_slope(*i, cur_z, tilt);
97 cur_z += i->track->get_type().get_path_length(0)*(end_z-start_z)/length;
101 void SlopeTool::flatten()
104 for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
106 unsigned nsn = i->track->get_n_snap_nodes();
107 for(unsigned j=0; j<nsn; ++j)
108 z += i->track->get_snap_node(j).position.z/nsn;
110 z /= static_cast<int>(tracks.size());
112 for(list<TrackOrder>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
114 Vector p = i->track->get_position();
115 i->track->set_position(Vector(p.x, p.y, z));
116 i->track->set_tilt(Angle::zero());
120 void SlopeTool::set_slope(TrackOrder &track, float z, const Angle &tilt)
122 const Vector &p = track.track->get_position();
123 float dz = tan(tilt)*track.track->get_type().get_path_length(0);
126 track.track->set_position(Vector(p.x, p.y, z+dz));
127 track.track->set_tilt(-tilt);
131 track.track->set_position(Vector(p.x, p.y, z));
132 track.track->set_tilt(tilt);