Переделать из stl в rtl

277
24 ноября 2017, 07:32

Всем доброго дня, необходимо было написать программу разрезания многоугольника прямой, дело сделано. Правда использовал библиотеку шаблонов stl, а это оказывается недопустимо в данном задании, как максимально просто перевести это дело на rtl? Код прикладываю:

class point
{
public:
    double x, y;
    int i;
    point(double _x, double _y)
    {
        x = _x;
        y = _y;
    }
    point()
    {
        point(0, 0);
    }
};
// Прямая
class line
{
public:
    double a, b, c;
    //ax + by + c = 0
    line(double _a = 0, double _b = 0, double _c = 0)
    {
        a = _a;
        b = _b;
        c = _c;
    }
};
class polygon
{
public:
    size_t size_polygon;
    vector<point> polygon_;

    //сам многоугольник, и его размер ( вершины )
    polygon(vector<point> _polygon_, size_t size_polygon_)
    {
        polygon_ = _polygon_;
        size_polygon = size_polygon_;
    }
};
// лежит ли точка в прямоугольнике, который образуют заданные точки
bool point_in_box(point t, point p1, point p2)
{
    return  (abs(t.x - min(p1.x, p2.x)) <= eps || min(p1.x, p2.x) <= t.x) &&
        (abs(max(p1.x, p2.x) - t.x) <= eps || max(p1.x, p2.x) >= t.x) &&
        (abs(t.y - min(p1.y, p2.y)) <= eps || min(p1.y, p2.y) <= t.y) &&
        (abs(max(p1.y, p2.y) - t.y) <= eps || max(p1.y, p2.y) >= t.y);
}
// уравнение прямой, проходящей через две точки
line toline(point p1, point p2)
{
    double a = p2.y - p1.y;
    double b = p1.x - p2.x;
    return line(a, b, -a * p1.x - b * p1.y);
}
// знак точки при подставлении в уравнение прямой
int point_in_line(line l, point p)
{
    double s = l.a * p.x + l.b * p.y + l.c;
    return s < -eps ? -1 : s > eps ? 1 : 0;
}
// параллельны ли прямые?
bool is_parallel_line(line l1, line l2)
{
    return abs(l1.a * l2.b - l2.a * l1.b) <= eps;
}
// совпадают ли прямые?
bool is_equal_line(line l1, line l2)
{
    return (abs(l1.a * l2.b - l2.a * l1.b) <= eps &&abs(l1.a * l2.c - l2.a * l1.c) <= eps && abs(l1.b * l2.c - l2.b * l1.c) <= eps);
}
// пересечение двух прямых
int cross_line(line l1, line l2, point &p)
{
    if (is_equal_line(l1, l2)) return 2;
    if (is_parallel_line(l1, l2)) return 0;
    p.x = (l2.b * l1.c - l1.b * l2.c) / (l2.a * l1.b - l1.a * l2.b);
    p.y = (l1.b != 0 ? (-l1.c - l1.a * p.x) / l1.b : (-l2.c - l2.a * p.x) / l2.b);
    return 1;
}

// пересекаются ли отрезки?
bool is_cross_segment(point p1, point p2, point p3, point p4)
{
    line l1 = toline(p1, p2);
    line l2 = toline(p3, p4);
    int sign1 = point_in_line(l1, p3) * point_in_line(l1, p4);
    int sign2 = point_in_line(l2, p1) * point_in_line(l2, p2);
    if (abs(sign1) <= eps && abs(sign2) <= eps)
        return point_in_box(p1, p3, p4) || point_in_box(p2, p3, p4) ||
        point_in_box(p3, p1, p2) || point_in_box(p4, p1, p2);
    return sign1 <= eps && sign2 <= eps;
}
// пересечение отрезков
bool cross_segment(point p1, point p2, point p3, point p4, point &t)
{
    // Строим прямые проходящие через эти отрезки и пересекаем их
    line l1 = toline(p1, p2);
    line l2 = toline(p3, p4);
    int flag = cross_line(l1, l2, t);
    if (flag == 0) return false;
    // Если прямые совпадают, проверяем каждый конец отрезка на принадлежность другому отрезку
    if (flag == 2)
    {
        if (point_in_box(p1, p3, p4)) { t = p1; return true; }
        if (point_in_box(p2, p3, p4)) { t = p2; return true; }
        if (point_in_box(p3, p1, p2)) { t = p3; return true; }
        if (point_in_box(p4, p1, p2)) { t = p4; return true; }
        return false;
    }
    // Если прямые пересекаются, проверяем принадлежит ли точка пересечения обоим отрезкам
    return point_in_box(t, p1, p2) && point_in_box(t, p3, p4);
}
// пересечение отрезка с прямой
int cross_segment_line(point p1, point p2, line l, point &p)
{
    line t = toline(p1, p2);
    int flag = cross_line(l, t, p);
    if (flag == 0) return 0;
    if (flag == 2) return 2;
    if (point_in_box(p, p1, p2)) return 1;
    return 0;
}
double area_triangle(point a, point b, point c)
{
    return 0.5 * (a.x * b.y + b.x * c.y + c.x * a.y - a.y * b.x - b.y * c.x - c.y * a.x);
}
//Лежит ли точка справа от отрезка в обходе против часовой стрелки?
bool ccw(point a, point b, point c)
{
    return area_triangle(a, b, c) > eps;
}

// выпуклый ли многоугольник?
bool is_convex(vector < point > p)
{
    int l, i, r;
    int n = p.size();
    bool isccw = ccw(p[n - 1], p[0], p[1]);
    for (i = 1; i < n; ++i)
    {
        l = (i - 1 + n) % n;
        r = (i + 1) % n;
        if (ccw(p[l], p[i], p[r]) != isccw)
            return false;
    }
    return true;
}
// расположение многоугольника отосительно прямой
//        1 - находится с положительной стороны
//        - 1 - находится с отрицательной стороны
//        0 - прямая пересекает одну из сторон многоугольника (сторону а не вершину)
int polygon_for_line(vector < point > p, line l)
{
    int i, j;
    int s = -2; // знак
    for (i = 0; i < p.size(); ++i)
    {
        int t = point_in_line(l, p[i]); // положение вершины относительно прямой
        if (t != 0)        // если точка не принадлежить прямой
            if (s != -2)     // если s мы вычислили
                if (t != s)        // если знаки различны, то прямая пересекает сторону многоугольника
                    return 0;
                else
                {
                }
            else
                s = t; // если s мы ещё не вычислили, присваиваем ему вычисленное значение
    }
    if (s == -2) return 0;
    return s;
}
// разрезание многоугольника по диагонали
void cut_polygon_for_edge(vector < point > p, int i1, int i2, vector < point > &p1, vector < point > &p2)
{
    int i;
    int n = p.size();
    for (i = i1; i != (i2 + 1) % n; i = (i + 1) % n)
        p1.push_back(p[i]);
    for (i = i2; i != (i1 + 1) % n; i = (i + 1) % n)
        p2.push_back(p[i]);
}
// разрезание выпуклого многоугольника по прямой
//        функция возвращает два многоугольника
//        первый многоугольник лежит с положительной стороны от прямой
//        второй - с отрицательной
void cut_convex_for_line(vector < point > p, line l, vector < point > &v1, vector < point > &v2, point &p1, point &p2)
{
    int n = p.size();
    int i, j;
    // находим точки пересечение прямой с многоугольником и вставляем их в многоугольник
    int c = 0; // счётчик пересечений многоугольника с прямой
    list < point > s(p.begin(), p.end()); // представляем многоугольник как список вершин
    list < point > ::iterator it, jt; // итераторы обходы
    list < point > ::iterator i1, i2; // итераторы вставленных точек
    for (it = s.begin(); it != s.end(); ++it)
    {
        jt = it;
        ++jt;
        if (jt == s.end()) jt = s.begin();
        // пересекаем прямую со стороной
        point t;
        int flag = cross_segment_line(*it, *jt, l, t);
        // если прямая проходит по стороне
        if (flag == 2)
        {
            if (polygon_for_line(p, l) > 0)    v1 = p;
            else    v2 = p;
            return;
        }
        // если прямая и сторона не пересекаются
        if (flag == 0) continue;
        // если прямая проходит через вершину многоугольника
        if (abs(t.x - (*it).x) <= eps && abs(t.y - (*it).y) <= eps)
        {
            if (c == 0) i1 = it;
            else i2 = it;
            ++c;
            continue;
        }
        if (abs(t.x - (*jt).x) <= eps && abs(t.y - (*jt).y) <= eps) continue;
        // иначе прямая пересекает сторону, вставляем точку пересечения в многоугольник
        ++it;
        it = s.insert(it, t);
        // увеличиваем счётчик пересечений многоугольника с прямой
        if (c == 0) i1 = it;
        else i2 = it;
        ++c;
    }
    // если прямая не пересекает многоугольник
    if (c != 2)
    {
        if (polygon_for_line(p, l) > 0)    v1 = p;
        else    v2 = p;
        return;
    }
    // представляем многоугольник массивом точек
    n = s.size();
    vector < point > all(s.begin(), s.end());
    int j1, j2;
    for (it = s.begin(), i = 0; it != s.end(); ++i, ++it)
    {
        if (it == i1) j1 = i;
        if (it == i2) j2 = i;
    }
    // режем многоугольник
    p1 = all[j1];
    p2 = all[j2];
    cut_polygon_for_edge(all, j1, j2, v1, v2);
    // если многоугольники имеют не то расположение которое нам требуется - меняем их местами
    if (polygon_for_line(v1, l) < 0)
        swap(v1, v2);
}

P.S. Видимо стоит переделывать все использованные вектора под дин. массивы? Если переделываю, то придется использовать их и на месте list ?

READ ALSO
Передача двумерного массива по ссылке С++

Передача двумерного массива по ссылке С++

Есть двумерный массив чиселInt mass[15][20] Нужно передать его в функцию так, чтобы изменение его в функции отражалось в main

219
Изменить код под статичный массив (c++)

Изменить код под статичный массив (c++)

Доброго времени сутокЕсть код, который нужно изменить под статичный массив

245
Проблемы с выводом на русском языке [дубликат]

Проблемы с выводом на русском языке [дубликат]

На данный вопрос уже ответили:

210