Справочник функций

Ваш аккаунт

Логин:
Пароль:
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:
Убрать блок ВКонтакте навсегда

Последние темы форума

Показать новые сообщения »

Почтовая рассылка



Подписчиков: 19086
Последний выпуск: 12.01.2012

Заливка сложной области

Автор: mike, www.codenet.ru
3 апреля 2005 года

Для заливки сложной замкнутой области удобно использовать функциюimagefilledpolygon:

int imagefilledpolygon ( resource image, array points, int num_points, int color )

где,

  • image- идентификатор изображения;
  • points- массив точек;
  • num_points- количество точек в полигоне;
  • color- цвет заливки.

Массив точек содержит X и Y координату каждой точки. Таким образом, для трех точек, массив содержит шесть элементов: Array( X1, Y1, X2, Y2, X3, Y3)

Пример 29.Вывод самого простого полигона (треугольник):

<?php
header ("Content-type: image/png");
$im = imagecreatetruecolor(320, 240);
$ink = imagecolorallocate($im, 255, 255, 255);

imagefilledpolygon($im, Array(
	100,100,
	120,180,
	210,160,
	), 3, $ink);

imagepng($im);
imagedestroy($im);
?>

Результат работы этой программы выглядит следующим образом:

Эта функция удобна тем, что линии полигона могут пересекаться, и заливка при этом работает корректно:

Карта России

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

Задача на первый взгляд сложная, так как контуры некоторых регионов России имеют неправильную форму и использовать функциюimagefillнельзя. По этому, я использовал функциюimagepolygonдля прорисовки контуров, и функциюimagefilledpolygonдля закрашивания регионов.

Метод, которым я нарисовал карту рассматривался в уроке 6.

Пример 30.Рисование карты России:

<?php
// Ширина и высота изображения
$W=500;
$H=375;

// Функция выводит контуры региона и закрашивает его внутреннюю часть

// $im       - идентификатор изображения
// $filename - имя файла содержащего контур региона (в формате
//             Adobe Illustrator  
// $maxw     - максимальное значение координаты X в файле с контурами
//             России (необходимо для того, чтобы все регионы
//             рисовались с одним масштабом)
// $maxh     - максимальное значение координаты Y в файле с контурами
//             России
// $color    - цвет, в который будет закрашиваться регион

function DrawIllustratorFile($im,$filename,$maxw,$maxh,$color) {
	GLOBAL $W,$H;

	// Чтения файла
	$d=file($filename);

	// Если массив $d содержит только один элемент,
	// то в качестве переноса строк используется символ
	// возврата каретки, и нам необходимо разбить текст
	// на строку вручную
	if (count($d)==1) $d=explode("\r",$d[0]);

	// С помощью регулярного выражение выберем координаты
	// всех точек.

	$poly=Array();
	for ($i=0;$i<count($d);$i++)
		if (preg_match("/([0-9.]+) ([0-9.]+) [lm]/",$d[$i],$r)) {
			$poly[]=$r[1];
			$poly[]=$r[2];
			}

	for ($i=0;$i<count($poly);$i+=2) {
		// Нормализуем координаты
		$poly[$i]/=$maxw;
		$poly[$i+1]/=$maxh;

		// Отмасштабируем координаты
		$poly[$i]*=($W-10);
		$poly[$i+1]*=($H-10);

		// Перевернем изображение по вертикали
		$poly[$i+1]=$H-$poly[$i+1];
		}

	// Вывод полигона
	imagefilledpolygon($im, $poly, count($poly)/2, $color);
	imagepolygon($im, $poly, count($poly)/2, $color["black"]);
	}

// Чтения файла
$d=file("russia.ai");

// Если массив $d содержит только один элемент,
// то в качестве переноса строк используется символ
// возврата каретки, и нам необходимо разбить текст
// на строку вручную
if (count($d)==1) $d=explode("\r",$d[0]);

