LINUX.ORG.RU

История изменений

Исправление LINUX-ORG-RU, (текущая версия) :

Ну из всего него тебе по надо (учитывая называния темы) только 1 функция point_intersect_line для нахождения пересечения «луча/точки/линии» с линией между двумя точками кривой. Всё остальное просто визуализация. Только у меня всё в координатах экрана и кривые от руки рисуются , а у тебя в своей системе координат и кривые предрасчитанные, но один фиг твои кривые это всё равно точки по которым ты кривые строишь так что чисто нахождение пересечения будет работать с чем угодно оно же float там везде, да и переписать на том на чём пишешь ты можно ибо я специально всё сделал на простых умножениях, делениях и прочем. Визуализацию пересечения можно просто всю выкинуть, тебе результат пересечений нужен для дальнейших вычислений же просто.

Вот на Сях

#include <math.h>
#include <stdio.h>

struct vec2
{
    float x;
    float y;
};

struct line
{
    struct vec2 start;
    struct vec2 end;
};

int point_intersect_line(struct vec2 line_start,struct vec2 line_end,struct vec2 point,float radius)
{

    struct vec2 v1 = {.x=0,.y=0};
    struct vec2 v2 = {.x=0,.y=0};
    struct vec2 v3 = {.x=0,.y=0};
    struct vec2 v4 = {.x=0,.y=0};
    struct vec2 normalized = {.x=0,.y=0};

    v1.x = line_end.x - line_start.x;
    v1.y = line_end.y - line_start.y;

    v2.x = point.x - line_start.x;
    v2.y = point.y - line_start.y;

    float len = sqrt(v1.x * v1.x + v1.y * v1.y);

    normalized.x = v1.x / len;
    normalized.y = v1.y / len;

    len = sqrt(v2.x * v2.x + v2.y * v2.y);
    v3.x = normalized.x * len;
    v3.y = normalized.y * len;

    if( (v3.x * v1.x) + (v3.y * v1.y) < 0 )
    {
        return 0;
    }

    if ((v3.x * v3.x + v3.y * v3.y) > (v1.x * v1.x + v1.y * v1.y))
    {
        return 0;
    }

    v4.x = v2.x - v3.x;
    v4.y = v2.y - v3.y;
    len = (v4.x * v4.x + v4.y * v4.y);

    if( len < radius)
    {
        return 1;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    //линия с котрой ищем пересечение
    struct line line =
    {
        .start.x = 10,
        .start.y = 10,
        .end.x   = 500,
        .end.y   = 500,
    };

    //луч / точка торую двигаем по оси Х до пересечения
    //с фиксированной (или нет) координатой Y
    struct vec2 point =
    {
        .x = 0,   // начинаем строить луч с 0
        .y = 160, // от балды
    };

    //шаг луча, можно сделать его float
    //если нужна точность
    //если raystep слишком большой, то он может перелететь
    //точку перечения и столкновения его с прямой не будет
    //и мы не узнаем точку пересечения.
    //но я шаг ниже указал в параметре функции как радиус
    //и мы не потеряем пересечение так что будет страдать только точность
    //но конкретно тут точность не страдает у меня тут целые числа и шаг 1 самый точный
    int raystep = 1;
    //это по сути предел кооринат по X
    //у нас же не бесконечная плоскость
    //на котрой мы ищем пересечение, выбирам наибольшее значение
    //на кривых по X и всё. Тоже может быть float без разницы вообще
    int MAX_X = 1000;

    //пускаем точку в полёт до пересечения
    for (size_t i = 0; i < MAX_X; ++i)
    {
        point.x = i; // двигаем её по нужной нам оси (осям)
        //и проверяем есть ли пересечение
        //raystep в качестве радиуса, можно писать отдельно хоть 0.1
        //но тогда шаг должен быть float и меньше радиуса так как радиус это область 
        //в котрой пересечение и если шаг больше то радиус может быть
        // перешагнут лол. 
        if (point_intersect_line(line.start,line.end,point,raystep))
        {
            printf("Пресечение линии start [x:%f y:%f] end [x:%f y:%f] в точке [x:%f y:%f]\n",
                  line.start.x,line.start.y,line.end.x,line.end.y,point.x,point.y);
            return 0;
        }else{
            //printf("Нет пресечения линии [x:%f y:%f] [x:%f y:%f]\n",
            //line.start.x,line.start.y,line.end.x,line.end.y,point.x,point.y);
        }
    }

    return 0;
}
dron@gnu:~$ gcc tt.c -lm
dron@gnu:~$ ./a.out 
Пресечение линии start [x:10.000000 y:10.000000] end [x:500.000000 y:500.000000] в точке [x:159.000000 y:160.000000]
dron@gnu:~$ 

Исходная версия LINUX-ORG-RU, :

Ну из всего него тебе по надо (учитывая называния темы) только 1 функция point_intersect_line для нахождения пересечения «луча/точки/линии» с линией между двумя точками кривой. Всё остальное просто визуализация. Только у меня всё в координатах экрана и кривые от руки рисуются , а у тебя в своей системе координат и кривые предрасчитанные, но один фиг твои кривые это всё равно точки по которым ты кривые строишь так что чисто нахождение пересечения будет работать с чем угодно оно же float там везде, да и переписать на том на чём пишешь ты можно ибо я специально всё сделал на простых умножениях, делениях и прочем. Визуализацию пересечения можно просто всю выкинуть, тебе результат пересечений нужен для дальнейших вычислений же просто.

Вот на Сях

#include <math.h>
#include <stdio.h>

struct vec2
{
    float x;
    float y;
};

struct line
{
    struct vec2 start;
    struct vec2 end;
};

int point_intersect_line(struct vec2 line_start,struct vec2 line_end,struct vec2 point,float radius)
{

    struct vec2 v1 = {.x=0,.y=0};
    struct vec2 v2 = {.x=0,.y=0};
    struct vec2 v3 = {.x=0,.y=0};
    struct vec2 v4 = {.x=0,.y=0};
    struct vec2 normalized = {.x=0,.y=0};

    v1.x = line_end.x - line_start.x;
    v1.y = line_end.y - line_start.y;

    v2.x = point.x - line_start.x;
    v2.y = point.y - line_start.y;

    float len = sqrt(v1.x * v1.x + v1.y * v1.y);

    normalized.x = v1.x / len;
    normalized.y = v1.y / len;

    len = sqrt(v2.x * v2.x + v2.y * v2.y);
    v3.x = normalized.x * len;
    v3.y = normalized.y * len;

    if( (v3.x * v1.x) + (v3.y * v1.y) < 0 )
    {
        return 0;
    }

    if ((v3.x * v3.x + v3.y * v3.y) > (v1.x * v1.x + v1.y * v1.y))
    {
        return 0;
    }

    v4.x = v2.x - v3.x;
    v4.y = v2.y - v3.y;
    len = (v4.x * v4.x + v4.y * v4.y);

    if( len < radius)
    {
        return 1;
    }

    return 0;
}

int main(int argc, char *argv[])
{
    //линия с котрой ищем пересечение
    struct line line =
    {
        .start.x = 10,
        .start.y = 10,
        .end.x   = 500,
        .end.y   = 500,
    };

    //луч / точка торую двигаем по оси Х до пересечения
    //с фиксированной (или нет) координатой Y
    struct vec2 point =
    {
        .x = 0,   // начинаем строить луч с 0
        .y = 160, // от балды
    };

    //шаг луча, можно сделать его float
    //если нужна точность
    //если raystep слишком большой, то он может перелететь
    //точку перечения и столкновения его с прямой не будет
    //и мы не узнаем точку пересечения.
    //но я шаг ниже указал в параметре функции как радиус
    //и мы не потеряем пересечение так что будет страдать только точность
    //но конкретно тут точность не страдает у меня тут целые числа и шаг 1 самый точный
    int raystep = 1;
    //это по сути предел кооринат по X
    //у нас же не бесконечная плоскость
    //на котрой мы ищем пересечение, выбирам наибольшее значение
    //на кривых по X и всё. Тоже может быть float без разницы вообще
    int MAX_X = 1000;

    //пускаем точку в полёт до пересечения
    for (size_t i = 0; i < MAX_X; ++i)
    {
        point.x = i; // двигаем её по нужной нам оси (осям)
        //и проверяем есть ли пересечение
        //raystep в качестве радиуса, можно писать отдельно хоть 0.1
        //но тогда шаг должен быть float так как радиус это область 
        //в котрой пересечение и если шаг больше то радиус может быть
        // перешагнут лол. 
        if (point_intersect_line(line.start,line.end,point,raystep))
        {
            printf("Пресечение линии start [x:%f y:%f] end [x:%f y:%f] в точке [x:%f y:%f]\n",
                  line.start.x,line.start.y,line.end.x,line.end.y,point.x,point.y);
            return 0;
        }else{
            //printf("Нет пресечения линии [x:%f y:%f] [x:%f y:%f]\n",
            //line.start.x,line.start.y,line.end.x,line.end.y,point.x,point.y);
        }
    }

    return 0;
}
dron@gnu:~$ gcc tt.c -lm
dron@gnu:~$ ./a.out 
Пресечение линии start [x:10.000000 y:10.000000] end [x:500.000000 y:500.000000] в точке [x:159.000000 y:160.000000]
dron@gnu:~$