#c
#c
Вопрос:
Какой самый простой способ определить, заблокирована ли прямая линия между ячейкой A и ячейкой B ячейкой C? т. е.
Если ячейка A равна [0, 0], ячейка B равна [2, 2], а ячейка C равна [1,1], ячейка C блокирует путь между ячейками A и B. Если ячейка B была любой другой ячейкой по этой диагонали ([3, 3], [4, 4], и т.д.), Ячейка C все равно будет блокировать путь между ячейками A и B. Но если ячейка C является любой другой ячейкой, она не блокирует этот путь.
Например, используя местоположения ячеек A, B и C, какие условия я должен был бы проверить для этого?
Комментарии:
1. они всегда горизонтальные, вертикальные или диагональные на 45 градусов или как?
2. Да, по горизонтали, вертикали или по любой диагонали 45 градусов.
3. Даже в общем случае вы можете рассматривать AB и AC как векторы, и если определитель равен нулю , они коллинеарны, тогда вам просто нужно посмотреть, находится ли AB в том же направлении, что и AC, и что AC короче AB
Ответ №1:
Некоторая простая линейная алгебра. Рассмотрим два вектора, AB и AC; они параллельны, если определитель равен нулю. Они указывают на одно и то же направление, если скалярное произведение положительное. И C находится вдоль пути AB, если предыдущее значение было истинным, а AC короче AB. Чтобы увидеть, короче ли AC, чем AB, мы можем сравнить квадраты их длин, избегая квадратного корня.
Таким образом, мы можем решить это с помощью сложений, вычитаний и умножений за постоянное время. Это работает даже для всех точных целочисленных координат; линии не обязательно должны быть горизонтальными, вертикальными или диагональными.
#include <stdio.h>
struct vec { int x; int y; };
int determinant(struct vec a, struct vec b) {
return a.x * b.y - b.x * a.y;
}
int dot_product(struct vec a, struct vec b) {
return a.x * b.x a.y * b.y;
}
int len_squared(struct vec v) {
return dot_product(v, v);
}
int blocks(struct vec a, struct vec b, struct vec c) {
struct vec ab = {b.x - a.x, b.y - a.y};
struct vec ac = {c.x - a.x, c.y - a.y};
return determinant(ab, ac) == 0 amp;amp;
dot_product(ab, ac) > 0 amp;amp;
len_squared(ac) < len_squared(ab);
}
int main(void) {
struct vec a = {0, 0}, b = {2, 2}, c = {1, 1};
if (blocks(a, b, c)) {
puts("Blocks");
}
else {
puts("Does not block");
}
}