// С помощью регулярного выражение выберем координаты
// всех точек и найдем точки с самыми большими координатами.
// Эти значения нам понадобятся для нормализации.
$maxw=$maxh=0;
for ($i=0;$i<count($d);$i++)
	if (preg_match("/([0-9.]+) ([0-9.]+) [lm]/",$d[$i],$r)) {
		if ($maxw<$r[1]) $maxw=$r[1];
		if ($maxh<$r[2]) $maxh=$r[2];
		}

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

// С помощью регулярного выражение выберем координаты
// всех полигонов. Формат Adobe Illustrator, прост, 
// при условии использования прямых линий
$points=Array();
$num=-1;
for ($i=0;$i<count($d);$i++) {

	// Первая точка в полигоне
	if (preg_match("/([0-9.]+) ([0-9.]+) [m]/",$d[$i],$r)) {
		$num++;
		$points[$num][]=$r[1];
		$points[$num][]=$r[2];
		}

	// Не первая точка в полигоне
	if (preg_match("/([0-9.]+) ([0-9.]+) [l]/",$d[$i],$r)) {
		$points[$num][]=$r[1];
		$points[$num][]=$r[2];
		}
	}

// Создадим изображение и выделим цвета
header ("Content-type: image/png");
$im = imagecreatetruecolor($W, $H);
$bg = imagecolorallocate($im, 255, 255, 255);
imagefilledrectangle($im,0,0,imagesx($im),imagesy($im),$bg);

$ink=imagecolorallocate($im,0,0,0);

// Вывод полигонов
for ($j=0;$j<count($points);$j++) {

	// Перерассчитанные координаты полигона
	// будем хранить в массиве $poly
	$poly=Array();

	for ($i=0;$i<count($points[$j]);$i+=2) {
		$x=$points[$j][$i];
		$y=$points[$j][$i+1];

		// Нормализуем координаты
		$x=$x/$maxw;
		$y=$y/$maxh;

		// Отмасштабируем координаты
		$x=$x*($W-10);
		$y=$y*($H-10);

		// Перевернем изображение по вертикали
		$y=$H-$y;

		// Заносим координаты в массив, по которому 
		// будет построен полигон
		$poly[]=$x;
		$poly[]=$y;
		}

	// Вывод полигона
	imagepolygon($im, $poly, count($poly)/2, $ink);
	}

// Выделим цвета для заливки регионов
$color=Array();
for ($i=196;$i<256;$i+=6) $color[]=imagecolorallocate($im,$i,$i,$i);
$color["black"]=$ink;

// Прорисовка и закрашивание регионов
DrawIllustratorFile($im,"arhangelsk.ai",$maxw,$maxh,$color[7]);
DrawIllustratorFile($im,"murmansk.ai",$maxw,$maxh,$color[5]);
DrawIllustratorFile($im,"novgorod.ai",$maxw,$maxh,$color[0]);
DrawIllustratorFile($im,"pertrozavodsk.ai",$maxw,$maxh,$color[3]);
DrawIllustratorFile($im,"pskov.ai",$maxw,$maxh,$color[8]);
DrawIllustratorFile($im,"s-petersburg.ai",$maxw,$maxh,$color[9]);
DrawIllustratorFile($im,"syktyvkar.ai",$maxw,$maxh,$color[3]);
DrawIllustratorFile($im,"vologda.ai",$maxw,$maxh,$color[4]);

imagepng($im);
imagedestroy($im);
?>

Так выглядит карта России до закрашивания регионов:

А окончательный результат работы этой программы выглядит следующим образом: (Терпения мне хватило только на обводку областей северо-западного федерального округа)

Скачать PHP скрипт рисующий карту России можно здесь.

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

Этот метод, в сочетании со сглаживанием изображения, я использовал для рисования карты мира на сайте http://top.novgorod.ru/. Вот как она выглядит:

Ссылки по теме


Назад | Оглавление | Далее

Оставить комментарий

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог