mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
101 lines
2.4 KiB
C++
101 lines
2.4 KiB
C++
#include "GeomTest.h"
|
|
|
|
Pointf LineCross(Pointf a, Pointf a1, Pointf b, Pointf b1)
|
|
{
|
|
Pointf A = a1 - a;
|
|
Pointf B = b1 - b;
|
|
double d = A.y * B.x - B.y * A.x;
|
|
if(d == 0)
|
|
return Null;
|
|
double tb = (A.x * (b.y - a.y) + A.y * (a.x - b.x)) / d;
|
|
if(tb <= 0 || tb >= 1)
|
|
return Null;
|
|
double ta = (B.x * tb + b.x - a.x) / A.x;
|
|
return ta > 0 && ta < 1 ? B * tb + b : Null;
|
|
}
|
|
|
|
static int sCrosses(Pointf a, double y0, Pointf b, Pointf b1, double y1)
|
|
{
|
|
double By = b1.y - b.y;
|
|
if(By == 0)
|
|
return (y0 < b.y && b.y < y1 || y0 > b.y && b.y > y1) &&
|
|
(a.y == b.y && a.x < b.x)/* || (a.y == b1.y && a.x < b1.x)*/;
|
|
if(a.y == b.y)
|
|
return (y0 < b.y && b.y < b1.y || y0 > b.y && b.y > b1.y) && b.x > a.x;
|
|
if(a.y == b1.y)
|
|
return 0;
|
|
// return (b.y < b1.y && b1.y < y2 || b.y > b1.y && b1.y > y2) && b1.x > a.x;
|
|
double tb = (a.y - b.y) / By;
|
|
return tb >= 0 && tb < 1 && (b1.x - b.x) * tb + b.x - a.x > 0;
|
|
}
|
|
|
|
|
|
bool InPolygon(Pointf p, const Vector<Pointf>& polygon)
|
|
{
|
|
int q = 0;
|
|
if(polygon.GetCount() < 2)
|
|
return false;
|
|
int n = polygon.GetCount();
|
|
for(int i = 0; i < polygon.GetCount(); i++)
|
|
q += sCrosses(p, polygon[(i + n - 1) % n].y, polygon[i], polygon[(i + 1) % n], polygon[(i + 2) % n].y);
|
|
return q & 1;
|
|
}
|
|
|
|
void GeomTest::LeftDown(Point p, dword flags)
|
|
{
|
|
p = 4 * p / 4;
|
|
if(flags & K_ALT) {
|
|
paintin = !paintin;
|
|
Refresh();
|
|
return;
|
|
}
|
|
if(flags & K_CTRL)
|
|
polygon.Clear();
|
|
polygon.Add(p);
|
|
Refresh();
|
|
}
|
|
|
|
void GeomTest::MouseMove(Point p, dword)
|
|
{
|
|
point = p;
|
|
Refresh();
|
|
}
|
|
|
|
void GeomTest::Paint(Draw& w)
|
|
{
|
|
Size sz = GetSize();
|
|
w.DrawRect(sz, SWhite);
|
|
if(polygon.GetCount() == 0)
|
|
return;
|
|
if(polygon.GetCount() == 1) {
|
|
w.DrawRect((int)polygon[0].x, (int)polygon[0].y, 1, 1, SBlack);
|
|
return;
|
|
}
|
|
for(int i = 0; i < polygon.GetCount() - 1; i++)
|
|
w.DrawLine(polygon[i], polygon[i + 1]);
|
|
w.DrawLine(polygon[i], polygon[0]);
|
|
// if(paintin)
|
|
for(int i = 0; i < polygon.GetCount(); i++) {
|
|
int y = polygon[i].y;
|
|
for(int x = 0; x < sz.cx; x++)
|
|
if(InPolygon(Pointf(x, y), polygon))
|
|
w.DrawRect(x, y, 1, 1, SLtCyan);
|
|
}
|
|
if(InPolygon(point, polygon))
|
|
w.DrawText(0, 0, "IN", Arial(20).Bold());
|
|
}
|
|
|
|
GeomTest::GeomTest()
|
|
{
|
|
BackPaint();
|
|
paintin = false;
|
|
polygon.Add(Pointf(100, 100));
|
|
polygon.Add(Pointf(200, 100));
|
|
polygon.Add(Pointf(150, 150));
|
|
polygon.Add(Pointf(250, 150));
|
|
}
|
|
|
|
GUI_APP_MAIN
|
|
{
|
|
GeomTest().Run();
|
|
}
|