Площадь между двумя линиями внутри квадрата [-1,+1] x [-1,+1]

Я работаю над проектом в Matlab и мне нужно найти площадь между двумя линиями внутри квадрата [-1,+1]x[-1,+1], пересекающимися в точке (xIntersection,yIntersection). Итак, идея состоит в том, чтобы вычесть две строки и проинтегрировать между [-1, xIntersection] и [xIntersection, +1], просуммировать результаты и, если они отрицательные, изменить знак.

Подробнее о том, как найти пересечение двух линий, можно узнать по этой ссылке.

Я использую функцию Matlab's integral(), вот фрагмент моего кода :

xIntersection = ((x_1 * y_2 - y_1 * x_2) * (x_3 - x_4) - (x_1 - x_2) * (x_3 * y_4 - y_3 * x_4) ) / ((x_1 - x_2) * (y_3 - y_4) - (y_1 - y_2) * (x_3 - x_4));

d = @(x) g(x) - f(x);
result = integral(d, -1, xIntersection) - int( d, xIntersection, 1)
if(result < 0),
    result = result * -1;
end

Обратите внимание, что я определил ранее в коде g(x) и f(x), но не сообщил об этом во фрагменте.

Проблема в том, что вскоре я понял, что линии могут пересекаться как внутри, так и снаружи квадрата, более того, они могут пересекать квадрат с любой его стороны, и количество возможных комбинаций очень быстро растет.

I.e.:

введите здесь описание изображениявведите здесь описание изображениявведите здесь описание изображениявведите здесь описание изображения

Это всего 4 случая, но учитывая, что f(+1), f(-1), g(+1), g(-1) могут находиться внутри интервала [-1,+1], над ним или под ним и что пересечение может быть внутри или снаружи квадрата, общее число равно 3 * 3 * 3 * 3 * 2 = 162.

Очевидно, что в каждом случае явная функция для интеграции, чтобы получить область между двумя линиями, отличается, но я не могу думать о написании случая переключения для каждого из них.

Есть идеи?


person Matteo    schedule 12.09.2013    source источник
comment
как вы понимаете "между строк"? Что должно произойти, если линии расположены под углом 90°?   -  person Chronial    schedule 12.09.2013


Ответы (3)


Я думаю, что мой ответ на ваш предыдущий вопрос по-прежнему применим по большей части.

Если вы хотите вычислить площадь области, ограниченной меньшим углом двух линий и границами квадрата, то вы можете забыть о пересечении и забыть обо всех различных случаях.

Вы можете просто использовать тот факт, что

  • площадь квадрата S равна 4
  • значение этого интеграла

    A = quadgk(@(x) ...
        abs( max(min(line1(x),+1),-1) - max(min(line2(x),+1),-1) ), -1, +1);
    

    дает вам площадь между линиями (иногда большой угол, иногда маленький угол)

  • значение min(A, S-A) является правильным ответом (всегда маленький угол).
person Rody Oldenhuis    schedule 12.09.2013
comment
+1 за ответ, и если бы я мог еще +1 за поиск этого нового вопроса; D - person Matteo; 12.09.2013
comment
Дайте мне знать, что вы думаете о моем ответе, хотя я считаю, что ваш ответ лучше, потому что требует меньше времени, и это не эмпирическое приближение. - person Matteo; 12.09.2013

Предполагая, что «между линиями» означает «внутри меньшего угла, образованного линиями»:

С линиями l и h, S := [-1,+1]x[-1,+1] и B в качестве границы S.

Преобразуйте l в форму l_1 + t*l_2 с векторами l_1 и l_2. Сделайте то же самое для ч.

  • Если пересечение не находится внутри S, найдите 4 пересечения l и h с B. Рассортируйте их так, чтобы получился выпуклый четырехугольник. Вычислите его площадь.
  • Else:
    • Find the intersection point p and find the intersection angle α between l_2 and h_2. and then check:
      • If α in [90°,180°] or α in [270°,360°], swap l and h.
      • Если α > 180°, установите l_2 = −l_2
    • Set l_1 := h_1 := p. Do once for positive t and negative t (forwards and backwards along l_2 and h_2 from p):
      • Find intersections s_l and s_h of l and h with B.
      • Если на той же границе B: вычислить площадь треугольника s_l, s_h, p
      • Если на соседних границах B: найдите угол c B между границами попадания и еще раз отсортируйте четыре точки s_l, s_h, p и c так, чтобы получился выпуклый четырехугольник, и вычислите его площадь.
      • Если на противоположных границах, найдите совпадающую сторону B (вы можете сделать это, посмотрев на направление s_l-p). Используя две его угловые точки c_1 и c_2, теперь у вас есть 5 точек, которые образуют многоугольник. Отсортируйте их так, чтобы многоугольник был выпуклым, и вычислите его площадь.

Это все еще довольно много случаев, но я не думаю, что есть способ обойти это. Вы можете несколько упростить это, также используя формулу многоугольника для треугольника и четырехугольника.

