该算法有几个可学习的地方:
(1)正负1思想
(2)对边界条件的处理
(3)数据结构的选择
code:
sweep.h
 #ifndef SWEEP_H
#ifndef SWEEP_H
 #define SWEEP_H
#define SWEEP_H


 struct Edge
struct Edge  {
{
 int nxty;
    int nxty;
 int curx;
    int curx;
 int dx, dy; // 所在扫描线的增量
    int dx, dy; // 所在扫描线的增量
 Edge *nxt;
    Edge *nxt;
 };
};

 //扫描线主算法
//扫描线主算法
 void sweep(int p[][2], int n, void (*setPixel)(int, int));
void sweep(int p[][2], int n, void (*setPixel)(int, int));
 #endif
#endif
sweep.cpp
 #include "sweep.h"
#include "sweep.h"
 #include <algorithm>
#include <algorithm>
 using namespace std;
using namespace std;

 const int MAXN = 1024;
const int MAXN = 1024;

 int cp[MAXN][2], n;
int cp[MAXN][2], n;

 inline bool cmp(int i, int j)
inline bool cmp(int i, int j)  {
{
 return cp[i][1] < cp[j][1] || (cp[i][1] == cp[j][1] && cp[i][0] < cp[j][0]);
    return cp[i][1] < cp[j][1] || (cp[i][1] == cp[j][1] && cp[i][0] < cp[j][0]);
 }
}


 Edge * e[MAXN], *h, *ph, *data;
Edge * e[MAXN], *h, *ph, *data;

 void insert(int ly, int px, int ind)
void insert(int ly, int px, int ind)  {
{
 int y1,y2,y, nxt, pre, flag=0;
    int y1,y2,y, nxt, pre, flag=0;

 nxt = (ind + 1) % n; pre = (ind - 1 + n) % n;
    nxt = (ind + 1) % n; pre = (ind - 1 + n) % n;
 y = cp[ind][1]; y1 = cp[nxt][1]; y2 = cp[pre][1];
    y = cp[ind][1]; y1 = cp[nxt][1]; y2 = cp[pre][1];
 if (y1 > y2) swap(y1, y2);
    if (y1 > y2) swap(y1, y2);

 if (y1 < y && y < y2)
    if (y1 < y && y < y2)  {
{
 //需缩短一个单位
        //需缩短一个单位
 flag = 1;
        flag = 1;
 }
    }

 h = e[ly]; ph=NULL;
    h = e[ly]; ph=NULL;

 while (h)
    while (h)  {
{
 if (h->dy > cp[ind][1] || (h->dy == cp[ind][1] && h->dx > cp[ind][0])) break;
        if (h->dy > cp[ind][1] || (h->dy == cp[ind][1] && h->dx > cp[ind][0])) break;
 ph = h;
        ph = h;
 h = h->nxt;
        h = h->nxt;
 }
    }
 
    
 data = new Edge;
    data = new Edge;
 data->curx = px; data->nxty = cp[ind][1]; data->dx = cp[ind][0] - px; data->dy = cp[ind][1] - ly; data->nxt = NULL;
    data->curx = px; data->nxty = cp[ind][1]; data->dx = cp[ind][0] - px; data->dy = cp[ind][1] - ly; data->nxt = NULL;
 if (flag) data->nxty--;
    if (flag) data->nxty--;


 if (ph)
    if (ph)  {
{    
 data->nxt = ph->nxt;
        data->nxt = ph->nxt;
 ph->nxt = data;
        ph->nxt = data;

 } else
    } else  {
{
 data->nxt = e[ly];
        data->nxt = e[ly];
 e[ly] = data;
        e[ly] = data;
 }
    }
 
    

 }
}

 int ex[MAXN][MAXN], ne[MAXN];
int ex[MAXN][MAXN], ne[MAXN];

 inline int abs(int a)
inline int abs(int a)  {
{
 return a > 0 ? a : -a;
    return a > 0 ? a : -a;
 }
}

 void makepoint(int line, Edge *h)
void makepoint(int line, Edge *h)  {
{
 int dx = h->dx, dy = h->dy, cnt=0;
    int dx = h->dx, dy = h->dy, cnt=0;
 int x, y, flag=1;
    int x, y, flag=1;
 if ((h->dx)*(h->dy)<0) flag=0;
    if ((h->dx)*(h->dy)<0) flag=0;

 for (y=line, x=h->curx; y<=h->nxty; y++)
    for (y=line, x=h->curx; y<=h->nxty; y++)  {
{
 ex[y][ne[y]++] = x;
        ex[y][ne[y]++] = x;
 cnt += 2*abs(dx);
        cnt += 2*abs(dx);

 while (cnt>=2*abs(dy))
        while (cnt>=2*abs(dy))  {
{
 cnt -= 2*abs(dy);
            cnt -= 2*abs(dy);
 if (flag) x++;
            if (flag) x++;
 else x--;
            else x--;
 }
        }
 }
    }
 }
}


 void sweep(int p[][2], int nn, void (*setPixel)(int, int))
