+ Geometry::ExtrudedShape<float, 3> ring(
+ Geometry::Intersection<float, 2>(
+ Geometry::Circle<float>(abs(radius)+0.02),
+ Geometry::Negation<float, 2>(Geometry::Circle<float>(abs(radius)-0.02))),
+ 0.01);
+ Geometry::HalfSpace<float, 3> start_wall(Vector(-1, 0, 0));
+ Geometry::HalfSpace<float, 3> end_wall(rotated_vector(Vector(1, 0, 0),
+ Angle::from_radians(length*(radius<0 ? -1 : 1))));
+ /* This box only exists so the bounding boxes of curves make sense. It
+ can be removed when libmspmath produces better bounding boxes. */
+ float w = sin(length)*(abs(radius)+0.02);
+ float h = (1-cos(length))*abs(radius-0.02)+0.04;
+ Geometry::TransformedShape<float, 3> bounds(
+ Geometry::Box<float>(w, h, 0.01),
+ Transform::translation(Vector(w/2, (h/2-0.02)*(radius<0 ? -1 : 1)-radius, 0.005)));
+ vector<const Shape *> shapes;
+ shapes.push_back(&ring);
+ shapes.push_back(&start_wall);
+ shapes.push_back(&end_wall);
+ shapes.push_back(&bounds);
+ shape = new Geometry::TransformedShape<float, 3>(
+ Geometry::Intersection<float, 3>::from_iterator_range(shapes.begin(), shapes.end()),
+ transform*Transform::translation(Vector(0, radius, 0.005)));