Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LAB1_B3 / Unit1

.cpp
Скачиваний:
14
Добавлен:
01.02.2019
Размер:
7.98 Кб
Скачать
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "math.h"
#include "ctime"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	srand(time(0));
	Timer1->Enabled = false;
	Timer1->Interval = 1000 / 120;
	iter = 120;
	gAngle = 0;
	gsX = gsY = 1;
	gdX = gdY = 0;
	EsX->Text = FloatToStr(gsX);
	EsY->Text = FloatToStr(gsY);
	EAngle->Text = FloatToStr(gAngle);
	EdX->Text = FloatToStr(gdX);
	EdY->Text = FloatToStr(gdY);
	for(int i = 0; i < 40; i++)
		points[i].Set(rand() % Image1->Width - Image1->Width / 2, rand() % Image1->Height - Image1->Height / 2);
	Refresh();
}

void TForm1::Refresh() {
	Image1->Canvas->Brush->Color = clWhite;
	Image1->Canvas->FillRect(Form1->Image1->Canvas->ClipRect);
	Image1->Canvas->Pen->Color = clSilver;
	Image1->Canvas->Rectangle(0, 0, Image1->Width, Image1->Height);
	DrawGrid();
	DrawAxes();
	trigon.Draw();
	CheckPoints();
	DrawPoints();
	Image1->Refresh();
}

int TForm1::round(double n) {
	return ((int) n % 2 ? (n - (int) n < 0.5 ? (int) n : (int) n + 1) : (n - (int) n > 0.5 ? (int) n + 1 : (int) n));
}

bool TForm1::pnpoly(point p[3], double x, double y) {
	bool c = false;
	for (int i = 0, j = 2; i < 3; j = i++)
	{
		if ((((p[i].ry <=y) && (y < p[j].ry)) || ((p[j].ry <= y) && (y < p[i].ry))) &&
			(x > (p[j].rx - p[i].rx) * (y - p[i].ry) / (p[j].ry - p[i].ry) + p[i].rx))
			c = !c;
	}
	return c;
}

void TForm1::DrawGrid() {
	for(int i = 0; i < mid.x; i += 20) {
		Image1->Canvas->MoveTo(mid.x + i, 0);
		Image1->Canvas->LineTo(mid.x + i, Image1->Height);
		Image1->Canvas->MoveTo(mid.x - i, 0);
		Image1->Canvas->LineTo(mid.x - i, Image1->Height);
	}
	for(int i = 0; i < mid.y; i += 20) {
		Image1->Canvas->MoveTo(0, mid.y + i);
		Image1->Canvas->LineTo(Image1->Width, mid.y + i);
		Image1->Canvas->MoveTo(0, mid.y - i);
		Image1->Canvas->LineTo(Image1->Width, mid.y - i);
	}
}

void TForm1::DrawAxes() {
	Image1->Canvas->Pen->Color = clBlack;
	Image1->Canvas->MoveTo(0, mid.y);
	Image1->Canvas->LineTo(mid.x * 2, mid.y);
	Image1->Canvas->MoveTo(mid.x, 0);
	Image1->Canvas->LineTo(mid.x, mid.y * 2);
}

void TForm1::CheckPoints() {
	for (int i = 0; i < 40; i++) {
		if(pnpoly(trigon.vertex, points[i].rx, points[i].ry))
			points[i].color = clBlack;
		else
			points[i].color = clWhite;
	}
}

void TForm1::DrawPoints() {
	for (int i = 0; i < 40; i++)
		points[i].Draw();
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	if(!Timer1->Enabled && (cScale->Checked || cRotate->Checked || cOffset->Checked)) Timer1->Enabled = true;
}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	static bool check = false;
	if (iter < 120) {
		iter++;
		if (check) cOffset->Checked = false;
		trigon.Transformation(gdX, gdY, 1 / (1 + gsX * (iter - 1)), 1 / (1 + gsY * (iter - 1)), 0);
		if (check) cOffset->Checked = true;
		trigon.Transformation(gdX, gdY, 1 + gsX * iter, 1 + gsY * iter, gAngle);
		Refresh();
		if(iter == 120) {
			Timer1->Enabled = false;
			check = false;
		}
	}
	else {
		iter = 0;
		gdX = StrToFloat(EdX->Text);
		gdY = StrToFloat(EdY->Text);
		if(cOffset->Checked) check = true;
		if(cScale->Checked) {
			gsX = (StrToFloat(EsX->Text) - 1) / 120;
			gsY = (StrToFloat(EsY->Text) - 1) / 120;
		}
		else gsX = gsY = 0;
		if(cRotate->Checked) gAngle = StrToFloat(EAngle->Text) / 120;
		else gAngle = 0;

	}
}

// Class point
point::point() {
	rx = 0;
	ry = 0;
	x = Form1->round(Form1->Image1->Width / 2);
	y = Form1->round(Form1->Image1->Height / 2);
}

void point::Set(double rx_, double ry_) {
	rx = rx_;
	ry = ry_;
	x = Form1->round(rx + Form1->mid.x);
	y = Form1->round(-ry + Form1->mid.y);
}

void point::Draw() {
	Form1->Image1->Canvas->Brush->Color = color;
	Form1->Image1->Canvas->Pen->Color = clBlack;
	Form1->Image1->Canvas->Ellipse(x - 2, y - 2, x + 2, y + 2);
}

