Интеграция данных с использованием двумерных взвешенных данных в 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 );
}
}
Итак, изображение создается без создания матрицы пикселей, группируя цвета. Граничные "кривые" будут автоматически присутствовать после того, как будет задано значение каждого пикселя изображения.