Интеграция данных с использованием двумерных взвешенных данных в 2D

Я пытаюсь найти несколько Java lib, пример кода (или отправную точку), чтобы помочь мне разобраться, как я могу интерполировать список из 2d точек с весом для создания интерполяции с помощью кривые уровня.

Googling Я выясняю, что существует несколько доступных алгоритмов, и я нашел объяснения с интересным контентом. Первый алгоритм, который я хочу попробовать, это интерполяция Inverse Distance Weighted.

Но со всей этой информацией у меня есть некоторые основные сомнения:

  • Чтобы создать одно изображение, как на картинке ниже, мне нужно сделать матрицу пикселей (с весом), интерполировать данные, группировать пиксели вместе (по диапазону цветов), а затем присоединить точки, нарисовать кривые и поставить значения ссылочного текста, такие как this?

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

Пример данных:

+-------------------+
|  X  |  Y  | WEIGHT|
+-------------------+
|  2  |  5  |   30  |
|  7  |  3  |   25  |
|  1  |  1  |   10  |
|  5  |  6  |   45  |
|  7  |  9  |   15  |
+-------------------+

Примеры правил:

  • Значение между 00-10: синий
  • Значение между 10-20: зеленый
  • Значение между 20-30: Желтый
  • Значение между 30-40: красный

Примеры результатов:

Shepard interpolation example

Данные примера, правила и результаты несовместимы, являются случайными примерами для объяснения моей проблемы.


Вот мой последний тестовый класс: http://pastebin.com/nD6MT8eS

Ответы

Ответ 1

Предполагая, что у вас есть класс Point, который вы можете использовать (например, java.awt.Point), вы можете поместить весы в карту:

Map<Point,Double> points = new HashMap<Point,Double>();
points.put( new Point(2,5), 30 )
...

Затем вы создаете изображение, и для каждой координаты x, y найдите лучший результат. Я предполагаю, что оценка - это обратное расстояние, умноженное на вес точки в таблице. Если да, то так:

image = createBitmap( width, height )
for( int x = 0; x < width; x++ )
    for( int y = 0; y < height; y++ )
    {
         double maxScore = -Double.MAX_VALUE
         for( Point p : points.keySet() ) 
         {
             double score = points.get(p)/p.distance( x, y ) //Inverse distance times point weight
             minDist = Math.max( maxScore, score )
         }
         image.setPixelColour( x, y, getColorForDistance( 1/minDist * points.get(p) )
    }

getColourForDistance (двойной уровень) должен быть очевиден, хотя вам нужно будет установить уровни правильно. Я предполагаю, что createBitmap (ширина, высота) создает изображение. Какой образ вы делаете, зависит от вашего приложения, а также от того, имеет ли он метод setPixelColour или аналогичный. Выбор класса очков будет зависеть и от вашего приложения.

Это не оптимизировано - это как минимум O (x * y * p), где p - количество точек. Если p становится большим, вы можете посмотреть более разумные структуры данных для хранения точек.

Ответ 2

В дополнение к ответам @mo-seph и @Xipan-Xiao вы можете посмотреть класс NonGridContourDataset из проекта jFreeChart, который реализует алгоритм обратного расстояния до мощности.

Ответ 3

Не знаю, как добавлять комментарии, поэтому я добавляю свои мысли в эту область ответа.

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

picture = createBitmap( width, height );
for( int x = 0; x < width; ++ x ){
    for( int y = 0;y < height; ++ y ){
        double value = interpolate( x, y, inputs );
        Color color = colorRangeOf( value );
        picture.setPixel( x, y, color );
    }
}

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