资讯专栏INFORMATION COLUMN

3D标签云

chenjiang3 / 901人阅读

摘要:资料正文部分了解了几个公式之后,标签云的旋转其实就很简单了。题外通过这次的练习才知道,学好数学是多么重要啊革命尚未成功,同志还需很努力参考文章解析标签云,其实很简单

开始之前

文章开始之前,应该了解几个重要的公式。回忆一下我们逝去的高中。

重要概念:

sinθ、cosθ的值得大小区间是[-1,1];

弧度跟角度的转换公式是:弧度 = π/180 * 角度。

公式:

1、在空间直角坐标系中,以坐标原点为球心,半径为R的球面的参数方程为:

x = r * sinθ * cosΦ;   
y = r * sinθ * sinΦ;  
z = r * cosθ;

说明:θ为点跟圆心的连线与z轴的夹角,Φ是点跟圆心连线在xy平面投影线与x轴的夹角(可以根据需要建立不同的坐标系,或者取不同的夹角,坐标的表达方式可以有很多,但原理是类似的)。

资料:http://baike.baidu.com/item/%E7%90%83%E9%9D%A2?fr=aladdin

2、旋转公式:

x1 = cosθ * x - sinθ * y;
y1 = cosθ * y + sinθ * x;

说明:(x,y)是开始的坐标,θ是旋转的角度,(x1,y1)是结束的坐标。球绕某一条轴的旋转可以抽象成圆绕圆心旋转,根据旋转前的坐标和角度可以求出旋转后的坐标。

资料:http://www.cnblogs.com/ywxgod/archive/2010/08/06/1793609.html

正文部分

了解了几个公式之后,3D标签云的旋转其实就很简单了。原理就是把标签当成一个点,通过设置不同的θ,Φ把它们平均分布在球面的各个坐标点上。 旋转x轴或者y轴达到球体旋转的目的。z轴是一条虚拟出来的轴,它与我们的屏幕垂直。我们不能真的实现一个立体的球体出来,但是我们可以通过"近大远小"达到视觉的欺骗,呈现一种立体的感觉。

原理差不多说完了,接下来开始具体的代码实现过程。

设置坐标

设置坐标是最重要,也是相对难的一步,因为我们要达到平均分布,避免分布太过集中或者重叠。因为半径是固定的,所以我们从角度出发,调整角度达到平均分布的目的。接下来我们引入一位大神的式子,我也不知道出处是那里,但是确实很好用,式子如下:

θ = arccos(((2 * i) - 1) / len - 1);
Φ = θ * sqrt(len * π);

第一个式子arccos中的((2 * i) - 1) / len - 1其实是一个[-1,1]区间上关于0对称分布的等差数列,通过反余弦转换成弧度值,的确是一个很高明的式子,学渣的我确实想不出来。第二个式子,是关于θ的等差(变量只有θ),不过参数sqrt(len * π)的取值就不是很懂了,还望知情的大神告知。

具体的代码如下:

分配坐标:

var init = function() {
    const tagEle = cloud.querySelectorAll(".tag"),
        tagLen = tagEle.length;
    for(let i = 0; i < tagLen; i++) {
        // 设置随机坐标,平均分布
        let a = Math.acos((2 * (i + 1) - 1) / tagLen - 1),        // θ = arccos(((2*(i+1))-1)/len - 1)
            b = a * Math.sqrt(tagLen * Math.PI),  // Φ = θ*sqrt(all * π)
            x = R * Math.sin(a) * Math.cos(b), // x轴坐标: x=r*sinθ*cosΦ
            y = R * Math.sin(a) * Math.sin(b), // y轴坐标: x=r*sinθ*cosΦ
            z = R * Math.cos(a),        // z轴坐标: z=r*cosθ
            t = new tag(tagEle[i] , x , y , z);

        tagEle[i].style.color = "#" + Math.floor(Math.random() * 0xffffff).toString(16);    // 设置随机颜色
        tags.push(t);
        t.move();    // 初始化位置
    }
    animate();  // 旋转
};

设置坐标及参数:

let scale = _focalLength / (_focalLength - this.z),
    alpha = (this.z + R) / (2 * R),
    ele = this.ele;
ele.style.fontSize = 14 * scale + "px";
ele.style.opacity = alpha + 0.5;
ele.style.zIndex = parseInt(scale * 100);
// 原点是 (cloud.offsetWidth/2, cloud.offsetHeight/2)
ele.style.left = this.x + cloud.offsetWidth / 2 - ele.offsetWidth/2 + "px";        
ele.style.top = this.y + cloud.offsetHeight / 2 - ele.offsetHeight/2 + "px";

scale、alpha 都是取关于z坐标的递增函数,所以可以根据需要调整函数达到更好的显示效果。

旋转

开始的时候我们简单介绍了圆的旋转,球的旋转其实类似圆。例如绕z轴旋转,其实改变的是x,y坐标的值,z坐标的值并没有变化。理解了这一层,我们可以得出绕x轴旋转的和y轴旋转的函数,分别为:

/*
绕x轴旋转
y = ycosθ - zsinθ;
z = ysinθ + zcosθ;
*/
function rotateX() {
    let cos = Math.cos(angleX),
        sin = Math.sin(angleX);
    tags.forEach(function(tag) {
        let y = tag.y * cos - tag.z * sin,
            z = tag.z * cos + tag.y * sin;
        tag.y = y;
        tag.z = z;
    })
};
/*
绕y轴旋转
x = xcosθ - zsinθ;
z = xsinθ + zcosθ;
*/
function rotateY() {
    let cos = Math.cos(angleY),
        sin = Math.sin(angleY);
    tags.forEach(function(tag) {
        let x = tag.x * cos - tag.z * sin,
            z = tag.z * cos + tag.x * sin;
        tag.x = x;
        tag.z = z;
    })
};

于是我们就能通过控制angleX、angleY的大小来达到旋转的目的了,值越大,单位时间旋转的角度越大,也就是旋转的速度越快。当然,旋转360度跟没旋转的效果是一样的,所以我们应该合理的设置单位时间和每一次旋转的角度值,让我们的眼睛知道它是个球,它在转!!!

全部代码

这是我在百度前端学院的一个课程练习的代码,代码全部放在Github上,希望对您有一点帮助。同时,Github求关注!!!

预览效果: http://alvin-liu.github.io/FrontCode/src/tagcloud/

代码地址: https://github.com/Alvin-Liu/FrontCode/blob/gh-pages/src/tagcloud/js/tagcloud.js

结束

以上内容来自一个前端低手的个人总结与整理,不足之处,还请指正。

题外:通过这次的练习才知道,学好数学是多么重要啊!!!

革命尚未成功,同志还需很努力!!!

参考文章:

解析3D标签云,其实很简单

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81911.html

相关文章

  • 基于计算的软件实现3D打印的潜力

    摘要:打印正在改变产品设计测试和制造的方式,而基于云计算的软件也正在帮助打印实现它的潜力。例如,一直在用基于云计算的软件来为客户定制化制造一款名为的产品。今年月,另外一家主要的打印公司宣布他们将追求一种新的基于云计算的软件策略。  3D打印正在改变产品设计、测试和制造的方式,而基于云计算的软件也正在帮助3D打印实现它的潜力。在云计算的帮助下,任何能连上互联网的人可以创造、调整存储和流设计,并将二者...

    Tychio 评论0 收藏0
  • 计算将怎样助力3D打印应用普及?

    摘要:打印正在改变产品设计测试和制造的方式,而基于云计算的软件也正在帮助打印实现它的潜力。在云计算的帮助下,任何能连上互联网的人可以创造调整存储和流设计,并将二者发送到世界上任何地方的打印机上。  3D打印正在改变产品设计、测试和制造的方式,而基于云计算的软件也正在帮助3D打印实现它的潜力。在云计算的帮助下,任何能连上互联网的人可以创造、调整存储和流设计,并将二者发送到世界上任何地方的3D打印机上...

    diabloneo 评论0 收藏0
  • Printr更新计算3D打印管理系统Formide

    摘要:近日,总部位于阿姆斯特丹的公司更新了其基于云计算的打印管理系统。基于云计算的打印管理系统的开发速度快,能提供超过桌面打印机自身的强大的功能,这非常令人着迷。比如,最新研制出的特色功能打印机的共享。更棒的是,公司宣布通过互联网更新。  近日,总部位于阿姆斯特丹的Printr公司更新了其基于云计算的3D打印管理系统——Formide。2015年年初,这家公司发布了一款外形像宝石的3D打印机控制器...

    Jioby 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<