void point::Transformation(double dX, double dY, double sX, double sY, double angle) {
	matrix
		matrixPoint(1, 3),
		matrixOffset(3, 3),
		matrixScale(3, 3),
		matrixRotate(3, 3),
		matrixOffsetP(3, 3),
		matrixOffsetPB(3, 3);
	matrixPoint.values[0][0] = this->rx; matrixPoint.values[0][1] = this->ry; matrixPoint.values[0][2] = 1;
	// Offset to Point
	matrixOffsetP.values[0][0] = 1;   matrixOffsetP.values[0][1] = 0; 	matrixOffsetP.values[0][2] = 0;
	matrixOffsetP.values[1][0] = 0;   matrixOffsetP.values[1][1] = 1; 	matrixOffsetP.values[1][2] = 0;
	matrixOffsetP.values[2][0] = -dX; matrixOffsetP.values[2][1] = -dY; matrixOffsetP.values[2][2] = 1;
	// Rotate
	matrixRotate.values[0][0] = cos(angle);   matrixRotate.values[0][1] = sin(angle);  matrixRotate.values[0][2] = 0;
	matrixRotate.values[1][0] = -sin(angle);  matrixRotate.values[1][1] = cos(angle);  matrixRotate.values[1][2] = 0;
	matrixRotate.values[2][0] = 0;  		  matrixRotate.values[2][1] = 0; 		   matrixRotate.values[2][2] = 1;
	// Scale
	matrixScale.values[0][0] = sX;   matrixScale.values[0][1] = 0;  matrixScale.values[0][2] = 0;
	matrixScale.values[1][0] = 0;    matrixScale.values[1][1] = sY; matrixScale.values[1][2] = 0;
	matrixScale.values[2][0] = 0;    matrixScale.values[2][1] = 0;  matrixScale.values[2][2] = 1;
	// Offset back
	matrixOffsetPB.values[0][0] = 1;  matrixOffsetPB.values[0][1] = 0; 	matrixOffsetPB.values[0][2] = 0;
	matrixOffsetPB.values[1][0] = 0;  matrixOffsetPB.values[1][1] = 1; 	matrixOffsetPB.values[1][2] = 0;
	matrixOffsetPB.values[2][0] = dX; matrixOffsetPB.values[2][1] = dY; matrixOffsetPB.values[2][2] = 1;
	matrixPoint = matrixPoint * matrixOffsetP * matrixRotate * matrixScale * matrixOffsetPB;
	if(Form1->cOffset->Checked) {
		// Offset
		matrixOffset.values[0][0] = 1;   matrixOffset.values[0][1] = 0; 	matrixOffset.values[0][2] = 0;
		matrixOffset.values[1][0] = 0; 	 matrixOffset.values[1][1] = 1; 	matrixOffset.values[1][2] = 0;
		matrixOffset.values[2][0] = dX / 120;  matrixOffset.values[2][1] = dY / 120; 	matrixOffset.values[2][2] = 1;
		matrixPoint = matrixPoint * matrixOffset;
	}
	this->Set(matrixPoint.values[0][0], matrixPoint.values[0][1]);
}

// Class triangle
triangle::triangle() {
	vertex[0].Set(0, 50);
	vertex[1].Set(-50, -50);
	vertex[2].Set(50, -50);
	side[0].Set(vertex[0], vertex[1]);
	side[1].Set(vertex[1], vertex[2]);
	side[2].Set(vertex[2], vertex[0]);
}

void triangle::Draw() {
	for(int i = 0; i < 3; i++)
		side[i].Draw();
	for(int i = 0; i < 3; i++)
		vertex[i].Draw();
}

void triangle::Transformation(double dX, double dY, double sX, double sY, double angle) {
	for(int i = 0; i < 3; i++)
		vertex[i].Transformation(dX, dY, sX, sY, 3.14159265359 * angle / 180.0);
	side[0].Set(vertex[0], vertex[1]);
	side[1].Set(vertex[1], vertex[2]);
	side[2].Set(vertex[2], vertex[0]);
}

// Class line
void line::Draw() {
	Form1->Image1->Canvas->Pen->Color = clGray;
	Form1->Image1->Canvas->Pen->Width = 2;
	Form1->Image1->Canvas->MoveTo(a.x, a.y);
	Form1->Image1->Canvas->LineTo(b.x, b.y);
	Form1->Image1->Canvas->Pen->Width = 1;
}

void line::FindNorm() {
	norm.x = b.x - a.x;
	norm.y = b.y - a.y;
}

void line::Set(point a_, point b_) {
	a = a_;
	b = b_;
	FindNorm();
}

// Class matrix
matrix::matrix(int rows_, int cols_) {
	rows = rows_;
	cols = cols_;
	for(int i = 0; i < rows; i++)
		for(int j = 0; j < cols; j++)
			values[i][j] = 0;
}

matrix matrix::operator *(matrix m) {
	matrix newMatrix(this->rows, m.cols);
	for(int i = 0; i < this->rows; i++)
		for(int j = 0; j < m.cols; j++)
			for(int k = 0; k < this->cols; k++)
				newMatrix.values[i][j] += this->values[i][k] * m.values[k][j];
	return newMatrix;
}


Соседние файлы в папке LAB1_B3