X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fdesigner%2Fmanipulator.cpp;h=2ee967679428ebdf1595b74669128a194b31291a;hb=ca9d278f9472206ad9a01190dcef9f0eb1bcc274;hp=9dbf1cbb8900c7c240caba8f6a9ebe48212a5ad8;hpb=8b7d4054b05002d82338775ac9b4ee764a8560e4;p=r2c2.git diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index 9dbf1cb..2ee9676 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; } @@ -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; @@ -243,22 +242,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 +289,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 +297,7 @@ void Manipulator::cancel() delete *i; extend_tracks.clear(); - angle = 0; + angle = Angle::zero(); signal_done.emit(false); } @@ -321,11 +313,11 @@ 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); } @@ -367,11 +359,10 @@ 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); } @@ -394,32 +385,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 +418,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 +434,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(); - center = Vector((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z); + const Vector &minp = bbox.get_minimum_point(); + const Vector &maxp = bbox.get_maximum_point(); + + 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,24 +525,21 @@ 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); } } } @@ -604,7 +559,7 @@ void Manipulator::set_slope(TrackOrder &track, float z, float dz) } } -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)); } }