Добавил:
farel
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:LAB1_B3 / Unit1
.cpp//---------------------------------------------------------------------------
#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;
}