У вас есть метод SVG с js для вычисления площади поверхности сложного многоугольника [duplicate]

Java - это кросс-платформа, MySQL - нет, поэтому вам придется создавать различные инсталляторы для нескольких платформ с разными двоичными файлами MySQL. Если вы хотите включить исходный код MySQL для систем, отличных от Windows, то это еще одна история ... поэтому я предполагаю, что вам нужна только установка для Windows.

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

Во-вторых, вы можете сделать молчащую установку MySQL. Как это делается, объясняется здесь

здесь .

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

Итак, сделав это, вы должны быть особенно осторожны, чтобы проверить, действительно ли порт 3306 уже запущен (порт по умолчанию MySQL), и другие проверки здравомыслия, чтобы увидеть, есть ли возможность другого экземпляра скрываться в фоновом режиме.

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

68
задан unutbu 3 December 2015 в 14:02
поделиться

15 ответов

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

Код Python, заданный многоугольником, представленным в виде списка (x, y) вершинных координат, неявно обертывающих от последней вершины к первому:

def area(p):
    return 0.5 * abs(sum(x0*y1 - x1*y0
                         for ((x0, y0), (x1, y1)) in segments(p)))

def segments(p):
    return zip(p, p[1:] + [p[0]])

Дэвид Лехави комментирует: стоит упомянуть, почему работает этот алгоритм: это применение теоремы Грина для функций -y и x; точно так же работает планиметр . Более конкретно:

Формула выше = integral_over_perimeter(-y dx + x dy) = integral_over_area((-(-dy)/dy+dx/dx) dy dx) = 2 Area

90
ответ дан Ry- 17 August 2018 в 10:59
поделиться
  • 1
    Стоит упомянуть, почему работает этот алгоритм: это приложение теоремы Грина для функций -y и x; точно так, как работает плоскомер. Более конкретно: Формула выше = integ_permieter (-y dx + x dy) = integ_area ((- (- dy) / dy + dx / dx) dydyx = 2 Площадь – David Lehavi 17 January 2009 в 07:44
  • 2
    Ссылка на сообщение мертва. У кого-нибудь есть другой? – Yakov 11 July 2011 в 13:42
  • 3
    Связанная дискуссия о списке рассылки compgeom-discuss@research.bell-labs.com для меня недоступна. Я скопировал сообщение из Google Cache: gist.github.com/1200393 – Andrew Андрей Листочкин 7 September 2011 в 13:10
  • 4
    @ perfectionm1ng направления переключения перевернут знак в сумме, но abs() удалит вырез. – Darius Bacon 19 November 2013 в 11:38
  • 5
    Ограничения: этот метод даст неправильный ответ для самопересекающихся многоугольников, где одна сторона пересекает другую, как показано справа. Он будет работать правильно, однако, для треугольников, регулярных и нерегулярных многоугольников, выпуклых или вогнутых многоугольников. ( mathopenref.com/coordpolygonarea.html [/ д0]) – OneWorld 12 October 2016 в 07:01

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

//don't forget to include cmath for abs function
struct Point{
  double x;
  double y;
}
// cross_product
double cp(Point a, Point b){ //returns cross product
  return a.x*b.y-a.y*b.x;
}

double area(Point * vertices, int n){  //n is number of sides
  double sum=0.0;
  for(i=0; i<n; i++){
    sum+=cp(vertices[i], vertices[(i+1)%n]); //%n is for last triangle
  }
  return abs(sum)/2.0;
}
0
ответ дан abe312 17 August 2018 в 10:59
поделиться
  • 1
    cp принимает два аргумента, но вы вызываете его одним. – user 9 July 2018 в 17:03
  • 2
    О, это был тип. Спасибо за указание. Починил это! :) – abe312 9 July 2018 в 19:41

Перекрестный продукт является классическим.

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

area = 0;
for( i = 0; i < N; i += 2 )
   area += x[i+1]*(y[i+2]-y[i]) + y[i+1]*(x[i]-x[i+2]);
area /= 2;

Я использую индекс массива для ясности. Эффективно использовать указатели. Хотя хорошие компиляторы сделают это за вас.

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

Алгоритм получается путем разворачивания и объединения двух последовательных итераций классического алгоритма кросс-произведения.

Я не уверен, как сравниваются два алгоритма относительно числовой точности. Мое впечатление, что вышеупомянутый алгоритм лучше классического, потому что умножение стремится восстановить потерю точности вычитания. При ограничении использования float, как и в случае с графическим процессором, это может иметь существенное значение.

EDIT: «Площадь треугольников и многоугольников 2D и 3D» описывает еще более эффективный метод

// "close" polygon
x[N] = x[0];
x[N+1] = x[1];
y[N] = y[0];
y[N+1] = y[1];

// compute area
area = 0;
for( size_t i = 1; i <= N; ++i )
  area += x[i]*( y[i+1] - y[i-1] );
