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

Вход на сайт

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

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

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

Пиривет сайт с работой закладчиком Работа курьером Значение финансов в повседневной жизни известно каждому, но что делать, если зарплата на постоянной работе невелика или ее вообще нет? Если у Вас нет профессии или возникли иные сложности, то...
Модные тренды медицинской одежды - новая эра стиля и комфорта в 2024 году https://fkmed.r... C нами Вы убедитесь: качественная, комфортная и модная медицинская одежда существует! В каталоге на сайте представлена медицинская одежда для врачей и...
14 070 руб https://www.eco... 38 900 руб https://www.eco... и выберите из списка ниже: Купить в 1 клик https://www.eco... По типу двигателя снегоотбрасыватель может быть: Купить в 1 клик https://www.eco...
Все изделия хорошо сидят на фигуре и отличаются высокой степенью комфортности https://fkmed.r... Комбинированные ткани с применением хлопка и синтетики - это оптимальный вариант для пошива формы https://fkmed.r... Специальная пропитка...
53 990 руб https://www.eco... Экономия 4 160 руб https://www.eco... Купить в 1 клик https://www.eco... Главными элементами устройства являются двигатель, металлический или пластиковый корпус и лопасти для уборки снега https://www.eco... Тип...

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

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

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

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

<html>
<body>
 
<canvas id="Canvas" width="750" height="750" style="border:1px solid #d3d3d3">
</canvas>
<p></p>
<button onclick="rotate_x()">Rotate</button>
 
<script>
 
function calc(){ // рассчет координат точек
	n=0;
	for(var i = 0; i <= 2*Math.PI; i+=0.1){
		n++;
		for(var j = 0; j <= 2*Math.PI; j+=0.1){
			xp.push(i);
			yp.push(j);
			zp.push(Math.sin(i)*Math.cos(j));
 
		}
	}
 
}
 
function clear(){ // очищаем холст
	ctx.fillStyle = 'black';
	ctx.fillRect(0,0,750,750);
}
 
 
function mlt(){// умножаем все координаты на масштаб - r
	for(var i = 0; i < xp2.length;i++){
        xp2[i]*=r;
        yp2[i]*=r;
 
	}
}
 
 
 
 
function overwrite(){ // переписываем точки в нужном порядке(снизу-вверх, cлева-направо)
	var ptr2 = 0;
	for(var i = n-1; i >= 0; i--){
		for(var j = i ; j < xp2.length; j+=n){
            xp3[ptr2] = xp2[j];
            yp3[ptr2] = yp2[j];
			ptr2++;
		}
	}
 
}
 
function draw(){ // функция рисования
	for(var i = 0; i < n; i++){ // рисуем первую кривую
		y_max[i]=yp3[i]; // запоминаем y-ки
 
    	var I_D = (xcr[i] * lx + ycr[i] * ly + zcr[i] * lz); // считаем  рассеянную составляющую освещенности в точке
        ctx.beginPath();
		if (I_D > 0) { //применяем к точке рассеянную составляющую, когда она > 0
			ctx.fillStyle = "rgba(" + 255*I_D + "," +255*I_D+","+255*I_D + "," +255 + ")"
		}else{
			ctx.fillStyle = "rgba(5,5,5,255)" // фоновая составляющая
		}
    	ctx.arc(xp3[i]+x0, yp3[i]+y0, 2, 0, Math.PI*2, true); // cтавим точку
    	ctx.fill();
 
	}
 
 
	for(var i = n; i < xp3.length; i+=n){// рисуем все остальные кривые 
		for(var j = 0; j < n; j++){
			if(y_max[j]>yp3[i+j]){// если точка видима, ставим её
				I_D = (xcr[i+j] * lx + ycr[i+j] * ly + zcr[i+j] * lz);
					if (I_D > 0){
					ctx.fillStyle = "rgba(" + 255*I_D + "," +255*I_D+","+255*I_D + "," +255+ ")"
					} else {
						ctx.fillStyle = "rgba(5,5,5,255)"
 
					}
 
				ctx.beginPath();
				ctx.arc(xp3[i+j]+x0, yp3[i+j]+y0, 2, 0, Math.PI*2, true);
				ctx.fill();
				y_max[j]=yp3[i+j];
			}
		}
	}
 
 
}
 
function rotate_x(){ // рассчет координат после вращения по оси X
	clear();
    // рассчитываем угол fi
	if (fi >= Math.PI*5/16 && sign == 1) sign = 2;
	if (fi <= 0 && sign == 2) sign = 1;
	if (sign == 1) fi +=(Math.PI / 16);
	if (sign == 2) fi -=(Math.PI / 16);
 
 
	var ptr1 = 0;
	for(var i = 0; i < zp.length;i++){
    	/* формула вращения графика на угол fi по оси X
    	    x'=x;
    	    y':=y*cos(fi)+z*sin(fi) ;
    	    z':=-y*sin(fi)+z*cos(fi) ; */
		var x=xp[i];
		var y=yp[i]*Math.cos(fi)+zp[i]*Math.sin(fi);
		var z=-(yp[i]*Math.sin(fi))+zp[i]*Math.cos(fi);
    	// запоминаем координаты после вращения
		xcr[i] = x;
		ycr[i] = y;
		zcr[i] = z;
    	//Проецируем точки на экран по формулам центральной проекции
		xp2[ptr1] =(k*x/(z+k));
    	        yp2[ptr1]= (k*y/(z+k));
		ptr1++;
	}
 
	mlt();
	overwrite();
	draw();
}
 
 
 
 
 
 
</script>
 
 
<script>
var c = document.getElementById("Canvas");
var ctx = c.getContext("2d");
var fi = 0;// угол вращения
var sign = 1;// для того, чтобы держать fi в нужном диапазоне (fi∈[0 , 5*PI/16])
var lx = 0.1, ly = 0.1, lz = 0.1; // координаты источника света
var x0 = 150, y0 = 150; // сдвиг относительно начала координат
var r = 70;// масшатаб
var k = 100;// расстояние до наблюдателя
var n; // количество x-координат
//координаты точек
var xp = [];
var yp = [];
var zp = [];
// координаты точек после вращения графика на угол fi
var xcr = [];
var ycr = [];
var zcr = [];
// координаты спроецированных точек
var xp2 = [];
var yp2 = [];
// координаты точек, записанные в нужном нам порядке для применения алгоритма плавающего горизонта (идём по графику снизу-вверх, cлева-направо)
var xp3 = [];
var yp3 = [];
var y_max = []; //Для хранения максимальных значений y при каждом значении x
 
calc();
rotate_x();
</script>
 
</body>
</html>

Прикрепленный файлРазмер
3D.zip1.97 кб