#include "stdafx.h"
#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
#include <glut.h>
#define N 11
GLint Width = 1000, Height = 700;
int n, n1; //количество точек
long time0; int delay = 1;
int l = 50;// размер клетки
int r = l / 5;//размер точки
int x, y, xl, xr, ynn, yv;//координаты;
float XS, YS; float px, py; float sx, sy, s1y, s1x;
int s; // строка
int massivx[N];
int massivy[N];
int *es = new int[n];
int zakrasit;//переменная для выбора функции закраски
int EST = 1, rebro = -1; //EST - для определения,внутри многоугольника или снаружи.
void obnulES() {
for (int i = 0; i < n1; i++)
es[i] = 0;
}
void writedata() {
int e = 0;
while (n > 0) {
cout << "Введите координаты x и y" << endl;
cin >> x;
x = x*l;
cin >> y;
y = y*l;
n--;
massivx[e] = x;
massivy[e] = y;
e++;
}
obnulES();
xl = massivx[0];
xr = massivx[0];
yv = massivy[0];
ynn = massivy[0];
for (int j = 1; j < n1; j++) {
if (massivx[j] < xl)
xl = massivx[j];
if (massivx[j]>xr)
xr = massivx[j];
if (massivy[j]>yv)
yv = massivy[j];
if (massivy[j] < ynn)
ynn = massivy[j];
}
massivx[n1] = massivx[0];
massivy[n1] = massivy[0];
}
void setka() { //сетка
for (int a = -Width / 2; a <= Width / 2; a++) {
if (a % l == 0) {
glColor3ub(255, 255, 255);
glBegin(GL_LINE_LOOP);
glVertex2f(a, Height / 2);
glVertex2f(a, -Height / 2);
glEnd();
}
}
for (int b = -Height / 2; b <= Height / 2; b++) {
if (b % l == 0) {
glColor3ub(255, 255, 255);
glBegin(GL_LINE_LOOP);
glVertex2f(-Width / 2, b);
glVertex2f(Width / 2, b);
glEnd();
}
}
glColor3ub(0, 255, 0);
glBegin(GL_LINE_LOOP);
glVertex2f(-Width / 2, 0);
glVertex2f(Width / 2, 0);
glEnd();
glColor3ub(0, 255, 0);
glBegin(GL_LINE_LOOP);
glVertex2f(0, -Height / 2);
glVertex2f(0, Height / 2);
glEnd();
glFlush();
}
void drawCircle(float x, float y, float r, int amountSegments) {
glColor3ub(0, 0, 255);
glBegin(GL_POLYGON);
for (int i = 0; i < amountSegments; i++) {
float angle = 2.0 * 3.1415926 * float(i) / float(amountSegments);
float dx = r * cosf(angle);
float dy = r * sinf(angle);
glVertex2f(x + dx, y + dy);
}
glEnd();
}
void mnog() { //построить многоугольник
for (int j = 0; j < n1; j++) {
drawCircle(massivx[j], massivy[j], r, 100);
glBegin(GL_LINE_LOOP);
glVertex2f(massivx[j], massivy[j]);
glVertex2f(massivx[j + 1], massivy[j + 1]);
glEnd();
}
}
void opredelit(int b) { //определяет приращение для каждого ребра многоугольника
px = massivx[b + 1] - massivx[b];
py = massivy[b + 1] - massivy[b];
if (abs(px) >= abs(py)) {
px = abs(px);
YS = py / px;
if (massivx[b] < massivx[b + 1])
XS = 1;
else XS = -1;
}
else {
if (massivy[b] < massivy[b + 1])
YS = 1;
else YS = -1;
py = abs(py);
XS = px / py;
}
sx = massivx[b];
sy = massivy[b];
}
void zakras(int v, int m) { //возрастает по X и по Y (быстрее по икс)
if (EST > 0)
{
if (v <= sx && sx < v + l && s < sy && sy < s + l)
{
if (es[m] == 0) goto label;
glColor3ub(255, 0, 0);
glBegin(GL_QUADS);
glVertex2f(v, s);
glVertex2f(v, s + l);
glVertex2f(v + l, s + l);
glVertex2f(v + l, s);
glEnd();
glFlush();
es[m]--;
rebro = 1;
if (es[m] == 0)
EST = -EST;
label:;
}
}
else
{
if (v < sx && sx <= v + l && s < sy && sy < s + l)
{
glColor3ub(255, 0, 0);
glBegin(GL_QUADS);
glVertex2f(v, s);
glVertex2f(v, s + l);
glVertex2f(v + l, s + l);
glVertex2f(v + l, s);
glEnd();
glFlush();
es[m]--;
rebro = 1;
if (es[m] == 0)
EST = -EST;
}
}
}
void Function(int v, int m) {
if (YS >= 0) {
if (XS >= 0) {
if (abs(px) >= abs(py))
while (sx < massivx[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
else
while (sy < massivy[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
}
else {
if (abs(px) >= abs(py))
while (sx >= massivx[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
else
while (sy < massivy[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
}
}
else {
if (XS >= 0) {
if (abs(px) >= abs(py))
while (sx < massivx[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
else
while (sy > massivy[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
}
else {
if (abs(px) >= abs(py))
while (sx >= massivx[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
else
while (sy > massivy[m + 1]) {
zakras(v, m);
if (rebro>0) goto label;
sx += XS;
sy += YS;
}
}
}
label:;
}
void kolvoreber() {
for (int m = 0; m < n1; m++) {
opredelit(m);
for (int i = xl; i < xr; i += l) {
sy = massivy[m];
sx = massivx[m];
rebro = -1;
if (YS >= 0) {
if (XS >= 0) {
if (abs(px) >= abs(py))
while (sx < massivx[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
else
while (sy < massivy[m + 1]) {
if (i <= sx && sx < i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
}
else {
if (abs(px) >= abs(py))
while (sx >= massivx[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
else
while (sy < massivy[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
}
}
else {
if (XS >= 0) {
if (abs(px) >= abs(py))
while (sx < massivx[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
else
while (sy > massivy[m + 1]) {
if (i <= sx && sx < i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
}
else {
if (abs(px) >= abs(py))
while (sx >= massivx[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
else
while (sy > massivy[m + 1]) {
if (i <= sx && sx <= i + l && s < sy && sy < s + l)
rebro = 1;
if (rebro > 0) {
es[m]++;
goto label;
}
sx += XS;
sy += YS;
}
}
}
label:;
}
}
rebro = -1;
}
void hard(int v) {
for (int m = 0; m < n1; m++) { //для каждого ребра
opredelit(m);
Function(v, m);
rebro = -1;
}
}
void strok() { //проверка для строки
EST = 1;
int k = 0;
cout << "Введите строку" << endl;
cin >> s;
s = s*l;
if (s > 0)
s -= l;
if (s >= ynn && s < yv)
k = 1;
if (k == 1) {
obnulES();
kolvoreber();
for (int i = xl; i < xr; i += l) {
hard(i);
if (EST < 0) {
glColor3ub(255, 0, 0);
glBegin(GL_QUADS);
glVertex2f(i, s);
glVertex2f(i, s + l);
glVertex2f(i + l, s + l);
glVertex2f(i + l, s);
glEnd();
glFlush();
}
}
}
}
void Display(void) {
cout << "Введите 1, чтобы нарисовать сетку" << endl;
cout << "Введите 2, чтобы построить многоугольник" << endl;
cout << "Введите 3, чтобы проверить очередную строку" << endl;
cout << "Введите 4, чтобы очистить экран" << endl;
cout << "Введите 5, чтобы удалить массивы x и y" << endl;
cin >> zakrasit;
switch (zakrasit) {
case 1:
setka();
break;
case 2:
mnog();
break;
case 3:
strok();
break;
case 4:
glClearColor(0, 0, 0, 1); //очистить экран
glClear(GL_COLOR_BUFFER_BIT);
break;
case 5:
delete[] massivx;
delete[] massivy;
exit(0);
}
glFlush();
glFinish();
}
void Reshape(GLint w, GLint h) { // окно
Width = w;
Height = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w / 2, w / 2, -h / 2, h / 2, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Keyboard(unsigned char key, int x, int y) { //для выхода из программы
#define ESCAPE '\033'
if (key == ESCAPE)
exit(0);
}
void Idle() {
if (clock() - time0 < delay)
return;
time0 = clock();
glutPostRedisplay();
}
void main(int argc, char *argv[]) {
setlocale(LC_ALL, "Russian");
cout << "Введите количество точек" << endl;
cin >> n;
n1 = n;
writedata();
time0 = clock();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(Width, Height);
glutCreateWindow("Работа 3");
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Keyboard);
glutIdleFunc(Idle);
glutMainLoop();
}