area /= 2;
14
ответ дан chmike 17 August 2018 в 10:59
поделиться
  • 1
    Я не могу представить, что второй фрагмент кода будет работать. Совершенно очевидно, что чем больше полигон находится по оси X, тем больше будет его площадь. – Cygon 29 April 2012 в 10:19
  • 2
    Это правильная математическая перестройка описанного выше алгоритма, экономя некоторые умножения. Вы правы, но области, определенные другими вершинами, будут вычитаться. Но это может привести к деградации точности. – chmike 14 May 2012 в 10:12
  • 3
    То, что вы упускаете из виду, состоит в том, что добавление всегда имеет некоторые отрицательные термины из-за вычитания y. Рассмотрим любую 2d многоугольную форму и сравниваем значения y последовательных вершин. Вы увидите, что некоторое вычитание даст отрицательное значение и некоторое положительное. – chmike 15 May 2012 в 16:52
  • 4
    Действительно, этот последний абзац - это то, что я не мог обдумать! С i & lt; = N это работает. Спасибо за ваше терпение, я все забираю :) – Cygon 15 May 2012 в 17:07
  • 5
    На боковой ноте область, возвращаемая алгоритмом, является «подписанной». (отрицательный или положительный, основанный на порядке точек), поэтому, если вы хотите, чтобы всегда положительная область использовала абсолютное значение. – NightElfik 6 November 2014 в 07:57

Реализация формулы Shoelace может быть выполнена в Numpy. Предполагая эти вершины:

import numpy as np
x = np.arange(0,1,0.001)
y = np.sqrt(1-x**2)

Мы можем определить следующую функцию для поиска области:

def PolyArea(x,y):
    return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1)))

И получение результатов:

print PolyArea(x,y)
# 0.26353377782163534

Избегать цикла делает эту функцию ~ 50X быстрее, чем PolygonArea:

%timeit PolyArea(x,y)
# 10000 loops, best of 3: 42 µs per loop
%timeit PolygonArea(zip(x,y))
# 100 loops, best of 3: 2.09 ms per loop

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

8
ответ дан Community 17 August 2018 в 10:59
поделиться

Лучше суммирования треугольников суммирует трапеции в декартовом пространстве:

area = 0;
for (i = 0; i < n; i++) {
  i1 = (i + 1) % n;
  area += (vertex[i].y + vertex[i1].y) * (vertex[i1].x - vertex[i].x) / 2.0;
}
1
ответ дан David Hanak 17 August 2018 в 10:59
поделиться

Или сделать контурный интеграл. Теорема Стокса позволяет выразить интеграл области как контурный интеграл. Маленькая квадратура Гаусса и ваш дядя Боб.

2
ответ дан duffymo 17 August 2018 в 10:59
поделиться

Код Python

Как описано здесь: http://www.wikihow.com/Calculate-the-Area-of-a-Polygon

] С pandas

import pandas as pd

df = pd.DataFrame({'x': [10, 20, 20, 30, 20, 10, 0], 'y': [-10, -10, -10, 0, 10, 30, 20]})
df = df.append(df.loc[0])

first_product = (df['x'].shift(1) * df['y']).fillna(0).sum()
second_product = (df['y'].shift(1) * df['x']).fillna(0).sum()

(first_product - second_product) / 2
600
0
ответ дан firelynx 17 August 2018 в 10:59
поделиться
  1. Установите базовую точку (наиболее выпуклую точку). Это будет ваша точка поворота треугольников.
  2. Рассчитайте самую левую точку (произвольную), отличную от вашей базовой точки.
  3. Рассчитайте вторую позицию слева направо
  4. Сохраните эту триангулированную область.
  5. Сдвиньте одну точку вправо на каждую итерацию.
  6. Суммируйте триангулированные области
1
ответ дан Joe Phillips 17 August 2018 в 10:59
поделиться
  • 1
    Убедитесь, что вы отрицаете, что область треугольника следующей точки перемещается «назад». – recursive 17 January 2009 в 21:24

C способ сделать это:

float areaForPoly(const int numVerts, const Point *verts)
{
    Point v2;
    float area = 0.0f;

    for (int i = 0; i<numVerts; i++){
        v2 = verts[(i + 1) % numVerts];
        area += verts[i].x*v2.y - verts[i].y*v2.x;
    }

    return area / 2.0f;
}
0
ответ дан Joseph 17 August 2018 в 10:59
поделиться

Моя склонность состояла в том, чтобы просто нарезать треугольники. Я не вижу, как что-то еще может избежать ужасно волосатого.

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

