%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% module #include "dk4conf.h" #if DK4_HAVE_MATH_H #ifndef MATH_H_INCLUDED #if DK4_ON_WINDOWS #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES 1 #endif #endif #include #define MATH_H_INCLUDED 1 #endif #endif #ifndef DK4GRA_H_INCLUDED #include "dk4gra.h" #endif #ifndef DK4GRAT_H_INCLUDED #include "dk4grat.h" #endif #ifndef GRA_H_INCLUDED #include "gra.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif void dk4gra_i_pattern( dk4_gra_t *gra, double xl, double xr, double yb, double yt, int pn, const double *val, int *backptr, dk4_er_t *erp ) { double x; double y; double dx; double dy; double ydiff; double alpha; double alpha1; double alpha2; double kappa; double dxdt0; double dxdt1; double dydt0; double dydt1; int passno; #if DK4_USE_ASSERT assert(NULL != gra); #endif switch (pn) { case DK4_GRA_PATTERN_30_DEGREE_RIGHT : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ y = val[2]; ydiff = (val[1] - val[0]) / sqrt(3.0); do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], (y + ydiff), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_30_DEGREE_SIEVE : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_30_DEGREE_RIGHT, val, backptr, erp ); dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_30_DEGREE_LEFT, val, backptr, erp ); } break; case DK4_GRA_PATTERN_45_DEGREE_LEFT : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ y = val[2]; ydiff = val[1] - val[0]; do { dk4gra_i_newpath_moveto(gra, val[1], y, backptr, erp); dk4gra_i_lineto(gra, val[0], (y + ydiff), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_45_DEGREE_RIGHT : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ y = val[2]; ydiff = val[1] - val[0]; do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], (y + ydiff), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_45_DEGREE_SIEVE : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_45_DEGREE_RIGHT, val, backptr, erp ); dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_45_DEGREE_LEFT, val, backptr, erp ); } break; case DK4_GRA_PATTERN_HORIZONTAL_BRICKS : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ passno = 0; y = val[2]; do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], y, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x = val[0]; if (0 != passno) { x += val[4]; } do { dk4gra_i_newpath_moveto(gra, x, y, backptr, erp); dk4gra_i_lineto(gra, x, (y + val[4]), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x += (2.0 * val[4]); } while (val[1] >= x); y += val[4]; passno = ((0 != passno) ? (0) : (1)); } while (val[3] >= y); } break; case DK4_GRA_PATTERN_VERTICAL_BRICKS : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ x = val[0]; passno = 0; do { dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp); dk4gra_i_lineto(gra, x, val[3], backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y = val[2]; if (0 != passno) { y += val[4]; } do { dk4gra_i_newpath_moveto(gra, x, y, backptr, erp); dk4gra_i_lineto(gra, (x + val[4]), y, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += (2.0 * val[4]); } while (val[3] >= y); x += val[4]; passno = ((0 != passno) ? (0) : (1)); } while (val[1] >= x); } break; case DK4_GRA_PATTERN_HORIZONTAL_LINES : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ y = val[2]; do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], y, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_VERTICAL_LINES : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ x = val[0]; do { dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp); dk4gra_i_lineto(gra, x, val[3], backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x += val[4]; } while (val[1] >= x); } break; case DK4_GRA_PATTERN_HORIZONTAL_VERTICAL_SIEVE : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_HORIZONTAL_LINES, val, backptr, erp ); dk4gra_i_pattern( gra, xl, xr, yb, yt, DK4_GRA_PATTERN_VERTICAL_LINES, val, backptr, erp ); } break; case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_LEFT : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ dx = val[4] / 4.0; passno = 0; y = val[2]; do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], y, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x = val[0]; switch (passno) { case 1: { x += (1.5 * val[4]); } break; case 2: { x += val[4]; } break; case 3: { x += (0.5 * val[4]); } break; } do { dk4gra_i_newpath_moveto(gra, (x - dx), y, backptr, erp); dk4gra_i_lineto(gra, (x + dx), (y + val[4]), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x += (2.0 * val[4]); } while (val[1] >= x); y += val[4]; passno++; if (4 <= passno) { passno = 0; } } while (val[3] >= y); } break; case DK4_GRA_PATTERN_HORIZONTAL_SHINGLES_RIGHT : { /* 0=xs 1=xe 2=ys 3=ye 4=dy */ dx = val[4] / 4.0; passno = 0; y = val[2]; do { dk4gra_i_newpath_moveto(gra, val[0], y, backptr, erp); dk4gra_i_lineto(gra, val[1], y, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x = val[0]; switch (passno) { case 1: { x += (0.5 * val[4]); } break; case 2: { x += val[4]; } break; case 3: { x += (1.5 * val[4]); } break; } do { dk4gra_i_newpath_moveto(gra, (x + dx), y, backptr, erp); dk4gra_i_lineto(gra, (x - dx), (y + val[4]), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x += (2.0 * val[4]); } while (val[1] >= x); y += val[4]; passno++; if (4 <= passno) { passno = 0; } } while (val[3] >= y); } break; case DK4_GRA_PATTERN_VERTICAL_SHINGLES_1 : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ dy = val[4] / 4.0; x = val[0]; passno = 0; do { dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp); dk4gra_i_lineto(gra, x, val[3], backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y = val[2]; switch (passno) { case 1: { y += (0.5 * val[4]); } break; case 2: { y += val[4]; } break; case 3: { y += (1.5 * val[4]); } break; } do { dk4gra_i_newpath_moveto(gra, x, (y + dy), backptr, erp); dk4gra_i_lineto(gra, (x + val[4]), (y - dy), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += (2.0 * val[4]); } while (val[3] >= y); x += val[4]; passno++; if (4 <= passno) { passno = 0; } } while (val[1] >= x); } break; case DK4_GRA_PATTERN_VERTICAL_SHINGLES_2 : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ dy = val[4] / 4.0; x = val[0]; passno = 0; do { dk4gra_i_newpath_moveto(gra, x, val[2], backptr, erp); dk4gra_i_lineto(gra, x, val[3], backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y = val[2]; switch (passno) { case 1: { y += (1.5 * val[4]); } break; case 2: { y += val[4]; } break; case 3: { y += (0.5 * val[4]); } break; } do { dk4gra_i_newpath_moveto(gra, x, (y - dy), backptr, erp); dk4gra_i_lineto(gra, (x + val[4]), (y + dy), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += (2.0 * val[4]); } while (val[3] >= y); x += val[4]; passno++; if (4 <= passno) { passno = 0; } } while (val[1] >= x); } break; case DK4_GRA_PATTERN_LARGE_FISH_SCALES : case DK4_GRA_PATTERN_SMALL_FISH_SCALES : { /* 0=xs 1=xe 2=ys 3=ye 4=dx 5=dy 6=r 7=a1 8=a2 */ passno = 0; alpha1 = (M_PI * val[7]) / 180.0; alpha2 = (M_PI * val[8]) / 180.0; alpha = alpha2 - alpha1; kappa = dk4gratool_kappa_for_angle(alpha); dxdt0 = -1.0 * val[6] * alpha * sin(alpha1); dydt0 = val[6] * alpha * cos(alpha1); dxdt1 = -1.0 * val[6] * alpha * sin(alpha2); dydt1 = val[6] * alpha * cos(alpha2); dxdt0 *= kappa; dydt0 *= kappa; dxdt1 *= kappa; dydt1 *= kappa; y = val[2]; do { x = val[0]; if (0 != passno) x -= (val[4] / 2.0); /* moveto */ dk4gra_i_newpath_moveto( gra, x, (y+val[5]), backptr, erp ); /* curveto */ dk4gra_i_curveto( gra, (x+dxdt0), (y+val[5]+dydt0), (x+val[4]-dxdt1), (y+val[5]-dydt1), (x+val[4]), (y+val[5]), backptr, erp ); x += val[4]; while (val[1] > x) { /* curveto */ dk4gra_i_curveto( gra, (x+dxdt0), (y+val[5]+dydt0), (x+val[4]-dxdt1), (y+val[5]-dydt1), (x+val[4]), (y+val[5]), backptr, erp ); x += val[4]; } /* stroke */ dk4gra_i_stroke(gra, backptr, erp); y += val[5]; passno = ((0 != passno) ? (0) : (1)); } while (val[3] >= y); } break; case DK4_GRA_PATTERN_CIRCLES : { /* 0=xs 1=xe 2=ys 3=ye 4=r */ x = val[0]; do { y = val[2]; do { dk4gra_i_circle( gra, (x+val[4]), (y+val[4]), val[4], backptr, erp ); dk4gra_i_stroke(gra, backptr, erp); y += 2.0 * val[4]; } while (val[3] >= y); x += (2.0 * val[4]); } while (val[1] >= x); } break; case DK4_GRA_PATTERN_HEXAGONS : { /* 0=xs 1=xe 2=ys 3=ye 4=dx 5=dy */ dx = val[4] / 6.0; dy = val[5] / 2.0; y = val[2]; do { x = val[0]; do { dk4gra_i_newpath_moveto(gra, x, (y+dy), backptr, erp); dk4gra_i_lineto(gra, (x + dx), y, backptr, erp); dk4gra_i_lineto(gra, (x + 3.0 * dx), y, backptr, erp); dk4gra_i_lineto(gra,(x + 4.0 * dx),(y + dy),backptr,erp); dk4gra_i_lineto(gra,(x + 3.0 * dx),(y+val[5]),backptr,erp); dk4gra_i_lineto(gra, (x + dx), (y + val[5]), backptr, erp); dk4gra_i_closepath(gra, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); dk4gra_i_newpath_moveto( gra, (x + 4.0 * dx), (y + dy), backptr, erp ); dk4gra_i_lineto(gra,(x + 6.0 * dx),(y + dy),backptr,erp); dk4gra_i_stroke(gra, backptr, erp); x += val[4]; } while (val[1] >= x); y += val[5]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_OCTAGONS : { /* 0=xs 1=xe 2=ys 3=ye 4=dx 5=co */ y = val[2]; do { x = val[0]; do { dk4gra_i_newpath_moveto( gra, (x + val[5]), y, backptr, erp ); dk4gra_i_lineto( gra, (x + val[4] - val[5]), y, backptr, erp ); dk4gra_i_lineto( gra, (x + val[4]), (y + val[5]), backptr, erp ); dk4gra_i_lineto( gra, (x + val[4]), (y + val[4] - val[5]), backptr, erp ); dk4gra_i_lineto( gra, (x + val[4] - val[5]), (y + val[4]), backptr, erp ); dk4gra_i_lineto( gra, (x + val[5]), (y + val[4]), backptr, erp ); dk4gra_i_lineto( gra, x, (y + val[4] - val[5]), backptr, erp ); dk4gra_i_lineto( gra, x, (y + val[5]), backptr, erp ); dk4gra_i_closepath(gra, backptr, erp); dk4gra_i_stroke(gra, backptr, erp); x += val[4]; } while (val[1] >= x); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_HORIZONTAL_TIRES : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ y = val[2]; do { x = val[0]; dk4gra_i_newpath_moveto(gra, x, y, backptr, erp); dk4gra_i_lineto( gra, (x + val[4] / 2.0), (y + val[4] / 2.0), backptr, erp ); dk4gra_i_lineto( gra, (x + val[4]), y, backptr, erp ); do { dk4gra_i_lineto( gra,(x + val[4] / 2.0),(y + val[4] / 2.0),backptr,erp ); dk4gra_i_lineto( gra, (x + val[4]), y, backptr, erp ); x += val[4]; } while (val[1] >= x); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; case DK4_GRA_PATTERN_VERTICAL_TIRES : { /* 0=xs 1=xe 2=ys 3=ye 4=dx */ x = val[0]; do { y = val[2]; dk4gra_i_newpath_moveto(gra, x, y, backptr, erp); dk4gra_i_lineto( gra, (x + val[4] / 2.0), (y + val[4] / 2.0), backptr, erp ); dk4gra_i_lineto( gra, x, (y + val[4]), backptr, erp ); do { dk4gra_i_lineto( gra,(x + val[4] / 2.0),(y + val[4] / 2.0),backptr,erp ); dk4gra_i_lineto( gra, x, (y + val[4]), backptr, erp ); y += val[4]; } while (val[3] >= y); dk4gra_i_stroke(gra, backptr, erp); x += val[4]; } while (val[1] >= x); } break; default : { /* 30 degree left */ /* 0=xs 1=xe 2=ys 3=ye 4=dy */ y = val[2]; ydiff = (val[1] - val[0]) / sqrt(3.0); do { dk4gra_i_newpath_moveto(gra, val[1], y, backptr, erp); dk4gra_i_lineto(gra, val[0], (y + ydiff), backptr, erp); dk4gra_i_stroke(gra, backptr, erp); y += val[4]; } while (val[3] >= y); } break; } } /* vim: set ai sw=4 ts=4 : */