//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TPoint MousePointA;
TPoint MousePointB;
TMouseButton MouseBtn;
TBitmap *bitm;
void Redraw();
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
typedef struct TVertex
{
union
{
struct {float x, y;};
float f[2];
};
} * PVertex;
typedef struct TEdge
{
TEdge() {};
TEdge(const float x1, const float y1, const float x2, const float y2)
{v1.x = x1; v1.y = y1; v2.x = x2; v2.y = y2;};
union
{
struct {TVertex v1, v2;};
TVertex v[2];
float f[4];
};
} *PEdge;
TEdge MackRectLine(const PEdge ped)
{
// ______
// | |
// | |
// |......|
//
TEdge ed;
ed.v2.x = ped->v2.x - ped->v1.x;
ed.v2.y = ped->v2.y - ped->v1.y;
ed.v1.x = ped->v1.x - ed.v2.y; // x * cos - y * sin;
ed.v1.y = ped->v1.y + ed.v2.x; // x * sin + y * cos;
ed.v2.x += ed.v1.x;
ed.v2.y += ed.v1.y;
return ed;
};
TVertex MackTriLine(const PEdge ped)
{
//
// /\
// / \
// /....\
//
TVertex v;
v.x = (ped->v2.x + ped->v1.x + ped->v1.y - ped->v2.y) / 2.0f;
v.y = (ped->v2.y + ped->v1.y + ped->v2.x - ped->v1.x) / 2.0f;
return v;
};
TColor ColorScale(const TColor clr, const scale)
{
return ((((clr & 0x000000ff) * scale) / 0xff) & 0xff) |
((((((clr & 0x0000ff00) >> 8) * scale) / 0xff) & 0xff) << 8) |
((((((clr & 0x00ff0000) >> 16) * scale) / 0xff) & 0xff) << 16);
};
TColor ColorLerp(const TColor clr1, const TColor clr2, const scale)
{
return ((((clr1 & 0x000000ff) * scale + (clr2 & 0x000000ff) * (0xff - scale)) / 0xff) & 0xff) |
((((((clr1 & 0x0000ff00) >> 8) * scale + ((clr2 & 0x0000ff00) >> 8) * (0xff - scale)) / 0xff) & 0xff) << 8) |
((((((clr1 & 0x00ff0000) >> 16) * scale + ((clr2 & 0x00ff0000) >> 16) * (0xff - scale)) / 0xff) & 0xff) << 16);
};
void DrawRectAndTriAngle(const PEdge ped, TCanvas *pcanv, int counter = 8,
const int colorstep = 8,
const TColor clrR1 = 0x0000ff00,
const TColor clrR2 = 0x00000000,
const TColor clrT1 = 0x000000ff,
const TColor clrT2 = 0x00000000)
{
if (counter <= 0)
{
return;
};
pcanv->Brush->Style = bsSolid;
TPoint p[5];
TEdge ed = MackRectLine(ped);
p[0] = Point(ed.v2.x, ed.v2.y);
p[1] = Point(ped->v2.x, ped->v2.y);
p[2] = Point(ped->v1.x, ped->v1.y);
p[3] = Point(ed.v1.x, ed.v1.y);
pcanv->Brush->Color = ColorLerp(clrR1, clrR2, (counter * 0xff) / colorstep);
pcanv->Pen->Color = pcanv->Brush->Color;
//pcanv->Polyline(p, 3);
p[4] = p[0];
pcanv->Polygon(p, 4);
p[1] = p[3];
TVertex v = MackTriLine(&ed);
p[2] = Point(v.x, v.y);
p[3] = p[0];
pcanv->Brush->Color = ColorLerp(clrT1, clrT2, (counter * 0xff) / colorstep);
pcanv->Pen->Color = pcanv->Brush->Color;
pcanv->Polygon(p, 4);
//-----------------------
TEdge ed0 = TEdge(ed.v1.x, ed.v1.y, v.x, v.y);
DrawRectAndTriAngle(&ed0, pcanv, counter - 1, colorstep, clrR1, clrR2, clrT1, clrT2);
ed0 = TEdge(v.x, v.y, ed.v2.x, ed.v2.y);
DrawRectAndTriAngle(&ed0, pcanv, counter - 1, colorstep, clrR1, clrR2, clrT1, clrT2);
};
void Redraw()
{
bitm->SetSize(Form1->ClientWidth, Form1->ClientHeight);
bitm->Canvas->Brush->Color = 0x00000000;
bitm->Canvas->Pen->Style = psClear;
bitm->Canvas->Rectangle(0, 0, Form1->ClientWidth, Form1->ClientHeight);
bitm->Canvas->Pen->Style = psSolid;
DrawRectAndTriAngle(
&TEdge(
MousePointA.X,
MousePointA.Y,
MousePointB.X,
MousePointB.Y),
bitm->Canvas, 10, 10,
0x00004080,
0x00008000,
0x0000ffff,
0x0000ff00);
Form1->Canvas->Draw(0, 0, bitm);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MousePointA = MousePointB = Point(Screen->Width / 2, (Screen->Height * 2) / 3);
bitm = new Graphics::TBitmap();
this->WindowState = wsMaximized;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
MouseBtn = Button;
if (MouseBtn == mbLeft)
{
MousePointA = Point(X, Y);
}
else
{
MousePointB = Point(X, Y);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (MouseBtn == mbLeft)
{
MousePointB = Point(X, Y);
}
else
{
MousePointA = Point(X, Y);
}
Redraw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
this->OnMouseUp(Sender, mbLeft, Shift, X, Y);
}
//---------------------------------------------------------------------------