X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Ftracktype.cpp;h=fbed4c1d8d6020b9b19ed4c234b1c002d43f8b64;hb=7a36d396eded897c421424905b2c938d770df341;hp=5b41e1f5f26f58ade0d2f13eb197d9adae5b6987;hpb=277e8e7e4230aa8867f507ace62476afe575cff1;p=r2c2.git diff --git a/source/libr2c2/tracktype.cpp b/source/libr2c2/tracktype.cpp index 5b41e1f..fbed4c1 100644 --- a/source/libr2c2/tracktype.cpp +++ b/source/libr2c2/tracktype.cpp @@ -1,10 +1,3 @@ -/* $Id$ - -This file is part of R²C² -Copyright © 2006-2011 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - #include #include "tracktype.h" @@ -14,7 +7,7 @@ using namespace Msp; namespace R2C2 { TrackType::TrackType(const ArticleNumber &an): - art_nr(an), + ObjectType(an), state_bits(0), autofit_preference(1) { } @@ -62,7 +55,7 @@ bool TrackType::is_dead_end() const const TrackType::Endpoint &TrackType::get_endpoint(unsigned i) const { if(i>=endpoints.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw out_of_range("TrackType::get_endpoint"); return endpoints[i]; } @@ -70,22 +63,21 @@ const TrackType::Endpoint &TrackType::get_endpoint(unsigned i) const TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const { if(epi>=endpoints.size()) - throw InvalidParameterValue("Endpoint index out of range"); + throw out_of_range("TrackType::get_point"); const TrackPart *part = 0; unsigned part_ep = 0; for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) { - if((endpoints[epi].paths&(1<get_path()!=path) + if(endpoints[epi].has_path(path) && i->get_path()!=path) continue; unsigned n_part_eps = (i->is_dead_end() ? 1 : 2); for(unsigned j=0; jget_point(j ? i->get_length() : 0); - float dx = p.pos.x-endpoints[epi].pos.x; - float dy = p.pos.y-endpoints[epi].pos.y; - if(dx*dx+dy*dy<1e-6) + Vector span = p.pos-endpoints[epi].pos; + if(dot(span, span)<1e-6) { part = &*i; part_ep = j; @@ -94,7 +86,7 @@ TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const } if(!part) - throw Exception("Internal error (endpoint does not match any part)"); + throw logic_error("internal error (endpoint does not match any part)"); while(1) { @@ -105,7 +97,7 @@ TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const d = plen-d; TrackPoint p = part->get_point(d); if(part_ep==1) - p.dir += M_PI; + p.dir += Angle::half_turn(); return p; } else @@ -113,13 +105,32 @@ TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const d -= plen; TrackPart *next = part->get_link(1-part_ep); if(!next) - throw InvalidParameterValue("Distance out of range"); + throw invalid_argument("TrackType::get_point"); part_ep = (next->get_link(0)==part ? 0 : 1); part = next; } } } +TrackPoint TrackType::get_nearest_point(const Vector &p) const +{ + TrackPoint result; + float dist = -1; + + for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) + { + TrackPoint n = i->get_nearest_point(p); + float d = distance(n.pos, p); + if(d::const_iterator i=parts.begin(); i!=parts.end(); ++i) @@ -144,21 +155,16 @@ void TrackType::collect_endpoints() { TrackPoint p = i->get_point(j ? i->get_length() : 0); if(j==0) - p.dir += M_PI; + p.dir += Angle::half_turn(); bool found = false; for(vector::iterator k=endpoints.begin(); k!=endpoints.end(); ++k) { - float dx = k->pos.x-p.pos.x; - float dy = k->pos.y-p.pos.y; + Vector d = k->pos-p.pos; - float da = k->dir-p.dir; - while(da>M_PI) - da -= M_PI*2; - while(da<-M_PI) - da += M_PI*2; + Angle da = wrap_balanced(k->dir-p.dir); - if(dx*dx+dy*dy<1e-6 && da>-0.01 && da<0.01) + if(dot(d, d)<1e-6 && abs(da).radians()<0.01) { k->paths |= 1<get_path(); found = true; @@ -172,19 +178,18 @@ void TrackType::collect_endpoints() } } -TrackType::Endpoint::Endpoint(float x, float y, float d, unsigned p): - pos(x, y), +TrackType::Endpoint::Endpoint(float x, float y, const Angle &d, unsigned p): + pos(x, y, 0), dir(d), paths(p) { } TrackType::Loader::Loader(TrackType &t): - Msp::DataFile::BasicLoader(t), + DataFile::DerivedObjectLoader(t), state_bits_set(false) { add("autofit_preference", &TrackType::autofit_preference); - add("description", &TrackType::description); add("object", &TrackType::object); add("state_bits", &Loader::state_bits); add("part", &Loader::part);