void sweep(int p[][2], int nn, void (*setPixel)(int, int))  {
{
 //对所有点按y坐标递增排序,y坐标相等的按x坐标递增排序
    //对所有点按y坐标递增排序,y坐标相等的按x坐标递增排序
 n = nn;
    n = nn;
 int i, j, k, ind, nxt, pre;
    int i, j, k, ind, nxt, pre;
 int *num = new int[n];    //点索引;
    int *num = new int[n];    //点索引;
 for (i=0; i<n; i++) num[i] = i;
    for (i=0; i<n; i++) num[i] = i;
 memcpy(cp, p, sizeof(cp));
    memcpy(cp, p, sizeof(cp));
 sort(num, num+n, cmp);
    sort(num, num+n, cmp);

 //建立有序边表
    //建立有序边表
 memset(e, 0, sizeof(e));
    memset(e, 0, sizeof(e));

 for (i=0; i<n; i++)
    for (i=0; i<n; i++)  {
{
 ind = num[i];
        ind = num[i]; 
 nxt = (ind + 1) % n;
        nxt = (ind + 1) % n; 
 pre = (ind - 1 + n) % n;
        pre = (ind - 1 + n) % n;
 if (p[nxt][1] > p[ind][1]) insert(p[ind][1], p[ind][0], nxt);
        if (p[nxt][1] > p[ind][1]) insert(p[ind][1], p[ind][0], nxt);
 if (p[pre][1] > p[ind][1]) insert(p[ind][1], p[ind][0], pre);
        if (p[pre][1] > p[ind][1]) insert(p[ind][1], p[ind][0], pre);
 }
    }

 //处理active edge list
    //处理active edge list
 memset(ne, 0, sizeof(ne));
    memset(ne, 0, sizeof(ne));

 for (i=0; i<MAXN; i++)
    for (i=0; i<MAXN; i++)  {
{
 h = e[i]; ph = NULL;
        h = e[i]; ph = NULL;


 while (h)
        while (h)  {
{
 makepoint(i, h);
            makepoint(i, h);
 h = h->nxt;
            h = h->nxt;
 }
        }
 sort(ex[i], ex[i]+ne[i]);
        sort(ex[i], ex[i]+ne[i]);
 for (j=0; j<ne[i]; j+=2)
        for (j=0; j<ne[i]; j+=2) 
 for (k=ex[i][j]; k<=ex[i][j+1]; k++)
            for (k=ex[i][j]; k<=ex[i][j+1]; k++)
 setPixel(k,i);
                setPixel(k,i);
 }
    }

 }
}
sweepline.cpp
 #include <stdlib.h>
#include <stdlib.h>
 #include <stdio.h>
#include <stdio.h>
 #include <GL/glut.h>
#include <GL/glut.h>
 #include "sweep.h"
#include "sweep.h"

 void myInit();
void myInit();

 void setPixel(int x, int y);
void setPixel(int x, int y);

 void myDisplay();
void myDisplay();


 int main(int argc, char **argv)
int main(int argc, char **argv)  {
{
 glutInit(&argc, argv);
    glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
 glutInitWindowSize(640, 480);
    glutInitWindowSize(640, 480);
 glutInitWindowPosition (100, 150);
    glutInitWindowPosition (100, 150);
 glutCreateWindow("SweepLine");
    glutCreateWindow("SweepLine");
 glutDisplayFunc(myDisplay);
    glutDisplayFunc(myDisplay);
 myInit();
    myInit();
 glutMainLoop();
    glutMainLoop();
 return 0;
    return 0;
 }
}



 void setPixel(int x, int y)
void setPixel(int x, int y)  {
{
 glBegin(GL_POINTS);
    glBegin(GL_POINTS);
 glVertex2i(x, y);
    glVertex2i(x, y);
 glEnd();
    glEnd();
 }
}


 void myInit()
void myInit()  {
{
 glClearColor(1.0, 1.0, 1.0, 0.0);
    glClearColor(1.0, 1.0, 1.0, 0.0);
 glColor3f(0.0, 0.0, 0.0);
    glColor3f(0.0, 0.0, 0.0);
 glMatrixMode(GL_PROJECTION);
    glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
    glLoadIdentity();
 gluOrtho2D(0.0, 640.0, 0.0, 480.0);
    gluOrtho2D(0.0, 640.0, 0.0, 480.0);
 }
}



 void myDisplay()
void myDisplay()  {
{
 int i, j;
    int i, j;
 glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_COLOR_BUFFER_BIT);
 int p[5][2];
    int p[5][2];
 p[0][0] = 100; p[0][1] = 300;
    p[0][0] = 100; p[0][1] = 300;
 p[1][0] = 200; p[1][1] = 50;
    p[1][0] = 200; p[1][1] = 50;
 p[2][0] = 300; p[2][1] = 100;
    p[2][0] = 300; p[2][1] = 100;
 p[3][0] = 400; p[3][1] = 0;
    p[3][0] = 400; p[3][1] = 0;
 p[4][0] = 350; p[4][1] = 470;
    p[4][0] = 350; p[4][1] = 470;
 sweep(p, 5, setPixel);
    sweep(p, 5, setPixel);
 glFlush();
    glFlush();
 }
}

posted on 2007-10-20 22:33 
豪 阅读(7850) 
评论(3)  编辑 收藏 引用  所属分类: 
计算机图形学