История изменений
Исправление 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:~$