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

Вход на сайт

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

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

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

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

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

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