#include <cmath>
+#include <msp/geometry/union.h>
#include "tracktype.h"
using namespace std;
namespace R2C2 {
-TrackType::TrackType(const ArticleNumber &an):
+TrackType::TrackType(const ArticleNumber &an, const TrackAppearance &ta):
ObjectType(an),
+ appearance(ta),
state_bits(0),
autofit_preference(1)
{ }
return endpoints[i];
}
-TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const
+OrientedPoint TrackType::get_point(unsigned epi, unsigned path, float d) const
{
if(epi>=endpoints.size())
throw out_of_range("TrackType::get_point");
unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
for(unsigned j=0; j<n_part_eps; ++j)
{
- TrackPoint p = i->get_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)
+ OrientedPoint p = i->get_point(j ? i->get_length() : 0);
+ Vector span = p.position-endpoints[epi].pos;
+ if(dot(span, span)<1e-6)
{
part = &*i;
part_ep = j;
{
if(part_ep==1)
d = plen-d;
- TrackPoint p = part->get_point(d);
+ OrientedPoint p = part->get_point(d);
if(part_ep==1)
- p.dir += M_PI;
+ p.rotation += Angle::half_turn();
return p;
}
else
}
}
-TrackPoint TrackType::get_nearest_point(const Vector &p) const
+OrientedPoint TrackType::get_nearest_point(const Vector &p) const
{
- TrackPoint result;
+ OrientedPoint result;
float dist = -1;
for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
{
- TrackPoint n = i->get_nearest_point(p);
- float d = distance(n.pos, p);
+ OrientedPoint n = i->get_nearest_point(p);
+ float d = distance(n.position, p);
if(d<dist || dist<0)
{
result = n;
return result;
}
-bool TrackType::collide_ray(const Vector &start, const Vector &dir, float width) const
-{
- for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
- if(i->collide_ray(start, dir, width))
- return true;
-
- return false;
-}
-
void TrackType::collect_endpoints()
{
endpoints.clear();
for(unsigned j=0; j<n_part_eps; ++j)
if(!i->get_link(j))
{
- TrackPoint p = i->get_point(j ? i->get_length() : 0);
+ OrientedPoint p = i->get_point(j ? i->get_length() : 0);
if(j==0)
- p.dir += M_PI;
+ p.rotation += Angle::half_turn();
bool found = false;
for(vector<Endpoint>::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.position;
- 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.rotation);
- 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<<i->get_path();
found = true;
}
if(!found)
- endpoints.push_back(Endpoint(p.pos.x, p.pos.y, p.dir, 1<<i->get_path()));
+ endpoints.push_back(Endpoint(p.position.x, p.position.y, p.rotation, 1<<i->get_path()));
}
}
}
-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)
{ }
void TrackType::Loader::finish()
{
obj.collect_endpoints();
+ vector<const Shape *> shapes;
+ for(vector<TrackPart>::iterator i=obj.parts.begin(); i!=obj.parts.end(); ++i)
+ {
+ i->create_shape();
+ shapes.push_back(&i->get_shape());
+ }
+ obj.shape = Geometry::Union<float, 3>::from_iterator_range(shapes.begin(), shapes.end()).clone();
}
void TrackType::Loader::part()