File indexing completed on 2024-12-22 04:04:15
0001 /* Copyright (C) 2001-2019 Peter Selinger. 0002 This file is part of Potrace. It is free software and it is covered 0003 by the GNU General Public License. See the file COPYING for details. */ 0004 0005 /* calculations with coordinate transformations and bounding boxes */ 0006 0007 #ifdef HAVE_CONFIG_H 0008 #include <config.h> 0009 #endif 0010 0011 #include <math.h> 0012 #include <string.h> 0013 0014 #include "trans.h" 0015 #include "bbox.h" 0016 0017 /* rotate the coordinate system counterclockwise by alpha degrees. The 0018 new bounding box will be the smallest box containing the rotated 0019 old bounding box */ 0020 void trans_rotate(trans_t *r, double alpha) { 0021 double s, c, x0, x1, y0, y1, o0, o1; 0022 trans_t t_struct; 0023 trans_t *t = &t_struct; 0024 0025 memcpy(t, r, sizeof(trans_t)); 0026 0027 s = sin(alpha/180*M_PI); 0028 c = cos(alpha/180*M_PI); 0029 0030 /* apply the transformation matrix to the sides of the bounding box */ 0031 x0 = c * t->bb[0]; 0032 x1 = s * t->bb[0]; 0033 y0 = -s * t->bb[1]; 0034 y1 = c * t->bb[1]; 0035 0036 /* determine new bounding box, and origin of old bb within new bb */ 0037 r->bb[0] = fabs(x0) + fabs(y0); 0038 r->bb[1] = fabs(x1) + fabs(y1); 0039 o0 = - min(x0,0) - min(y0,0); 0040 o1 = - min(x1,0) - min(y1,0); 0041 0042 r->orig[0] = o0 + c * t->orig[0] - s * t->orig[1]; 0043 r->orig[1] = o1 + s * t->orig[0] + c * t->orig[1]; 0044 r->x[0] = c * t->x[0] - s * t->x[1]; 0045 r->x[1] = s * t->x[0] + c * t->x[1]; 0046 r->y[0] = c * t->y[0] - s * t->y[1]; 0047 r->y[1] = s * t->y[0] + c * t->y[1]; 0048 } 0049 0050 /* return the standard cartesian coordinate system for an w x h rectangle. */ 0051 void trans_from_rect(trans_t *r, double w, double h) { 0052 r->bb[0] = w; 0053 r->bb[1] = h; 0054 r->orig[0] = 0.0; 0055 r->orig[1] = 0.0; 0056 r->x[0] = 1.0; 0057 r->x[1] = 0.0; 0058 r->y[0] = 0.0; 0059 r->y[1] = 1.0; 0060 r->scalex = 1.0; 0061 r->scaley = 1.0; 0062 } 0063 0064 /* rescale the coordinate system r by factor sc >= 0. */ 0065 void trans_rescale(trans_t *r, double sc) { 0066 r->bb[0] *= sc; 0067 r->bb[1] *= sc; 0068 r->orig[0] *= sc; 0069 r->orig[1] *= sc; 0070 r->x[0] *= sc; 0071 r->x[1] *= sc; 0072 r->y[0] *= sc; 0073 r->y[1] *= sc; 0074 r->scalex *= sc; 0075 r->scaley *= sc; 0076 } 0077 0078 /* rescale the coordinate system to size w x h */ 0079 void trans_scale_to_size(trans_t *r, double w, double h) { 0080 double xsc = w/r->bb[0]; 0081 double ysc = h/r->bb[1]; 0082 0083 r->bb[0] = w; 0084 r->bb[1] = h; 0085 r->orig[0] *= xsc; 0086 r->orig[1] *= ysc; 0087 r->x[0] *= xsc; 0088 r->x[1] *= ysc; 0089 r->y[0] *= xsc; 0090 r->y[1] *= ysc; 0091 r->scalex *= xsc; 0092 r->scaley *= ysc; 0093 0094 if (w<0) { 0095 r->orig[0] -= w; 0096 r->bb[0] = -w; 0097 } 0098 if (h<0) { 0099 r->orig[1] -= h; 0100 r->bb[1] = -h; 0101 } 0102 } 0103 0104 /* adjust the bounding box to the actual vector outline */ 0105 void trans_tighten(trans_t *r, potrace_path_t *plist) { 0106 interval_t i; 0107 dpoint_t dir; 0108 int j; 0109 0110 /* if pathlist is empty, do nothing */ 0111 if (!plist) { 0112 return; 0113 } 0114 0115 for (j=0; j<2; j++) { 0116 dir.x = r->x[j]; 0117 dir.y = r->y[j]; 0118 path_limits(plist, dir, &i); 0119 if (i.min == i.max) { 0120 /* make the extent non-zero to avoid later division by zero errors */ 0121 i.max = i.min+0.5; 0122 i.min = i.min-0.5; 0123 } 0124 r->bb[j] = i.max - i.min; 0125 r->orig[j] = -i.min; 0126 } 0127 }