当前位置: 首页 > news >正文

连云港网站制作上海网站建设优化

连云港网站制作,上海网站建设优化,什么网站做婚礼请柬,中国苏州官网几年前就在网上曾看见过这种效果,但一直不知道叫什么名字 前一阵无意在9ria(天地会)论坛上看到了一篇专门讲这个的文章:AS3 元球(Metaball),不过有点遗憾的是那篇文章上的代码直接复制下来都不能调试,花了点…

几年前就在网上曾看见过这种效果,但一直不知道叫什么名字

2010062814294548.png 

前一阵无意在9ria(天地会)论坛上看到了一篇专门讲这个的文章:AS3 元球(Metaball),不过有点遗憾的是那篇文章上的代码直接复制下来都不能调试,花了点时间整理了一下,终于调试通过了,贴在这里分享一下:

Metaball的公式:

2010062814211934.gif

其中,x、y是舞台上的任意一个点,x0、y0是metaball的位置,R为半径。从公式上看,可以理解为万有引力的变种(即引力与距离成反比,与半径与正比)

先定义一个Metaball类(注:相对于原文而言,增加了vx,vy速度变量,用于后面演示运动的效果):

package {public class Metaball {public var radius:Number;public var x:int;public var y:int;public var original_radius:Number;public var vx:Number;//x轴速度public var vy:Number;//y轴速度public function Metaball(x:Number,y:Number,radius:Number) {this.x=x;this.y=y;this.original_radius = radius;//保存原始半径this.radius=radius*radius;//设置为radius的二次方,有助于后面优化性能  }public function equation(tx:Number,ty:Number):Number {//Metaball公式的体现: return radius/((x-tx)*(x-tx)+(y-ty)*(y-ty));//因为之前Radius已经是平方值了,这里就不再用平方根处理(就是上面提到的优化性能的解释)}}
}

接下来是如何运用:

var sW:Number=stage.stageWidth;//舞台宽度
var sH:Number=stage.stageHeight;//舞台高度
var canvas:BitmapData=new BitmapData(sW,sH,false,0xff000000);//默认生成一个黑背景的BitmapData
var rect:Rectangle=canvas.rect;//canvas的矩形区域
var pt:Point=new Point(rect.left,rect.top);//rect的左上顶点
var blurFilter:BlurFilter=new BlurFilter(10,10);//定义一个模糊滤镜
var metaballs:Array = new Array();//用于保存n个metaball的数组
var ballNumber:uint=5;//小球数目
var i:uint=0;//循环变量
var minThreshold:int=0x000009;//最小阈值
var maxThreshold:int=0x000020;//最大阈值
var bitMap:Bitmap = new Bitmap();//最终用来显示的位图对象
var isHollow:Boolean=false;//是否空心图形function init() {for (i=0; i<ballNumber; i++) {var b:Metaball=new Metaball(Math.random()*sW,Math.random()*sH,20 + Math.random()*80);if (b.x>sW-b.original_radius) {b.x=sW-b.original_radius;} else if (b.x < b.original_radius) {b.x=b.original_radius;}if (b.y>sH-b.original_radius) {b.y=sH-b.original_radius;} else if (b.y<b.original_radius) {b.y=b.original_radius;}b.vx = (Math.random()*2-1)*2;b.vy = (Math.random()*2-1)*2;metaballs.push(b);}addChild(bitMap);addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}function enterFrameHandler(e:Event):void {for (i=0; i<ballNumber; i++) {var b:Metaball=metaballs[i];b.x+=b.vx;b.y+=b.vy;if (b.x>=sW-b.original_radius) {b.x=sW-b.original_radius;b.vx*=-1;} else if (b.x<b.original_radius) {b.x=b.original_radius;b.vx*=-1;}if (b.y>=sH-b.original_radius) {b.y=sH-b.original_radius;b.vy*=-1;} else if (b.y<b.original_radius) {b.y=b.original_radius;b.vy*=-1;}}canvas.dispose();canvas = new BitmapData(sW,sH,false,0xff000000);canvas.lock();canvas.floodFill(0,0,0);var sum:Number=0;for (var ty:int = 0; ty < stage.stageHeight; ty++) {for (var tx:int = 0; tx < stage.stageWidth; tx++) {sum=0;for (var i:int = 0; i < metaballs.length; i++) {sum+=metaballs[i].equation(tx,ty);}if (! isHollow) {if (sum>=minThreshold) {canvas.setPixel(tx, ty, 0xFFFFFF);}} else {if (sum>=minThreshold&&sum<=maxThreshold) {canvas.setPixel(tx, ty, 0xFFFFFF);}}}}canvas.applyFilter(canvas,rect,pt,blurFilter);canvas.unlock();bitMap.bitmapData=canvas;
}init();

 