Как отсортировать точки, чтобы получился выпуклый многоугольник/четырехугольник: выберите любую из них как p_1, а затем отсортируйте остальные точки по углу до p_1.

Если вы определите функцию intersection и функцию polygon_area, которая берет список точек, сортирует их и возвращает площадь, этот алгоритм должен быть довольно простым в реализации.

редактировать: Изображение, поясняющее комментарий: введите здесь описание изображения

person Chronial    schedule 12.09.2013
comment
спасибо за публикацию, все еще пытаюсь понять ваш ответ! ;D спасибо за указание, что между действительно означает внутри меньший угол. У меня есть пара вопросов, если вы можете мне помочь: я думаю, что l_1 - это скаляр, а не вектор, верно? И что вы подразумеваете под поменять местами l и h? И, наконец, что вы подразумеваете под Set l_1 := h_1 := p. Сделайте один раз для положительного t и отрицательного t (вперед и назад по l_2 и h_2 от p):? - person Matteo; 12.09.2013
comment
нет, l_1 — это вектор — это «начальная точка» линии (=любая точка на линии). Вот почему мы можем позже установить l_1 и h_1 в p, поскольку мы знаем, что p находится как на l, так и на h. «Поменять местами l и h» означает «установить l_1=h_1 и l_2=h_2 и установить h_1 и h_2 на то, что l_1 и l_2 где раньше. - person Chronial; 12.09.2013
comment
Для «положительного t»: скажем, l пересекается с B в s_1 и s_2. Теперь есть (скаляр) t_1, так что p + t_1•l_2 = s_1, и (скаляр) t_2, так что p + t_2•l_2 = s_2. Теперь один из этих t будет положительным, а другой — отрицательным. Мы это знаем, потому что p находится между s_1 и s_2. Это помогло? - person Chronial; 12.09.2013
comment
Добавил картинку для прояснения ситуации. Весь смысл переключения, реверсирования и положительного/отрицательного направления заключается в том, чтобы убедиться, что вы действительно смотрите под меньшим углом, а не под более широким. Но я думаю, что замена может на самом деле не требуется. - person Chronial; 12.09.2013
comment
Я разместил ответ и хотел бы услышать ваши комментарии по нему. Заранее спасибо! - person Matteo; 12.09.2013

Привет, ребята, спасибо за ваши ответы, я также подумал об эмпирическом методе определения площади между линиями и хотел поделиться им для обсуждения и полноты.

Если вы возьмете большое количество случайных точек внутри квадрата [-1,+1]x[-1,+1], вы можете измерить площадь как долю точек, попадающих в область между двумя линиями.

Вот небольшой фрагмент и два изображения, чтобы показать разную точность эмпирического результата, полученного с разным количеством точек.

minX = -1;
maxX = +1;

errors = 0;
size = 10000;

for j=1:size,

    %random point in [-1,+1]
    T(j,:) = minX + (maxX - minX).*rand(2,1); 

    %equation of the two lines is used to compute the y-value
    y1 = ( ( B(2) - A(2) ) / ( B(1) - A(1) ) ) * (T(j,1) - A(1)) + A(2);
    y2 = (- W(1) / W(2)) * T(j,1) -tresh / W(2);

    if(T(j,2) < y1),
        %point is under line one
        Y1 = -1;
    else
        %point is above line one
        Y1 = +1;
    end

    if(T(j,2) < y2),
        %point is under line two 
        Y2 = -1;
    else
        %point is above line two
        Y2 = +1;
    end

    if(Y1 * Y2 < 0),

        errors = errors + 1;
        scatter(T(j,1),T(j,2),'fill','r')
    else
        scatter(T(j,1),T(j,2),'fill','g')
    end

end

area = (errors / size) / 4;

И вот два изображения, это, безусловно, занимает больше времени, чем решение, опубликованное @Rody, но, как вы видите, вы можете сделать его точным.

  • Количество баллов = 2000

Количество баллов = 2000

Количество баллов = 10000

Количество баллов = 10000

person Matteo    schedule 12.09.2013
comment
Хотя идея интересная, этот метод очень неточный/медленный. Я бы рекомендовал использовать сетку вместо случайных точек — так вы получите более предсказуемый результат, а также станет понятно, сколько точек нужно для получения точного результата, если угол небольшой. Может быть, точнее: абсолютную ошибку можно контролировать, но относительная ошибка будет очень большой для малых углов. И если вы берете много точек, этот метод становится невероятно медленным для на самом деле довольно простого расчета. - person Chronial; 12.09.2013
comment
Вы когда-нибудь слышали об [интеграции Монте-Карло] (en.wikipedia.org/wiki/Monte_Carlo_integration? )? :) - person Rody Oldenhuis; 12.09.2013
comment
Извините, я с мобильного, но вы поняли :) - person Rody Oldenhuis; 12.09.2013
comment
@Chronial и Роди - спасибо за отзыв, ребята, вы мне очень помогли. Я буду придерживаться ответа Роди, потому что он был самым быстрым, точным и элегантным! - person Matteo; 13.09.2013