CSSASSCSSASS

三人行必有我师焉,择其善者而从之,其不善者而改之
三人行必有我师焉,择其善者而从之,其不善者而改之
三人行必有我师焉,择其善者而从之,其不善者而改之
三人行必有我师焉,择其善者而从之,其不善者而改之
三人行必有我师焉,择其善者而从之,其不善者而改之

  在canvas 2D API下实现3D效果(3D版心形函数的绘制) 作者:ONEBOYS    发表时间: 2011年02月24号,星期四     阅读:4,411 次  

html5的canvas为我们提供了浏览器原生支持的绘图API。
(或者怎么说呢,大多数浏览器已经为我们提供了原生的绘图API:HTML5的canvas)
目前,这个API只提供2D context,并不支持3D绘图,但是web上从来就不缺牛人,各种canvas下绘制的3D效果层出不穷,令人吱吱称赞。
有3D圣诞树:http://www.romancortes.com/blog/how-i-did-the-1kb-christmas-tree
有3D的FPS:使用 HTML 5 canvas 和光线投影算法创建伪 3D 游戏
还有3D俄罗斯:http://www.benjoffe.com/code/games/torus/
不胜枚举…

其实,无论canvas是否提供API,在我们目前这种二维显示设备下显示,势必都要将3维形状投影到2维平面坐标上。无论多炫的3D效果也只是二维平面上的投影。
对于此,读过《三体》特别是第三部《死神永生》的同学或许会大有感触吧。

人们总是喜欢用这样一个类比:想象生活在三维空间中的一张二维平面画中的扁片人,不管这幅画多么丰富多彩,其中的二维人只能看到周围世界的侧面,在他们眼中,周围的人和事物都是一些长短不一的线段而已。只有当一个二维扁片人从画中飘出来,进人三维空间,再回头看那幅画,才能看到画的全貌。
这个类比,其实也只是进一步描述了四维感觉的不可描述。

关于《三体——死神永生》里四维空间(不算时间维)的讨论,这里还有篇有意思的博文:四维世界的堵车问题

好了,言归正传。
下面提供一个三维到二维的投影算法(from www.benjoffe.com):

var theta = 4.2; //转角
var eleva = 0.6; //仰角
function iso(x,y,z){
var dist = Math.sqrt(x*x+y*y);
var angle = (x==0 && y==0) ? 0 : Math.atan(y/x) + theta + ((x<0)? Math.PI : 0);

x=Math.cos(angle)*dist;
y=-Math.sin(angle)*dist;
var fact = (y*Math.cos(eleva) + z*Math.sin(eleva)+8)/8;
y=y*Math.sin(eleva) - z*Math.cos(eleva);
x*=fact;
y*=fact;

return {
x: x,
y: y
};
}

输入是x,y,z三个三维坐标下的值,输出是x,y两个二维坐标值。

我们应用一下:
下面是一个3D球