大概原理就是根据公式遍历舞台上的每个像素点,得到一个计算值,如果该值在指定的阈值之间,就设置为白色。

空心Metaball:

2010063015530110.jpg
在线演示

实心Metaball:

2010063015531088.jpg
在线演示

正如大家所看到的,效果虽然不错,但是运行效率也是极低的,因为要逐像素处理。

如何提高性能?这个就得借助上一篇里刚学过的PixelBender,原文的作者已经帮我们写了一个PixdelBender的脚本:

<languageVersion : 1.0;>kernel Metaballs
<   namespace : "com.rocketmandevelopment";
vendor : "Rocketman Development";
version : 1;
description : "Fast Metaballs";
>
{
parameter float minThreshold
<
minValue:float(0.0);
maxValue:float(2.0);
defaultValue:float(0.9);
description: "minThreshold";
>;
//no max threshold because I want these balls completely filled
parameter float3 ball1
<//this is where it gets odd. Pixel bender with flash doesn't support loops, so you must pass in each ball individually. This limits the amount of balls to the amount defined in the filter
minValue:float3(0.0,0.0,0.0); //storing the data is also odd. We'll use a float3, which is like an array of 3 float values.
maxValue:float3(640.0,480.0,50.0); //this first is the x, second is y, and the third is radius.
defaultValue:float3(50.0,50.0,20.0);
description: "ball1, params, x,y,radius";
>;parameter float3 ball2
<
minValue:float3(0.0,0.0,0.0);
maxValue:float3(640.0,480.0,50.0);//this example only supports two balls
defaultValue:float3(100.0,100.0,20.0);
description: "ball2, params, x,y,radius";
>;input image4 src;
output pixel4 dst;void
evaluatePixel()
{
dst = sampleNearest(src,outCoord());
dst.rbg = float3(0,0,0);//sets the current pixel to black so the image is cleared before redrawing
float2 coord = outCoord(); //get the coordinate of the pixel
float sum = 0.0; //get the sum and set it to 0
sum += (ball1.z)/((ball1.x-coord.x)*(ball1.x-coord.x)+(ball1.y-coord.y)*(ball1.y-coord.y)); //add to the sum using the formula from the first example
sum += (ball2.z)/((ball2.x-coord.x)*(ball2.x-coord.x)+(ball2.y-coord.y)*(ball2.y-coord.y));
if(sum >= minThreshold){
dst.rgb = float3(255,255,255); //set it to black if its within the threshold
}}
}

借助于PixelBender Toolkit可以将它导出为flash所需要的二进制文件metall.pbj,然后在Flash中测试一把:

package {import flash.display.Sprite;import flash.events.Event;import flash.filters.BlurFilter;import flash.filters.ShaderFilter;import flash.utils.ByteArray;import flash.display.Bitmap;import flash.display.BitmapData;import flash.display.Shader;import flash.display.ShaderPrecision;[SWF(height=300,width=300)]public class PixelBenderMetaballs extends Sprite {[Embed(source='metaball.pbj',mimeType='application/octet-stream')]private static const MetaballsFilter:Class;private const canvas:BitmapData=new BitmapData(300,300,false,0);private const blur:BlurFilter=new BlurFilter(10,10,1);private var metaballsFilter:ShaderFilter;private var b1:Metaball;private var b2:Metaball;private var b:Bitmap;public function PixelBenderMetaballs() {b=new Bitmap(canvas);b.smoothing=true;addChild(b);var ba:ByteArray = new MetaballsFilter() as ByteArray;var s:Shader=new Shader(ba);metaballsFilter=new ShaderFilter(s);metaballsFilter.shader.data.src.image=canvas;b1=new Metaball(100,100,Math.random()*20 + 30);b2=new Metaball(150,150,Math.random()*20 + 30);b1.vx = (Math.random()*2-1)*5;b1.vy = (Math.random()*2-1)*5;b2.vx = (Math.random()*2-1)*5;b2.vy = (Math.random()*2-1)*5;metaballsFilter.shader.data.ball1.value=[b1.x,b1.y,b1.radius];metaballsFilter.shader.data.ball2.value=[b2.x,b2.y,b2.radius];metaballsFilter.shader.precisionHint=ShaderPrecision.FAST;b.filters=[metaballsFilter];addEventListener(Event.ENTER_FRAME, enterFrameHandler);}private function enterFrameHandler(e:Event):void {b1.x+=b1.vx;b1.y+=b1.vy;			checkWalls(b1);b2.x += b2.vx;b2.y += b2.vy;checkWalls(b2);metaballsFilter.shader.data.ball1.value=[b1.x,b1.y,b1.radius];metaballsFilter.shader.data.ball2.value=[b2.x,b2.y,b2.radius];b.filters=[metaballsFilter,blur];}private function checkWalls(ball:Metaball):void {var sw:Number=stage.stageWidth;var sh:Number=stage.stageHeight;var adjust:uint=15;if (ball.x>sw-ball.original_radius-adjust) {				ball.x=sw-ball.original_radius-adjust;ball.vx*=-1;} else if (ball.x < ball.original_radius + adjust) {				ball.x=ball.original_radius+adjust;ball.vx*=-1;}if (ball.y>sh-ball.original_radius-adjust) {				ball.y=sh-ball.original_radius-adjust;ball.vy*=-1;} else if (ball.y<ball.original_radius+adjust) {				ball.y=ball.original_radius+adjust;ball.vy*=-1;}}}
}

