<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CTAPbIu_MABP&#039;s BLOG &#187; canvas</title>
	<atom:link href="http://mabp.kiev.ua/tag/canvas/feed/" rel="self" type="application/rss+xml" />
	<link>http://mabp.kiev.ua</link>
	<description>энтузиазм = 1/опыт © Старый Мавр</description>
	<lastBuildDate>Sat, 12 May 2012 07:40:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Canvas Overlay</title>
		<link>http://mabp.kiev.ua/2010/11/05/canvas-overlay/</link>
		<comments>http://mabp.kiev.ua/2010/11/05/canvas-overlay/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 14:56:35 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[map]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1291</guid>
		<description><![CDATA[Скуки ради решил сделать Canvas Overlay. В основе естественно Raphaël Overlay, но немного переделанный. Если все пойдет хорошо сделаю из них один. На самом деле показывать пока практически нечего. Надо еще сильно подумать над синхронизацией и выставлением интервалов. А пока пример:]]></description>
			<content:encoded><![CDATA[<p>Скуки ради решил сделать Canvas Overlay. В основе естественно <a href="http://mabp.kiev.ua/2010/09/10/raphael-overlay/">Raphaël Overlay</a>, но немного переделанный. Если все пойдет хорошо сделаю из них один.</p>
<span id="more-1291"></span>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/content/source/googlemaps/CanvasOverlay-0.1.js"></script>
<script type="text/javascript" src="/content/js/canvas-overlay.js"></script>

<p>На самом деле показывать пока практически нечего. Надо еще сильно подумать над синхронизацией и выставлением интервалов. А пока пример:</p>



<div id="map" style="width:600px;height:400px;"></div>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/11/05/canvas-overlay/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Карты генштаба 43 года</title>
		<link>http://mabp.kiev.ua/2010/10/28/maps-of-staff-43/</link>
		<comments>http://mabp.kiev.ua/2010/10/28/maps-of-staff-43/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 18:12:24 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[map]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1281</guid>
		<description><![CDATA[Давно зрела идея о черно-белых картах, да все никак руки не доходили. И вот дошли... К сожалению заменить картинки на карте Земли не получилось бы по двум причинам: Я конечно не уверен, но мне кажется, это бы нарушило лицензионное соглашение. А я хоть и не мего законопослушный но делать этого в отношении гугла не хочу... [...]]]></description>
			<content:encoded><![CDATA[<p>Давно зрела идея о черно-белых картах, да все никак руки не доходили. И вот дошли...</p>
<span id="more-1281"></span>


<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/content/source/googlemaps/EuclideanProjection.js"></script>
<script type="text/javascript" src="/content/source/googlemaps/GrayscaleMapType.js"></script>
<script type="text/javascript" src="/content/js/maps-of-staff-43.js"></script>

<p>К сожалению заменить картинки на карте Земли не получилось бы по двум причинам:</p>
<p>Я конечно не уверен, но мне кажется, это бы нарушило лицензионное соглашение. А я хоть и не мего законопослушный но делать этого в отношении гугла не хочу... вот были бы это карты от микрософта...</p>
<p>Вторая причина загадочная </p>
<blockquote>Security error" code: "1000</blockquote>
<p>Прямиком из фаербага. По идеи она возникает тогда когда я хочу получить getImageData картинки со стороннего домена. В общем я это еще узнаю.</p>
<p>Но не смотря на все трудности я все же сделал черно-белую карту с этой гнусной рожей которая мне уже порядком надоела.</p>

<div id="map" style="width: 600px; height: 800px;"></div>

<p>Куда бы его на этот раз сунуть свои шаловливые рученьки?!</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/10/28/maps-of-staff-43/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hypotrochoid</title>
		<link>http://mabp.kiev.ua/2010/10/24/hypotrochoid/</link>
		<comments>http://mabp.kiev.ua/2010/10/24/hypotrochoid/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 20:19:11 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1276</guid>
		<description><![CDATA[Много чего полезного принес мне конкурс JS1k. Вот и сегодня разбирая одну из работ я приготовил материал для статьи. На самом деле стоило бы дать линк на эту работу но я его не знаю. То есть как, автор приготовил это для конкурса, но линк на работу не дал. В общем по результатам разбора примера, найден [...]]]></description>
			<content:encoded><![CDATA[<p>Много чего полезного принес мне конкурс <a href="http://js1k.com/home" rel="nofollow external">JS1k</a>. Вот и сегодня разбирая одну из работ я приготовил материал для статьи.</p>
<span id="more-1276"></span>

<script src="/content/source/hypotrochoid.js" type="text/javascript"></script> 
<script src="/content/js/hypotrochoid.js" type="text/javascript"></script>

<p>На самом деле стоило бы дать линк на эту работу но я его не знаю. То есть как, автор приготовил <a href="http://mudcu.be/labs/JS1k/BreathingGalaxies.html" rel="nofollow external">это</a> для конкурса, но линк на работу не дал.</p>
<p>В общем по результатам разбора примера, найден проеб. При попытке оптимизировать отрисовку, оптимизация не случилась :)</p>
<p>То есть автор сделал как-то так</p>

<pre><code class="javascript">
setInterval(function(){
	while(25--){
		c.beginPath();
		x = ...
		y = ...
		if(a){
			c.moveTo(a, b);
			c.lineTo(x, y);
		}
		a = x
		b = y
		c.stroke()
	}
}, 16); 
</code></pre>

<p>пытаясь запихнуть в один интервал отрисовку нескольких линий, а надо было выкинуть beginPath и stroke за цикл</p>

<pre><code class="javascript">
setInterval(function(){
	c.beginPath();
	while(25--){
		x = ...
		y = ...
		с[!!a?"lineTo":"moveTo"](x, y);
		a = x
		b = y
	}
	c.stroke()
}, 16)
</code></pre>

<p>Но я не об этом. Я тут приготовил пример на поиграться :)</p>

<div style="margin:auto;width:400px;height:400px;" id="hypotrochoid"></div>
<div style="text-align:center;">
<label for="outerRadius">радиус</label>
<input type="text" name="outerRadius" id="outerRadius" value="0.4005"/><br/>
<label for="">цвет HSL</label>
<input type="text" name="hue" id="hue" value="100"/><br/>
<input type="button" id="apply" value="зафигачить"/>
</div>

<p>Радиус, это дробное число до 0,5. Почему до 0,5? Потому что 0,2 = 0,8 и 0,4 = 0,6. Ну вы поняли они зеркальные. Чтобы звездочка начала крутиться советую добавить 0,005. Наслаждайтесь :)</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/10/24/hypotrochoid/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Raphaël Overlay</title>
		<link>http://mabp.kiev.ua/2010/09/10/raphael-overlay/</link>
		<comments>http://mabp.kiev.ua/2010/09/10/raphael-overlay/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 00:20:16 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[Raphaël]]></category>
		<category><![CDATA[SVG]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1250</guid>
		<description><![CDATA[После недавних экспериментов я решил создать что-то, чем действительно можно пользоваться для рисования по картам. Ссылка для скачивания в самом низу страницы. Начал с примитивов - прямоугольников (картинок) и кругов (эллипсов). Дело совершенно не хитрое перевел координату в точки по карте и умножил сторону (радиус) на два в степени приближение. // рисуем круг из центра [...]]]></description>
			<content:encoded><![CDATA[<p>После <a href="http://mabp.kiev.ua/2010/08/22/google-maps-v3-and-raphael/">недавних</a> <a href="http://mabp.kiev.ua/2010/09/04/google-maps-v3-raphael-overlay/">экспериментов</a> я решил создать что-то, чем действительно можно пользоваться для рисования по картам.</p>

<span id="more-1250"></span>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/content/source/raphael/raphael-1.5.2.js"></script>
<script type="text/javascript" src="/content/source/googlemaps/RaphaelOverlay-0.9.3.js"></script>
<script type="text/javascript" src="/content/js/raphael-overlay.js"></script>

<p>Ссылка для скачивания в самом низу страницы.</p>
<p>Начал с примитивов - прямоугольников (картинок) и кругов (эллипсов). Дело совершенно не хитрое перевел координату в точки по карте и умножил сторону (радиус) на два в степени приближение.</p>

<pre><code class="javascript">

// рисуем круг из центра координат с радиусом

Overlay.prototype.onAdd = function() {
	
	var center = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(0,0)), // центр мира
		worldWidth = this.getProjection().getWorldWidth(); // длина мира
			
	this.div = document.createElement('div'); // наш слой
	this.div.style.border = 'none';
	this.div.style.position = 'absolute';
	this.div.style.overflow = 'visible';
	this.div.style.left = center.x - worldWidth / 2 + 'px'; // от левого края карты
	this.div.style.top = center.y - worldWidth / 2 + 'px'; // от верха карты
	this.div.style.width = worldWidth+'px'; // шириной в карту
	this.div.style.height = worldWidth+'px'; // высотой в карту
	
	// таким образом див полностью перекрывает одну (центральную) секцию карты
	// заметте, карта повторяеться горизонтально 
	// но этот слой лежит только поверх одной секции не перекрывая соседние
	
	this.getPanes().overlayImage.appendChild(this.div); // добавляем слой на карту
	this.canvas = Raphael(this.div); // делаем из слоя холст для рисования
	
};

Overlay.prototype.draw = function() {
	var center = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(0,0)), // центр круга
		worldWidth = this.getProjection().getWorldWidth(), // длина карты
		left = center.x - worldWidth / 2, // край карты
		top = center.y - worldWidth / 2, // край карты
		scale = 1 &lt;&lt; this.getMap().getZoom(), // увеличение ( Math.pow(2, zoom))
		r = scale * radius, // реальный радиус
		x = center.x - left, // координата по слою
		y = center.y - top; // координата по слою
		
		this.canvas.clear(); // чистим холст от старых картинок
		this.canvas.circle(x, y, r); // рисуем круг
		
}

</code></pre>

<p>Вот собственно простейший пример и готов. Но мне же этого мало! А что если круг нарисовать с радиусом больше чем worldWidth/2? Тогда он будет вылазить за рамки слоя и будет обрезан по краям. Но это же не кошерно (или не по фен-шую :) ). Что же делать? Надо расширить слой. Слой расширяется в четырех направлениях так как он выпирает за границы слоя со всех четырех сторон. просто расширить слой не достаточно потому как див перестанет выпирать только справа и снизу, надо еще сместить див влево и вверх, но если сместили див надо поправить координаты круга. Для тех кто не дружит с математикой как я все страшно запутано поэтому показываю на примере.</p>

<pre><code class="javascript">

// r > worldWidth / 2 по условию

Overlay.prototype.draw = function() {
	var center = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(0,0)), // центр круга
		worldWidth = this.getProjection().getWorldWidth(), // длина карты
		left = center.x - worldWidth / 2, // край карты
		top = center.y - worldWidth / 2, // край карты
		scale = 1 &lt;&lt; this.getMap().getZoom(), // увеличение ( Math.pow(2, zoom))
		r = scale * radius, // реальный радиус
		x = center.x - left, // координата по слою
		y = center.y - top, // координата по слою
		
		// отступы
		offsetLeft = r - x,
		offsetTop = r - y,
		offsetRight = r + x - worldWidth,
		offsetBottom = r + y - worldWidth,
		
		// длина и высота учитывая отступы
		fullWorkdWidth = offsetLeft + worldWidth + offsetRight,
		fullWorkdHeight = offsetTop + worldWidth + offsetBottom;
		
		// изменяем положение слоя и размеры холста
		this.div.style.left = left - offsetLeft + 'px';
		this.div.style.top = top - offsetTop + 'px';
		this.div.style.width = fullWorkdWidth + 'px';
		this.div.style.height = fullWorkdHeight + 'px';
		this.canvas.setSize(fullWorkdWidth, fullWorkdHeight);
		
		this.canvas.clear();
		this.canvas.circle(x, y, r); // рисуем круг
		
}

</code></pre>

<p>В результате получаеться где-то такая фигура</p>

<div id="map1" style="width:600px;height:400px;"></div>

<p>Примерно так же рассчитываться прямоугольники, но показывать их просто так не интересно, интересно станет когда фигур на карте будет больше одной и выпирать они будут за края карты с разных сторон и на разную длину. В этом случаи надо сначала просчитать все фигуры, найти максимальные отступы, подвинуть слой, сместить фигуры и только потом что-то рисовать. Пробуем:</p>

<div id="map2" style="width:600px;height:400px;"></div>

<p>Походу с примитивами разобрались, Но кому нужны эти примитивы? Все хотят отмечать на карте разного рода кривые и полигоны (многогранники), что же, нужно и это реализовать. Возьмем пример которым пользуется Dmitry Baranovskiy, автор RaphaelJS - это <a href="http://ru.wikipedia.org/wiki/Лист_Мёбиуса" rel="nofollow external">петля Мёбиуса</a>, знак бесконечности или просто перевернутая восьмерка для людей без воображения. Задаётся она вот такими координатами <span style="color:#107020;font-weight:bold;">M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z</span>. Координаты как вы ведите относительные (это видно из маленьких "с"), но даже если бы они были абсолютными это было бы не страшно. Первое что делаем переводим абсолютные в относительные, потом смещаем первую точку куда нам надо и умножаем все остальные точки по известной формуле.</p>


<pre><code class="javascript">

Overlay.prototype.draw = function() {
	var center = this.getProjection().fromLatLngToDivPixel(new google.maps.LatLng(0,0)), // точка смещения
		worldWidth = this.getProjection().getWorldWidth(), // длина карты
		left = center.x - worldWidth / 2, // край карты
		top = center.y - worldWidth / 2, // край карты
		scale = 1 &lt;&lt; this.getMap().getZoom(), // увеличение ( Math.pow(2, zoom))
		path = Raphael.pathToRelative(Raphael.parsePathString("M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z"));
		line = [];
			
		for (var i in path) {
			for (var j in path[i]) {
				if (j == 0) {
					line[i] = [path[i][j]]; // буква
				} else if (i==0 &#038;& j==1) {
					line[i].push(center.x - left + path[i][j]); // начальная точка по X
				} else if (i==0 &#038;& j==2) {
					line[i].push(center.y - top + path[i][j]); // начальная точка по Y
				} else {
					line[i].push(path[i][j] * scale);  // все остальные точки
				}
			}
		}
		
		this.canvas.clear();
		this.canvas.path(line);
		
}

</code></pre>

<div id="map3" style="width:600px;height:400px;"></div>

<p>Единственный минус рисования кривой (как и текста), это то что пока не нарисуешь не узнаешь размеров, конечно можно долго высчитывать их по координатам но по моему это того не стоит, особенно если координаты относительные. С другой стороны узнать размер можно после рисования, вытереть и сместить все что нужно и нарисовать по новой, но по моему это требует еще больше усилий, хотя формулой для этого я не поделиться не могу.</p>

<pre><code class="javascript">

	// для кривой (рисуеться с левого верхнего края)
	var path = this.canvas.path(line),
		width = path.getBBox().width,
		height = path.getBBox().height,
		x = point.x - left,
		y = point.y - top;
		
	// для текста (рисуеться из центра)
	var text = this.canvas.text(point.x, point.y, text),
		width = text.getBBox().width,
		height = text.getBBox().height,
		x = point.x - width / 2 - left,
		y = point.y - height / 2 - top;

</code></pre>

<p>С основными возможностями и трудностями рисования разобрались переходим к конкретным примерам</p>

<p>Прямоугольники</p>
<p>Есть пять разный вариантов нарисовать прямоугольник</p>
<ul>
<li>Ограничить область на карте с помощью границ (LatLngBounds)</li>
<li>Нарисовать как во всех графических редакторах из верхнего левого угла с привязкой к координате</li>
<li>Нарисовать как круг указав координату центра</li>
<li>Нарисовать от левого верхнего угла в определенной точке на карте, при этом надо знать размер дива с картой и сам прямоугольник не будет менять позиции про движении карты, а уедет за край видимой области</li>
<li>То же что и предыдущий, только из центра</li>
</ul>

<pre><code class="javascript">

	var map = new google.maps.Map(document.getElementById("map"), {
		zoom: 0,
		center: new google.maps.LatLng(0,0),
		mapTypeId: google.maps.MapTypeId.SATELLITE
	});

	new RaphaelOverlay({
		map:map,
		shapes : [{
			// прямоугольник ограниченный парой координат
			// может пропадать при движении карты
			// из-за отрицательной длинны
			position : new google.maps.LatLngBounds(
				// верхний првым угол (north-east)
				new google.maps.LatLng(-50, -100), 
				// нижний левый угол (south-west)
				new google.maps.LatLng(50, 100)
			),
			type: "rect",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#00f', 
				"fill-opacity": 0.3
			}
		},{
			// обычный прямоугольник нарисованный 
			// из верхнего левого угла
			// от координат 
			position : new google.maps.LatLng(85, -175),
			// и имеющий размеры 100x100
			size : new google.maps.Size(100, 100),
			type: "rect",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#0f0', 
				"fill-opacity": 0.3
			}
		},{
			// прямоугольник нарисованный 
			// из центра
			// от координат
			center : new google.maps.LatLng(-85, 175),
			// и имеющий размеры 100x100
			size : new google.maps.Size(100, 100),
			type: "rect",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		},{
			// прямоугольник нарисованный 
			// из верхнего левого угла
			// от верхнего левого угла карты
			// такой прямоугольник не меняет позиции 
			// при движении карты
			position : new google.maps.Point(300, 100),
			size : new google.maps.Size(100, 100),
			type: "rect",
			// скругление углов
			radius: 10,
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#ff0', 
				"fill-opacity": 0.3
			}
		},{
			// такой же как предыдущий, только 
			// из центра 
			center : new google.maps.Point(300, 100),
			size : new google.maps.Size(100, 100),
			type: "rect",
			// скругление углов
			radius: 10,
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f0f', 
				"fill-opacity": 0.3
			}
		}]
	});

</code></pre>

<div id="map4" style="width:600px;height:400px;"></div>

<p>Картинки</p>
<p>По большому счету ничем не отличаются от прямоугольников, кроме того что имеют ссылку на картинку и не имеют скругления углов</p>

<pre><code class="javascript">

	new RaphaelOverlay({
		map:map,
		shapes : [{
			// ссылка на картинку
			src : "http://upload.wikimedia.org/wikipedia/commons/d/d6/Wikipedia-logo-v2-en.png",
			position : new google.maps.LatLng(85, -175),
			size : new google.maps.Size(135, 155),
			type: "image"
		}]
	});

</code></pre>

<div id="map5" style="width:600px;height:400px;"></div>

<p>Круги и овалы</p>

<pre><code class="javascript">

	new RaphaelOverlay({
		map:map,
		shapes : [{
			// у круга центр совпадает с позицией
			// но центр приоритетнее
			center: new google.maps.LatLng(85, 175),
			type: "circle",
			radius: 100,
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#0f0', 
				"fill-opacity": 0.3
			}
		},{
			// как и квадрат круг и овал можно рисовать
			// из фиксированной точки
			position: new google.maps.Point(300, 100),
			type: "circle",
			radius: 100,
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		},{
			// овал отличается от круга двумя радиусами
			position: new google.maps.LatLng(-85, -175),
			type: "ellipse",
			rx: 100,
			ry: 50,
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#00f', 
				"fill-opacity": 0.3
			}
		}]
	});

</code></pre>

<div id="map6" style="width:600px;height:400px;"></div>

<p>Кривые и полигоны</p>

<pre><code class="javascript">

	new RaphaelOverlay({
		map:map,
		shapes : [{
			// Фигура нарисованная по координатам
			// может менять ширину при движении карты
			position : [
				new google.maps.LatLng(84, -175),
				new google.maps.LatLng(84, 175),
				new google.maps.LatLng(0, 0)
			],
			type: "polygon",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		},{
			// Фигура нарисованная по кривой 
			// с абсолютными координатами
			position: new google.maps.LatLng(85, -175),
			path: "M 0 0 L 200 0 L 100 200 z",
			type: "path",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		},{
			// Фигура нарисованная по кривой 
			// с относительными координатами
			position: new google.maps.LatLng(85, -175),
			path: "M100,100c0,50 100-50 100,0c0,50 -100-50 -100,0z",
			type: "path",
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		}]
	});

</code></pre>

<div id="map7" style="width:600px;height:400px;"></div>

<p>Текст</p>
<pre><code class="javascript">

	new RaphaelOverlay({
		map:map,
		shapes : [{
			position: new google.maps.LatLng(0, 0),
			text : "CTAPbIu_MABP",
			type: "text",
			attr : {
				fill: '#fff', 
				"font-size" : 20
			}
		}]
	});

</code></pre>

<div id="map8" style="width:600px;height:400px;"></div>

<p>Похоже это все, забыл только сказать что есть еще настройка приближения. Поскольку во всех примерах приближение поставлено минимальное, то при приближении хотя бы 10 все фигуры распадутся и будет очень некрасиво. Это происходит по разным причинам - кривизна SVG или VML или переполнение int32 в параметре ширины или высоты. Поэтому я сделал поправку на приближение. Первых два пункта интуитивно понятны это минимальное и максимальное приближение на котором видно фигуру, а третий пункт это приближение на котором заданы координаты кривых. То есть фигуру видно с 3 по 5 приближение, но координаты были рассчитаны при нулевом то можно это указать, иначе считается что они были заданы по меньшему из видимых. Смотрите пример с 3 по 5 приближение возле маркера.</p>

<pre><code class="javascript">

	new RaphaelOverlay({
		map:map,
		shapes : [{
			position: new google.maps.LatLng(0, 0),
			path: "M0,0c0,50 100-50 100,0c0,50 -100-50 -100,0z",
			type: "path",
			zoom : {
				min : 3,
				max : 5,
			},
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		},{
			position: new google.maps.LatLng(0, 0),
			path: "M0,0c0,50 100-50 100,0c0,50 -100-50 -100,0z",
			type: "path",
			zoom : {
				min : 3,
				max : 5,
				adjusted : 0
			},
			attr : {
				stroke: '#fff', 
				"stroke-width":2, 
				fill: '#f00', 
				"fill-opacity": 0.3
			}
		}]
	});

</code></pre>

<div id="map9" style="width:600px;height:400px;"></div>

<p> Скачать скрипт можно тут <a href="http://mabp.kiev.ua/content/source/googlemaps/RaphaelOverlay-0.9.3.js">DOWNLOAD LINK</a>. Вот и все, надеюсь будет хоть кому-то полезно!</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/09/10/raphael-overlay/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Прямоугольник с закругленными углами на холсте</title>
		<link>http://mabp.kiev.ua/2010/09/03/rectangle-with-rounded-corners-on-canvas/</link>
		<comments>http://mabp.kiev.ua/2010/09/03/rectangle-with-rounded-corners-on-canvas/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 18:42:11 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1246</guid>
		<description><![CDATA[По моему название не очень звучит? Ну да неважно, в общем это еще один черновик от которого пора избавиться. Встречайте функция для рисования закругленных углов. function roundedRect(ctx,x,y,width,height,radius){ ctx.beginPath(); ctx.moveTo(x,y+radius); ctx.lineTo(x,y+height-radius); ctx.quadraticCurveTo(x,y+height,x+radius,y+height); ctx.lineTo(x+width-radius,y+height); ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); ctx.lineTo(x+width,y+radius); ctx.quadraticCurveTo(x+width,y,x+width-radius,y); ctx.lineTo(x+radius,y); ctx.quadraticCurveTo(x,y,x,y+radius); ctx.stroke(); } Работает как-то так:]]></description>
			<content:encoded><![CDATA[<p>По моему название не очень звучит? Ну да неважно, в общем это еще один черновик от которого пора избавиться. Встречайте функция для рисования закругленных углов.</p>

<span id="more-1246"></span>

<script type="text/javascript" src="/content/js/rectangle-with-rounded-corners-on-canvas.js"></script>  

<pre><code class="javascript">
function roundedRect(ctx,x,y,width,height,radius){
	ctx.beginPath();
	ctx.moveTo(x,y+radius);
	ctx.lineTo(x,y+height-radius);
	ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
	ctx.lineTo(x+width-radius,y+height);
	ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
	ctx.lineTo(x+width,y+radius);
	ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
	ctx.lineTo(x+radius,y);
	ctx.quadraticCurveTo(x,y,x,y+radius);
	ctx.stroke();
}
</code></pre>

<p>Работает как-то так:</p>

<div style="text-align:center;">
	<canvas id="canvas" width="150" height="150"></canvas>
</div>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/09/03/rectangle-with-rounded-corners-on-canvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Куб с градиентом</title>
		<link>http://mabp.kiev.ua/2009/07/14/cube-with-a-gradient/</link>
		<comments>http://mabp.kiev.ua/2009/07/14/cube-with-a-gradient/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 21:12:22 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1094</guid>
		<description><![CDATA[Поработал еще над кубом, теперь рисуются только те грани и ребра которые видны. Странно что при размере куба 10, грани перестают быть видимыми если общая сумма углов грани по оси Z равно 150. При изменении размера куба никаких пропорций найти не удалось :( Еще хотел натянуть на грани текстуры но у меня явно не тот [...]]]></description>
			<content:encoded><![CDATA[<p>Поработал еще над кубом, теперь рисуются только те грани и ребра которые видны. Странно что при размере куба 10, грани перестают быть видимыми если общая сумма углов грани по оси Z равно 150. При изменении размера куба никаких пропорций найти не удалось :(</p>

<p>Еще хотел натянуть на грани текстуры но у меня явно не тот подход к рисованию и я решил что лучше забить. Зато натянул на куб градиент:</p>
<span id="more-1094"></span>
<script type="text/javascript" src="/content/source/cube/cube-0.4.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>Цацкайтесь на здоровье, пишите где мои проебы, как их поправить или просто пишите. Следующих версий ждать не стоит я скорее всего займусь чем-то на <a href="http://mabp.kiev.ua/category/programming/java/">Java</a>, или на YUI.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/14/cube-with-a-gradient/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Куб3</title>
		<link>http://mabp.kiev.ua/2009/07/13/cube3/</link>
		<comments>http://mabp.kiev.ua/2009/07/13/cube3/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 18:39:56 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1092</guid>
		<description><![CDATA[Это третья версия кубика, на этот раз со стеклянными гранями, развлекайтесь: Из изменений: добавлина матрица граней, то есть порядок соединения вершин this.G = [ [0,1,2,3,4,5], [1,2,3,0,5,6], [2,6,7,4,1,2], [3,5,6,7,0,1], ] и новый цикл для обхода матрицы for(var i=0;i&#60;6;i++){ this.plot.beginPath(); this.plot.fillStyle = "rgba("+(i&#60;3?255:0)+","+((i&#60;1&#124;&#124;i&#62;3)?255:0)+","+(i&#62;2?255:0)+",0.5)"; this.plot.moveTo(this.V2d[0][this.G[0][i]],this.V2d[1][this.G[0][i]]); this.plot.lineTo(this.V2d[0][this.G[1][i]],this.V2d[1][this.G[1][i]]); this.plot.lineTo(this.V2d[0][this.G[2][i]],this.V2d[1][this.G[2][i]]); this.plot.lineTo(this.V2d[0][this.G[3][i]],this.V2d[1][this.G[3][i]]); this.plot.closePath(); this.plot.fill(); } PS Пользователи IE идут на хуй, потому [...]]]></description>
			<content:encoded><![CDATA[<p>Это третья версия кубика, на этот раз со стеклянными гранями, развлекайтесь:</p>
<span id="more-1092"></span>

<script type="text/javascript" src="/content/source/cube/cube-0.3.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>Из изменений: добавлина матрица граней, то есть порядок соединения вершин </p>

<pre><code class="javascript">
this.G = [
	[0,1,2,3,4,5],
	[1,2,3,0,5,6],
	[2,6,7,4,1,2],
	[3,5,6,7,0,1],
]
</code></pre>
<p>и новый цикл для обхода матрицы</p>

<pre><code class="javascript">
for(var i=0;i&lt;6;i++){
	this.plot.beginPath();
	this.plot.fillStyle = "rgba("+(i&lt;3?255:0)+","+((i&lt;1||i&gt;3)?255:0)+","+(i&gt;2?255:0)+",0.5)";
	this.plot.moveTo(this.V2d[0][this.G[0][i]],this.V2d[1][this.G[0][i]]);
	this.plot.lineTo(this.V2d[0][this.G[1][i]],this.V2d[1][this.G[1][i]]);
	this.plot.lineTo(this.V2d[0][this.G[2][i]],this.V2d[1][this.G[2][i]]);
	this.plot.lineTo(this.V2d[0][this.G[3][i]],this.V2d[1][this.G[3][i]]);
	this.plot.closePath();
	this.plot.fill();
}
</code></pre>
<p>PS Пользователи <a href="http://mabp.kiev.ua/tag/ie/">IE</a> идут на хуй, потому что он не поддерживает полупрозрачности фона rgba(255,255,255,0.5)</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/13/cube3/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Кубик Маврика</title>
		<link>http://mabp.kiev.ua/2009/07/13/mabps-cube/</link>
		<comments>http://mabp.kiev.ua/2009/07/13/mabps-cube/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 09:33:58 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1089</guid>
		<description><![CDATA[Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже квадрат на плоскости развернуть. Но терпение и труд все перетрут, наверное ;) Вторая редакция кубика не имеет ничего общего с первой. Все полностью переделано. Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже <a href="http://mabp.kiev.ua/2009/07/10/square-mavrevicha/">квадрат</a> на плоскости развернуть. Но терпение и труд все перетрут, наверное ;)</p>
<span id="more-1089"></span>
<p>Вторая редакция кубика не имеет ничего общего с <a href="http://mabp.kiev.ua/2009/07/12/cube-mauritius/">первой</a>. Все полностью переделано.  Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота куба, я решил сделать так, как делается в нормальнйо трехмерной графике. Нарисовать сцену, положить в координаты [0,0,0] центр куба, по векторам высчитать вершины и нарисовать между ними линии. Что собственно с успехом и реализовал.</p>

<script type="text/javascript" src="/content/source/cube/cube-0.2.js"></script>
<script type="text/javascript" src="/content/source/excanvas.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>теперь как видите ничего нигде не точит и все прекрасно отображается. пришлось конешно пошаманить, прописать все углы, ребра и векторы но зато теперь все идеально. Куб можно изменять в размерах, отдалять и приближать "камеру", красить в произвольный цвет и все это при помощи настроек.</p>

<p>По просьбе Adw0rd'a выкладываю сырцы которые все это генерируют:</p>

<pre><code class="javascript">
Cube = function(options){
	this.init(options);
}

Cube.prototype = {
	
	color : "#000000", // цвет граней
	plot : null, // 2d context
	size : 10, // размер куба
	focalLens : 0, // расстояние от центра куба до камеры
	theta : [0,0], // углы поворотов по осям в радианах
	V2d : [[],[]], // вектора в двухмерной проекции
	
	T : [], // Translation vector
	E : [[],[]], // Edges
	R : [[],[],[]], // Rotation matrix
	V : [[],[],[]], // Vertices

	init : function(options){
		
		for (var i in options)
			this[i] = options[i];
			
		if(!this.focalLens)
			this.focalLens = this.plot.canvas.width;
			
		var self = this;
		document.onmousemove = function(event){
			self.theta = [event.clientX / 100, event.clientY / 100];
			self.draw();
		}			
			
		this.createScene();
		this.draw();
	},
	
	createScene : function (){
		var s = this.size;
		
		this.V = [
			[-s, s, s,-s,-s, s, s,-s],
			[-s,-s, s, s,-s,-s, s, s],
			[-s,-s,-s,-s, s, s, s, s],
		];
		
		this.E = [
			[0,1,2,3,4,5,6,7,0,1,2,3],
			[1,2,3,0,5,6,7,4,4,5,6,7],
		];
		
		this.R = [
			[1,0,0],
			[0,1,0],
			[0,0,1],
		];
		
		this.T = [0,0,0];
	},

	updVertices : function (){
		var x, y, z;
		
		for(var i=0;i&lt;8;i++){
			x=this.R[0][0]*this.V[0][i]+this.R[0][1]*this.V[1][i]+this.R[0][2]*this.V[2][i]+this.T[0];
			y=this.R[1][0]*this.V[0][i]+this.R[1][1]*this.V[1][i]+this.R[1][2]*this.V[2][i]+this.T[1];
			z=this.R[2][0]*this.V[0][i]+this.R[2][1]*this.V[1][i]+this.R[2][2]*this.V[2][i]+this.T[2];

			this.V2d[0][i]=this.plot.canvas.width/2+x*this.focalLens/z;
			this.V2d[1][i]=this.plot.canvas.height/2+y*this.focalLens/z;
		}
	},


	setTransformation : function (x, y, z, anglex, angley){
		var 
		sx = Math.sin(anglex),
		cx = Math.cos(anglex),
		sy = Math.sin(angley),
		cy = Math.cos(angley);
		
		this.R = [
			[ cx   , 0 ,  sx],
			[ sx*sy, cy, -cx*sy],
			[-sx*cy, sy,  cx*cy],
		];
		this.T = [x,y,z];
	},

	drawModel : function (){
		this.plot.beginPath();
		this.plot.strokeStyle=this.color;
		for(var i=0;i&lt;12;i++){
			this.plot.moveTo(this.V2d[0][this.E[0][i]],this.V2d[1][this.E[0][i]]);
			this.plot.lineTo(this.V2d[0][this.E[1][i]],this.V2d[1][this.E[1][i]]);
			this.plot.stroke();
		}
	},
	
	drawCells : function(){
		this.plot.fillStyle="black";
		for(var i=100,l=this.plot.canvas.width;i&lt;l;i+=100){
			this.plot.fillRect(0,i,l,1);
			this.plot.fillRect(i,0,1,l);
		}
	
	},

	draw : function (){
		var self = this;

		this.plot.clearRect(0,0,this.plot.canvas.width,this.plot.canvas.height);
		this.setTransformation(0.0, 0.0, 40.0, this.theta[0], this.theta[1]);
		this.updVertices();
		this.drawCells();
		this.drawModel();
	},
}


window.onload=function(){
	var plot = document.getElementById("cube").getContext("2d"),
	
	cube = new Cube({plot:plot,color:"#00FF00",size:10});
}
</code></pre>


<p>И еще три строчки HTML:</p>

<pre><code class="html">
&lt;script type="text/javascript" src="/content/source/cube-0.2.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/content/source/excanvas.js"&gt;&lt;/script&gt;
&lt;div style="text-align:center;"&gt;&lt;canvas  id="cube" width="500" height="500"/&gt;&lt;/div&gt;
</code></pre>

<p>но это не конец, в следующей версии планируется натяжка текстур на грани и добавление света, или раскраска сторон с добавлением полупрозрачности, я еще не решил что буду делать.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/13/mabps-cube/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Куб Маврикия</title>
		<link>http://mabp.kiev.ua/2009/07/12/cube-mauritius/</link>
		<comments>http://mabp.kiev.ua/2009/07/12/cube-mauritius/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 13:56:20 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1088</guid>
		<description><![CDATA[Название изначально задумывалось как "Кубик Маврика", на подобие с Кубиком Рубика, но Google перевел его как "cube mauritius", что означает "Куб Маврикия", так и оставил. После записи о вращении квадрата я немного полистал учебники по геометрии, и даже "основы учебного академического рисунка", и поднабрался знаний по поводу того что и как должно быть. И вот [...]]]></description>
			<content:encoded><![CDATA[<p>Название изначально задумывалось как "Кубик Маврика", на подобие с Кубиком Рубика, но <a href="http://mabp.kiev.ua/tag/google/">Google</a> перевел его как "cube mauritius", что означает "Куб Маврикия", так и оставил.</p>

<p>После записи о <a href="http://mabp.kiev.ua/2009/07/10/square-mavrevicha/">вращении квадрата</a> я немного полистал учебники по геометрии, и даже "основы учебного академического рисунка", и поднабрался знаний по поводу того что и как должно быть. И вот пришло время поделится этим с вами.</p>
<span id="more-1088"></span>

<p>Я решил что до того как рисовать красивые полупрозрачные грани неплохо было бы научится вращать вершины. Чем собственно и занялся. Четыре точки вращаются в трех плоскостях. Но там немного хитро по оси OX вращение происходит при передвижении мышки вперед назад, а по оси OY и/или OZ происходит при передвижении мышки из стороны в сторону и зависит от того на какой грани лежит куб.</p>

<p>Развлекаемся:</p>
<script type="text/javascript" src="/content/source/cube/cube-0.1.js"></script>
<script type="text/javascript" src="/content/source/excanvas.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>Весь код показывать не буду, если захотите посмотрите, но главную функцию, которая рассчитывает позиции вершин обязательно надо показать.</p>

<pre><code class="javascript">
function(){
	var data = [],
	dim = this.dimension,
	o = this.theta;
	for (var x = -dim; x <= dim; x += 2 * dim)
		for (var y = -dim; y <= dim; y += 2 * dim)
			for (var z = -dim; z <= dim; z += 2 * dim){
				var 
				a = x * Math.cos(o.x) - y * Math.sin(o.x),
				b = x * Math.sin(o.x) + y * Math.cos(o.x),
				c = b * Math.cos(o.y) - z * Math.sin(o.y),
				d = b * Math.sin(o.y) + z * Math.cos(o.y);
				data.push({
					left : 250 + a * (d + 2) * 50,
					top  : 250 + c * (d + 2) * 50,
				});
			}
	return data;
}
</code></pre>

<p>Единственным недостатком такого способа расчета координат есть то, что если поставить куб так чтобы взгляд шел сразу по двум граням, то дальняя вершина, которая должна сливаться с передней (то есть взгляд должен идти по ребру) сильно выходит за рамки куба. Но я так понял что я не первый кто пользуется этим способом, так что думаю что ничего страшного.</p>
<p>В планах на ближайшее будущее новый куб у которого ничего никуда не вылазит.</p>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/12/cube-mauritius/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Квадрат Мавревича</title>
		<link>http://mabp.kiev.ua/2009/07/10/square-mavrevicha/</link>
		<comments>http://mabp.kiev.ua/2009/07/10/square-mavrevicha/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 13:31:57 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1085</guid>
		<description><![CDATA[В школе терпеть не мог математику, особенно тригонометрию. И вот те на - вырос и понял что неплохо было бы перечитать учебник за 7-8-9 (какой то там) класс. А все почему потому что в течении 4 часов не мог развернуть несчастный 4-х угольник на 30 градусов. В оригинале конечно был квадрат, но то что я [...]]]></description>
			<content:encoded><![CDATA[<p>В школе терпеть не мог математику, особенно тригонометрию. И вот те на -  вырос и понял что неплохо было бы перечитать учебник за 7-8-9 (какой то там) класс. А все почему потому что в течении 4 часов не мог развернуть несчастный 4-х угольник на 30 градусов. В оригинале конечно был квадрат, но то что я из него делал можно с натяжкой назвать даже 4-х угольником. Я его даже пару раз в бантик завязал.</p>

<span id="more-1085"></span>

<script type="text/javascript" src="/content/source/excanvas.js"></script>
<script type="text/javascript" src="/content/js/square-of-mavrevich.js"></script>

<p>А началось все с того что я увидел имитацию <a href="http://www.benjoffe.com/code/demos/canvascape/" rel="nofollow external">Counter Strike</a> нарисованную при помощи векторной графике и <a href="http://mabp.kiev.ua/tag/javascript/">javascript</a> в canvas. Я решил написать нечто подобное. Но с чего начать? Я решил нарисовать кубик который можно вращать во все стороны. До кубика дело не дошло. Проблемы возникли еще с первой стороной. Блядская математика. В общем как я уже говорил, я пытался повернуть квадрат хоть как-нибудь, хоть куда-нибудь целых 4 часа. Более того не сумел найти ни одно учебника по 2D графике в котором бы внятно описывалось как создавать псевдо-трехмерные объекты, с формулами. Ближе к часу ночи вспомнил про книгу "Как самому создать трехмерную игру", вспомнил громким матом. Выругался и полез искать учебник по математике для школы, нашел <a href="http://www.mathematics.ru/" rel="nofollow external">mathematics.ru</a>, стало немного проще, но все равно квадратик развернулся только в два ночи, когда я синусы, косинусы, плюсы и минусы расставлял почти не думая, пытаясь забрутфорсить формулу.</p>
<p>Вот такая хоботня у меня получилась: красным цветом исходный квадрат, черным - повернутый.</p>

<div style="text-align:center;"><canvas  id="sqrt" width="400" height="400"/></div>

<p>Рисуется это вот таким мегаламерским кодом засунутым в онлоад, ничего я скоро исправлюсь.</p>

<pre><code class="javascript">
	var plot = document.getElementById("sqrt").getContext("2d"),
	theta = 30 * Math.PI / 180,
	delta = [Math.cos(theta),Math.sin(theta)];
	radius = 100 * Math.sqrt(2);

	// Горизонтальные полосы
	plot.fillRect(0,100,400,1)
	plot.fillRect(0,200,400,1)
	plot.fillRect(0,300,400,1)
	
	// Вертикальные полосы
	plot.fillRect(100,0,1,400)
	plot.fillRect(200,0,1,400)
	plot.fillRect(300,0,1,400)
	
	// Красный квадрат
	plot.beginPath();
	plot.fillStyle = "red";
	plot.moveTo(100, 100);
	plot.lineTo(100, 300);
	plot.lineTo(300, 300);
	plot.lineTo(300, 100);
	plot.closePath();
	plot.fill();
	
	// черный квадрат Малевича
	plot.beginPath();
	plot.fillStyle = "black";
	plot.moveTo(200 - radius * delta[1], 200 - radius * delta[0]);
	plot.lineTo(200 + radius * delta[0], 200 - radius * delta[1]);
	plot.lineTo(200 + radius * delta[1], 200 + radius * delta[0]);
	plot.lineTo(200 - radius * delta[0], 200 + radius * delta[1]);
	plot.closePath();
	plot.fill();
</code></pre>

<p>Спонсор картинки в <a href="http://mabp.kiev.ua/tag/ie/">IE 6 и 7</a> - Google co своим скриптом <a href="http://code.google.com/p/explorercanvas/" rel="nofollow external">explorercanvas</a>, <a href="http://mabp.kiev.ua/tag/ie/">IE 8</a> идет на хуй.</p>
<p>Вывод из этой басни такой: надо было учить математику в школе, а потом появляются посты такие как этот и <a href="http://mabp.kiev.ua/2009/01/27/markovs-chains/">прошлый</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/10/square-mavrevicha/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

