Я сделать карту, которая делает положение игровых объектов (Project Zomboid зомби):Создать цветовой градиент, описывающий дискретное распределение точек
Как пользователь отъезжает, одиночные точки больше не полезны. Вместо этого я хотел бы распределить зомби в области с использованием градиента красного цвета. Я попытался зациклиться на всех зомби для каждого визуализированного пикселя и покрасить его в ответ на сумму квадратов расстояний до зомби. Результат:
Это слишком размыто. Кроме того, на результаты больше влияют зомби, которые являются AWAY из точек - мне нужно больше влиять на них зомби, которые закрыты. Так что это просто математика. Вот код, который я использовал:
var h = canvas.height;
var w = canvas.width;
// To loop over more than 1 pixel (performance)
var tileSize = 10;
var halfRadius = Math.floor(tileSize/2);
var time = performance.now();
// "Squared" because we didnt unsquare it
function distanceSquared(A, B) {
return (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y);
}
// Loop for every x,y pixel (or region of pixels)
for(var y=0; y<h; y+=tileSize) {
for(var x=0; x<w; x+=tileSize) {
// Time security - stop rendering after 1 second
if(performance.now()-time>1000) {
x=w;y=h;break;
}
// Convert relative canvas offset to absolute point on the map
var point = canvasPixeltoImagePixel(x, y);
// For every zombie add sqrt(distance from this point to zombie)
var distancesRoot = 0;
// Loop over the zombies
var zombieCoords;
for(var i=0; i<zombies_length; i++) {
// Get single zombie coordinates as {x:0, y:0}
if((coords=zombies[i].pixel)==null)
coords = zombies[i].pixel = tileToPixel(zombies[i].coordinates[0], zombies[i].coordinates[1], drawer);
// square root is a) slow and b) probably not what I want anyway
var dist = distanceSquared(coords, point);
distancesRoot+=dist;
}
// The higher the sum of distances is, the more intensive should the color be
var style = 'rgba(255,0,0,'+300000000/distancesRoot+')';
// Kill the console immediatelly
//console.log(style);
// Maybe we should sample and cache the transparency styles since there's limited ammount of colors?
ctx.fillStyle = style;
ctx.fillRect(x-halfRadius,y-halfRadius,tileSize,tileSize);
}
}
Я довольно хорошо с теоретическим объяснением, как это сделать, но если вы сделаете простой пример холста с некоторыми точками, что было бы удивительным.
Если вы могли бы построить эту базу скрипку, я думаю, мало кто из нас ответил бы сейчас. Интересно, будет ли просто радиальный градиент, скажем, 0,6 globalAlpha, уже небезопасным. (используя ctx.scale перед рисованием дуг). – GameAlchemist
Ваше описание звучит как [heatmap] (http://www.patrick-wied.at/static/heatmapjs/). – markE