papervision3d学习笔记:卷轴-清明上河图
papervision3d学习笔记:卷轴-清明上河图
2010年11月23日
( 本来很想尝试csdn 上传图片,可是发现今天csdn 上传图片已经超出了20m,图片很麻烦)
今天,将之前的东西改写了一下发现有很多趣味的地方。没想到原来还可以这样子。将一张清明上河图的平面卷成这种圆柱的形状。
在卷的时候,是怎样将图片卷成圆柱形状?其实采用办法个人比较笨拙一点,但是实现起来会很简单。
基本过程是将图片进行拆片,
我们加载一张图片之后,通过位图复制的办法,按等分的办法将其分割一块块,然后利用这些碎片,就可以根据我们的喜好来组合拼的办法,这样看起来一张清明上河图就变成了卷轴的形状了。至于怎样算每一个角度偏移?这里又会涉及到圆的计算办法。利用三角函数计算出来 。有兴趣可以尝试一下。
当中里面使用pv3d 两种交互办法,这种交互过程是在一本pv3d教程当中提取出来。里面有距离检测法,和通过鼠标让摄影机移动的交互办法。很实用的技巧。
距离检测法:鼠标向中心点位置靠近,在这个距离当中鼠标的mouseX和mouseY会产生变化值,这样一来他们向中心点的连线距离就会产生一个变化值
摄影机移动:通过移动摄影机的x和y,z的空间坐标值,从而让视角产生不同的变化。
代码清单: package { import flash.events.Event; import flash.events.MouseEvent; import flash.display.*; import flash.net.*; import flash.geom.*; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.view.BasicView; import org.papervision3d.materials.BitmapMaterial; public class Main extends BasicView { private var grid:DisplayObject3D; private var shapeList:Array=[]; private var image_width:Number = 0;//一张图片宽度 private var image_height:Number = 0;//一张图片宽度 private var easeOut:Number = 0.3; private var reachX:Number = 0.5; private var reachY:Number = 0.5; private var reachZ:Number = 0.05; public function Main() { stage.frameRate = 40; init(); startRendering(); } private function init():void { this.camera.z=500; grid = new DisplayObject3D(); scene.addChild(grid); loadImage("1.jpg"); } //加载图片 private function loadImage(url:String):void { var loader:Loader=new Loader(); loader.contentLoaderInfo.addEventListener(Event.CO MPLETE,onLoadImageComplete); loader.load(new URLRequest(url)); } private function onLoadImageComplete(event:Event):void { event.currentTarget.removeEventListener(Event.COMP LETE,onLoadImageComplete); var bitmapData:BitmapData = Bitmap(event.currentTarget.content).bitmapData; creatSprite(bitmapData,24,"x"); bitmapData.dispose(); } //创建一组图形 private function creatSprite(bitmapData:BitmapData,n:int,direction: String="x"):void { var width:Number; var height:Number; if (direction == "x") { width = bitmapData.width / n;//图片宽度 height = bitmapData.height; image_width = width; } if (direction == "y") { width = bitmapData.width;//图片宽度 height = bitmapData.height / n; image_height = height; } for (var i:int=0; i<n; i++) { var bmpData:BitmapData = new BitmapData(width,height); var tempX:Number = direction == "x" ? width:0; var tempY:Number = direction == "x" ? 0:height; bmpData.copyPixels(bitmapData,new Rectangle(i*tempX,i*tempY,width,height),new Point(0,0)); var material:BitmapMaterial=new BitmapMaterial(bmpData);//位图材质 material.oneSide=false; var plane:Plane=new Plane(material,width,height); grid.addChild(plane); shapeList.push(plane); } render(shapeList,image_width); } //构建这种图 private function render(array:Array,rad:Number):void { var len:int = array.length; var angle:Number = 360 / len; rad = rad * 0.5 / Math.sin(angle * 0.5 * Math.PI / 180);//算出半径 for (var i:int=0; i<len; i++) { array[i].x = Math.cos(i * angle * Math.PI / 180) * rad; array[i].z = Math.sin(i * angle * Math.PI / 180) * rad; array[i].rotationY = - i * angle + 270;//偏移角度 } } override protected function onRenderTick(e:Event=null):void { //距离检测 var xDist:Number = mouseX - stage.stageWidth * 0.5; var yDist:Number = mouseY - stage.stageHeight * 0.5; //给摄影机添加缓冲效果 camera.x += (xDist - camera.x * reachX) * easeOut; camera.y += (yDist- camera.y * reachY) * easeOut; camera.z += (-mouseY * 2 - camera.z ) * reachZ; super.onRenderTick();//渲染 } } }