|
|
faaf7d |
/*
|
|
|
faaf7d |
......... 2015 Ivan Mahonin
|
|
|
faaf7d |
|
|
|
faaf7d |
This program is free software: you can redistribute it and/or modify
|
|
|
faaf7d |
it under the terms of the GNU General Public License as published by
|
|
|
faaf7d |
the Free Software Foundation, either version 3 of the License, or
|
|
|
faaf7d |
(at your option) any later version.
|
|
|
faaf7d |
|
|
|
faaf7d |
This program is distributed in the hope that it will be useful,
|
|
|
faaf7d |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
faaf7d |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
faaf7d |
GNU General Public License for more details.
|
|
|
faaf7d |
|
|
|
faaf7d |
You should have received a copy of the GNU General Public License
|
|
|
faaf7d |
along with this program. If not, see <http: licenses="" www.gnu.org="">.</http:>
|
|
|
faaf7d |
*/
|
|
|
faaf7d |
|
|
|
faaf7d |
#include "contourbuilder.h"
|
|
|
faaf7d |
|
|
|
faaf7d |
using namespace std;
|
|
|
faaf7d |
|
|
|
faaf7d |
void ContourBuilder::build_simple(vector<vector> &c) {</vector>
|
|
|
faaf7d |
const float min_segment_length = 0.001f;
|
|
|
faaf7d |
const float rounds = 10.f;
|
|
|
faaf7d |
const float rounds2 = 1.f;
|
|
|
faaf7d |
|
|
|
faaf7d |
vector<vector> back;</vector>
|
|
|
faaf7d |
|
|
|
faaf7d |
float angle = 360.f;
|
|
|
faaf7d |
float offset = 0.25f/(rounds + 1.f);
|
|
|
faaf7d |
|
|
|
faaf7d |
// go front
|
|
|
faaf7d |
while(true) {
|
|
|
faaf7d |
float radius = angle/360.f/(rounds + 1.f);
|
|
|
faaf7d |
float step = min_segment_length*180.f/M_PI/radius;
|
|
|
faaf7d |
if (radius > 1.f - 2.f*offset) break;
|
|
|
faaf7d |
|
|
|
faaf7d |
float fr = radius + offset;
|
|
|
faaf7d |
float fx = fr*sinf(angle/180.f*M_PI);
|
|
|
faaf7d |
float fy = fr*cosf(angle/180.f*M_PI);
|
|
|
faaf7d |
|
|
|
faaf7d |
float br = radius - offset;
|
|
|
faaf7d |
float bx = br*sinf(angle/180.f*M_PI);
|
|
|
faaf7d |
float by = br*cosf(angle/180.f*M_PI);
|
|
|
faaf7d |
|
|
|
faaf7d |
c.push_back(Vector(fx, fy));
|
|
|
faaf7d |
back.push_back(Vector(bx, by));
|
|
|
faaf7d |
|
|
|
faaf7d |
angle += step;
|
|
|
faaf7d |
}
|
|
|
faaf7d |
|
|
|
faaf7d |
float max_angle = angle;
|
|
|
faaf7d |
|
|
|
faaf7d |
while(true) {
|
|
|
faaf7d |
float radius = max_angle/360.f/(rounds + 1.f)
|
|
|
faaf7d |
+ (max_angle-angle)/360.f/rounds2;
|
|
|
faaf7d |
float step = min_segment_length*180.f/M_PI/radius;
|
|
|
faaf7d |
if (radius < 1.f/(rounds + 1.f))
|
|
|
faaf7d |
break;
|
|
|
faaf7d |
|
|
|
faaf7d |
float fr = radius + offset;
|
|
|
faaf7d |
float fx = fr*sinf(angle/180.f*M_PI);
|
|
|
faaf7d |
float fy = fr*cosf(angle/180.f*M_PI);
|
|
|
faaf7d |
|
|
|
faaf7d |
float br = radius - offset;
|
|
|
faaf7d |
float bx = br*sinf(angle/180.f*M_PI);
|
|
|
faaf7d |
float by = br*cosf(angle/180.f*M_PI);
|
|
|
faaf7d |
|
|
|
faaf7d |
c.push_back(Vector(fx, fy));
|
|
|
faaf7d |
back.push_back(Vector(bx, by));
|
|
|
faaf7d |
|
|
|
faaf7d |
angle += step;
|
|
|
faaf7d |
}
|
|
|
faaf7d |
|
|
|
faaf7d |
|
|
|
faaf7d |
// go back
|
|
|
faaf7d |
c.reserve(c.size() + back.size() + 1);
|
|
|
faaf7d |
for(vector<vector>::reverse_iterator ri = back.rbegin(); ri != back.rend(); ++ri)</vector>
|
|
|
faaf7d |
c.push_back(*ri);
|
|
|
faaf7d |
|
|
|
faaf7d |
// close
|
|
|
faaf7d |
c.push_back(c.front());
|
|
|
faaf7d |
}
|
|
|
faaf7d |
|
|
|
93cbac |
void ContourBuilder::build_car(Contour &c, const Vector &o, Real s) {
|
|
|
faaf7d |
c.move_to( Vector( 5, -1)*s + o);
|
|
|
faaf7d |
c.line_to( Vector( 4, -1)*s + o);
|
|
|
faaf7d |
c.conic_to( Vector( 2, -1)*s + o, Vector( 0, -1)*s);
|
|
|
faaf7d |
c.line_to( Vector(-2, -1)*s + o);
|
|
|
faaf7d |
c.conic_to( Vector(-4, -1)*s + o, Vector( 0, -1)*s);
|
|
|
faaf7d |
c.line_to( Vector(-5, -1)*s + o);
|
|
|
faaf7d |
c.line_to( Vector(-5, 1)*s + o);
|
|
|
faaf7d |
c.line_to( Vector(-4, 1)*s + o);
|
|
|
faaf7d |
c.cubic_to( Vector(-1, 3)*s + o, Vector( 0, 2)*s, Vector( 4, 0)*s);
|
|
|
faaf7d |
c.cubic_to( Vector( 3, 1)*s + o, Vector( 4, 0)*s, Vector( 2, -2)*s);
|
|
|
faaf7d |
c.line_to( Vector( 5, 1)*s + o);
|
|
|
faaf7d |
c.close();
|
|
|
faaf7d |
}
|
|
|
faaf7d |
|
|
|
faaf7d |
void ContourBuilder::build(Contour &c) {
|
|
|
93cbac |
Real scale = 0.8/5.0;
|
|
|
faaf7d |
|
|
|
faaf7d |
int count = 100;
|
|
|
93cbac |
Real size = (Real)(count + 2)/(Real)(count);
|
|
|
93cbac |
Real step = 2.0*size/(Real)(count + 1);
|
|
|
93cbac |
Real origin = step - size;
|
|
|
93cbac |
Real s = 2*size*scale/(Real)(count);
|
|
|
faaf7d |
for(int i = 0; i < count; ++i)
|
|
|
faaf7d |
for(int j = 0; j < count; ++j)
|
|
|
faaf7d |
build_car(c, Vector(origin + i*step, origin + j*step), s);
|
|
|
faaf7d |
|
|
|
faaf7d |
count = 100;
|
|
|
93cbac |
size = (Real)(count + 2)/(Real)(count);
|
|
|
93cbac |
step = 2.0*size/(Real)(count + 1);
|
|
|
faaf7d |
origin = step - size;
|
|
|
93cbac |
s = size*scale/(Real)(count);
|
|
|
faaf7d |
for(int i = 0; i < count; ++i)
|
|
|
faaf7d |
for(int j = 0; j < count; ++j)
|
|
|
faaf7d |
build_car(c, Vector(origin + i*step, origin + j*step), s);
|
|
|
faaf7d |
|
|
|
faaf7d |
build_car(c, Vector::zero(), scale);
|
|
|
faaf7d |
build_car(c, Vector::zero(), 0.5*scale);
|
|
|
faaf7d |
}
|
|
|
faaf7d |
|