36 p2[
X] =
length * std::cos(angle);
37 p2[
Y] =
length * std::sin(angle);
61 Point B = anchor + dir;
94 double ,
double ,
double c3,
double c4,
double mu,
cairo_t *cr = NULL) {
96 Point B = anchor1 + dir1 * (c3 + mu);
97 Point C = anchor2 - dir2 * (c4 + mu);
115 double c1,
double c2,
double ,
double ,
double ,
cairo_t *cr = NULL) {
116 cout <<
"create_bezier_along_curve -- start" << endl;
123 Point A = curve1.valueAt(t1 - c1 * segdist);
124 Point B = curve1.valueAt(t1) + n * 0.1;
125 Point C = curve2.valueAt(t2) - n * 0.1;
126 Point D = curve2.valueAt(t2 + c2 * segdist);
135 cout <<
"create_bezier_along_curve -- end" << endl;
139class OffsetTester:
public Toy {
143 void draw(
cairo_t *cr, std::ostringstream *notify,
int width,
int height,
bool save, std::ostringstream *timer_stream)
override {
145 double slider_top =
w/4.;
146 double slider_bot =
w*3./4.;
147 double slider_margin = 40;
148 double slider_middle = (slider_top + slider_bot) / 2;
150 if(psh.
pts.empty()) {
151 psh.
pts.emplace_back(200,300);
152 psh.
pts.emplace_back(350,250);
153 psh.
pts.emplace_back(500,280);
154 psh.
pts.emplace_back(700,300);
156 psh.
pts.emplace_back(400,300);
157 psh.
pts.emplace_back(550,250);
158 psh.
pts.emplace_back(700,280);
159 psh.
pts.emplace_back(900,300);
161 psh.
pts.emplace_back(900,500);
162 psh.
pts.emplace_back(700,480);
163 psh.
pts.emplace_back(550,450);
164 psh.
pts.emplace_back(400,500);
166 psh_rand.
pts.emplace_back(slider_margin,slider_bot);
167 psh_rand.
pts.emplace_back(slider_margin,slider_top);
168 psh_rand.
pts.emplace_back(slider_margin,slider_top);
169 psh_rand.
pts.emplace_back(slider_margin,slider_top);
170 psh_rand.
pts.emplace_back(slider_margin,slider_top);
171 psh_rand.
pts.emplace_back(slider_margin,slider_bot);
172 psh_rand.
pts.emplace_back(slider_margin,slider_middle);
175 psh_rand.
pts[0][
X] = slider_margin;
176 if (psh_rand.
pts[0][
Y]<slider_top) psh_rand.
pts[0][
Y] = slider_top;
177 if (psh_rand.
pts[0][
Y]>slider_bot) psh_rand.
pts[0][
Y] = slider_bot;
178 psh_rand.
pts[1][
X] = slider_margin + 15;
179 if (psh_rand.
pts[1][
Y]<slider_top) psh_rand.
pts[1][
Y] = slider_top;
180 if (psh_rand.
pts[1][
Y]>slider_bot) psh_rand.
pts[1][
Y] = slider_bot;
181 psh_rand.
pts[2][
X] = slider_margin + 30;
182 if (psh_rand.
pts[2][
Y]<slider_top) psh_rand.
pts[2][
Y] = slider_top;
183 if (psh_rand.
pts[2][
Y]>slider_bot) psh_rand.
pts[2][
Y] = slider_bot;
184 psh_rand.
pts[3][
X] = slider_margin + 45;
185 if (psh_rand.
pts[3][
Y]<slider_top) psh_rand.
pts[3][
Y] = slider_top;
186 if (psh_rand.
pts[3][
Y]>slider_bot) psh_rand.
pts[3][
Y] = slider_bot;
187 psh_rand.
pts[4][
X] = slider_margin + 60;
188 if (psh_rand.
pts[4][
Y]<slider_top) psh_rand.
pts[4][
Y] = slider_top;
189 if (psh_rand.
pts[4][
Y]>slider_bot) psh_rand.
pts[4][
Y] = slider_bot;
190 psh_rand.
pts[5][
X] = slider_margin + 75;
191 if (psh_rand.
pts[5][
Y]<slider_top) psh_rand.
pts[5][
Y] = slider_top;
192 if (psh_rand.
pts[5][
Y]>slider_bot) psh_rand.
pts[5][
Y] = slider_bot;
193 psh_rand.
pts[6][
X] = slider_margin + 90;
194 if (psh_rand.
pts[6][
Y]<slider_top) psh_rand.
pts[6][
Y] = slider_top;
195 if (psh_rand.
pts[6][
Y]>slider_bot) psh_rand.
pts[6][
Y] = slider_bot;
197 *notify <<
"Sliders:" << endl << endl << endl << endl;
198 *notify <<
"0 - segment distance" << endl;
199 *notify <<
"1 - start anchor randomization" << endl;
200 *notify <<
"2 - end anchor randomization" << endl;
201 *notify <<
"3 - start rounding randomization" << endl;
202 *notify <<
"4 - end rounding randomization" << endl;
203 *notify <<
"5 - start/end rounding increase randomization" << endl;
204 *notify <<
"6 - additional offset of the upper anchors (to modify the segment angle)" << endl;
206 for(
unsigned i = 0; i < psh_rand.
size(); ++i) {
210 cairo_set_line_width(cr,.5);
214 cairo_set_line_width (cr, 2);
230 cairo_set_line_width (cr, 1);
237 double lambda1 = 1.0 - (psh_rand.
pts[1][
Y] - slider_top) * 2.0/
w;
238 double lambda2 = 1.0 - (psh_rand.
pts[2][
Y] - slider_top) * 2.0/
w;
239 double lambda3 = 1.0 - (psh_rand.
pts[3][
Y] - slider_top) * 2.0/
w;
240 double lambda4 = 1.0 - (psh_rand.
pts[4][
Y] - slider_top) * 2.0/
w;
241 double mu = 1.0 - (psh_rand.
pts[5][
Y] - slider_top) * 2.0/
w;
243 double off = 0.5 - (psh_rand.
pts[6][
Y] - slider_top) * 2.0/
w;
245 double segdist = (slider_bot - psh_rand.
pts[0][
Y]) / (slider_bot - slider_top) * 0.1;
246 if (segdist < 0.01) {
250 vector<Point> pts_bot;
251 vector<Point> pts_top;
252 vector<Point> dirs_bot;
253 vector<Point> dirs_top;
255 for(
double i = 0.0; i < 1.0; i += segdist) {
259 dirs_bot.push_back(tangent1.
valueAt(i) * 20);
260 dirs_top.push_back(tangent2.
valueAt(i) * 20);
264 for(
int i = 0; i <
num; ++i) {
265 cout <<
"c1_bot[" << i <<
"]: " <<
c1_bot[i] << endl;
268 for (
int i = 0; i <
num-1; ++i) {
271 cout <<
"c3_bot[" << i <<
"]: " <<
c3_bot[i] << endl;
273 dirs_bot[i], dirs_top[i],
274 0, 0,
c3_bot[i] * lambda3,
c4_top[i] * lambda4, mu, cr);
285 dirs_top[i], dirs_bot[i+1],
286 0, 0,
c4_bot[i] * lambda4,
c3_top[i] * lambda3, mu, cr);
320 for (
int i = 0; i <
num; ++i) {
350int main(
int argc,
char **argv) {
351 init(argc, argv,
new OffsetTester);
Various trigoniometric helper functions.
Conversion between Bezier control points and SBasis curves.
Adaptor that creates 2D functions from 1D ones.
Sequence of contiguous curves, aka spline.
void append(Curve *curve)
Add a new curve to the end of the path.
Function defined as discrete pieces.
output_type valueAt(double t) const
Two-dimensional point that doubles as a vector.
Rotation around the origin.
Geom::D2< Geom::SBasis > asBezier()
std::vector< Geom::Point > pts
vector< Handle * > handles
virtual void save(FILE *f)
virtual void draw(cairo_t *cr, std::ostringstream *notify, int w, int h, bool save, std::ostringstream *timing_stream)
Lifts one dimensional objects into 2D.
BezierCurveN< 3 > CubicBezier
Cubic (order 3) Bezier curve.
double Coord
Floating point type used to store coordinates.
Various utility functions.
Coord length(LineSegment const &seg)
PathVector path_from_piecewise(Piecewise< D2< SBasis > > const &B, double tol, bool only_cubicbeziers=false)
Make a path from a d2 sbasis.
Bezier derivative(Bezier const &a)
D2< T > rot90(D2< T > const &a)
Piecewise< D2< SBasis > > unitVector(D2< SBasis > const &vect, double tol=.01, unsigned order=3)
void cairo_line_to(cairo_t *cr, Geom::Point p1)
void draw_cross(cairo_t *cr, Geom::Point h)
void cairo_path(cairo_t *cr, Geom::Path const &p)
void cairo_move_to(cairo_t *cr, Geom::Point p1)
void cairo_d2_sb(cairo_t *cr, Geom::D2< Geom::SBasis > const &p)
Obsolete 2D SBasis function class.
two-dimensional geometric operators.
some std functions to work with (pw)s-basis
Conversion between SBasis and Bezier basis polynomials.
Polynomial in symmetric power basis (S-basis)
CubicBezier create_bezier_along_curve(Piecewise< D2< SBasis > > const &curve1, Piecewise< D2< SBasis > > const &curve2, double segdist, Coord const t1, Coord const t2, Point const &n, double c1, double c2, double, double, double, cairo_t *cr=NULL)
CubicBezier create_bezier(Point const &anchor, double angle, double length, double dx1, double dx2, cairo_t *cr=NULL)
void draw_segment(cairo_t *cr, Point const &p1, Point const &p2)
CubicBezier create_bezier_again(Point const &anchor1, Point const &anchor2, Point const &dir1, Point const &dir2, double, double, double c3, double c4, double mu, cairo_t *cr=NULL)
void cairo_set_source_rgba(cairo_t *cr, colour c)
void init(int argc, char **argv, Toy *t, int width=600, int height=600)