缓和数组中的数据以平滑 PHP 中的曲线
Ease data in array to smooth a curve in PHP
我正在使用 API 获取 GPX 点的高程数据,并尝试创建它的图形表示。我的问题是 API 中的每个点相隔 90 米,而我的 GPX 点相隔 5 米,导致连续几个点在突然改变到新高度之前具有相同的高度。
基本上,我得到了这样一个数组:
[0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15...]
您如何在缓和曲线的同时将其绘制为表示海拔高度的 PNG 图像?我需要能够更改输出图片的大小。
我正在尝试将我的阵列更改为类似的东西,但我不确定该怎么做以及这是否是最佳解决方案:
[0, 0, 0, 0, 5, 5, 10, 10, 10, 12, 13, 15, 15, 15, 15...]
感谢任何提示,我不习惯处理图片和数据缓动。
这是在 "average" 基础上平滑点的基本方法:
<?php
$points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
$refined = [];
foreach($points as $index => $point) {
// make sure we don't divide by 0
$prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
$next = isset($points[$index + 1]) ? $points[$index + 1] : false;
if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
$total = $point;
if($prev) {
$total += $prev;
$total = $total / 2;
}
if($next) {
$total += $next;
$total = $total / 2;
}
$refined[] = round($total, 0);
} else {
$refined[] = $point;
}
}
echo implode(" ", $points);
echo "<hr>";
echo implode(" ", $refined);
结果:
0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
---------------------------------------
0 0 0 0 5 10 10 10 10 13 14 15 15 15 15
要增加平滑度,您需要一种更精细的方法,它具有前瞻性、后视性和更高的采样量……您可能还可以在点之间进行插值——但我排除了这一点上面的示例。要进行插值,您可以执行以下操作:
<?php
$points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
$refined = [];
foreach($points as $index => $point) {
$prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
$next = isset($points[$index + 1]) ? $points[$index + 1] : false;
if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
$refined[] = $point;
while($next && $point < $next) {
$point++;
$refined[] = $point;
}
} else {
$refined[] = $point;
}
}
echo implode(" ", $points);
echo "<hr>";
echo implode(" ", $refined);
将产生:
0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
---------------------------------------------------------------------------
0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 11 12 13 14 15 15 15 15 15 15
要绘制图像,我们需要更多信息。数组中的点不是二维的……意味着没有 X 或 Y,除非我们假设每个点将 X 轴增加一个像素?如果是这样,这是一个粗略的镜头:
$width = count($refined);
$height = max($refined);
$gd = imagecreatetruecolor($width, $height);
// Allocate a color
$red = imagecolorallocate($gd, 255, 0, 0);
foreach($refined as $x => $y) {
imagesetpixel($gd, $x, $height-$y, $red);
}
header('Content-Type: image/png');
imagepng($gd);
我正在使用 API 获取 GPX 点的高程数据,并尝试创建它的图形表示。我的问题是 API 中的每个点相隔 90 米,而我的 GPX 点相隔 5 米,导致连续几个点在突然改变到新高度之前具有相同的高度。
基本上,我得到了这样一个数组:
[0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15...]
您如何在缓和曲线的同时将其绘制为表示海拔高度的 PNG 图像?我需要能够更改输出图片的大小。
我正在尝试将我的阵列更改为类似的东西,但我不确定该怎么做以及这是否是最佳解决方案:
[0, 0, 0, 0, 5, 5, 10, 10, 10, 12, 13, 15, 15, 15, 15...]
感谢任何提示,我不习惯处理图片和数据缓动。
这是在 "average" 基础上平滑点的基本方法:
<?php
$points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
$refined = [];
foreach($points as $index => $point) {
// make sure we don't divide by 0
$prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
$next = isset($points[$index + 1]) ? $points[$index + 1] : false;
if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
$total = $point;
if($prev) {
$total += $prev;
$total = $total / 2;
}
if($next) {
$total += $next;
$total = $total / 2;
}
$refined[] = round($total, 0);
} else {
$refined[] = $point;
}
}
echo implode(" ", $points);
echo "<hr>";
echo implode(" ", $refined);
结果:
0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
---------------------------------------
0 0 0 0 5 10 10 10 10 13 14 15 15 15 15
要增加平滑度,您需要一种更精细的方法,它具有前瞻性、后视性和更高的采样量……您可能还可以在点之间进行插值——但我排除了这一点上面的示例。要进行插值,您可以执行以下操作:
<?php
$points = [0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15];
$refined = [];
foreach($points as $index => $point) {
$prev = isset($points[$index - 1]) ? $points[$index - 1] : false;
$next = isset($points[$index + 1]) ? $points[$index + 1] : false;
if($point > 0 || ($prev && $prev > 0) || ($next && $next > 0)) {
$refined[] = $point;
while($next && $point < $next) {
$point++;
$refined[] = $point;
}
} else {
$refined[] = $point;
}
}
echo implode(" ", $points);
echo "<hr>";
echo implode(" ", $refined);
将产生:
0 0 0 0 0 10 10 10 10 10 15 15 15 15 15
---------------------------------------------------------------------------
0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 10 10 10 10 10 11 12 13 14 15 15 15 15 15 15
要绘制图像,我们需要更多信息。数组中的点不是二维的……意味着没有 X 或 Y,除非我们假设每个点将 X 轴增加一个像素?如果是这样,这是一个粗略的镜头:
$width = count($refined);
$height = max($refined);
$gd = imagecreatetruecolor($width, $height);
// Allocate a color
$red = imagecolorallocate($gd, 255, 0, 0);
foreach($refined as $x => $y) {
imagesetpixel($gd, $x, $height-$y, $red);
}
header('Content-Type: image/png');
imagepng($gd);