X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fdesigner%2Fmanipulator.cpp;h=b61d9a7ae5e28642344554f01b001f9887480c12;hb=107a7f787d406f1f664c4986557f9a896e0845ea;hp=9dbf1cbb8900c7c240caba8f6a9ebe48212a5ad8;hpb=8b7d4054b05002d82338775ac9b4ee764a8560e4;p=r2c2.git diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index 9dbf1cb..b61d9a7 100644 --- a/source/designer/manipulator.cpp +++ b/source/designer/manipulator.cpp @@ -14,8 +14,7 @@ Manipulator::Manipulator(Designer &d, Input::Mouse &m, Selection &s): designer(d), mouse(m), selection(s), - mode(NONE), - angle(0) + mode(NONE) { mouse.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Manipulator::button_press), false)); mouse.signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Manipulator::axis_motion), false)); @@ -37,7 +36,7 @@ void Manipulator::start_rotate() if(mode) cancel(); - rot_origin = atan2(gpointer.y-center.y, gpointer.x-center.x); + rot_origin = Geometry::atan2(gpointer.y-center.y, gpointer.x-center.x); mode = ROTATE; } @@ -102,9 +101,9 @@ void Manipulator::flatten() float z = 0; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - z += i->object->get_position().z; - if(Track *track = dynamic_cast(i->object)) - z += track->get_slope()/2; + unsigned nsn = i->object->get_n_snap_nodes(); + for(unsigned j=0; jobject->get_snap_node(j).position.z/nsn; } z /= static_cast(objects.size()); @@ -113,7 +112,7 @@ void Manipulator::flatten() Vector p = i->object->get_position(); i->object->set_position(Vector(p.x, p.y, z)); if(Track *track = dynamic_cast(i->object)) - track->set_slope(0); + track->set_tilt(Angle::zero()); } update_objects(); @@ -139,7 +138,7 @@ void Manipulator::even_slope(bool smooth) float total_len = 0; list order; - Track *cur = *neighbors.begin(); + Track *cur = dynamic_cast(*neighbors.begin()); while(tracks2.size()) { bool rev = false; @@ -164,7 +163,7 @@ void Manipulator::even_slope(bool smooth) total_len += cur->get_type().get_total_length(); } - set::iterator nb = neighbors.begin(); + set::iterator nb = neighbors.begin(); int epi = (*nb)->get_link_slot(*order.front().track); float start_z = (*nb)->get_snap_node(epi).position.z; ++nb; @@ -178,27 +177,26 @@ void Manipulator::even_slope(bool smooth) while((end_z-start_z)*dir/total_len>cur_slope+0.025 && order.size()>2) { cur_slope += 0.025; + Angle tilt = Geometry::atan(cur_slope); + + set_slope(order.front(), start_z, tilt); + start_z += order.front().track->get_type().get_path_length(0)*dir*cur_slope; + total_len -= order.front().track->get_type().get_path_length(0); + order.pop_front(); - float dz = order.front().track->get_type().get_total_length()*dir*cur_slope; - set_slope(order.front(), start_z, dz); - start_z += dz; - total_len -= order.front().track->get_type().get_total_length(); - order.erase(order.begin()); - - dz = order.back().track->get_type().get_total_length()*dir*cur_slope; - set_slope(order.back(), end_z-dz, dz); - end_z -= dz; - total_len -= order.back().track->get_type().get_total_length(); - order.erase(--order.end()); + end_z -= order.back().track->get_type().get_path_length(0)*dir*cur_slope; + set_slope(order.back(), end_z, tilt); + total_len -= order.back().track->get_type().get_path_length(0); + order.pop_back(); } } float cur_z = start_z; + Angle tilt = Geometry::atan((end_z-start_z)/total_len); for(list::iterator i=order.begin(); i!=order.end(); ++i) { - float dz = i->track->get_type().get_total_length()*(end_z-start_z)/total_len; - set_slope(*i, cur_z, dz); - cur_z += dz; + set_slope(*i, cur_z, tilt); + cur_z += i->track->get_type().get_path_length(0)*(end_z-start_z)/total_len; } update_objects(); @@ -243,22 +241,15 @@ void Manipulator::connect() if(abs(dz)>0.02) continue; - float adiff = sn1.rotation+M_PI-sn2.rotation; - while(adiff<-M_PI) - adiff += M_PI*2; - while(adiff>M_PI) - adiff -= M_PI*2; - if(abs(adiff)>0.01) + Angle adiff = wrap_balanced(sn1.rotation+Angle::half_turn()-sn2.rotation); + if(abs(adiff).radians()>0.01) continue; - float c = cos(sn1.rotation); - float s = sin(sn1.rotation); - float dx = sn2.position.x-sn1.position.x; - float dy = sn2.position.y-sn1.position.y; - if(abs(dx*s-dy*c)>limit) + Vector delta = rotated_vector(sn2.position-sn1.position, -sn1.rotation); + if(abs(delta.y)>limit) continue; - gap = dx*c+dy*s; + gap = delta.x; if(gap<0) continue; @@ -297,7 +288,7 @@ void Manipulator::cancel() for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - i->object->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z)); + i->object->set_position(center+i->pos); i->object->set_rotation(i->rot); } @@ -305,7 +296,7 @@ void Manipulator::cancel() delete *i; extend_tracks.clear(); - angle = 0; + angle = Angle::zero(); signal_done.emit(false); } @@ -321,16 +312,16 @@ void Manipulator::button_press(unsigned btn) { Mode m = mode; mode = NONE; - angle = 0; + angle = Angle::zero(); if(m!=EXTEND) { - for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) + for(set::iterator i=neighbors.begin(); i!=neighbors.end(); ++i) for(vector::iterator j=objects.begin(); j!=objects.end(); ++j) j->object->break_link(**i); } - const set <racks = designer.get_layout().get_tracks(); + const set <racks = designer.get_layout().get_all(); for(set::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) { bool ok = true; @@ -367,15 +358,14 @@ void Manipulator::axis_motion(unsigned axis, float value, float) if(mode==MOVE) { - Vector delta(gpointer.x-move_origin.x, gpointer.y-move_origin.y, 0); - Vector offset(center.x+delta.x, center.y+delta.y, center.z); + Vector offset = center+gpointer-move_origin; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - i->object->set_position(Vector(offset.x+i->pos.x, offset.y+i->pos.y, offset.z+i->pos.z)); + i->object->set_position(offset+i->pos); i->object->set_rotation(i->rot); } - const set <racks = designer.get_layout().get_tracks(); + const set <racks = designer.get_layout().get_all(); float limit = max(designer.get_layout().get_catalogue().get_gauge(), designer.get_camera_controller().get_view_scale()/100.0f); MObject *snapped = 0; @@ -394,32 +384,29 @@ void Manipulator::axis_motion(unsigned axis, float value, float) if(snapped) { - float da = snapped->object->get_rotation()-snapped->rot; - float c = cos(da); - float s = sin(da); + Angle da = snapped->object->get_rotation()-snapped->rot; + Transform trans = Transform::rotation(da, Vector(0, 0, 1)); const Vector &sp = snapped->object->get_position(); for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { if(&*i==snapped) continue; - Vector dp(i->pos.x-snapped->pos.x, i->pos.y-snapped->pos.y, 0); - i->object->set_position(Vector(sp.x+c*dp.x-s*dp.y, sp.y+s*dp.x+c*dp.y, sp.z+i->pos.z-snapped->pos.z)); + i->object->set_position(sp+trans.transform(i->pos-snapped->pos)); i->object->set_rotation(i->rot+da); } } } else if(mode==ROTATE) { - float a = atan2(gpointer.y-center.y, gpointer.x-center.x); + Angle a = Geometry::atan2(gpointer.y-center.y, gpointer.x-center.x); angle += a-rot_origin; rot_origin = a; + Transform trans = Transform::rotation(angle, Vector(0, 0, 1)); for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - float c = cos(angle); - float s = sin(angle); - i->object->set_position(Vector(center.x+c*i->pos.x-s*i->pos.y, center.y+s*i->pos.x+c*i->pos.y, center.z+i->pos.z)); + i->object->set_position(center+trans.transform(i->pos)); i->object->set_rotation(angle+i->rot); } } @@ -430,12 +417,12 @@ void Manipulator::axis_motion(unsigned axis, float value, float) signal_status.emit(format("Elevation: %+.0fmm (%.0fmm)", dz*1000, (center.z+dz)*1000)); for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) - i->object->set_position(Vector(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz)); + i->object->set_position(center+i->pos+Vector(0, 0, dz)); } else if(mode==EXTEND) { Vector pos; - float dir = 0; + Angle dir; float length = 0; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { @@ -446,18 +433,14 @@ void Manipulator::axis_motion(unsigned axis, float value, float) continue; Snap sn = i->object->get_snap_node(j); - float c = cos(sn.rotation); - float s = sin(sn.rotation); - float dx = gpointer.x-sn.position.x; - float dy = gpointer.y-sn.position.y; + Vector delta = rotated_vector(gpointer-sn.position, -sn.rotation); - float len = dx*c+dy*s; - if(len bbox; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) - { - // XXX Use generic bounding box when it is implemented - if(Track *track = dynamic_cast(i->object)) - { - unsigned n_endpoints = track->get_type().get_endpoints().size(); - for(unsigned j=0; jget_snap_node(j).position; - if(i==objects.begin() && j==0) - minp = maxp = p; - else - { - minp.x = min(minp.x, p.x); - maxp.x = max(maxp.x, p.x); - minp.y = min(minp.y, p.y); - maxp.y = max(maxp.y, p.y); - minp.z = min(minp.z, p.z); - } - } - } - else - { - const Vector &p = i->object->get_position(); - minp.x = min(minp.x, p.x); - maxp.x = max(maxp.x, p.x); - minp.y = min(minp.y, p.y); - maxp.y = max(maxp.y, p.y); - minp.z = min(minp.z, p.z); - } - } + bbox = bbox|i->object->get_bounding_box(); + + const Vector &minp = bbox.get_minimum_point(); + const Vector &maxp = bbox.get_maximum_point(); - center = Vector((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z); + center = (minp+maxp)/2.0f; + center.z = minp.z; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - const Vector &p = i->object->get_position(); - i->pos = Vector(p.x-center.x, p.y-center.y, p.z-center.z); + i->pos = i->object->get_position()-center; i->rot = i->object->get_rotation(); } } @@ -567,44 +524,42 @@ void Manipulator::update_neighbors() neighbors.clear(); for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - Track *track = dynamic_cast(i->object); - if(!track) - continue; - - const vector &links = track->get_links(); - for(vector::const_iterator j=links.begin(); j!=links.end(); ++j) + unsigned nls = i->object->get_n_link_slots(); + for(unsigned j=0; jobject->get_link(j); + if(!linked) continue; - if(neighbors.count(*j)) + if(neighbors.count(linked)) continue; bool ok = true; for(vector::iterator k=objects.begin(); (k!=objects.end() && ok); ++k) - ok = (k->object!=*j); + ok = (k->object!=linked); if(ok) - neighbors.insert(*j); + neighbors.insert(linked); } } } -void Manipulator::set_slope(TrackOrder &track, float z, float dz) +void Manipulator::set_slope(TrackOrder &track, float z, const Angle &tilt) { const Vector &p = track.track->get_position(); + float dz = tan(tilt)*track.track->get_type().get_path_length(0); if(track.rev) { track.track->set_position(Vector(p.x, p.y, z+dz)); - track.track->set_slope(-dz); + track.track->set_tilt(-tilt); } else { track.track->set_position(Vector(p.x, p.y, z)); - track.track->set_slope(dz); + track.track->set_tilt(tilt); } } -vector Manipulator::create_straight(const R2C2::Vector &start, float dir, float length, float limit) +vector Manipulator::create_straight(const R2C2::Vector &start, const Angle &dir, float length, float limit) { const Catalogue::TrackMap &track_types = designer.get_catalogue().get_tracks(); std::map types_by_length; @@ -665,8 +620,7 @@ vector Manipulator::create_straight(const R2C2::Vector &start, float di if(!lengths.empty()) { Vector pos = start; - float c = cos(dir); - float s = sin(dir); + Transform trans = Transform::rotation(dir, Vector(0, 0, 1)); for(vector::iterator i=lengths.begin(); i!=lengths.end(); ++i) { Track *track = new Track(designer.get_layout(), *get_item(types_by_length, *i)); @@ -677,8 +631,7 @@ vector Manipulator::create_straight(const R2C2::Vector &start, float di track->link_to(*trks.back()); trks.push_back(track); - pos.x += c**i; - pos.y += s**i; + pos += trans.transform(Vector(*i, 0, 0)); } }