Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.
Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.
Спасибо за статью. Я не Ваш студент. Но мне она помогла написать функцию для Канторова множества на Python для черепашки: import turtle def kanter(x, y, d):     if d > 1:         turtle...
Как реализовать в данном примере границы расчёта?

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Скриншот к примеру
Среда программирования: 
JavaScript

Задача: Определить количество общих точек двух отрезков: нуль, одна или бесконечное множество.

Описание работы программы:

По щелчку левой кнопки мыши считываются координаты четырех точек (концов отрезков AB и CD) и, переведенные из экранной системы координат в декартову, добавляются в массив points. Для уменьшения количества проверок координаты сортируются таким образом, чтобы A была левее B, а C левее D.

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

Затем запускается функция chek, подробное описание работы которой можно увидеть в комментариях в коде.

Для вычисления косого произведения векторов используется функция PseudoScalar.

Код программы: 

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8"/>
	<title>Количесвто общих точек двух отрезков</title>
	<canvas id="canvas" width="500" height="500" style="border: 1px solid grey"></canvas>
	<script>
		var x, y;
		let points = []; //массив для хранения точек A, B, C, D
		var canvas = document.getElementById("canvas");
		var ctx = canvas.getContext('2d');
		//по нажатию левой кнопки мыши ставятся точки:
		window.onload=function(){ 
		    canvas.addEventListener('click', (e) => {
		    	//заполняем массив точками с декартовыми координатами:
		    	if (points.length < 4) points.push({x: e.pageX - 250, y: 250 - e.pageY});   
	        	//делаем А всегда левее В и С всегда левее D для уменьшения количества проверок:
	        	if (points.length === 4) {
		        	if (points[0].x > points[1].x) [points[0], points[1]] = [points[1], points[0]];
		        	if (points[2].x > points[3].x) [points[2], points[3]] = [points[3], points[2]];
		        	if (points[0].x === points[1].x && points[0].y > points[1].y) [points[0], points[1]] = [points[1], points[0]];
		        	if (points[2].x === points[3].x && points[2].y > points[3].y) [points[2], points[3]] = [points[3], points[2]];
	        	}
	            draw();
			});
		}
        function draw() {       	
		    ctx.strokeStyle = "#000";
			ctx.fillStyle = "#fff";
		    ctx.fillRect(0, 0, 500, 500);
			ctx.fillStyle = "#000";	
			//отрисовка точек (возврат к экранной системе координат):
			for (var i = 0; i < points.length; i++) {
	            ctx.beginPath();
	            ctx.arc(250 + points[i].x, 250 - points[i].y, 2, 0, 2*Math.PI, false);
	            ctx.stroke();
	            ctx.fill();
		    }
		    //при щелчке мышью в одном и том же месте:
			if (points.length > 1) {
			    if (points.length === 2 && points[0].x === points[1].x && points[0].y === points[1].y) {
	        		alert("Вы построили вырожденный отрезок. После перезагрузки страницы попробуйте еще раз.");		    	
			    }
			    //отрисовка отрезка АВ (возврат к экранной системе координат):
			    else {
					ctx.beginPath();
				    ctx.moveTo(250 + points[0].x, 250 - points[0].y);
				    ctx.lineTo(250 + points[1].x, 250 - points[1].y);
					ctx.stroke();
					ctx.closePath();			    	
				}
			}
		    //при щелчке мышью в одном и том же месте:
			if (points.length > 3) {
			    if (points.length === 4 && points[2].x === points[3].x && points[2].y === points[3].y) {
					alert("Вы построили вырожденный отрезок. После перезагрузки страницы попробуйте еще раз.");
			    }
			    //отрисовка отрезка CD (возврат к экранной системе координат):
			    else {
					ctx.beginPath();
					ctx.moveTo(250 + points[2].x, 250 - points[2].y);
					ctx.lineTo(250 + points[3].x, 250 - points[3].y);
					ctx.stroke();
					ctx.closePath();
					check();
			    }
			}
        }
        function check() { 
        	console.log(points);        
        	//считаем определители, полученные из условия равенства уравнений прямых, содержащих наши отрезки, для проверки их пересечения/наложения:       	
        	var det = (points[1].x - points[0].x) * (points[2].y - points[3].y) - (points[2].x - points[3].x) * (points[1].y - points[0].y); 
        	var detl = (points[2].x - points[0].x) * (points[2].y - points[3].y) - (points[2].y - points[0].y) * (points[2].x - points[3].x);
        	var detm = (points[1].x - points[0].x) * (points[2].y - points[0].y) - (points[1].y - points[0].y) * (points[2].x - points[0].x);
        	var X, Y;
        	//случай, когда отрезки имеют общий конец (A=D):
        	if (points[0].x === points[3].x && points[0].y === points[3].y) {
        		alert('Отрезки имеют одну общую точку ('+points[0].x+'; '+points[0].y+')');
        	}
        	//случай, когда отрезки имеют общий конец (В=С):
        	else if (points[1].x === points[2].x && points[1].y === points[2].y) {
        		alert('Отрезки имеют одну общую точку ('+points[1].x+'; '+points[1].y+')');	
        	}
        	else {
        		if (det === 0) {
        			if (detl === 0 && detm === 0) {
        				//случай равенства всех определителей нулю означает расположение отрезков на одной прямой (они либо имеют общий сегмент, либо не имеют общих точек).
        				if (points[0].x === points[1].x) {
        					if ((points[0].y < points[2].y && points[2].y < points[1].y) || (points[2].y < points[0].y && points[0].y < points[3].y) || (points[0].y === points[2].y || points[1].y === points[3].y)) {
        						alert('Отрезки имеют бесконечное множество общих точек');
        					}
        				}
        				else if ((points[0].x < points[2].x && points[2].x < points[1].x) || (points[2].x < points[0].x && points[0].x < points[3].x) || (points[0].x === points[2].x || points[1].x === points[3].x)) {
        					alert('Отрезки имеют бесконечное множество общих точек');
        				}
        				else alert('Отрезки не имеют общих точек');
        			}
        			else alert('Отрезки не имеют общих точек');
        		}
        		//случай, когда концы отрезка АВ расположены по разные стороны от отрезка CD и концы отрезка CD расположены по разные стороны от отрезка АВ (пересечение):
        		else if (Math.sign(PseudoScalar(points[2], points[3], points[2], points[0])) != Math.sign(PseudoScalar(points[2], points[3], points[2], points[1])) && Math.sign(PseudoScalar(points[0], points[1], points[0], points[3])) != Math.sign(PseudoScalar(points[0], points[1], points[0], points[2]))) {
        			//вычисление координат точки пересечения:
        			X = points[0].x + (detl / det) * (points[1].x - points[0].x);
        			Y = points[0].y + (detl / det) * (points[1].y - points[0].y);
        			alert('Отрезки имеют одну общую точку ('+X+'; '+Y+')');		
        		}
        		else alert('Отрезки не имеют общих точек');
        	}
        }
        //функция для вычисления косого произведения векторов АВ и CD:
        function PseudoScalar(A, B, C, D) {
			return (B.x - A.x) * (D.y - C.y) - (D.x - C.x) * (B.y - A.y);
		}
	</script>
</head>
<body>
</body>
</html>

Прикрепленный файлРазмер
memetova_common_points_source.zip2.2 кб