Commit 65bfea0c authored by Alexey Hohlov's avatar Alexey Hohlov
Browse files

Новые операции над векторами, полигонами и оптимизация.

Добавлено скалярное произведение, более корректное преобразование из
точки в вектор, добавлена процедура проверки нахождения точки внутри
полигона а так же оптимизированы процедуры добавления вершин в полигон,
вращения и перемещения полигонов.
parent 65fdea09
......@@ -55,6 +55,7 @@ class CVector
{
public:
CVector(float nx = 0, float ny = 0, float nz = 0);
CVector(const CPoint& p);
float len();
float dir();
......@@ -80,6 +81,12 @@ public:
CVector& operator*=(const float val);
CVector& operator/=(const float val);
float operator*(const CVector& vec);
float operator*(const CPoint& vec);
void normal();
void normalize(void);
bool operator==(const CVector& vec);
~CVector();
......@@ -93,6 +100,8 @@ private:
CVector _pos;
float _angle;
void translate();
protected:
public:
......@@ -111,6 +120,8 @@ public:
void move(CVector pos);
CVector pos();
bool pointIn(CPoint point);
~CPoly();
};
......
......@@ -126,6 +126,13 @@ CVector::CVector(float nx, float ny, float nz)
z = nz;
}
CVector::CVector(const CPoint &p)
{
x = p.x;
y = p.y;
z = p.z;
}
float CVector::len()
{
return sqrt(x * x + y * y + z * z);
......@@ -235,6 +242,34 @@ bool CVector::operator==(const CVector& vec)
return x == vec.x && y == vec.y && z == vec.z;
}
float CVector::operator *(const CVector& vec)
{
return x * vec.x + y * vec.y;
}
float CVector::operator *(const CPoint& vec)
{
return x * vec.x + y * vec.y;
}
void CVector::normal()
{
float tmp = x;
x = -y;
y = tmp;
normalize();
}
void CVector::normalize()
{
float len = sqrt(x * x + y * y);
x /= len;
y /= len;
}
CVector::~CVector()
{
......@@ -293,49 +328,62 @@ void CPoly::AddVertex(float x, float y)
for (i = 0; i < vertex_count - 1; i++) {
_x = vertex_arr[i].x;
_y = vertex_arr[i].y;
vertex_arr_t[i].x = _x * Cos(_angle) + _y * Sin(_angle) + _pos.x;
vertex_arr_t[i].y = _x * Sin(_angle) - _y * Cos(_angle) + _pos.y;
if (_angle == 0.0f) {
vertex_arr_t[i].x = _x + _pos.x;
vertex_arr_t[i].y = _x + _pos.y;
} else {
vertex_arr_t[i].x = _x * Cos(_angle) + _y * Sin(_angle) + _pos.x;
vertex_arr_t[i].y = _x * Sin(_angle) - _y * Cos(_angle) + _pos.y;
}
}
}
vertex_arr[vertex_count - 1] = point(x, y);
vertex_arr_t[vertex_count - 1].x = x * Cos(_angle) + y * Sin(_angle) + _pos.x;
vertex_arr_t[vertex_count - 1].y = x * Sin(_angle) - y * Cos(_angle) + _pos.y;
if (_angle == 0.0f) {
vertex_arr_t[vertex_count - 1].x = x + _pos.x;
vertex_arr_t[vertex_count - 1].y = x + _pos.y;
} else {
vertex_arr_t[vertex_count - 1].x = x * Cos(_angle) + y * Sin(_angle) + _pos.x;
vertex_arr_t[vertex_count - 1].y = x * Sin(_angle) - y * Cos(_angle) + _pos.y;
}
if (sqrt(x*x + y*y) > radius)
radius = sqrt(x*x + y*y);
}
void CPoly::rotate(float angle)
void CPoly::translate()
{
float x;
float y;
uint32_t i;
_angle = angle;
float x, y;
for (uint8_t i = 0; i < vertex_count; i++) {
for (i = 0; i < vertex_count; i++) {
x = vertex_arr[i].x;
y = vertex_arr[i].y;
vertex_arr_t[i].x = x * Cos(angle) + y * Sin(angle) + _pos.x;
vertex_arr_t[i].y = x * Sin(angle) - y * Cos(angle) + _pos.y;
if (_angle == 0.0f) {
vertex_arr_t[i].x = x + _pos.x;
vertex_arr_t[i].y = x + _pos.y;
} else {
vertex_arr_t[i].x = x * Cos(_angle) + y * Sin(_angle) + _pos.x;
vertex_arr_t[i].y = x * Sin(_angle) - y * Cos(_angle) + _pos.y;
}
}
}
void CPoly::move(CVector pos)
void CPoly::rotate(float angle)
{
float dx, dy;
_angle = angle;
translate();
}
dx = pos.x - _pos.x;
dy = pos.y - _pos.y;
void CPoly::move(CVector pos)
{
_pos = pos;
for (uint8_t i = 0; i < vertex_count; i++) {
vertex_arr_t[i].x += dx;
vertex_arr_t[i].y += dy;
}
translate();
}
CVector CPoly::pos()
......@@ -348,6 +396,76 @@ float CPoly::angle()
return _angle;
}
bool CPoly::pointIn(CPoint point)
{
/*float dist;
uint32_t i;
CVector n;
CVector a;
CVector b;
float d;
CVector p;
p.x = point.x;
p.y = point.y;
p.z = 0.0f;
for (i = 0; i < vertex_count; i++) {
a.x = vertex_arr_t[i].x;
a.y = vertex_arr_t[i].y;
b.x = vertex_arr_t[(i + 1) % vertex_count].x;
b.y = vertex_arr_t[(i + 1) % vertex_count].y;
n = b - a;
n.y = -n.y;
n.z = 0.0f;
//n.normalize();
fprintf(stdout, "n: %g,%g\n", n.x, n.y);
d = n * a;
dist = n * p - d; // ok
std::cout << std::flush;
if (dist > 0.0f) {
return false;
}
}
fprintf(stdout, "point %g,%g in polygon(%g,%g - %g,%g), dist = %g\n", p.x, p.y, vertex_arr_t[i].x, a.y, b.x, b.y, dist);
std::cout << std::flush;
return true;*/
float x1, x2;
float y1, y2;
uint32_t i;
int c = 0;
for (i = 0; i < vertex_count; i++) {
x1 = vertex_arr_t[i].x;
x2 = vertex_arr_t[(i + 1) % vertex_count].x;
y1 = vertex_arr_t[i].y;
y2 = vertex_arr_t[(i + 1) % vertex_count].y;
if ((((y1 <= point.y) && (point.y < y2)) || ((y2 <= point.y) && (point.y < y1))) &&
(point.x > (x2 - x1) * (point.y - y1) / (y2 - y1) + x1)) {
c = !c;
}
}
if (c) {
fprintf(stdout, "point %g,%g in polygon\n", point.x, point.y);
std::cout << std::flush;
}
return c;
}
CPoly::~CPoly()
{
delete [] vertex_arr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment