flash位图技术研究篇(9):2D平面映射球体

    技术2025-01-14  11

    原文:http://www.codeproject.com/KB/graphics/Sphere_mapping.aspx?msg=2178656

     

        昨晚在codeproject 里面无意当中看了一篇关于2D平面映射的球体的文章,该作者使用了一个平面的图片映射成球体。记得在3dmax里面材质贴图的时候就有这样映射的显示,按这种映射关系可以映射出球体,圆柱等的图片是存在的。

     

       按该作者的做法,他使用的映射是按比例去做。例如一张图片 100x50的图片,宽度是100,高度是50,球体可以展开一张平面图,按经度和纬度表示。经度(0--360度) 纬度(0-180度)区间显示。

     

      那么要找到对应关系就是如下:  例如(x-x0)/(宽度-x0)*经度(w1-w2)+w1;//(w1 =360,w2=0,x0=0)

      x是变化的值,这样就能够找到对应的经度,同理(y-x0)/(高度-y0)*纬度(w1-w2)+w1;//(w1 =180,w2=0,y0=0)

     

     

    作者使用c#来实现这种效果,笔者将其转化as3的实现方式表现。

     

    平面图:

     

     转换球体:

     

     

    package { import flash.display.Sprite; import flash.events.*; import flash.display.Loader; import flash.display.Bitmap; import flash.display.BitmapData; import flash.net.*; import flash.geom.*; import flash.utils.ByteArray; public class Main extends Sprite { private var loader:Loader; private var url:String="2.jpg"; //纬度 private var phi0:Number=0.0; private var phi1:Number=Math.PI; //经度 private var theta0:Number=0.0; private var theta1:Number=2*Math.PI; //半径 private var radius:Number=150; private var newBmp:BitmapData; public function Main() { init(); } private function init():void { //外部加载一张位图 loader=new Loader(); loader.load(new URLRequest(url)); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadComplete); } private function onLoadComplete(event:Event):void { var bitmapData:BitmapData=Bitmap(loader.content).bitmapData; newBmp=new BitmapData(550,400,false,0x0); //获取每一个像素点值 for (var i:int=0; i<bitmapData.width; i++) { for (var j:int=0; j<bitmapData.height; j++) { var theta:Number=MapCoordinate(0,bitmapData.width,theta1,theta0,i);//经度 var phi:Number=MapCoordinate(0,bitmapData.height,phi0,phi1,j);//纬度 var px:Number=radius*Math.sin(phi)*Math.cos(theta); var py:Number=radius*Math.sin(phi)*Math.sin(theta); var pz:Number=radius*Math.cos(phi); RotX(1.5,py,pz); RotY(-2.5,px,pz); if (pz>0) { var color:uint=bitmapData.getPixel(i,j); var ix:int=int(px)+stage.stageWidth/2; var iy:int=int(py)+stage.stageHeight/2; newBmp.setPixel(ix,iy,color); } } } bitmapData.dispose();//释放位图资源 addChild(new Bitmap(newBmp)); } //转换映射 //0-width //0-2*pi 进行映射转换 private function MapCoordinate(i1:Number,i2:Number,w1:Number,w2:Number,p:Number):Number { return (p - i1) / (i2 - i1) * (w2 - w1) + w1; } //旋转x轴 private function RotX(angle:Number,y:Number,z:Number):void { var py:Number=Math.cos(angle)*y-Math.sin(angle)*z; var pz:Number=Math.sin(angle)*y+Math.cos(angle)*z; y=py; z=pz; } //旋转y轴 private function RotY(angle:Number,x:Number,z:Number):void { var px:Number=Math.cos(angle)*x-Math.sin(angle)*z; var pz:Number=Math.sin(angle)*x+Math.cos(angle)*z; x=px; z=pz; } } }

     

    最新回复(0)