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

Вход на сайт

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

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

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

dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(
У Вас число превысит максимальное число int. Можно использовать в Вашем случае uint, но лучше все переписать на double.
Добавление к программе строки glutReshapeFunc(changeSize); приводит к тому, что треугольник перестаёт совсем отрисовываться.
Выдаёт ошибку glut32.dll не найден! При том, что он лежит в System32! Всё решил) Нужно отправить не в System32, а в System.

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

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