Добавлен Devion,
не публикуется
Псевдоскаляр (косое произведение векторов, псевдоскалярное произведение векторов) - базовая операция, широко применяемая в вычислительной геометрии.
Формулы
Псевдоскаляр можно быть представлен следующими способами:
a.x*b.y - b.x*a.y
abs(a.magnitude)*abs(b.magnitude)*sin(angle)
Применение
Псевдоскалярное произведение возвращает ориентированную площадь параллелограмма.
Часто применяется для:
нахождения ориентированной площади треугольника
/// <summary>
/// Площадь треугольника
/// </summary>
public static float triangle(Vector2 a, Vector2 b, Vector2 c)
{
return pseudo(a - b, c - b) / 2f;
}
нахождения ориентированной площади многоугольника
Для каждых двух точек каждого ребра многоугольника находим ориентированную площадь. Результаты суммируем и делим на 2
Таким образом при обходе верхних точек мы будем получать площадь треугольников больше нужной, но при суммировании с площадью нижних точек (знак которых обратный), получим площадь фигуры.
Предполагается что вы суммируете площади треугольников. Для повышения точности вычислений деление на 2 мы делаем не сразу, а под конец.
Таким образом при обходе верхних точек мы будем получать площадь треугольников больше нужной, но при суммировании с площадью нижних точек (знак которых обратный), получим площадь фигуры.
Предполагается что вы суммируете площади треугольников. Для повышения точности вычислений деление на 2 мы делаем не сразу, а под конец.
/// <summary>
/// Площадь простого многоугольника
/// </summary>
public static float simplePolygon(Vector2[] points)
{
var area = 0f;
for (int i = 0; i < points.Length; i++)
{
var a = points[i];
var b = points[(i + 1) % points.Length];
area += pseudo(a, b);
}
return area / 2f;
}
определения направления точек фигуры
signed area < 0 - по часовой
signed area > 0 - против часовой
signed area > 0 - против часовой
определения положения точки относительно луча
pseudo(b-a, point-a);
< 0 - точка справа,
> 0 - точка слева,
== 0 - точка на прямой
< 0 - точка справа,
> 0 - точка слева,
== 0 - точка на прямой
/// <summary>
/// Возвращает коэффициент направления точки относительно луча. Больше нуля - слева, меньше - справа, равно - на прямой
/// </summary>
public static float getDirectionCoef(Vector2 a1, Vector2 a2, Vector2 point)
{
var p1 = a2 - a1;
var p2 = point - a1;
return pseudo(p1, p2);
}
/// <summary>
/// Указывает, лежит ли точка слева от указанной прямой
/// </summary>
public static bool isLeft(Vector2 a1, Vector2 a2, Vector2 point)
{
return pseudo(a2 - a1, point - a1) > 0;
}
/// <summary>
/// Указывает, лежит ли точка справа от указанной прямой
/// </summary>
public static bool isRight(Vector2 a1, Vector2 a2, Vector2 point)
{
return pseudo(a2 - a1, point - a1) < 0;
}
проверки параллельности прямых
Достаточным условием при проверке параллельности является выражение:
pseudo(a2-a1, b2-b1) == 0
нахождения пересечений между отрезками
Используется как часть алгоритма.
Код
/// <summary>
/// Косое произведение векторов
/// </summary>
public static float pseudo(Vector2 a, Vector2 b)
{
return (a.x * b.y).unbox() - (b.x * a.y).unbox();
}
/// <summary>
/// Скалярное произведение векторов
/// </summary>
public static float pseudo(Vector2 a, Vector2 zero, Vector2 b)
{
return pseudo(a - zero, b - zero);
}
/// <summary>
/// Косое произведение векторов
/// </summary>
public static float pseudo(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
{
return pseudo(a2 - a1, b2 - b1);
}
Функции используют unboxing для сохранения точности вычисляемого значения (что особенно важно при нахождении параллельных прямых и сравнении с 0).
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован Devion
Простовато ему видите ли, ну офигеть новость сообщил.