00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "aaLine.h"
00031
00032 #include <iostream>
00033
00034
00035
00036 int ipart(double x)
00037 {
00038 return((int)x);
00039 }
00040
00041
00042
00043 double fpart(double x)
00044 {
00045 return(x-ipart(x));
00046 }
00047
00048
00049
00050 double rfpart(double x)
00051 {
00052 return(1.0-fpart(x));
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 void sub(unsigned char &ch, unsigned char val)
00074 {
00075 if (val < ch)
00076 ch = val;
00077 }
00078
00079
00080 #define PLOTX(x, y, c1, c2) sub(data[0+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00081 sub(data[1+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00082 sub(data[2+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00083 sub(data[0+3*(x+(y+1)*stride)], (unsigned char)(255*(1.0-c2))); \
00084 sub(data[1+3*(x+(y+1)*stride)], (unsigned char)(255*(1.0-c2))); \
00085 sub(data[2+3*(x+(y+1)*stride)], (unsigned char)(255*(1.0-c2)));// \
00086 // cerr << ">x" << x << ",y" << y << ",c1" << c1 << ",c2" << c2 << '\n';
00087
00088
00089 #define PLOTY(x, y, c1, c2) sub(data[0+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00090 sub(data[1+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00091 sub(data[2+3*(x+y*stride)], (unsigned char)(255*(1.0-c1))); \
00092 sub(data[0+3*(x+1+y*stride)], (unsigned char)(255*(1.0-c2))); \
00093 sub(data[1+3*(x+1+y*stride)], (unsigned char)(255*(1.0-c2))); \
00094 sub(data[2+3*(x+1+y*stride)], (unsigned char)(255*(1.0-c2)));// \
00095 // cerr << ">x" << x << ",y" << y << ",c1" << c1 << ",c2" << c2 << '\n';
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 void aaline(unsigned char *data, int stride, int x1, int x2, float y1, float y2)
00132 {
00133 double dx = x2-x1;
00134 double dy = y2-y1;
00135 double gradient = dy/dx;
00136 double xend, yend, interx, intery;
00137 int xpxl1, ypxl1, xpxl2, ypxl2, x, y;
00138 if ((gradient < 1.0) && (gradient > -1.0))
00139 {
00140
00141 xpxl1 = x1;
00142 intery = y1+gradient;
00143 xpxl2 = x2;
00144 for (x = xpxl1; x <= xpxl2; ++x)
00145 {
00146 PLOTX(x, ipart(intery), rfpart(intery), fpart(intery));
00147 intery = intery + gradient;
00148 }
00149 }
00150 else
00151 {
00152 dx = x2-x1;
00153 dy = y2-y1;
00154 gradient = dx/dy;
00155 yend = ipart(y1+0.5);
00156 ypxl1 = (int)yend;
00157 yend = ipart(y2+0.5);
00158 xend = x2+gradient*(yend-y2);
00159 ypxl2 = (int)yend;
00160 if (gradient > 0.0)
00161 {
00162 interx = x1;
00163 for (y = ypxl1; y <= ypxl2; ++y)
00164 {
00165 PLOTY(ipart(interx), y, rfpart(interx), fpart(interx));
00166 interx = interx+gradient;
00167 }
00168 }
00169 else
00170 {
00171 interx = xend;
00172 for (y = ypxl2; y <= ypxl1; ++y)
00173 {
00174 PLOTY(ipart(interx), y, rfpart(interx), fpart(interx));
00175 interx = interx+gradient;
00176 }
00177 }
00178 }
00179 }
00180
00181
00182
00183 #define PLOTCX(x, y, c1, c2) data[0+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[0+3*(x+y*stride)]+r*c1); \
00184 data[1+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[1+3*(x+y*stride)]+g*c1); \
00185 data[2+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[2+3*(x+y*stride)]+b*c1); \
00186 data[0+3*(x+(y+1)*stride)] = (unsigned char)((1.0-c2)*data[0+3*(x+(y+1)*stride)]+r*c2); \
00187 data[1+3*(x+(y+1)*stride)] = (unsigned char)((1.0-c2)*data[1+3*(x+(y+1)*stride)]+g*c2); \
00188 data[2+3*(x+(y+1)*stride)] = (unsigned char)((1.0-c2)*data[2+3*(x+(y+1)*stride)]+b*c2);
00189
00190
00191
00192 #define PLOTCY(x, y, c1, c2) data[0+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[0+3*(x+y*stride)]+r*c1); \
00193 data[1+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[1+3*(x+y*stride)]+g*c1); \
00194 data[2+3*(x+y*stride)] = (unsigned char)((1.0-c1)*data[2+3*(x+y*stride)]+b*c1); \
00195 data[0+3*(x+1+y*stride)] = (unsigned char)((1.0-c2)*data[0+3*(x+1+y*stride)]+r*c2); \
00196 data[1+3*(x+1+y*stride)] = (unsigned char)((1.0-c2)*data[1+3*(x+1+y*stride)]+g*c2); \
00197 data[2+3*(x+1+y*stride)] = (unsigned char)((1.0-c2)*data[2+3*(x+1+y*stride)]+b*c2);
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 void aacolline(unsigned char *data, int stride, int x1, int x2, float y1, float y2, unsigned char r, unsigned char g, unsigned char b)
00214 {
00215 double dx = x2-x1;
00216 double dy = y2-y1;
00217 double gradient = dy/dx;
00218 double xend, yend, interx, intery;
00219 int xpxl1, ypxl1, xpxl2, ypxl2, x, y;
00220 if ((gradient < 1.0) && (gradient > -1.0))
00221 {
00222
00223 xpxl1 = x1;
00224 intery = y1+gradient;
00225 xpxl2 = x2;
00226 for (x = xpxl1; x <= xpxl2; ++x)
00227 {
00228 PLOTCX(x, ipart(intery), rfpart(intery), fpart(intery));
00229 intery = intery + gradient;
00230 }
00231 }
00232 else
00233 {
00234 dx = x2-x1;
00235 dy = y2-y1;
00236 gradient = dx/dy;
00237 yend = ipart(y1+0.5);
00238 ypxl1 = (int)yend;
00239 yend = ipart(y2+0.5);
00240 xend = x2+gradient*(yend-y2);
00241 ypxl2 = (int)yend;
00242 if (gradient > 0.0)
00243 {
00244 interx = x1;
00245 for (y = ypxl1; y <= ypxl2; ++y)
00246 {
00247 PLOTCY(ipart(interx), y, rfpart(interx), fpart(interx));
00248 interx = interx+gradient;
00249 }
00250 }
00251 else
00252 {
00253 interx = xend;
00254 for (y = ypxl2; y <= ypxl1; ++y)
00255 {
00256 PLOTCY(ipart(interx), y, rfpart(interx), fpart(interx));
00257 interx = interx+gradient;
00258 }
00259 }
00260 }
00261 }
00262
00263
00264
00265 #define PLOTCSY(x, y, c1, c2) if ((x-stroke/2 >= 0) && (x-stroke/2 < w) && (y >= 0) && (y < h)) { \
00266 data[0+3*(x-stroke/2+y*stride)] = FXREDVAL(c)*a*c1+(1.0-a*c1)*data[0+3*(x-stroke/2+y*stride)]; \
00267 data[1+3*(x-stroke/2+y*stride)] = FXGREENVAL(c)*a*c1+(1.0-a*c1)*data[1+3*(x-stroke/2+y*stride)]; \
00268 data[2+3*(x-stroke/2+y*stride)] = FXBLUEVAL(c)*a*c1+(1.0-a*c1)*data[2+3*(x-stroke/2+y*stride)]; } \
00269 for (i = 1; i < stroke; ++i) \
00270 if ((i+x-stroke/2 >= 0) && (i+x-stroke/2 < w) && (y >= 0) && (y < h)) { \
00271 data[0+3*(i+x-stroke/2+y*stride)] = FXREDVAL(c)*a+(1.0-a)*data[0+3*(i+x-stroke/2+y*stride)]; \
00272 data[1+3*(i+x-stroke/2+y*stride)] = FXGREENVAL(c)*a+(1.0-a)*data[1+3*(i+x-stroke/2+y*stride)]; \
00273 data[2+3*(i+x-stroke/2+y*stride)] = FXBLUEVAL(c)*a+(1.0-a)*data[2+3*(i+x-stroke/2+y*stride)]; } \
00274 if ((x+(int)(0.5+(float)stroke/2.0) >= 0) && (x+(int)(0.5+(float)stroke/2.0) < w) && (y >= 0) && (y < h)) { \
00275 data[0+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)] = FXREDVAL(c)*a*c2+(1.0-a*c2)*data[0+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)]; \
00276 data[1+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)] = FXGREENVAL(c)*a*c2+(1.0-a*c2)*data[1+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)]; \
00277 data[2+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)] = FXBLUEVAL(c)*a*c2+(1.0-a*c2)*data[2+3*(x+(int)(0.5+(float)stroke/2.0)+y*stride)]; }
00278
00279
00280 #define PLOTCSX(x, y, c1, c2) if ((x >= 0) && (x < w) && (y-stroke/2 >= 0) && (y-stroke/2 < h)) { \
00281 data[0+3*(x+(y-stroke/2)*stride)] = FXREDVAL(c)*a*c1+(1.0-a*c1)*data[0+3*(x+(y-stroke/2)*stride)]; \
00282 data[1+3*(x+(y-stroke/2)*stride)] = FXGREENVAL(c)*a*c1+(1.0-a*c1)*data[1+3*(x+(y-stroke/2)*stride)]; \
00283 data[2+3*(x+(y-stroke/2)*stride)] = FXBLUEVAL(c)*a*c1+(1.0-a*c1)*data[2+3*(x+(y-stroke/2)*stride)]; } \
00284 for (i = 1; i < stroke; ++i) \
00285 if ((x >= 0) && (x < w) && (y+i-stroke/2 >= 0) && (y+i-stroke/2 < h)) { \
00286 data[0+3*(x+(y+i-stroke/2)*stride)] = FXREDVAL(c)*a+(1.0-a)*data[0+3*(x+(y+i-stroke/2)*stride)]; \
00287 data[1+3*(x+(y+i-stroke/2)*stride)] = FXGREENVAL(c)*a+(1.0-a)*data[1+3*(x+(y+i-stroke/2)*stride)]; \
00288 data[2+3*(x+(y+i-stroke/2)*stride)] = FXBLUEVAL(c)*a+(1.0-a)*data[2+3*(x+(y+i-stroke/2)*stride)]; } \
00289 if ((x >= 0) && (x < w) && (y+(int)(0.5+(float)stroke/2.0) >= 0) && (y+(int)(0.5+(float)stroke/2.0) < h)) { \
00290 data[0+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)] = FXREDVAL(c)*a*c2+(1.0-a*c2)*data[0+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)]; \
00291 data[1+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)] = FXGREENVAL(c)*a*c2+(1.0-a*c2)*data[1+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)]; \
00292 data[2+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)] = FXBLUEVAL(c)*a*c2+(1.0-a*c2)*data[2+3*(x+(y+(int)(0.5+(float)stroke/2.0))*stride)]; }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 void aacolstrokeline(unsigned char *data, int stride, int x1, int x2, float y1, float y2, FXColor c, int stroke, int w, int h)
00309 {
00310 int i;
00311 float a = FXALPHAVAL(c)/255.0;
00312 double dx = x2-x1;
00313 double dy = y2-y1;
00314 double gradient = dy/dx;
00315 double xend, yend, interx, intery;
00316 int xpxl1, ypxl1, xpxl2, ypxl2, x, y;
00317 if ((gradient < 1.0) && (gradient > -1.0))
00318 {
00319
00320 xpxl1 = x1;
00321 intery = y1+gradient;
00322 xpxl2 = x2;
00323 for (x = xpxl1; x <= xpxl2; ++x)
00324 {
00325 PLOTCSX(x, ipart(intery), rfpart(intery), fpart(intery));
00326 intery = intery + gradient;
00327 }
00328 }
00329 else
00330 {
00331 dx = x2-x1;
00332 dy = y2-y1;
00333 gradient = dx/dy;
00334 yend = ipart(y1+0.5);
00335 ypxl1 = (int)yend;
00336 yend = ipart(y2+0.5);
00337 xend = x2+gradient*(yend-y2);
00338 ypxl2 = (int)yend;
00339 if (gradient > 0.0)
00340 {
00341 interx = x1;
00342 for (y = ypxl1; y <= ypxl2; ++y)
00343 {
00344 PLOTCSY(ipart(interx), y, rfpart(interx), fpart(interx));
00345 interx = interx+gradient;
00346 }
00347 }
00348 else
00349 {
00350 interx = xend;
00351 for (y = ypxl2; y <= ypxl1; ++y)
00352 {
00353 PLOTCSY(ipart(interx), y, rfpart(interx), fpart(interx));
00354 interx = interx+gradient;
00355 }
00356 }
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void aarampcolstrokeline(unsigned char *data, int stride, int x1, int x2, float y1, float y2, FXColor sc, FXColor ec, int stroke, int w, int h)
00377 {
00378 int i;
00379 float a = FXALPHAVAL(sc)/255.0;
00380 double dx = x2-x1;
00381 double dy = y2-y1;
00382 double gradient = dy/dx;
00383 double xend, yend, interx, intery;
00384 int xpxl1, ypxl1, xpxl2, ypxl2, x, y;
00385 float interp;
00386 FXColor c;
00387 if ((gradient < 1.0) && (gradient > -1.0))
00388 {
00389
00390 xpxl1 = x1;
00391 intery = y1+gradient;
00392 xpxl2 = x2;
00393 for (x = xpxl1; x <= xpxl2; ++x)
00394 {
00395 interp = (float)(x-xpxl1)/(float)(xpxl2-xpxl1);
00396 c = FXRGB((float)FXREDVAL(sc)*(1.0-interp)+(float)FXREDVAL(ec)*interp, (float)FXGREENVAL(sc)*(1.0-interp)+(float)FXGREENVAL(ec)*interp, (float)FXBLUEVAL(sc)*(1.0-interp)+(float)FXBLUEVAL(ec)*interp);
00397 PLOTCSX(x, ipart(intery), rfpart(intery), fpart(intery));
00398 intery = intery + gradient;
00399 }
00400 }
00401 else
00402 {
00403 dx = x2-x1;
00404 dy = y2-y1;
00405 gradient = dx/dy;
00406 yend = ipart(y1+0.5);
00407 ypxl1 = (int)yend;
00408 yend = ipart(y2+0.5);
00409 xend = x2+gradient*(yend-y2);
00410 ypxl2 = (int)yend;
00411 if (gradient > 0.0)
00412 {
00413 interx = x1;
00414 for (y = ypxl1; y <= ypxl2; ++y)
00415 {
00416 interp = (float)(y-ypxl1)/(float)(ypxl2-ypxl1);
00417 c = FXRGB((float)FXREDVAL(sc)*(1.0-interp)+(float)FXREDVAL(ec)*interp, (float)FXGREENVAL(sc)*(1.0-interp)+(float)FXGREENVAL(ec)*interp, (float)FXBLUEVAL(sc)*(1.0-interp)+(float)FXBLUEVAL(ec)*interp);
00418 PLOTCSY(ipart(interx), y, rfpart(interx), fpart(interx));
00419 interx = interx+gradient;
00420 }
00421 }
00422 else
00423 {
00424 interx = xend;
00425 for (y = ypxl2; y <= ypxl1; ++y)
00426 {
00427 interp = (float)(y-ypxl2)/(float)(ypxl1-ypxl2);
00428 c = FXRGB((float)FXREDVAL(sc)*(1.0-interp)+(float)FXREDVAL(ec)*interp, (float)FXGREENVAL(sc)*(1.0-interp)+(float)FXGREENVAL(ec)*interp, (float)FXBLUEVAL(sc)*(1.0-interp)+(float)FXBLUEVAL(ec)*interp);
00429 PLOTCSY(ipart(interx), y, rfpart(interx), fpart(interx));
00430 interx = interx+gradient;
00431 }
00432 }
00433 }
00434 }