2010063015533155.jpg
在线演示

很明显,现在看上去流畅多了。

上面提到的都是极其精确的标准做法,如果要求不高,其实这种效果可以直接用Bitmap + 模糊滤镜来模似(不过看上去效果有点假),大概原理就直接把二个圆形进行重叠,然后把最终的(并集)图形边缘模糊处理。(该方法是从一位老外的博客上看到的)

var ballNum:uint=5;
var balls:Array = new Array();
var sW:Number=stage.stageWidth;
var sH:Number=stage.stageHeight;
var container:Sprite = new Sprite();
var bmd:BitmapData=new BitmapData(sW,sH,false,0x00000000);
var bitmap:Bitmap;
var i:uint=0;
var rect:Rectangle=new Rectangle(0,0,sW,sH);
var pt:Point=new Point(0,0);
var filter:BlurFilter=new BlurFilter(10,10);function init() {for (i=0; i<ballNum; i++) {var b:Ball=new Ball(15+Math.random()*20,0xffffff);balls.push(b);b.x = (sW - b.width)*Math.random() + b.radius;b.y = (sH - b.width)*Math.random() + b.radius;b.vx=(Math.random()*2-1)*1;b.vy=(Math.random()*2-1)*1;container.addChild(b);}bmd.draw(container);bmd.applyFilter(bmd, rect, pt, filter);bitmap=new Bitmap(bmd);addChild(bitmap);addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}function enterFrameHandler(e:Event):void {for (i=0; i<ballNum; i++) {var b:Ball=balls[i];b.x+=b.vx;b.y+=b.vy;var adjust:uint=5;if (b.x>=sW-b.radius-adjust) {b.x=sW-b.radius-adjust;b.vx*=-1;} else if (b.x<b.radius+adjust) {b.x=b.radius+adjust;b.vx*=-1;}if (b.y>=sH-b.radius-adjust) {b.y=sH-b.radius-adjust;b.vy*=-1;} else if (b.y<b.radius+adjust) {b.y=b.radius+adjust;b.vy*=-1;}}bmd.dispose();bmd=new BitmapData(sW,sH,false,0x00000000);bmd.draw(container);bmd.applyFilter(bmd, rect, pt, filter);bitmap.bitmapData=bmd;
}init();

2010063015535048.jpg
在线演示

文中所用源代码下载:http://cid-2959920b8267aaca.office.live.com/self.aspx/Flash/metaball.rar

转载于:https://www.cnblogs.com/yjmyzz/archive/2010/06/28/1766712.html

http://www.wooajung.com/news/34912.html

相关文章:

  • 做微商进哪个网站安全吗怎么免费建立网站
  • 深圳建网站公司怎么选择百度下载
  • 网站修改备案号网络整合营销
  • 军事最新新闻播报青岛网络优化代理
  • 重新下载一个微信seo培训公司
  • 罗湖网站建设优化精准营销的三要素
  • 马蜂窝网站怎么做网络广告投放方案
  • 中国建设官网首页汕头seo不错
  • 宝鸡专业做网站百度seo标题优化软件
  • 简历旅游网站开发经验百度app下载官方免费下载最新版
  • 怎么用电脑windows做网站杭州搜索推广公司
  • 学校网站建设的优势和不足新闻博客软文自助推广
  • iis网站无法启动网络营销技能大赛优秀作品
  • 上海哪个区买房最好百度seo
  • 自己做网站步骤广告买卖网
  • 海报图片素材win优化大师官网
  • easyui做门户网站网站优化外包价格
  • 企业网站建站 广州 视频360地图怎么添加商户
  • 网站正在建设中中文网站安全检测平台
  • asp新闻发布网站模板怎么建网站教程图解
  • 深圳燃气公司上班时间seo顾问张智伟
  • 人才网站建设方案网店seo名词解释
  • 网站建设788gg网站seo查询站长之家
  • 网站开发时遇不到算法今日十大热点新闻事件
  • 昆明网站建设系统今日国内新闻大事件
  • 水资源论证网站建设公众号怎么推广
  • 建立一个公司的网站seo关键词排名优化价格
  • 福建石狮有做网站的没地推团队如何收费
  • ui做的好的网站有哪些网页设计是干嘛的
  • 建站用什么平台好武汉seo顾问