Vyplňování oblastí

InvertFill

student.cpp

///////////////////////////////////////////////////////////////////////////////
// Soubor studentskych funkci
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
// include
 
#include "main.h"
 
#include <assert.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <math.h>
 
///////////////////////////////////////////////////////////////////////////////
// name spaces
 
using namespace std;
 
///////////////////////////// UDELAT VE CVICENI ///////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
// seminkove vyplnovani
// x, y - souradnice pocatecniho bodu/seminka
// color - vyplnovaci barva
void FloodFill(int x, int y, const S_RGBA & color)
{
	// Zde zanechte vas kod
}
 
///////////////////////////////// DOMACI UKOL /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// radkove vyplnovani
// points - vektor vrcholu oblast, posledni hranice je z posledniho do prvniho bodu.
// color - barva hranic
 
void InvertEdge(int x1, int y1, int x2, int y2) {
	if (x1 == x2) {
		return;
	}
	bool steep = abs(y1 - y2) > abs(x1 - x2);
	if (steep) {
		SWAP(x1, y1);
		SWAP(x2, y2)
	}
	if (x1 > x2) {
		SWAP(x1, x2);
		SWAP(y1, y2);
	}
	int step_y = 1;
	if (y1 > y2) {
		step_y = -1;
	}
	int dx = abs(x2 - x1);
	int dy = abs(y2 - y1);
	int P = 2 * dy - dx;
	int P1 = 2 * dy;
	int P2 = P1 - 2 * dx;
	int y = y1;
	int oldy;
	int oldx;
	if (steep) {
		oldy = y;
		oldx = x1;
	} else {
		oldy = -1;
		oldx = -1;
	}
	for (int x = x1; x < x2; x++) {
		int myx = x;
		int myy = y;
		if (myx < 0) {
			myx = 0;
		}
		if (myx > frame_w) {
			myx = frame_w;
		}
		if (myy < 0) {
			myy = 0;
		}
		if (myy > frame_h) {
			myy = frame_h;
		}
		int linestart;
		if (steep) {
			if (oldy != myy) {
				linestart = myx;
				while (linestart < frame_h) {
					fill_buffer[linestart+frame_h*myy] = !fill_buffer[linestart+frame_h*myy];
					linestart++;
					}
			}
		} else {
			if (oldx != myx) {
				linestart = myy;
				while (linestart < frame_h) {
					fill_buffer[linestart+frame_h*myx] = !fill_buffer[linestart+frame_h*myx];
					linestart++;
				}
			}
		}
		oldy = myy;
		oldx = myx;
		if (P >= 0) {
			P += P2;
			y += step_y;
		} else {
			P += P1;
		}
	}
}
 
void InvertFill(const SeedStack & points, const S_RGBA & color)
{
	if (points.size() == 0) {
		return;
	}
	/* Stencil init */
	for (int w = 0; w < frame_w; w++) {
		for (int h = 0; h < frame_h; h++) {
			fill_buffer[frame_w * w + h] = false;
		}
	}
 
	/* Fill stencil */
	for (unsigned int i = 0; i < points.size() - 1; i++) {
		InvertEdge(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y);
	}
	InvertEdge(points.front().x, points.front().y, points.back().x, points.back().y);
 
	/* Draw stencil */
	for (int w = 0; w < frame_w; w++) {
		for (int h = 0; h < frame_h; h++) {
			if (fill_buffer[frame_w * w + h] == true) {
				PutPixel(w, h, tile_buffer[(h % tile_h) * tile_w + (w % tile_w)]);
			}
		}
	}
 
	/* Draw edges */
	for (unsigned int i = 0; i < points.size() - 1; i++) {
		Bresenham(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y, color);
	}
	Bresenham(points.front().x, points.front().y, points.back().x, points.back().y, color);
}