Solid cylinder

In this example below you will see how to do a Solid cylinder with some HTML / CSS and Javascript

Bogus implementation. Its doesnt work properly

Thumbnail
This awesome code was written by arcollector, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright arcollector ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Solid cylinder</title>
  
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js" type="text/javascript"></script>

<div class="viewport">
	<canvas class="viewport-canvas"></canvas>
</div>
  
  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/arcollector/solid-cylinder-jpgqv */
	html {
		background: #ddd;
	}
	.viewport {
		margin: 10px auto;
		border: 1px solid #ccc;
		width: 480px;
		height: 360px;
	}
	.viewport-canvas {
		width: 100%;
		height: 100%;
		background: #000;
	}

/*Downloaded from https://www.codeseek.co/arcollector/solid-cylinder-jpgqv */
	// need for dat.GUI
	var settings = {
		rotationPitch: 4.89778,
		rotationRoll: 2.28319,
		rotationYaw: 2.58539,
		zOffset : -350,
		angularDistorision : 1200
	};
	
	var getRandomColor = function() {
		return 'rgb( ' + Math.floor( Math.random() * 1000 % 256 ) + ', ' + Math.floor( Math.random() * 1000 % 256 ) + ' , ' + Math.floor( Math.random() * 1000 % 256 ) + ')';
	};
	
	/*
	* Draws a solid 3D cylinder using the plane equation
	* method of hidden surface removal.
	*/

	var canvas = document.querySelector( '.viewport-canvas' ),
		context = canvas.getContext( '2d' );
	var WORLD_WIDTH = 800;
	var WORLD_HEIGHT = 600;
	var SCREEN_WIDTH = context.canvas.width;
	var SCREEN_HEIGHT = context.canvas.height;
	
	// world coordinates
	var x = 0, y = 0, z = 0;
	// polygon vertices
	var x1, x2, x3, x4;
	var y1, y2, y3, y4;
	var z1, z2, z3, z4;
	// display coords
	var sx1, sx2, sx3, sx4, sx5;
	var sy1, sy2, sy3, sy4, sy5;
	// output of 3D perspective formulas
	var xa, ya, za;
	// angular perspective factor
	var d = 1200;
	// yaw angle
	var r1 = 5.89778;
	// roll angle
	var r2 = 6.28319;
	// pitch angle
	var r3 = .58539;
	// sine rotation factors
	var sr1, sr2, sr3;
	// cosine rotation factors
	var cr1, cr2, cr3;
	// viewpoint position
	var mx = 0, my = 0, mz = 350;
	// scaling values used in mapping routine
	var rx, ry;
	// visibility factor in hidden surface routine
	var sp;
	// temporary values of sp
	var sp1, sp2, sp3;
	// cylinder surface & vertex counters
	var q, q1, q2;
	// spherical coordinate angles
	var r4 = 6.28319, r5 = 6.28319;
	// 36 sets of xyz view coords, upper
	var B11 = [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ];
	// 36 sets of xyz view coords, lower
	var B12 = [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ];
	// 36 sets sx, sy display coords, upper
	var B21 = [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ];
	// 36 sets sx. sy display coords, lower
	var B22 = [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ];
	// rotation factors
	var sr4, cr4, sr5, cr5;
	
	var q1, q2;
	
	/*
	* CALCULATE SIN, COS FACTORS
	*/
	var rotation = function() {
		sr1 = Math.sin( settings.rotationYaw );
		sr2 = Math.sin( settings.rotationRoll );
		sr3 = Math.sin( settings.rotationPitch );
		cr1 = Math.cos( settings.rotationYaw );
		cr2 = Math.cos( settings.rotationRoll );
		cr3 = Math.cos( settings.rotationPitch );
	};
	
	/*
	* STANDARD 3D FORMULAS
	*/
	var calc3D = function() {
		x *= -1;
		xa = cr1*x-sr1*z;
		za = sr1*x+cr1*z;
		x = cr2*xa+sr2*y;
		ya = cr2*y-sr2*xa;
		z = cr3*za-sr3*ya;
		y = sr3*ya;
		x = x+mx;
		y = y+my;
		z = z+settings.zOffset;
		sx = settings.angularDistorision*x/z;
		sy = settings.angularDistorision*y/z;
	};
	
	/*
	* MAP CARTESIAN COORDS TO PHYSICAL SCREEN COORDS
	*/
	var toViewport = function() {
		sx = sx+WORLD_WIDTH/2;
		sy = sy+WORLD_HEIGHT/2;
		rx = SCREEN_WIDTH/WORLD_WIDTH;
		ry = SCREEN_HEIGHT/WORLD_HEIGHT;
		sx = sx*rx;
		sy = sy*ry;
	};
	
	/*
	* HIDDEN SURFACE VISIBILITY TEST
	*/
	var visibilityTest = function() {
		sp1 = x1*(y2*z3-y3*z2);
		sp1 *= -1;
		sp2 = x2*(y3*z1-y1*z3);
		sp3 = x3*(y1*z2-y2*z1);
		sp = sp1 - sp2 - sp3;
	};
	
	/*
	* CALCULATE WORLD COORDS FOR CYLINDER
	* This subroutine uses sine and cosine to calculate the x, y, z
	* coordinates of various vertices at each end of the 3D cylinder.
	* The variables r4 and r5 refer to yaw and roll in the 3D
	* spherical coordinates system, respectively.
	*/
	var cylinderCoords = function() {
		sr4 = Math.sin( r4 );
		cr4 = Math.cos( r4 );
		sr5 = Math.sin( r5 );
		cr5 = Math.cos( r5 );
		x1 = sr5*x;
		y = cr5*x;
		x = cr4*x1;
		z = sr4*x1;
	};
	
	/*
	* DRAW 4-SIDED SOLID POLYGON IN A 3D SPACE
	*/
	var drawSurface = function() {
		// get view coords
		x1 = B11[q1][0];
		y1 = B11[q1][1];
		z1 = B11[q1][2];
		x2 = B11[q2][0];
		y2 = B11[q2][1];
		z2 = B11[q2][2];
		x3 = B12[q2][0];
		y3 = B12[q2][1];
		z3 = B12[q2][2];
		visibilityTest();
		// test if surface visible
		if( sp > 0 ) {
			return;
		}
		// retrieve display coords
		sx1 = B21[q1][0];
		sy1 = B21[q1][1];
		sx2 = B21[q2][0];
		sy2 = B21[q2][1];
		sx3 = B22[q2][0];
		sy3 = B22[q2][1];
		sx4 = B22[q1][0];
		sy4 = B22[q1][1];
		x = x1 + .5*(x3-x1);
		y = y1 + .5*(y3-y1);
		z = z1 + .5*(z3-z1);
		sx = settings.angularDistorision*x/z;
		sy = settings.angularDistorision*y/z;
		toViewport();
		// draw solid polygon
		drawPoly();
	};
	
	/*
	* DRAW 4-SIDED SOLID POLYGON IN 3D SPACE
	*/
	var drawPoly = function() {
		context.beginPath();
		context.moveTo( sx1, sy1 );
		context.lineTo( sx2, sy2 );
		context.lineTo( sx3, sy3 );
		context.lineTo( sx4, sy4 );
		context.closePath();
		context.strokeStyle = '#fff';
		context.stroke();
		context.fillStyle = getRandomColor();
		context.fill();
	};
	
	var draw = function() {
		context.clearRect( 0, 0, context.canvas.width, context.canvas.height );

		// calculate the yaw, roll, pitch factors
		rotation();
		
		// calculate coordinates for near end of cylinder
		r5 = 0;
		r4 = 0;
		for( i = 0; i < 36; i++ ) {
			x = 30;
			cylinderCoords();
			z = z + 60;
			calc3D();
			toViewport();
			// store view coords
			B11[i][0] = x;
			B11[i][1] = y;
			B11[i][2] = z;
			// store display coords
			B21[i][0] = sx;
			B21[i][1] = sy;
			// increment r5 by 10 degress
			r5 = r5 + .17453;
		}
		
		// calculate coordinates for far end of cylinder
		r4 = 0;
		r5 = 0;
		for( var i = 1; i < 36; i++ ) {
			x = 30;
			cylinderCoords();
			z = z - 60;
			calc3D();
			toViewport();
			// store view coords
			B12[i][0] = x;
			B12[i][1] = y;
			B12[i][2] = z;
			// store display coords
			B22[i][0] = sx;
			B22[i][1] = sy;
			// increment r5 by 10 degress
			r5 = r5 + .17453;
		}
		
		// draw surfaces of 3D cylinder
		// 36 four-sided polygons 
		for( q1 = 0; q1 < 36; q1++ ) {
			q2 = q1 + 1;
			if( q2 > 35 ) {
				q2 = 0;
			}
			drawSurface();
		}
		
		// draw near end of 3D cylinder
		x1 = B11[0][0];
		y1 = B11[0][1];
		z1 = B11[0][2];
		x2 = B11[25][0];
		y2 = B11[25][1];
		y2 = B11[25][2];
		x3 = B11[11][0];
		y3 = B11[11][1];
		z3 = B11[11][2];
		visibilityTest();
		if( sp < 0 ) {
			for( q1 = 0; q1 < 36; q1++ ) {
				q2 = q1 + 1;
				if( q2 > 35 ) {
					q2 = 0;
				}
				sx1 = B21[q1][0];
				sy1 = B21[q1][1];
				sx2 = B21[q2][0];
				sy2 = B21[q2][1];
				context.beginPath();
				context.moveTo( sx1, sy1 );
				context.lineTo( sx2, sy2 );
				context.stroke();
				context.closePath();
			}
		}
	};

	var gui = new dat.GUI();
	gui.add( settings, 'rotationPitch', 1, 2*Math.PI ).onChange( draw );
	gui.add( settings, 'rotationRoll', 1, 2*Math.PI ).onChange( draw );
	gui.add( settings, 'rotationYaw', 1, 2*Math.PI ).onChange( draw );
	gui.add( settings, 'zOffset', -500, 1000 ).onChange( draw );
	gui.add( settings, 'angularDistorision', 0, 5000 ).onChange( draw );

 // init
	draw();

Comments