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

Вход на сайт

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

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

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

Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё
огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации
dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(

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

Рейтинг@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 кб