0
ответ дан Loren Pechtel 17 August 2018 в 10:59
поделиться
  • 1
    Волосатая часть об этом состоит в том, что если ваши три последовательные точки определяют треугольник снаружи или частично вне полигона, тогда у вас есть проблема. – Richard 17 November 2012 в 21:44
  • 2
    @ Рихард: Вот почему квалификация около 180 градусов. Если вы срезаете треугольник за полигоном, вы получите слишком много градусов. – Loren Pechtel 18 November 2012 в 22:28
  • 3
    вам может понадобиться лучше описать, как вы находите угол. В плоской геометрии нет способа иметь 3 точки как часть треугольника и иметь любой угол или комбинацию углов, превышающих 180 градусов - проверка кажется бессмысленной. – Richard 19 November 2012 в 00:09
  • 4
    @Richard: На вашем полигоне у вас есть угол каждого перехода. Если соответствующий треугольник будет располагаться вне полигона, угол между двумя сегментами будет больше 180 градусов. – Loren Pechtel 19 November 2012 в 21:08
  • 5
    Вы имеете в виду, что внутренний угол двух соседних краевых сегментов будет больше 180 градусов. – Richard 19 November 2012 в 22:36

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

1
ответ дан MattK 17 August 2018 в 10:59
поделиться

Набор точек без каких-либо других ограничений не обязательно однозначно определяет многоугольник.

Итак, сначала вам нужно решить, какой полигон построить из этих точек - возможно, выпуклый корпус? http://en.wikipedia.org/wiki/Convex_hull

Затем триангулируем и вычисляем область. http://www.mathopenref.com/polygonirregulararea.html

4
ответ дан mbeckish 17 August 2018 в 10:59
поделиться
  • 1
    Я уверен, что оригинальный плакат означает список очков. – Ben 1 June 2018 в 17:37

Вычислить область многоугольника

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry1# polygon_area

int cross(vct a,vct b,vct c)
{
    vct ab,bc;
    ab=b-a;
    bc=c-b;
    return ab.x*bc.y-ab.y*bc.x;
}    
double area(vct p[],int n)
{ 
    int ar=0;
    for(i=1;i+1<n;i++)
    {
        vct a=p[i]-p[0];
        vct b=p[i+1]-p[0];
        area+=cross(a,b);
    }
    return abs(area/2.0);
}    
3
ответ дан Steve 17 August 2018 в 10:59
поделиться
  • 1
    Это 3-летний вопрос с 34 upvotes на принятом ответе. Расскажите, как ваш ответ лучше, чем любой другой уже опубликованный ответ. – Mark Taylor 4 October 2012 в 22:05
  • 2
    Это пример в c, а не python. Не лучше, но приятно иметь его на разных языках – underdoeg 27 August 2015 в 14:11

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

. Для общего непересекающегося многоугольника вам нужно суммировать произведение произведения (опорная точка, точка a) (контрольная точка, точка b), где a и b являются «рядом» друг с другом.

Предполагая, что у вас есть список точек, которые определяют многоугольник в порядке (порядок, когда точки i и i + 1 образуют линию многоугольника):

Сумма (кросс-произведение ((точка 0, точка i), (точка 0, точка i + 1)) для i = 1 до n - 1.

Возьмите величину этого поперечного произведения и у вас есть площадь поверхности.

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

4
ответ дан Tim Cooper 17 August 2018 в 10:59
поделиться

независимое от языка решение:

GIVEN: многоугольник может ВСЕГДА состоять из n-2 треугольников, которые не перекрываются (n = количество точек OR сторон). 1 треугольник = трехгранный многоугольник = 1 треугольник; 1 квадрат = 4-сторонний многоугольник = 2 треугольника; и т. д. ad nauseam QED

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

, если вы возьмете любые 3 последовательные точки в пути многоугольников и создаете треугольник с этими точками, вы будете имеют один и только один из трех возможных сценариев:

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

, нас интересуют только случаи, которые попадают в первый вариант (полностью содержащийся).

каждый раз, когда мы находим один из них, мы прерываем его, вычисляем его площадь (легко peasy, не будем объяснять формулу здесь) и создаем новый многоугольник с одной меньшей стороной (эквивалентный полигону с этим треугольником, отрубленным ). пока мы не оставим только один треугольник.

как реализовать это программно:

создать массив (последовательных) точек, которые представляют путь ВОКРУГ многоугольника. начните в точке 0. запустите массив, создавая треугольники (по одному за раз) из точек x, x + 1 и x + 2. преобразуйте каждый треугольник из формы в область и пересечь его с областью, созданной из многоугольника. Если полученное пересечение идентично исходному треугольнику, то указанный треугольник полностью содержится в многоугольнике и может быть отрублен. удалите x + 1 из массива и начните снова с x = 0. в противном случае (если треугольник находится вне [частично или полностью] многоугольника), переходите к следующей точке x + 1 в массиве.

дополнительно, если вы хотите интегрироваться с отображением и начинать с геоинтеграции, вы должны преобразовать из геоинформации на экранные точки FIRST. это требует решения моделирования и формулы для формы земли (хотя мы склонны думать о Земле как о шаре, это на самом деле нерегулярная яйцевидная (яйцо) с вмятинами). существует много моделей, для получения дополнительной информации wiki. важная проблема заключается в том, считаете ли вы район плоской или изогнутой. в общем, «маленькие» области, где точки до нескольких километров друг от друга, не будут вызывать значительную ошибку, если рассматривать плоские и не выпуклые.

1
ответ дан user836725 17 August 2018 в 10:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: