#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <unistd.h>
using namespace std;
int wWidth, wHeight;
const double PI = acos(-1.0);
typedef struct
{
int x;
int y;
} Point;
typedef struct
{
float R;
float G;
float B;
} RGB;
typedef struct Edge
{
int ymax;
float x;
float dx;
Edge *nxtEdge;
} Edge;
Edge ET[100];
typedef struct
{
int x1, x2, y1, y2;
float dx;
int id;
} Line;
Line line[10];
bool cmp(Edge i, Edge j){
return i.x <= j.x;
}
void myDraw(float Pos[2], float Length, float theta, RGB rgb)
{
glBegin(GL_LINE_LOOP);
float Short = Length * sin(0.1 * PI) / sin(0.7 * PI);
float beta = 18 + theta;
float p1[2];
glColor3f(rgb.R, rgb.G, rgb.B);
for (int i = 0; i < 5; i++)
{
p1[0] = Length * cos(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0];
p1[1] = Length * sin(i * 2 * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1];
glVertex2fv(p1);
line[(i * 2) % 10].x1 = (int)p1[0], line[(i * 2) % 10].y1 = (int)p1[1];
line[(i * 2 + 9) % 10].x2 = (int)p1[0], line[(i * 2 + 9) % 10].y2 = (int)p1[1];
p1[0] = Short * cos((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[0];
p1[1] = Short * sin((i * 2 + 1) * 0.2 * PI + beta * 3.1415926 / 180.0) + Pos[1];
glVertex2fv(p1);
line[(i * 2) % 10].x2 = (int)p1[0], line[(i * 2) % 10].y2 = (int)p1[1];
line[(i * 2 + 1) % 10].x1 = (int)p1[0], line[(i * 2 + 1) % 10].y1 = (int)p1[1];
}
glEnd();
}
void ETbuild()
{
for (int i = 0; i < 10; i++) {
if (line[i].y1 != line[i].y2) {
if (ET[line[i].y1].nxtEdge == NULL) {
Edge *tmp = new Edge();
tmp -> ymax = line[i].y2;
tmp -> x = line[i].x1;
tmp -> dx = line[i].dx;
ET[line[i].y1].nxtEdge = tmp;
}
else {
Edge *tmpl = ET[line[i].y1].nxtEdge;
while (tmpl -> nxtEdge != NULL) {
tmpl = tmpl -> nxtEdge;
}
Edge *tmp = new Edge();
tmp -> ymax = line[i].y2;
tmp -> x = line[i].x1;
tmp -> dx = line[i].dx;
tmp -> nxtEdge = NULL;
tmpl -> nxtEdge = tmp;
}
}
else {
glLineWidth(5);
glColor3f(0, 0, 1);
glBegin(GL_LINES);
glVertex2f(line[i].x1, line[i].y1);
glVertex2f(line[i].x2, line[i].y2);
glEnd();
}
}
}
void lineScanFill() {
Edge *edge = new Edge();
for (int i = 0; i < 100; i++)
{
Edge *tmp = ET[i].nxtEdge;
if (tmp != NULL) {
Edge *tmpa = edge;
while (tmpa -> nxtEdge != NULL) {
tmpa = tmpa -> nxtEdge;
}
tmpa -> nxtEdge = tmp;
}
Edge *tmpb = edge;
int flag = 0;
while (tmpb -> nxtEdge != NULL) {
while (i >= (tmpb -> nxtEdge -> ymax)) {
if (tmpb -> nxtEdge -> nxtEdge != NULL)
tmpb -> nxtEdge = tmpb -> nxtEdge -> nxtEdge;
else {
tmpb -> nxtEdge = NULL;
flag = 1;
break;
}
}
if(flag) break;
tmpb = tmpb -> nxtEdge;
}
Edge nedge[10];
int idx = 0;
Edge *tmpc = edge;
while (tmpc -> nxtEdge != NULL) {
nedge[idx].ymax = tmpc -> nxtEdge -> ymax;
nedge[idx].x = tmpc -> nxtEdge -> x;
nedge[idx].dx = tmpc -> nxtEdge -> dx;
idx++;
tmpc = tmpc -> nxtEdge;
}
cout << "idx " << idx << endl;
if(idx % 2 == 1) continue;
sort(nedge, nedge + idx, cmp);
for(int j = 0; j < idx; j += 2){
cout << "hello" << endl;
glLineWidth(5);
glColor3f(0, 0, 1);
glBegin(GL_LINES);
glVertex2f(nedge[j].x, i);
glVertex2f(nedge[j + 1].x, i);
glEnd();
cout << nedge[j].x << " " << nedge[j + 1].x << " ";
}
cout << endl;
Edge *tmpd = edge;
while(tmpd -> nxtEdge != NULL){
tmpd -> nxtEdge -> x = tmpd -> nxtEdge -> x + tmpd -> nxtEdge -> dx;
tmpd = tmpd -> nxtEdge;
}
}
}
void swap(int &x, int &y) {
int tmp = x; x = y; y = tmp;
}
void swapLine() {
for (int i = 0; i < 10; i++) {
if (line[i].y1 > line[i].y2)
{
swap(line[i].x1, line[i].x2);
swap(line[i].y1, line[i].y2);
}
line[i].dx = (line[i].x1 - line[i].x2) * 1.0 / (line[i].y1 - line[i].y2);
line[i].id = i;
}
}
void display()
{
glClearColor(0, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
float pCenter[] = {50.0, 50.0};
RGB rgb = {1, 0, 0};
myDraw(pCenter, 25.0, 0, rgb);
swapLine();
ETbuild();
lineScanFill();
glFlush();
}
void myReshape(GLsizei w, GLsizei h)
{
wWidth = w; wHeight = h;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D(0, w / 5, 0, h / 5);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glViewport (0, 0, w, h);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(300, 300);
glutInitWindowSize(500, 500);
glutCreateWindow("example");
gluOrtho2D(0, 100, 0, 100);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutMainLoop();
return 0;
}