Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* DRAWLINE - Line drawing algorithm.
- drawline.c ver1.02 for Digital Mars C by FrozenVoid
- see ->fvdrawline function for implementation
- original content licensed under UFIL1.02 http://pastebin.com/L3p9XK3T
- portions of file are licensed under other licenses(check source of content)
- @..\dmc -gg -Nc -Jm -o+all -o-dv %1.c -o%1.exe
- */
- #include "void.h" //v1.51 http://pastebin.com/qkifnqzq
- u4 pixels[0xffff]={0};
- #define putpixel(x,y,color) px&=0xFFFF;pixels[px++]=x;pixels[px++]=y;pixels[px++]=color; //writes coords+color
- //Reference code from http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%91%D1%80%D0%B5%D0%B7%D0%B5%D0%BD%D1%85%D1%8D%D0%BC%D0%B0#.D0.A0.D0.B5.D0.B0.D0.BB.D0.B8.D0.B7.D0.B0.D1.86.D0.B8.D1.8F_.D0.BD.D0.B0_C.2B.2B
- void refdrawline(int x1, int y1, int x2, int y2,u4 color) {
- const int deltaX = abs(x2 - x1);
- const int deltaY = abs(y2 - y1);
- const int signX = x1 < x2 ? 1 : -1;
- const int signY = y1 < y2 ? 1 : -1;
- u4 col=color;u4 px=0;
- //
- int error = deltaX - deltaY;
- //
- putpixel(x2,y2,col);
- while(x1 != x2 || y1 != y2) {
- putpixel(x1,y1,col);
- const int error2 = error * 2;
- //
- if(error2 > -deltaY) {
- error -= deltaY;
- x1 += signX;
- }
- if(error2 < deltaX) {
- error += deltaX;
- y1 += signY;
- }
- }
- }
- // OPs drawline
- //http://dis.4chan.org/read/prog/1375979965/1
- v0 opdrawline(s4 x,s4 y,s4 a,s4 b,u4 color){
- u4 col=color;u4 px=0;
- f4 x0=x;
- f4 y0=y;
- f4 x1=a;
- f4 y1=b;
- f4 dx = x1-x0;
- f4 dy = y1-y0;
- f4 len = _inline_sqrtf(dx*dx+dy*dy);
- dx /= len;
- dy /= len;
- for (u4 k=0;k<=len;k++){
- putpixel(floorf((x0)),floorf((y0)),col);
- x0 += dx;
- y0 += dy;
- }
- }
- //Union drawline
- //http://hbfs.wordpress.com/2009/07/28/faster-than-bresenhams-algorithm/
- typedef
- union
- {
- int32_t i;
- struct
- {
- int16_t lo; // endian-specific!
- int16_t hi;
- };
- } fixed_point;
- v0 unidrawline(int x1, int y1, int x2, int y2,u4 color){
- int dx=x2-x1;
- int dy=y2-y1;
- int d=2*dy-dx;
- int e=2*dy;
- int ne=2*(dy-dx);
- int x=x1;
- int y=y1;
- u4 col=color;u4 px=0;
- fixed_point f;
- int32_t m=((int32_t)(y2-y1)<<16)/(x2-x1);
- f.i=y1<<16;
- for (x=x1;x<=x2;x++,f.i+=m)
- {
- fixed_point g=f;
- g.i+=32767;
- putpixel(x,g.hi,col);
- }
- }
- //EFLA-E http://www.edepot.com/linee.html
- v0 eflaedrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;
- bool yLonger=false;
- int shortLen=y2-y;
- int longLen=x2-x;
- if (abs(shortLen)>abs(longLen)) {
- int swap=shortLen;
- shortLen=longLen;
- longLen=swap;
- yLonger=true;
- }
- int decInc;
- if (longLen==0) decInc=0;
- else decInc = (shortLen << 16) / longLen;
- if (yLonger) {
- if (longLen>0) {
- longLen+=y;
- for (int j=0x8000+(x<<16);y<=longLen;++y) {
- putpixel(j >> 16,y,col);
- j+=decInc;
- }
- return;
- }
- longLen+=y;
- for (int j=0x8000+(x<<16);y>=longLen;--y) {
- putpixel(j >> 16,y,col);
- j-=decInc;
- }
- return;
- }
- if (longLen>0) {
- longLen+=x;
- for (int j=0x8000+(y<<16);x<=longLen;++x) {
- putpixel(x,j >> 16,col);
- j+=decInc;
- }
- return;
- }
- longLen+=x;
- for (int j=0x8000+(y<<16);x>=longLen;--x) {
- putpixel(x,j >> 16,col);
- j-=decInc;
- }
- }
- //EFLA-D http://www.edepot.com/lined.html
- v0 efladdrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;
- bool yLonger=false;
- int incrementVal, endVal;
- int shortLen=y2-y;
- int longLen=x2-x;
- if (abs(shortLen)>abs(longLen)) {
- int swap=shortLen;
- shortLen=longLen;
- longLen=swap;
- yLonger=true;
- }
- endVal=longLen;
- if (longLen<0) {
- incrementVal=-1;
- longLen=-longLen;
- } else incrementVal=1;
- int decInc;
- if (longLen==0) decInc=0;
- else decInc = (shortLen << 16) / longLen;
- int j=0;
- if (yLonger) {
- for (int i=0;i!=endVal;i+=incrementVal) {
- putpixel(x+(j >> 16),y+i,col);
- j+=decInc;
- }
- } else {
- for (int i=0;i!=endVal;i+=incrementVal) {
- putpixel(x+i,y+(j >> 16),col);
- j+=decInc;
- }
- }
- }
- //EFLA-C http://www.edepot.com/linec.html
- v0 eflacdrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;
- bool yLonger=false;
- int incrementVal, endVal;
- int shortLen=y2-y;
- int longLen=x2-x;
- if (abs(shortLen)>abs(longLen)) {
- int swap=shortLen;
- shortLen=longLen;
- longLen=swap;
- yLonger=true;
- }
- endVal=longLen;
- if (longLen<0) {
- incrementVal=-1;
- longLen=-longLen;
- } else incrementVal=1;
- double decInc;
- if (longLen==0) decInc=(double)shortLen;
- else decInc=((double)shortLen/(double)longLen);
- double j=0.0;
- if (yLonger) {
- for (int i=0;i!=endVal;i+=incrementVal) {
- putpixel(x+(int)j,y+i,col);
- j+=decInc;
- }
- } else {
- for (int i=0;i!=endVal;i+=incrementVal) {
- putpixel(x+i,y+(int)j,col);
- j+=decInc;
- }
- }
- }
- //EFLA-B http://www.edepot.com/lineb.html
- v0 eflabdrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;
- bool yLonger=false;
- int incrementVal;
- int shortLen=y2-y;
- int longLen=x2-x;
- if (abs(shortLen)>abs(longLen)) {
- int swap=shortLen;
- shortLen=longLen;
- longLen=swap;
- yLonger=true;
- }
- if (longLen<0) incrementVal=-1;
- else incrementVal=1;
- double multDiff;
- if (longLen==0.0) multDiff=(double)shortLen;
- else multDiff=(double)shortLen/(double)longLen;
- if (yLonger) {
- for (int i=0;i!=longLen;i+=incrementVal) {
- putpixel(x+(int)((double)i*multDiff),y+i,col);
- }
- } else {
- for (int i=0;i!=longLen;i+=incrementVal) {
- putpixel(x+i,y+(int)((double)i*multDiff),col);
- }
- }
- }
- //EFLA-A http://www.edepot.com/linea.html
- v0 eflaadrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;
- bool yLonger=false;
- int incrementVal;
- int shortLen=y2-y;
- int longLen=x2-x;
- if (abs(shortLen)>abs(longLen)) {
- int swap=shortLen;
- shortLen=longLen;
- longLen=swap;
- yLonger=true;
- }
- if (longLen<0) incrementVal=-1;
- else incrementVal=1;
- double divDiff;
- if (shortLen==0) divDiff=longLen;
- else divDiff=(double)longLen/(double)shortLen;
- if (yLonger) {
- for (int i=0;i!=longLen;i+=incrementVal) {
- putpixel(x+(int)((double)i/divDiff),y+i,col);
- }
- } else {
- for (int i=0;i!=longLen;i+=incrementVal) {
- putpixel(x+i,y+(int)((double)i/divDiff),col);
- }
- }
- }
- //OPT EFLA http://www.simppa.fi/blog/extremely-fast-line-algorithm-as3-optimized/
- v0 optefladrawline(int x, int y, int x2, int y2,u4 color){
- u4 px=0;u4 col=color;int i;
- int shortLen= y2-y;
- int longLen= x2-x;
- bool yLonger;
- if(((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)))
- {
- shortLen ^= longLen;
- longLen ^= shortLen;
- shortLen ^= longLen;
- yLonger= true;
- }
- else
- {
- yLonger = false;
- }
- int inc= longLen < 0 ? -1 : 1;
- double multDiff= longLen == 0 ? shortLen : shortLen / longLen;
- if (yLonger)
- {
- for ( i = 0; i != longLen; i += inc)
- {
- putpixel(x + i*multDiff, y+i, col);
- }
- }
- else
- {
- for (i = 0; i != longLen; i += inc)
- {
- putpixel(x+i, y+i*multDiff, col);
- }
- }
- }
- //peronedrawline http://willperone.net/Code/codeline.php
- void peronedrawline(int x1, int y1, int x2, int y2, int color)
- {u4 px=0;u4 col=color;
- int cx, cy,
- ix, iy,
- dx, dy,
- ddx= x2-x1, ddy= y2-y1;
- if (!ddx) { //vertical line special case
- if (ddy > 0) {
- cy= y1;
- do {putpixel(x1, cy++, col);}
- while (cy <= y2);
- return;
- } else {
- cy= y2;
- do{ putpixel(x1, cy++, col);}
- while (cy <= y1);
- return;
- }
- }
- if (!ddy) { //horizontal line special case
- if (ddx > 0) {
- cx= x1;
- do{ putpixel(cx, y1, col);}
- while (++cx <= x2);
- return;
- } else {
- cx= x2;
- do{ putpixel(cx, y1, col);}
- while (++cx <= x1);
- return;
- }
- }
- if (ddy < 0) { iy= -1; ddy= -ddy; }//pointing up
- else iy= 1;
- if (ddx < 0) { ix= -1; ddx= -ddx; }//pointing left
- else ix= 1;
- dx= dy= ddx*ddy;
- cy= y1, cx= x1;
- if (ddx < ddy) { // < 45 degrees, a tall line
- do {
- dx-=ddy;
- do {
- putpixel(cx, cy, col);
- cy+=iy, dy-=ddx;
- } while (dy >=dx);
- cx+=ix;
- } while (dx > 0);
- } else { // >= 45 degrees, a wide line
- do {
- dy-=ddx;
- do {
- putpixel(cx, cy, col);
- cx+=ix, dx-=ddy;
- } while (dx >=dy);
- cy+=iy;
- } while (dy > 0);
- }
- }
- //Optimized Bresenham algorithm by FrozenVoid
- //based on union drawline
- v0 fvdrawline(u4 x1,u4 y1,u4 x2,u4 y2,u4 color){
- u4 px=0;u4 col=color;
- int dx=x2-x1;
- int dy=y2-y1;
- int d=2*dy-dx;
- int e=2*dy;
- int ne=2*(dy-dx);
- int reg x=x1;
- int y=y1;
- int reg f=0;
- int32_t reg m=((int32_t)(y2-y1)<<16)/(x2-x1);
- f=y1<<16;x=x1;
- for (x=x1;x<=x2;x++,f+=m){putpixel(x,((f+32767)>>16),col);}
- }
- #define tstart exstart=rdtsc();
- #define tend exend=rdtsc();
- #define bench(msg) pr("%s cycles spent:%"PRIu64"\n",#msg,exend-exstart);
- #define func(name) tstart;for(h=0;h<10000;h++)name(x1,y1,x2,y2,color);tend;bench(name);
- STDSTART //benchmarks
- u8 exstart,exend;u4 pixels[0xFFFF]={0};u4 h;
- s4 x1=ru2();
- s4 x2=ru2();
- s4 y1=ru2();
- s4 y2=ru2();
- u4 color=ru4();
- func(refdrawline);
- func(opdrawline);
- func(eflaedrawline);
- func(efladdrawline);
- func(eflacdrawline);
- func(eflabdrawline);
- func(eflaadrawline);
- func(optefladrawline);
- func(peronedrawline);
- func(unidrawline);
- func(fvdrawline);
- //for use with start/REALTIME drawline.exe
- u1 bchar;
- pr("Any key+enter to close");;scanf("%c",&bchar);
- STDEND
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement