Глава 2  ◄     Содержание     ►   Глава 4


Three.js и геометрия.   Глава 3   Библиотека WebGeometry и холст HTML5 (часть 1)

Перейдем к рассмотрению библиотеки WebGeometry используемой для рачета координат вершин 3D моделей. Oписание всех входящих в нее функций можно найти здесь. Библиотека включает в себя Javascript функциии для работы с 2D и 3D объектами. В основном для построения моделей используются трехмерные объекты библиотеки - 3D-точки, 3D-вектора, прямые в пространстве и плоскости. Но иногда требуются и чисто двумерные объекты - 2D-точки, 2D-вектора, прямые на плоскости и окружности. В библиотеке 2D и 3D объекты четко разделены. Отдельно присутствут функции для построений на плоскости и отдельно для построений в пространстве. Кроме того в библиотеке большую роль играют функции для работы с матрицами. Для 2D и 3D матриц также присутствуют функции для обеих размерностей по отдельности. Но функции с матрицами нам практически никогда не понадобятся, хотя они играют очень важную роль в библиотеке WebGeometry. На их основе построены функции работающие с точками, прямыми и плоскостями, которые нам требуются в дальнейшем для построения многогранников.
  Начнем с рассмотрения функций библиотеки предназначенных для работы с 2D объектами. В данном разделе мы рассмотрим на примерах как можно использовать функции библиотеки WebGeometry применительно к построениям на плоскости.

Точка на холсте

В показанной ниже программе показано как можно расположить 2D-точку на холсте. При помощи контроллера dat.GUI точку можно перемещать по холсту.

Основная часть исходного текста программы с подробными комментариями объясняющими ее работу:

	var elem1 = document.getElementById('canvas_01');
	var ctx1 = elem1.getContext("2d");
	elem1.style.position = "relative";
	elem1.style.border = "1px solid";

/*
   // Функции сопряжения координат холста с координатами используемыми в WebGeometry, WebGL и three.js
   // Используются внутри функций csp, axes, txt_c (и других ...) для пересчета координат используемых 
   // в WebGeometry, WebGL и three.js в координаты используемые при построениях на холсте (HTML5 canvas).
   function fx(val)
   {
	  var res = val * SCALE + xC;
	  return res;
   }

   function fy(val)
   {
	  var res = - val * SCALE + yC;
	  return res;
   }	
*/	
	
	SCALE = 100;           // задает масштаб
	xC = elem2.width / 2;  // задает положение начала координат по оси OX
	yC = elem2.height / 2; // задает положение начала координат по оси OY
	
	// начало координат
	var pt00 = new Point2D(0, 0);
	// рисуем точку в начале координат коричневым цветом
	csp(ctx1, pt00, 2, "Brown");
	// обозначаем начало координат символом "O" коричневым цветом
	text1(ctx1, "O", pt00, "rt", "up", "Brown");
	// рисуем оси коричневым цветом с размахом линий по OX и OY равным 1.8
	axes(ctx1, 1.8, 1.8, 0.5, "Brown");
	
	// canvas ctx1
	// точка с координатами ( 1.2, -1.2)
	var pt0 = new Point2D( 1.2, -1.2);
	csp(ctx1, pt0, 10, "B"); // рисуем точку pt0 синим цветом
	// формируем строку с координатами точки pt0
	var t1 = (roundNumber(pt0[0], 2)).toString(); // преобразование значения в строку
	var t2 = (roundNumber(pt0[1], 2)).toString(); // преобразование значения в строку
	var t = t1 + ", " + t2;
	// отображаем сформированную строку синим цветом 
	// рядом с pt0 - чуть правее и чуть выше самой точки
	text1(ctx1, t, pt0, "rt", "up", "B");

	// переменная controller1 используется dat.GUI
	var controller1 = new function() 
	{
		this.X = pt0[0];
		this.Y = pt0[1];
	}();	
	// Создаем новый объект dat.GUI.
	var gui = new dat.GUI({ autoPlace: false });
	gui.domElement.id = 'gui';
	gui_container1.appendChild(gui.domElement);
	
	var f1_1 = gui.addFolder('Point position');	
	// используется для изменения координаты X точки pt0
	f1_1.add(controller1, 'X', -2.0, 2.0).onChange( function() 
	{
		pt0[0] = (controller1.X); // задаем новое значение координаты X
		// так как новое значение координаты X то требуется
		// очистить экран
		ctx1.clearRect(0, 0, elem1.width, elem1.height);
		// перерисовываем экран с новым положением точки pt0
		axes(ctx1, 1.8, 1.8, 0.5, "Brown");
		csp(ctx1, pt0, 10, "B");
		var t1 = (roundNumber(pt0[0], 2)).toString(); 
		var t2 = (roundNumber(pt0[1], 2)).toString();
		var t = t1 + ", " + t2;
		text1(ctx1, t, pt0, "rt", "up", "B");
		csp(ctx1, pt00, 2, "Brown");
		text1(ctx1, "O", pt00, "rt", "up", "Brown");
	});
	// используется для изменения координаты Y точки pt0
	f1_1.add(controller1, 'Y', -2.0, 2.0).onChange( function() 
	{
		pt0[1] = (controller1.Y); // задаем новое значение координаты Y
		// так как новое значение координаты Y то требуется
		// очистить экран
		ctx1.clearRect(0, 0, elem1.width, elem1.height)
		// перерисовываем экран с новым положением точки pt0
		axes(ctx1, 1.8, 1.8, 0.5, "Brown");
		csp(ctx1, pt0, 10, "B");
		var t1 = (roundNumber(pt0[0], 2)).toString();
		var t2 = (roundNumber(pt0[1], 2)).toString();
		var t = t1 + ", " + t2;
		text1(ctx1, t, pt0, "rt", "up", "B");	
		csp(ctx1, pt00, 2, "Brown");
		text1(ctx1, "O", pt00, "rt", "up", "Brown");		
	});

Кроме библиотеки WebGeometry в дальнейшем при выводе на холст мы будем использовать некоторое количество вспомогательных функций, исходный текст которых находится в файле canvas2D.js. Они представляют собой небольшую обертку вокруг стандартного API HTML5 Canvas и позволяют вывести на экран точки, текст, прямые и окружности при помощи сокращенной записи. Эти функции в качестве параметров получают координаты не привязанные к холсту (как в HTML5 Canvas), а непосредственно значения получаемые в процессе расчетов с помощью функций входящих в WebGeomrtry. Также большинство этих функций позволяют задать цвет точек, текста, прямых и окружностей, размер точек и толщину линий.

В приведенном выше исходном тексте использовалась только одна функция создания 2D-точки из библиотеки WebGeometry. Она создает точку с координатами (1.2, -1.2):

   var pt0 = new Point2D(1.2, -1.2);

Исходный текст вспомогательных функций (csp, txt_c и др.), предназначенных для отображения на холсте точек, прямых и текста, можно найти (как говорилось ранее) в файле canvas2D.js.

Прямые на холсте

Создадим две прямые и отобразим их на холсте. Первая прямая задается двумя точками (точки обозначенные на холсте как 1 и 2):

   var pt1 = new Point2D ( -1.1, -0.8); // черная точка 1
   var pt2 = new Point2D ( 1.1, 0.8);   // черная точка 2
   var line1 = new Line2D(pt1, pt2);    // создаваемая прямая
Вторая прямая задается своим направлением при помощи вектора, и точкой принадлежащей создаваемой прямой. При помощи функции IntersectionTwoLines определяем точку пересечения двух прямых:
   var vec = new Vector2D(0.95, -0.2); // вектор синего цвета
   var pt3 = new Point2D ( -1.0, 0.7); // точка point синего цвета
   var line2 = new Line2D();           // объявление прямой line2
   // назначение прямой line2 требуемых параметров
   line2.CreateLineVectorPoint(vec, pt3);
   // определяем координаты точки пересечения прямых line1 и line2
   var point = line1.IntersectionTwoLines(line2); // точка имеющая красный цвет

При помощи dat.GUI можно задавать координаты точек 1 и 2 через которые проходит первая прямая и кординаты вектора и точки для второй прямой.

Возможно представляет интерес посмотреть как это все рисуется на холсте. Далее приведен текст функции cross выполняющий вычисления и отрисовку на холсте с подробными комментариями:

	function cross(pt1, pt2, pt3, vec)
	{
		// pt1 и pt2 задают line1
		// pt3 и vec задают line2
		ctx2.clearRect(0, 0, elem2.width, elem2.height);
		ctx2.lineWidth = 1.0;
		ctx2.font = "12px Arial";
		axes(ctx2, 1.8);
		
		// Создаем вспомогательную прямую лежащую на оси OX
		var pt00 = new Point2D(0, 0); // начало координат
		var OX = new Line2D(pt00, new Point2D(1, 0));
		
		csp(ctx2, pt1, 6); // черная точка 1
		csp(ctx2, pt2, 6); // черная точка 2
		var line1 = new Line2D(pt1, pt2); // создаем line1
		line(ctx2, pt2, pt1); // отображаем line1 на холсте
		
		// Для отрисовки вектора на экране
		// создаем сначала прямую лежащую на векторе
		// Переменная vec объявлена вне данной функции и изменяется в dat.GUI
		vec.Normer();
		var line_vec = new Line2D(pt00, vec);
		// Отображаем вектор на холсте.
		// Предположим, что он исходит из начала координат и идет в точку с координатами vec.
		// В WebGeometry предполагается, что векторы являются свободными и задают только направление.
		// Поэтому можем условно привязать вектор к любой точке - в том числе и к началу координат.
		vector(ctx2, pt00, vec, "B"); 
		txt_c(ctx2, "vector", vec, "rt", "up", "B"); // отображаем слово "vector"
		// При помощи функции Angle библиотеки WebGeometry определяем угол наклона стрелки на холсте
		var ang = (line_vec.Angle(OX) +  90*DEGREE);
		// Затем рисуем стрелку на конце вектора
		arrow(ctx2, vec, ang, 0.4, "B");
		csp(ctx2, pt3, 6, "B"); // отображаем на холсте точку pt3 синим цветом
		txt_c(ctx2, "point", pt3, "lt", "up", "B"); // отображаем на холсте слово point синим цветом
		
		// Создаем прямую line2
		var line2 = new Line2D(); // объявление прямой line2
		// назначение прямой line2 требуемых параметров
		line2.CreateLineVectorPoint(vec, pt3);
		
		//  находим вспомогательную точку pt_temp для изображения на холсте line2
		var pt_temp = line2.IntersectionTwoLines(OX);
		//  прямая line2 проходит через точки pt3 и pt_temp
		// отображаем line2 при помощи функции line (смотри в canvas2D.js)
		line(ctx2, pt3, pt_temp, "B"); 
		
		txt_c(ctx2, "1", pt1, "lt", "up"); // отображаем слово "1" на холсте
		txt_c(ctx2, "2", pt2, "lt", "up"); // отображаем слово "2" на холсте
		
		var point = line1.IntersectionTwoLines(line2); 
		csp(ctx2, point, 8, "R");
		var t1 = (roundNumber(point[0], 2)).toString();
		var t2 = (roundNumber(point[1], 2)).toString();
		var t = t1 + ", " + t2;
		txt_c(ctx2, t, point, "rt", "up", "R"); // отображаем координаты точки пересечения 
						// прямых на холсте красным цветом
		
		csp(ctx2, pt00, 8, "B"); // отображаем точку лежащую в начале координат (8 - размер точки в px)
	}

В приведенном выше листинге использовались следующие функции библиотеки WebGeometry:
Vector2D
(Vector2D) Normer
Line2D
(Line2D) CreateLineVectorPoint
(Line2D) Angle
(Line2D) IntersectionTwoLines

Окружность и прямая на холсте

В качестве типичного примера создадим окружность и прямую и затем найдем точки их пересечения. На холст окружность и прямую отображает следующая программа:

По тексту программы можно посмотреть как используются некоторые функции библиотеки WebGeometry для отображения на холст прямых, окружностей и т.д. В следующем листинге в качестве функции определяющей точки пересечения окружности и прямой используется функция Intersection_LineCircle. Эта функция возвращает массив из двух элементов типа Point2D. Эти два элемента массива представляют собой две точки пересечения прямой с плоскостью.

function draw_line_circle(ctx, O, pt1, pt2, R)	
{
	axes(ctx, 1.8, 1.8, 0.5, "Brown"); // оси координат
	
	csp(ctx, O, 5, "B"); // центр окружности
	var t1 = (roundNumber(O[0], 2)).toString();
	var t2 = (roundNumber(O[1], 2)).toString();
	var t = t1 + ", " + t2;
	text1(ctx, t, O, "rt", "up", "B");

	circle(ctx, O, R, 1, "B");
	
	// радиус - прямая со стрелкой на одном конце
	var line_radius = new Line2D(O, new Point2D(O[0] + 6, O[1] + 3));
	var cir = new Circle2D(O, R); // Окружность с центром O и радиусом R
	
	// определяем место где нарисуем стрелку радиуса
	var points = cir.Intersection_LineCircle(line_radius);
	if (points == null)
	{
		return null;
	}	
	var x, y;
	// в качестве места для стрелки выбираем где координата Y 
	// точки пересесечения имеет меньшее значение
	if (points[0][1] > points[1][1])
	{
		x = points[1][0];
		y = points[1][1];
	}
	else
	{
		x = points[0][0];
		y = points[0][1];
	}				
	// точка для стрелки 
	var point_radius = new Point2D(x, y);

	// радиус
	segment_arrow(ctx, O, point_radius, 1, 0.2, "Black")
	text1(ctx, "R", point_radius, "lt", "dn", "B");
	
	// прямая OX задается для определения угла используемого 
	// для проведения отрезка со стрелкой на конце примыкающем к окружности
	var O = new Point2D(0, 0); // начало координат
	var OX = new Line2D(O, new Point2D(1, 0));
	// определяем угол
	var ang = (line_radius.Angle(OX) - 90*DEGREE);
	// рисуем стрелку на конце отрезка
	arrow(ctx, point_radius, ang, 0.2, "B");	
	
	// задаем прямую line_var пересекающуюся с окружностью
	csp(ctx, pt1, 6);
	csp(ctx, pt2, 6);
	text1(ctx, "1", pt1, "rt", "up");
	text1(ctx, "2", pt2, "rt", "up");	
	var line_var = new Line2D(pt1, pt2); // прямая задается двумя точками
	line(ctx, pt2, pt1, -3, 3, 1, "Black"); // отображаем line_var
	
	// находим две точки пересечения
	points = cir.Intersection_LineCircle(line_var);
	if (points == null)
	{
		return null;
	}
	csp(ctx, points[0], 6, "R"); // первая точка пересечения
	csp(ctx, points[1], 6, "R"); // вторая точка пересечения
	
	// координаты первой точки
	var t1 = (roundNumber(points[0][0], 2)).toString();
	var t2 = (roundNumber(points[0][1], 2)).toString();
	var t = t1 + ", " + t2;
	text1(ctx, t, points[0], "rt", "up", "R");
	
	// координаты второй точки
	t1 = (roundNumber(points[1][0], 2)).toString();
	t2 = (roundNumber(points[1][1], 2)).toString();
	t = t1 + ", " + t2;
	text1(ctx, t, points[1], "rt", "up", "R");	
}

Две окружности на холсте

Создадим две окружности у которых можно менять координаты их центров и радиусы. Найдем точки пересечения окружностей друг с другом. Они определяются с помощью функции Intersection_TwoCircles

	var cir1 = new Circle2D(O1, R1); // первая окружность
	var cir2 = new Circle2D(O2, R2); // вторая окружность
	var points = cir1.Intersection_TwoCircles(cir2);
	if (points == null)
	{
	   return null; // нет пересечения окружностей
	}	
	// пересечение есть
	...................
	...................	

Исходный текст программы пересечения двух окружностей находится в файле two_circles.js.

Сопряжение окружностей

Иногда возникает задача плавного соединения двух окружностей. Рисунок 1 иллюстрирует это построение. Фактически оно сводится к сопряжению окружностей cir1 и cir2 дугой третьей окружности cir3. Окружность cir3 имеет внутреннее касание к окружностям cir1 и cir2 в точках F и G. Термин “внутреннее касание” означает, что центры дуг окружностей cir1, cir2 и cir3 находятся по одну сторону от точек их касания. Будем считать, что заданы радиусы R1 и R2 основных окружностей cir1 и cir2, а также радиус сопрягающей окружности R3. Предположим также, что известно расположение центров O1 и O2 основных окружностей. Требуется найти положение центра O3 сопрягающей окружности и координаты точек касания F и G.

Для нахождения центра O3 окружности сопряжения cir3 построим две вспомогательные окружности с радиусами равными значениям R1 – R3 и R2 – R3. Центры этих вспомогательных окружностей поместим в центры основных окружностей O1 и O2 соответственно. Тогда центр O3 окружности cir3 можно найти как точку пересечения вспомогательных окружностей. Для нахождения точек пересечения окружности cir3 с окружностями cir1 и cir2 создается окружность с центром O3 и радиусом, отличающимся в большую сторону от R3 на очень малую величину epsilon. Следовательно радиус этой окружности равен (R3 + epsilon). Введение этой малой величины необходимо для того, чтобы в процессе проведения вычислений заведомо обеспечить пересечение соответствующих окружностей. В предельном случае, когда значение epsilon стремится к 0, две точки пересечения сливаются и превращаются в одну точку касания окружностей. Пересечение окружности cir3 с радиусом равным (R3 + epsilon) с окружностями cir1 и cir2 даст точки касания F и G. Точки пересечения окружностей определяются с помощью функции Intersection_TwoCircles

Функция отрисовки сопряжения двух окружностей третьей окружностью приведена ниже.

function draw_three_circles(ctx, O1, O2, O3, R1, R2, R3)	
{
	axes(ctx, 1.8, 1.8, 0.5, "Black");  // рисуем оси черным цветом
	
	// Необходимо провести сопряжение следующих двух окружностей.
	var cir1 = new Circle2D(O1, R1); 
	var cir2 = new Circle2D(O2, R2); 
	
	// Рисуем и обозначаем центр O1 коричневым цветом
	csp(ctx, O1, 5, "Brown");
	text1(ctx, "O1", O1, "rt", "up", "Brown");
	// Рисуем дугу с центром O1 и радиусом R1 коричневым цветом
	arc(ctx, O1, R1, 1, "Brown", 5, 120);
	
	// Рисуем и обозначаем центр O2 синим цветом
	csp(ctx, O2, 5, "B");
	text1(ctx, "O2", O2, "rt", "up", "B");
	// Рисуем дугу с центром O2 и радиусом R2 синим цветом
	arc(ctx, O2, R2, 1, "B", -60, 60);
	
	// Радиусы вспомогательных окружностей должны быть > 0 
	if (R2 - R3 <= 0.0)
	{
		return null;
	}
	if (R1 - R3 <= 0.0)
	{
		return null;
	}
	
	// Создаем две вспомогательные окружности.
	var R2_R3 = new Circle2D(O2, R2 - R3); 
	var R1_R3 = new Circle2D(O1, R1 - R3); 
	
	// Две дуги вспомогательных окружностей рисуем черным цветом и толщиной равной 0.3
	arc(ctx, O1, R1 - R3, 0.3, "Black", 5, 120);  // рисуем дугу с центром O1 и радиусом R1 - R3
	arc(ctx, O2, R2 - R3, 0.3, "Black", -60, 60); // рисуем дугу с центром O2 и радиусом R2 - R3

	// Находим точки пересечения двух окружностей между собой
	// Переменная points представляет собой массив из двух точек типа Point2D.
	var points = R2_R3.Intersection_TwoCircles(R1_R3);
	if (points == null)
	{
		return null;
	}		
	// Центр сопрягающей окружности O3
	if (points[0][0] > points[1][0])
	{
		O3[0] = points[0][0]; O3[1] = points[0][1]
	}
	else
	{
		O3[0] = points[1][0]; O3[1] = points[1][1]			
	}

	// Создаем сопрягающую окружность чуть большего 
	// радиуса чем R3 (для проверки)
	var cir3 = new Circle2D(O3, R3 + 0.00001); // R3 + EPSILON);
	csp(ctx, O3, 5, "R"); // рисуем точку красным цветом
	text1(ctx, "O3", O3, "rt", "up", "R"); // обозначаем точку как "O3" красным цветом
	circle(ctx, O3, R3, 1, "R"); // рисуем окружность красным цветом 
	                             // с центром в точке O3 и радиусом равным R3

	// Проверяем пересекаются или нет окружность 
	// cir2 с сопрягающей окружностью cir3
	// Координаты двух точек пересечения полученные в результате
	// работы функции Intersection_TwoCircles должны 
	// отличаться совершенно незначительно по своим значениям
	// и в пределе переходить в одну точку касания окружностей "G".
	points = cir2.Intersection_TwoCircles(cir3);
	if (points == null)
	{
		return null;
	}			
	// Первая точка "G" сопряжения/касания 
	var G = new Point2D(); // объявление точки
	G[0] = points[0][0];
	G[1] = points[0][1];
	csp(ctx, G, 3, "R"); // рисуем точку красным цветом
	text1(ctx, "G", G, "lt", "dn", "R"); // обозначаем точку как "G"
	
	// Проверяем пересекаются или нет окружность 
	// cir1 с сопрягающей окружностью cir3
	// Координаты двух точек пересечения полученные в результате
	// работы функции Intersection_TwoCircles должны 
	// отличаться совершенно незначительно по своим значениям
	// и в пределе переходить в одну точку касания окружностей "F".
	points = cir1.Intersection_TwoCircles(cir3);
	if (points == null)
	{
		return null;
	}	
	// Вторая точка "F" сопряжения/касания 
	var F = new Point2D(); // объявление точки
	F[0] = points[0][0];
	F[1] = points[0][1];
	csp(ctx, F, 3, "R"); // рисуем точку красным цветом
	text1(ctx, "F", F, "lt", "dn", "R"); // обозначаем точку как "F"
	
	// Предварительные расчеты требующиеся для рисования дуги сопряжения.
	// Вычисляем углы начала и конца дуги сопряжения.
	var line_O3_F = new Line2D(O3, F);
	var line_O3_G = new Line2D(O3, G);
	var line_hor = new Line2D(O3, new Point2D(O3[0] + 1, O3[1]));
	var ang_F_degree = (180 / Math.PI) * line_O3_F.Angle(line_hor);
	var ang_G_degree = (180 / Math.PI) * line_O3_G.Angle(line_hor);
	
	// Рисуем "жирную" дугу сопряжения окружностей красным цветом
	arc(ctx, O3, R3, 4, "R",  -ang_G_degree, -ang_F_degree);
}

Полный текст программы сопряжения окружностей с отрисовкой на холсте находится в файле three_circles.js.

Построение правильного пятиугольника

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

Однако эти построения можно провести только при помощи циркуля и линейки. В книге Джона Аллена "Базовые геометрические формы для дизайнеров и архитекторов" (издательство Питер 2016г.) подробно рассматриваются такие построения. Воспользуемся этой книгой и построим пятиугольник (pentagon), шестиугольник (hexagon) и семиугольник (heptagon). Только в качестве циркуля (как это делается в книге) будем использовать функцию создания окружности, а в качестве линейки (она используется в книге) - функцию создания прямой из библиотеки WebGeometry. Начнем с пятиугольника.

Начертим окружность с центром в точке O. Проведем горизонтальный диаметр окружности и получим точки пересечения A и B. В книге эти точки просто отмечаются карандашом, а мы используем для этого функцию Intersection_LineCircle из библиотеки WebGeometry. Раствором циркуля равным радиусу исходной окружности из точки B проведем дугу (вместо дуг при вычислениях используем функции Circle2D) пересекающую окружность в точках C и D. Соединим точки C и D чтобы найти точку E, делящую отрезок OB на две равные части. Затем проводим вертикальную ось через точку O и пересекающую окружность в точке F.

Установив ножку циркуля в точке E, раствором циркуля, равным EF, проведем дугу, пересекающую горизонтальную ось в точке G. Установив ножку циркуля в точке F, раствором циркуля, равным FG, проведем дугу пересекающую окружность в точках H и J. Из точек H и J проведем дуги, используя тот же раствор циркуля, чтобы найти точки K и L. FJKLH - искомый пятиугольник. Точки пересечения дуг окружностей определяются с помощью функции Intersection_TwoCircles

Исходный текст программы построения пятиугольника приведен в файле pentagon.js.

Построение правильного шестиугольника

Перейдем к построению правильного шестиугольника.

Начертим произвольную окружность с центром в точке O и радиусом OA равным значению R. В качестве точки A может быть выбрана произвольная точка лежащая на окружности. Установив ножку циркуля в точке A и используя тот же самый радиус проведем через центр O дугу BC (от одной стороны окружности до другой). Из точки B проведем дугу через точки A, O и новую точку D на окружности. Таким же образом из точки D проведем еще одну дугу от точки B, чтобы найти точку E.
    Далее продолжаем рисовать дуги из точек E, F и C, пока не получится шестиугольник ABDEFC.

Исходный текст программы построения шестиугольника приведен в файле hexagon.js. При расчетах его вершин координаты точек пересечения дуг между собой мы опредеделяем при помощи функции Intersection_TwoCircles входящей в состав библиотеки WebGeometry, а рисуем дуги на холсте используя функцию arc из файла canvas2D.js. Эта функция сделана на основе одноименной функции arc входящей в HTML5 Canvas.

Построение почти правильного семиугольника

Построим почти правильный семиугольник. Как пишет (в упомянутой выше книге) Джон Аллен это построение точно на 99.9%.

Начертим произвольный круг с центром в точке O и радиусом OC равным значению R. Построим квадрат EFGH вокруг этого круга. Из точек E и F проведем две дуги, имеющие радиус, равный отрезку EF, и пересекающиеся в точке J внутри квадрата. EFJ - равносторонний треугольник, пересекающий изначальную окружность в точках K и L. CK и CL можно считать сторонами правильного семиугольника с точностью 99.9%.
    Установив раствор циркуля равным CK и двигаясь по окружности начиная из точки K, отметим остальные четыре точки семиугольника. В результате получится семиугольник CKMNPQL. Исходный текст программы построения семиугольника приведен в файле heptagon.js.

  В следующей главе мы продолжим рассмотрение примеров с функциями библиотеки WebGeometry предназначенными для построений на плоскости.

   Глава 2  ◄     Содержание     ►   Глава 4