Blame c++/contourgl/contourbuilder.cpp

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