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 #include <cstdlib>
00028 #include <cmath>
00029
00030
00031
00032
00033 #include "DrawLine.hpp"
00034
00035
00036
00037
00038 namespace kn{
00039
00040
00041
00042
00043
00044 void drawLine(ImageRGB8u &image,
00045 const int x1, const int y1,
00046 const int x2, const int y2,
00047 const unsigned char r,
00048 const unsigned char g,
00049 const unsigned char b){
00050
00051 int dx = std::abs(x2 - x1);
00052 int dy = std::abs(y2 - y1);
00053
00054
00055 if(dy>dx) drawLineY(image, x1, y1, x2, y2, r, g, b);
00056 else drawLineX(image, x1, y1, x2, y2, r, g, b);
00057 }
00058
00059
00060 void drawLine(ImageGS8u &image,
00061 const int x1, const int y1,
00062 const int x2, const int y2,
00063 const unsigned char greyLevel){
00064
00065 int dx = std::abs(x2 - x1);
00066 int dy = std::abs(y2 - y1);
00067
00068
00069 if(dy>dx) drawLineY(image, x1, y1, x2, y2, greyLevel);
00070 else drawLineX(image, x1, y1, x2, y2, greyLevel);
00071 }
00072
00073
00074 void drawLine(ImageRGB8u &image,
00075 const double line[3],
00076 const unsigned char r,
00077 const unsigned char g,
00078 const unsigned char b){
00079
00080
00081 unsigned int x1,x2,y1,y2;
00082
00083 if(fabs(line[0])*1.0e5 < line[1]){
00084 x1 = x2 = (unsigned int)(-line[2]/line[0]);
00085 y1 = 0;
00086 y2 = image.height();
00087 }
00088 else{
00089 x1 = 0;
00090 y1 = (unsigned int)(-line[2]/line[1]);
00091 x2 = image.width();
00092 y2 = (unsigned int)(-(line[2]+line[0]*image.width())/line[1]);
00093 }
00094
00095
00096 drawLine(image, x1, y1, x2, y2, r, g, b);
00097 }
00098
00099
00100 void drawLine(ImageGS8u &image,
00101 const double line[3],
00102 const unsigned char greyLevel){
00103
00104
00105 unsigned int x1,x2,y1,y2;
00106
00107 if(fabs(line[0])*1.0e5 < line[1]){
00108 x1 = x2 = (unsigned int)(-line[2]/line[0]);
00109 y1 = 0;
00110 y2 = image.height();
00111 }
00112 else{
00113 x1 = 0;
00114 y1 = (unsigned int)(-line[2]/line[1]);
00115 x2 = image.width();
00116 y2 = (unsigned int)(-(line[2]+line[0]*image.width())/line[1]);
00117 }
00118
00119
00120 drawLine(image, x1, y1, x2, y2, greyLevel);
00121 }
00122
00123
00124 void drawLineY(ImageRGB8u &image,
00125 const int x1, const int y1,
00126 const int x2, const int y2,
00127 const unsigned char r,
00128 const unsigned char g,
00129 const unsigned char b){
00130
00131 if(y1-y2 == 0) return;
00132
00133
00134 int xf1 = int2FloatingInt(x1);
00135 int yf1 = int2FloatingInt(y1);
00136 int xf2 = int2FloatingInt(x2);
00137 int yf2 = int2FloatingInt(y2);
00138
00139
00140 if(yf1>yf2){
00141 std::swap(xf1,xf2);
00142 std::swap(yf1,yf2);
00143 }
00144
00145
00146 int a = (int)( (xf1-xf2)/(double)(yf1-yf2) * ( ((int)1)<<16) );
00147
00148
00149 while(yf1 < yf2){
00150 drawPixel(image, xf1, yf1, r, g, b);
00151 xf1 += a;
00152 yf1 += int2FloatingInt(1);
00153 }
00154 }
00155
00156
00157
00158 void drawLineY(ImageGS8u &image,
00159 const int x1, const int y1,
00160 const int x2, const int y2,
00161 const unsigned char greyLevel){
00162
00163 if(y1-y2 == 0) return;
00164
00165
00166 int xf1 = int2FloatingInt(x1);
00167 int yf1 = int2FloatingInt(y1);
00168 int xf2 = int2FloatingInt(x2);
00169 int yf2 = int2FloatingInt(y2);
00170
00171
00172 if(yf1>yf2){
00173 std::swap(xf1,xf2);
00174 std::swap(yf1,yf2);
00175 }
00176
00177
00178 int a = (int)( (xf1-xf2)/(double)(yf1-yf2) * ( ((int)1)<<16) );
00179
00180
00181 while(yf1 < yf2){
00182 drawPixel(image, xf1, yf1, greyLevel);
00183 xf1 += a;
00184 yf1 += int2FloatingInt(1);
00185 }
00186 }
00187
00188
00189 void drawLineX(ImageRGB8u &image,
00190 const int x1, const int y1,
00191 const int x2, const int y2,
00192 const unsigned char r,
00193 const unsigned char g,
00194 const unsigned char b){
00195
00196 if(x1-x2 == 0) return;
00197
00198
00199 int xf1 = int2FloatingInt(x1);
00200 int yf1 = int2FloatingInt(y1);
00201 int xf2 = int2FloatingInt(x2);
00202 int yf2 = int2FloatingInt(y2);
00203
00204
00205 if(xf1>xf2){
00206 std::swap(xf1,xf2);
00207 std::swap(yf1,yf2);
00208 }
00209
00210
00211 int a = (int)( (yf1-yf2)/(double)(xf1-xf2) * ( ((int)1)<<16) );
00212
00213
00214 while(xf1 < xf2){
00215 drawPixel(image, xf1, yf1, r, g, b);
00216 xf1 += int2FloatingInt(1);
00217 yf1 += a;
00218 }
00219 }
00220
00221
00222 void drawLineX(ImageGS8u &image,
00223 const int x1, const int y1,
00224 const int x2, const int y2,
00225 const unsigned char greyLevel){
00226
00227 if(x1-x2 == 0) return;
00228
00229
00230 int xf1 = int2FloatingInt(x1);
00231 int yf1 = int2FloatingInt(y1);
00232 int xf2 = int2FloatingInt(x2);
00233 int yf2 = int2FloatingInt(y2);
00234
00235
00236 if(xf1>xf2){
00237 std::swap(xf1,xf2);
00238 std::swap(yf1,yf2);
00239 }
00240
00241
00242 int a = (int)( (yf1-yf2)/(double)(xf1-xf2) * ( ((int)1)<<16) );
00243
00244
00245 while(xf1 < xf2){
00246 drawPixel(image, xf1, yf1, greyLevel);
00247 xf1 += int2FloatingInt(1);
00248 yf1 += a;
00249 }
00250 }
00251
00252
00253 void drawPixel(ImageRGB8u &image,
00254 int x0, int y0,
00255 const unsigned char r,
00256 const unsigned char g,
00257 const unsigned char b){
00258 int y1 = y0 >> 16;
00259 int y2 = y1+1;
00260
00261 double val = static_cast<double>(y0 & 0xFFFF) / static_cast<double> (0xFFFF);
00262
00263 x0 = x0 >> 16;
00264
00265 if(x0>=0 && x0<(int)image.width() && y1>=0 && y1<(int)image.height()){
00266 image(x0,y1)[0] = (unsigned char)((1.0-val)*((int)r)) + (unsigned char)(val*((int)image(x0,y1)[0]));
00267 image(x0,y1)[1] = (unsigned char)((1.0-val)*((int)g)) + (unsigned char)(val*((int)image(x0,y1)[1]));
00268 image(x0,y1)[2] = (unsigned char)((1.0-val)*((int)b)) + (unsigned char)(val*((int)image(x0,y1)[2]));
00269 }
00270
00271 if(x0>=0 && x0<(int)image.width() && y2>=0 && y2<(int)image.height()){
00272 image(x0,y2)[0] = (unsigned char)(val*((int)r)) + (unsigned char)((1.0-val)*image(x0,y2)[0]);
00273 image(x0,y2)[1] = (unsigned char)(val*((int)g)) + (unsigned char)((1.0-val)*image(x0,y2)[1]);
00274 image(x0,y2)[2] = (unsigned char)(val*((int)b)) + (unsigned char)((1.0-val)*image(x0,y2)[2]);
00275 }
00276 }
00277
00278
00279 void drawPixel(ImageGS8u &image,
00280 int x0, int y0,
00281 const unsigned char greyLevel){
00282 int y1 = y0 >> 16;
00283 int y2 = y1+1;
00284
00285 double val = static_cast<double>(y0 & 0xFFFF) / static_cast<double> (0xFFFF);
00286
00287 x0 = x0 >> 16;
00288
00289 if(x0>=0 && x0<(int)image.width() && y1>=0 && y1<(int)image.height())
00290 image(x0,y1) = (unsigned char)((1.0-val)*greyLevel);
00291
00292 if(x0>=0 && x0<(int)image.width() && y2>=0 && y2<(int)image.height())
00293 image(x0,y2) = (unsigned char)(val*greyLevel);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 }