以上代码是对球面的方程 x^2+y^2+z^2=r^2进行求解,将解(x,y,z)代入iso方法,最后根据输出二维坐标进行绘图。
对于这个球面方程的解法,也是各有各的写法。
(这里有个Functions 3D的应用,用来将方程式输出成3D图形:http://www.benjoffe.com/code/tools/functions3d/

如果你知道这篇文章的话:笛卡尔情书的秘密——心形函数的绘制
我相信你也很可能知道网上还有一个3D版是心形函数:(x^2 + (9/4)y^2 + z^2 – 1)^3 – x^2*z^3 – (9/80)y^2*z^3 = 0
下面我将使用上面的iso方法在canvas中绘制出来。

我都给你画了这么多心了,难道非得让我把自己的心掏出来吗~~~~

咳咳…

回来,我们知道,三维空间下的坐标系不止直角坐标一种,还有 圆柱坐标系,球坐标系等等。
下面我们将iso方法转换一下,是输入使用球坐标系值(θ,Φ,r)——转角,仰角,球半径。
首先我们先要知道,三维直角坐标系于球坐标系的换算式:

x=rsinθcosφ  
y=rsinθsinφ   
z=rcosθ

呃哦…
代入iso函数后我们发现iso变的更简单了:

var theta = 4.2; //转角
var eleva = 0.6; //仰角
function iso(a,b,r){
var x,y,z
x=r*Math.cos(a+this.theta)*Math.sin(b);
y=r*Math.sin(a+this.theta)*Math.sin(b);
z=r*Math.cos(b);

var fact = (y*Math.cos(this.eleva) + z*Math.sin(this.eleva)+8)/8;
y=y*Math.sin(this.eleva) + z*Math.cos(this.eleva);
x*=fact;
y*=fact;
return {
x: x,
y: y
};
}

下面是我们使用球坐标系绘制的三维图形(三维投射到二维的图形)

   

  三体赋 作者:ONEBOYS    发表时间: 2011年02月11号,星期五     阅读:1,533 次  

夕阳残 血色骤 清梦徒留(叶文洁)
一念成魔 嫉世如仇(伊文斯)
嬉笑侈侈不休 半生难逢敌手(史强)
琴弦封喉 知己难求(汪淼)
思虑尘埋心头 魂色万古芳流(章北海)
志怎酬 出师未捷身先殁(泰勒&雷迪亚兹)
鸾凤相左 凝噎泪满首(希恩斯&山杉惠子)
毕一生 功成名就(萨伊)
怎敌她 似水娇柔(庄颜)
本色终现 力挽沧海横流(罗辑)
但使干戈永日休(三体世界1379号监听员)

星作酬 宇为舟 孤胆独谋(云天明)
冷若磐石 一诺千秋(维德)
啜碧茗在小楼 仗剑拨弄素手(智子)
歌缅过往 画作弥留(歌者)
情已叩 夫复何求(褚岩)
望天涯 此生相守(关一帆)
咫尺侯 沧海桑田几许惆(艾AA)
大爱如佛 奈何终是谬(程心)

悔当初 血气方遒
而如今 覆水难收
流光若返 万事皆再从头
天下同 谁人能说
(三体文明)

三百年 恩怨情仇
一朝散 烟消云走
曲终人廋 曾记多少风流
唯往事悠悠
(人类文明)

作曲/编曲:李丙雨
填词:胡尘
演唱:大若
动画剪辑:青衿

《三体》Ⅲ : http://book.douban.com/subject/5363767/

   

  种花 作者:ONEBOYS    发表时间: 2011年01月24号,星期一     阅读:1,372 次  

一片两片三四片,
五片六片七八片,
九片十片十一片,
花开彼岸难相见。

前回植树,今日种花。
(如果你用的是firefox,chrome,safari,opera或者是ie9浏览器,你就能见到我的花儿了)

   

  植树 作者:ONEBOYS    发表时间: 2011年01月21号,星期五     阅读:991 次  

在闪吧看见一棵树,移植到canvas+javascript里来。

用setInterval让它动起来

上面的代码除了添加了动画效果外,还将绘制函数移出了递归函数,在递归函数里,保存坐标值,最后按这些坐标值将树的各个枝干叶子一起绘出来(原来是递归一遍绘一次的)。

   

  offsetLeft/Top Bug in Firefox 作者:ONEBOYS    发表时间: 2011年01月17号,星期一     阅读:1,051 次  

之前在这篇文章offsetX/Y for Firefox中有顺带提到ie6,ie7对于offsetLeft的不标准行为。

obj.offsetLeft是相对与“offsetParent”的距离,按标准应该是距其上级中定位元素的距离(如果不存在这个元素,则相对于整个页面文档)。
而对于ie6,ie7,obj.offsetLeft是相对其直接父级的距离——显然他们没有遵循标准。

而今天提到的兼容问题则要归咎于firefox的不合群。

当子级相对于父级绝对定位,而父级又有这两个属性:overflow:hidden; border:10px solid #999;时,
在firefox看来,子级的offsetLeft就需要再减去border值。很怪异的解释。