1%%	options
2
3copyright owner	=	Dirk Krause
4copyright year	=	2017-xxxx
5SPDX-License-Identifier:	BSD-3-Clause
6
7%%	module
8
9#include "dk4conf.h"
10
11#if	DK4_HAVE_MATH_H
12#ifndef	MATH_H_INCLUDED
13#if	DK4_ON_WINDOWS
14#ifndef	_USE_MATH_DEFINES
15#define	_USE_MATH_DEFINES 1
16#endif
17#endif
18#include <math.h>
19#define	MATH_H_INCLUDED 1
20#endif
21#endif
22
23
24#ifndef	DK4GRA_H_INCLUDED
25#include <libdk4gra/dk4gra.h>
26#endif
27
28#ifndef	DK4GRAT_H_INCLUDED
29#include <libdk4gra/dk4grat.h>
30#endif
31
32#ifndef	GRA_H_INCLUDED
33#include <libdk4gra/gra.h>
34#endif
35
36#if DK4_HAVE_ASSERT_H
37#ifndef	ASSERT_H_INCLUDED
38#include <assert.h>
39#define	ASSERT_H_INCLUDED 1
40#endif
41#endif
42
43
44void
45dk4gra_i_pattern(
46	dk4_gra_t		*gra,
47	double			 xl,
48	double			 xr,
49	double			 yb,
50	double			 yt,
51	int				 pn,
52	const double	*val,
53	int				*backptr,
54	dk4_er_t		*erp
55)
56{
57	double	x;
58	double	y;
59	double	dx;
60	double	dy;
61	double	ydiff;
62	double	alpha;
63	double	alpha1;
64	double	alpha2;
65	double	kappa;
66	double	dxdt0;
67	double	dxdt1;
68	double	dydt0;
69	double	dydt1;
70	int		passno;
71#if	DK4_USE_ASSERT
72	assert(NULL != gra);
73#endif
74	switch (pn) {
75		case DK4_GRA_PATTERN_30_DEGREE_RIGHT : {
76			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
77			y = val[2];
78			ydiff = (val[1] - val[0]) / sqrt(3.0);
79			do {
80				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
81				dk4gra_i_lineto(gra, val[1], (y + ydiff), backptr, erp);
82				dk4gra_i_stroke(gra, backptr, erp);
83				y += val[4];
84			} while (val[3] >= y);
85		} break;
86		case DK4_GRA_PATTERN_30_DEGREE_SIEVE : {
87			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
88			dk4gra_i_pattern(
89				gra, xl, xr, yb, yt,
90				DK4_GRA_PATTERN_30_DEGREE_RIGHT, val, backptr, erp
91			);
92			dk4gra_i_pattern(
93				gra, xl, xr, yb, yt,
94				DK4_GRA_PATTERN_30_DEGREE_LEFT, val, backptr, erp
95			);
96		} break;
97		case DK4_GRA_PATTERN_45_DEGREE_LEFT : {
98			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
99			y = val[2];
100			ydiff = val[1] - val[0];
101			do {
102				dk4gra_i_newpath_moveto(gra, val[1], y, backptr, erp);
103				dk4gra_i_lineto(gra, val[0], (y + ydiff), backptr, erp);
104				dk4gra_i_stroke(gra, backptr, erp);
105				y += val[4];
106			} while (val[3] >= y);
107		} break;
108		case DK4_GRA_PATTERN_45_DEGREE_RIGHT : {
109			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
110			y = val[2];
111			ydiff = val[1] - val[0];
112			do {
113				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
114				dk4gra_i_lineto(gra, val[1], (y + ydiff), backptr, erp);
115				dk4gra_i_stroke(gra, backptr, erp);
116				y += val[4];
117			} while (val[3] >= y);
118		} break;
119		case DK4_GRA_PATTERN_45_DEGREE_SIEVE : {
120			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
121			dk4gra_i_pattern(
122				gra, xl, xr, yb, yt,
123				DK4_GRA_PATTERN_45_DEGREE_RIGHT, val, backptr, erp
124			);
125			dk4gra_i_pattern(
126				gra, xl, xr, yb, yt,
127				DK4_GRA_PATTERN_45_DEGREE_LEFT, val, backptr, erp
128			);
129		} break;
130		case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : {
131			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
132			passno = 0;
133			y = val[2];
134			do {
135				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
136				dk4gra_i_lineto(gra, val[1], y, backptr, erp);
137				dk4gra_i_stroke(gra, backptr, erp);
138				x = val[0];
139				if (0 != passno) { x += val[4]; }
140				do {
141					dk4gra_i_newpath_moveto(gra, x, y, backptr, erp);
142					dk4gra_i_lineto(gra, x, (y + val[4]), backptr, erp);
143					dk4gra_i_stroke(gra, backptr, erp);
144					x += (2.0 * val[4]);
145				} while (val[1] >= x);
146				y += val[4];
147				passno = ((0 != passno) ? (0) : (1));
148			} while (val[3] >= y);
149		} break;
150		case DK4_GRA_PATTERN_VERTICAL_BRICKS : {
151			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
152			x = val[0];
153			passno = 0;
154			do {
155				dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp);
156				dk4gra_i_lineto(gra, x, val[3], backptr, erp);
157				dk4gra_i_stroke(gra, backptr, erp);
158				y = val[2];
159				if (0 != passno) { y += val[4]; }
160				do {
161					dk4gra_i_newpath_moveto(gra, x, y, backptr, erp);
162					dk4gra_i_lineto(gra, (x + val[4]), y, backptr, erp);
163					dk4gra_i_stroke(gra, backptr, erp);
164					y += (2.0 * val[4]);
165				} while (val[3] >= y);
166				x += val[4];
167				passno = ((0 != passno) ? (0) : (1));
168			} while (val[1] >= x);
169		} break;
170		case DK4_GRA_PATTERN_HORIZONTAL_LINES : {
171			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
172			y = val[2];
173			do {
174				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
175				dk4gra_i_lineto(gra, val[1], y, backptr, erp);
176				dk4gra_i_stroke(gra, backptr, erp);
177				y += val[4];
178			} while (val[3] >= y);
179		} break;
180		case DK4_GRA_PATTERN_VERTICAL_LINES : {
181			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
182			x = val[0];
183			do {
184				dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp);
185				dk4gra_i_lineto(gra, x, val[3], backptr, erp);
186				dk4gra_i_stroke(gra, backptr, erp);
187				x += val[4];
188			} while (val[1] >= x);
189		} break;
190		case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : {
191			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
192			dk4gra_i_pattern(
193				gra, xl, xr, yb, yt,
194				DK4_GRA_PATTERN_HORIZONTAL_LINES, val, backptr, erp
195			);
196			dk4gra_i_pattern(
197				gra, xl, xr, yb, yt,
198				DK4_GRA_PATTERN_VERTICAL_LINES, val, backptr, erp
199			);
200		} break;
201		case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : {
202			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
203			dx = val[4] / 4.0;
204			passno = 0;
205			y = val[2];
206			do {
207				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
208				dk4gra_i_lineto(gra, val[1], y, backptr, erp);
209				dk4gra_i_stroke(gra, backptr, erp);
210				x = val[0];
211				switch (passno) {
212					case 1: {
213						x += (1.5 * val[4]);
214					} break;
215					case 2: {
216						x += val[4];
217					} break;
218					case 3: {
219						x += (0.5 * val[4]);
220					} break;
221				}
222				do {
223					dk4gra_i_newpath_moveto(gra, (x - dx), y, backptr, erp);
224					dk4gra_i_lineto(gra, (x + dx), (y + val[4]), backptr, erp);
225					dk4gra_i_stroke(gra, backptr, erp);
226					x += (2.0 * val[4]);
227				} while (val[1] >= x);
228				y += val[4];
229				passno++;
230				if (4 <= passno) { passno = 0; }
231			} while (val[3] >= y);
232		} break;
233		case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : {
234			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
235			dx = val[4] / 4.0;
236			passno = 0;
237			y = val[2];
238			do {
239				dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp);
240				dk4gra_i_lineto(gra, val[1], y, backptr, erp);
241				dk4gra_i_stroke(gra, backptr, erp);
242				x = val[0];
243				switch (passno) {
244					case 1: {
245						x += (0.5 * val[4]);
246					} break;
247					case 2: {
248						x += val[4];
249					} break;
250					case 3: {
251						x += (1.5 * val[4]);
252					} break;
253				}
254				do {
255					dk4gra_i_newpath_moveto(gra, (x + dx), y, backptr, erp);
256					dk4gra_i_lineto(gra, (x - dx), (y + val[4]), backptr, erp);
257					dk4gra_i_stroke(gra, backptr, erp);
258					x += (2.0 * val[4]);
259				} while (val[1] >= x);
260				y += val[4];
261				passno++;
262				if (4 <= passno) { passno = 0; }
263			} while (val[3] >= y);
264		} break;
265		case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : {
266			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
267			dy = val[4] / 4.0;
268			x = val[0];
269			passno = 0;
270			do {
271				dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp);
272				dk4gra_i_lineto(gra, x, val[3], backptr, erp);
273				dk4gra_i_stroke(gra, backptr, erp);
274				y = val[2];
275				switch (passno) {
276					case 1: {
277						y += (0.5 * val[4]);
278					} break;
279					case 2: {
280						y += val[4];
281					} break;
282					case 3: {
283						y += (1.5 * val[4]);
284					} break;
285				}
286				do {
287					dk4gra_i_newpath_moveto(gra, x, (y + dy), backptr, erp);
288					dk4gra_i_lineto(gra, (x + val[4]), (y - dy), backptr, erp);
289					dk4gra_i_stroke(gra, backptr, erp);
290					y += (2.0 * val[4]);
291				} while (val[3] >= y);
292				x += val[4];
293				passno++; if (4 <= passno) { passno = 0; }
294			} while (val[1] >= x);
295		} break;
296		case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : {
297			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
298			dy = val[4] / 4.0;
299			x = val[0];
300			passno = 0;
301			do {
302				dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp);
303				dk4gra_i_lineto(gra, x, val[3], backptr, erp);
304				dk4gra_i_stroke(gra, backptr, erp);
305				y = val[2];
306				switch (passno) {
307					case 1: {
308						y += (1.5 * val[4]);
309					} break;
310					case 2: {
311						y += val[4];
312					} break;
313					case 3: {
314						y += (0.5 * val[4]);
315					} break;
316				}
317				do {
318					dk4gra_i_newpath_moveto(gra, x, (y - dy), backptr, erp);
319					dk4gra_i_lineto(gra, (x + val[4]), (y + dy), backptr, erp);
320					dk4gra_i_stroke(gra, backptr, erp);
321					y += (2.0 * val[4]);
322				} while (val[3] >= y);
323				x += val[4];
324				passno++; if (4 <= passno) { passno = 0; }
325			} while (val[1] >= x);
326		} break;
327		case DK4_GRA_PATTERN_LARGE_FISH_SCALES :
328		case DK4_GRA_PATTERN_SMALL_FISH_SCALES : {
329			/* 0=xs 1=xe 2=ys 3=ye 4=dx 5=dy 6=r 7=a1 8=a2 */
330			passno = 0;
331			alpha1 = (M_PI * val[7]) / 180.0;
332			alpha2 = (M_PI * val[8]) / 180.0;
333			alpha  = alpha2 - alpha1;
334			kappa  = dk4gratool_kappa_for_angle(alpha);
335			dxdt0 = -1.0 * val[6] * alpha * sin(alpha1);
336			dydt0 =  val[6] * alpha * cos(alpha1);
337			dxdt1 = -1.0 * val[6] * alpha * sin(alpha2);
338			dydt1 =  val[6] * alpha * cos(alpha2);
339			dxdt0 *= kappa; dydt0 *= kappa; dxdt1 *= kappa; dydt1 *= kappa;
340			y = val[2];
341			do {
342				x = val[0];
343				if (0 != passno) x -= (val[4] / 2.0);
344				/* moveto */
345				dk4gra_i_newpath_moveto(
346					gra, x, (y+val[5]), backptr, erp
347				);
348				/* curveto */
349				dk4gra_i_curveto(
350					gra,
351					(x+dxdt0), (y+val[5]+dydt0),
352					(x+val[4]-dxdt1), (y+val[5]-dydt1),
353					(x+val[4]), (y+val[5]),
354					backptr, erp
355				);
356				x += val[4];
357				while (val[1] > x) {
358					/* curveto */
359					dk4gra_i_curveto(
360						gra,
361						(x+dxdt0), (y+val[5]+dydt0),
362						(x+val[4]-dxdt1), (y+val[5]-dydt1),
363						(x+val[4]), (y+val[5]),
364						backptr, erp
365					);
366					x += val[4];
367				}
368				/* stroke */
369				dk4gra_i_stroke(gra, backptr, erp);
370				y += val[5];
371				passno = ((0 != passno) ? (0) : (1));
372			} while (val[3] >= y);
373		} break;
374		case DK4_GRA_PATTERN_CIRCLES : {
375			/* 0=xs 1=xe 2=ys 3=ye 4=r */
376			x = val[0];
377			do {
378				y = val[2];
379				do {
380					dk4gra_i_circle(
381						gra, (x+val[4]), (y+val[4]), val[4], backptr, erp
382					);
383					dk4gra_i_stroke(gra, backptr, erp);
384					y += 2.0 * val[4];
385				} while (val[3] >= y);
386				x += (2.0 * val[4]);
387			} while (val[1] >= x);
388		} break;
389		case DK4_GRA_PATTERN_HEXAGONS : {
390			/* 0=xs 1=xe 2=ys 3=ye 4=dx 5=dy */
391			dx = val[4] / 6.0;
392			dy = val[5] / 2.0;
393			y = val[2];
394			do {
395				x = val[0];
396				do {
397					dk4gra_i_newpath_moveto(gra, x, (y+dy), backptr, erp);
398					dk4gra_i_lineto(gra, (x + dx), y, backptr, erp);
399					dk4gra_i_lineto(gra, (x + 3.0 * dx), y, backptr, erp);
400					dk4gra_i_lineto(gra,(x + 4.0 * dx),(y + dy),backptr,erp);
401					dk4gra_i_lineto(gra,(x + 3.0 * dx),(y+val[5]),backptr,erp);
402					dk4gra_i_lineto(gra, (x + dx), (y + val[5]), backptr, erp);
403					dk4gra_i_closepath(gra, backptr, erp);
404					dk4gra_i_stroke(gra, backptr, erp);
405					dk4gra_i_newpath_moveto(
406						gra, (x + 4.0 * dx), (y + dy), backptr, erp
407					);
408					dk4gra_i_lineto(gra,(x + 6.0 * dx),(y + dy),backptr,erp);
409					dk4gra_i_stroke(gra, backptr, erp);
410					x += val[4];
411				} while (val[1] >= x);
412				y += val[5];
413			} while (val[3] >= y);
414		} break;
415		case DK4_GRA_PATTERN_OCTAGONS : {
416			/* 0=xs 1=xe 2=ys 3=ye 4=dx 5=co */
417			y = val[2];
418			do {
419				x = val[0];
420				do {
421					dk4gra_i_newpath_moveto(
422						gra, (x + val[5]), y, backptr, erp
423					);
424					dk4gra_i_lineto(
425						gra, (x + val[4] - val[5]), y, backptr, erp
426					);
427					dk4gra_i_lineto(
428						gra, (x + val[4]), (y + val[5]), backptr, erp
429					);
430					dk4gra_i_lineto(
431						gra, (x + val[4]), (y + val[4] - val[5]), backptr, erp
432					);
433					dk4gra_i_lineto(
434						gra, (x + val[4] - val[5]), (y + val[4]), backptr, erp
435					);
436					dk4gra_i_lineto(
437						gra, (x + val[5]), (y + val[4]), backptr, erp
438					);
439					dk4gra_i_lineto(
440						gra, x, (y + val[4] - val[5]), backptr, erp
441					);
442					dk4gra_i_lineto(
443						gra, x, (y + val[5]), backptr, erp
444					);
445					dk4gra_i_closepath(gra, backptr, erp);
446					dk4gra_i_stroke(gra, backptr, erp);
447					x += val[4];
448				} while (val[1] >= x);
449				y += val[4];
450			} while (val[3] >= y);
451		} break;
452		case DK4_GRA_PATTERN_HORIZONTAL_TIRES : {
453			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
454			y = val[2];
455			do {
456				x = val[0];
457				dk4gra_i_newpath_moveto(gra, x, y, backptr, erp);
458				dk4gra_i_lineto(
459					gra, (x + val[4] / 2.0), (y + val[4] / 2.0), backptr, erp
460				);
461				dk4gra_i_lineto(
462					gra, (x + val[4]), y, backptr, erp
463				);
464				do {
465					dk4gra_i_lineto(
466						gra,(x + val[4] / 2.0),(y + val[4] / 2.0),backptr,erp
467					);
468					dk4gra_i_lineto(
469						gra, (x + val[4]), y, backptr, erp
470					);
471					x += val[4];
472				} while (val[1] >= x);
473				dk4gra_i_stroke(gra, backptr, erp);
474				y += val[4];
475			} while (val[3] >= y);
476		} break;
477		case DK4_GRA_PATTERN_VERTICAL_TIRES : {
478			/* 0=xs 1=xe 2=ys 3=ye 4=dx */
479			x = val[0];
480			do {
481				y = val[2];
482				dk4gra_i_newpath_moveto(gra, x, y, backptr, erp);
483				dk4gra_i_lineto(
484					gra, (x + val[4] / 2.0), (y + val[4] / 2.0), backptr, erp
485				);
486				dk4gra_i_lineto(
487					gra, x, (y + val[4]), backptr, erp
488				);
489				do {
490					dk4gra_i_lineto(
491						gra,(x + val[4] / 2.0),(y + val[4] / 2.0),backptr,erp
492					);
493					dk4gra_i_lineto(
494						gra, x, (y + val[4]), backptr, erp
495					);
496					y += val[4];
497				} while (val[3] >= y);
498				dk4gra_i_stroke(gra, backptr, erp);
499				x += val[4];
500			} while (val[1] >= x);
501		} break;
502		default :  {	/* 30 degree left */
503			/* 0=xs 1=xe 2=ys 3=ye 4=dy */
504			y = val[2];
505			ydiff = (val[1] - val[0]) / sqrt(3.0);
506			do {
507				dk4gra_i_newpath_moveto(gra, val[1], y, backptr, erp);
508				dk4gra_i_lineto(gra, val[0], (y + ydiff), backptr, erp);
509				dk4gra_i_stroke(gra, backptr, erp);
510				y += val[4];
511			} while (val[3] >= y);
512		} break;
513	}
514}
515
516
517
518
519/* vim: set ai sw=4 ts=4 : */
520