绘制球形

package
{
	import flash.display.GraphicsTrianglePath;
	import flash.display.Sprite;
	import flash.display.TriangleCulling;
	import flash.events.Event;
	import flash.geom.Vector3D;
	
	/**
	 *  @author:Gaara
	 *  2012-3-14
	 *
	 **/
	[SWF(width="800", height="600" ,frameRate="30", backgroundColor="#FFFFFF")]
	public class DrawBall extends Sprite
	{
		private const D:int = 300;
		
		//定义路径类
		private var triangPath:GraphicsTrianglePath;
		
		private var sprite:Sprite = new Sprite;
		
		private var indices:Vector.<int> = new Vector.<int>;
		private var uvtData:Vector.<Number> =  new Vector.<Number>;
		private var vertices:Vector.<Vector3D> = new Vector.<Vector3D>;
		private var angel:int = 0;
		
		
		
		private const RADIUS:int = 100;//半径
		
		private var cols:int = 20;//分成多少份
		private var rows:int = 20;
		
		private var radian:Number = 2 * Math.PI / cols;//弧度
		
		
		public function DrawBall()
		{
			sprite.x = this.stage.stageWidth / 2;
			sprite.y =  this.stage.stageHeight /2;
			addChild(sprite);
			
			for (var i:int = 0;i < rows; i++) 
			{
				for (var i2:int = 0; i2 < cols; i2++) 
				{
					var angel2:Number = i2 * Math.PI / cols - Math.PI/2;
					var before:Vector3D =  new Vector3D(
						Math.cos(radian * i) * RADIUS * Math.cos(angel2), 
						Math.sin(angel2) * RADIUS,
						Math.sin(radian * i) * RADIUS * Math.cos(angel2));
					vertices.push(before);
					
					uvtData.push(i2/cols,i/rows,1);
				}
			}
			
			for (var j:int = 0;j < rows; j++) 
			{
				for (var k:int = 0; k < cols; k++) 
				{
					//前面的点
					if(j<rows-1 && k < cols-1){
						indices.push(j*cols+k,j*cols+k+1,(j+1)*cols+k);
						indices.push(j*cols+k+1,(j+1)*cols+k+1,(j+1)*cols+k);
					}
				}
				
				
			}
			
			addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		
		protected function onEnterFrame(event:Event):void
		{
			angel++;
			var radianx:Number = mouseX /180*Math.PI;
			var radiany:Number = mouseY /180*Math.PI;
			
			var newVertices:Vector.<Number> = new Vector.<Number>;
			
			for (var i:int = 0; i < vertices.length; i++) 
			{
				var vec3d:Vector3D =  vertices[i]
				var newX:Number = Math.cos(radianx) * vec3d.x -  Math.sin(radianx) * vec3d.z;
				var newZ:Number = Math.cos(radianx) * vec3d.z +  Math.sin(radianx) * vec3d.x;
				
				var newX2:Number = Math.cos(radiany) * newX -  Math.sin(radiany) * vec3d.y;
				var newY:Number = Math.cos(radiany) * vec3d.y +  Math.sin(radiany) * newX;
				
				var scale:Number =  D/(D+newZ);
				uvtData[i*3+2] = scale;
				
				newVertices.push(scale * newX2);
				newVertices.push(scale * newY);
			}
			
			sprite.graphics.clear();
			sprite.graphics.beginBitmapFill(ResConfig.myLpBmp.bitmapData);
			sprite.graphics.drawTriangles(newVertices,indices,uvtData,TriangleCulling.POSITIVE);
			sprite.graphics.endFill();
			
		}		
	}
}

仔细观察发现还有不少问题。最后一列没有接上。然后绘制成网格观察。

最后加上接边的代码,调整网格大小后,终于成形。

package
{
	import flash.display.GraphicsTrianglePath;
	import flash.display.Sprite;
	import flash.display.TriangleCulling;
	import flash.events.Event;
	import flash.geom.Vector3D;
	
	/**
	 *  @author:Gaara
	 *  2012-3-14
	 *
	 **/
	[SWF(width="800", height="600" ,frameRate="30", backgroundColor="#000000")]
	public class DrawBall extends Sprite
	{
		private const D:int = 300;
		
		//定义路径类
		private var triangPath:GraphicsTrianglePath;
		
		private var sprite:Sprite = new Sprite;
		
		private var indices:Vector.<int> = new Vector.<int>;
		private var uvtData:Vector.<Number> =  new Vector.<Number>;
		private var vertices:Vector.<Vector3D> = new Vector.<Vector3D>;
		private var angel:int = 0;
		
		
		
		private const RADIUS:int = 100;//半径
		
		private var cols:int = 40;//分成多少份
		private var rows:int = 40;
		
		private var radian:Number = 2 * Math.PI / cols;//弧度
		
		
		public function DrawBall()
		{
			sprite.x = this.stage.stageWidth / 2;
			sprite.y =  this.stage.stageHeight /2;
			addChild(sprite);
			
			for (var i:int = 0;i < rows; i++) 
			{
				var newRadian:Number =  Math.PI / (cols -1) * i - Math.PI / 2;
				var x1:Number = Math.cos(newRadian) * RADIUS ;//减去90度。从最上面开始,计算出圆环的半径

				for (var i2:int = 0; i2 < cols; i2++) 
				{
					var angel2:Number = i2 * radian;
					var before:Vector3D =  new Vector3D(
						x1* Math.cos(angel2), 
						Math.sin(newRadian) * RADIUS,
						x1 * Math.sin(angel2));
					vertices.push(before);
					trace(" y:"+before.y + "x:"+ before.x + "z:"+before.z);
					uvtData.push(i2/cols,i/rows,1);
				}
			}
			
			for (var j:int = 0;j < rows; j++) 
			{
				for (var k:int = 0; k < cols; k++) 
				{
					//前面的点
					if(j<(rows - 1) && k <(cols - 1)){
						indices.push(j*cols+k,(j+1)*cols+k+1,(j+1)*cols+k);
						indices.push(j*cols+k,j*cols+k+1,(j+1)*cols+k+1);
					}
					else if(k == (cols -1)){
						indices.push(j*cols+k,(j+1)*cols,(j+1)*cols+k);
						indices.push(j*cols+k,j*cols,(j+1)*cols);
					}
				}
			}
			
			addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		
		protected function onEnterFrame(event:Event):void
		{
			angel++;
			var radianx:Number = mouseX /180*Math.PI;
			var radiany:Number = mouseY /180*Math.PI;
			
			var newVertices:Vector.<Number> = new Vector.<Number>;
			
			for (var i:int = 0; i < vertices.length; i++) 
			{
				var vec3d:Vector3D =  vertices[i]
				var newX:Number = Math.cos(radianx) * vec3d.x -  Math.sin(radianx) * vec3d.z;
				var newZ:Number = Math.cos(radianx) * vec3d.z +  Math.sin(radianx) * vec3d.x;
				
				var newX2:Number = Math.cos(radiany) * newX -  Math.sin(radiany) * vec3d.y;
				var newY:Number = Math.cos(radiany) * vec3d.y +  Math.sin(radiany) * newX;
				
				var scale:Number =  D/(D+newZ);
				uvtData[i*3+2] = scale;
				
				newVertices.push(scale * newX2);
				newVertices.push(scale * newY);
			}
			
			sprite.graphics.clear();
			sprite.graphics.beginBitmapFill(ResConfig.myLpBmp.bitmapData);
		//	sprite.graphics.lineStyle(1,0xFF0000);
			sprite.graphics.drawTriangles(newVertices,indices,uvtData,TriangleCulling.NEGATIVE);
			sprite.graphics.endFill();
			
		}		
	}
}

绘制方法

先将球形横切n刀,然后使用公式

var newRadian:Number =  Math.PI / (cols -1) * i - Math.PI / 2;

计算出从最上方的点到最下方的点的弧度,切出来的面每个点的y坐标都相等。Math.sin(newRadian) * RADIUS,

然后再计算圆上的坐标确定x,z;这部分以及索引以绘制圆筒相同。

原文地址:https://www.cnblogs.com/riaol/p/2398155.html