HTML5实现3D和2D可视化QuadTree四叉树碰撞检测

在HT for
Web中2D和3D应用都协理树状构造数据的来得,表现效果区别,2D上的树状构造在显示层级关系显明,然而假如数据量大的话,看起来就没那么直观,找到钦命的节点相比较困苦,而3D上的树状构造在突显上协作HT
for
Web的弹力布局组件博览会示相比直观,一眼望去可以把全路树状布局数据看个大致,不过在弹力构造的意义下,其档期的顺序布局看得就不是那么清楚了。所以那时候构造清晰的3D树的急需就来了,那么这一个3D树具体长成啥样呢,大家来合作亲眼见到下~

分子力(molecular
forceState of Qatar,又称分子间效技巧、范得瓦耳斯力,是指成员间的相互作用。当二分子相距较远时,首要突显为吸重力,这种力入眼根源一个分子被另一个成员随即间赶快转移的电偶极矩所极化而孳生的相互影响;当二分子特别周围时,则排斥力成为首要的,那是由于各成员的外层电子云开始重叠而发出的排外功用。

HTML5贯彻3D和2D可视化QuadTree四叉树碰撞检查实验

QuadTree四叉树看名称就会想到其意义正是树状的数据构造,其每一种节点有七个男女节点,可将二维平面递归分割子区域。QuadTree常用于空间数据库索引,3D的椎体可以看到区域裁剪,以至图片解析管理,大家明天介绍的是QuadTree最常被游戏领域接受到的碰撞检查评定。接纳QuadTree算法将大大裁减需求测量试验碰撞的次数,进而加强游戏刷新质量,本文例子基于HT
for
Web的Canvas拓扑图和WebGL的3D引擎构件,通过GraphView和Graph3dView分享同大器晚成数据模型DataModel,同期表现QuadTree算法下的2D和3D碰撞视图效果:

澳门新浦京娱乐游戏 1

QuadTree的兑现存成都百货上千一再寻思的版本,小编采纳的是

自家构建了HT(

内需专一从quadtree.retrieve(rect卡塔尔国获取需求检验的矩形对象数组中会包含小编图元,同一时间那几个只是是唯恐会碰撞的图元,并不代表已经碰撞了,由于咱们例子是矩形,因而接纳ht.Default.intersectsRect(r1,
r2卡塔尔(قطر‎最后判别是不是相交,要是您的例子是圈子则足以行使总结三个圆心间隔是不是低于三个半径来调整是还是不是相交,因而最后剖断的行业内部依据游戏项目会有差距。

行使了QuadTree依然庞大了增进了运算质量,不然九二十一个图元就需求100*玖十九次的监测,作者这么些事例场景下日常也就100*(10~30)的量:

澳门新浦京娱乐游戏 2

澳门新浦京娱乐游戏,除去碰撞检查评定外QuadTree算法还或许有大多风趣的应用领域,风乐趣能够嬉戏这一个

澳门新浦京娱乐游戏 3

持有代码如下供仿照效法:

function init(){      d = 200;    speed = 8;    dataModel = new ht.DataModel();                                    g3d = new ht.graph3d.Graph3dView(dataModel);                                                      g2d = new ht.graph.GraphView(dataModel);                       mainSplit = new ht.widget.SplitView(g3d, g2d);                       mainSplit.addToDOM();                                            g2d.translate(300, 220);          g2d.setZoom(0.8, true);          for(var i=0; i<100; i++) {        var node = new ht.Node();        node.s3(randMinMax(5, 30), 10, randMinMax(5, 30));        node.p3(randMinMax(-d/2, d/2), 0, randMinMax(-d/2, d/2));        node.s({            'batch': 'group',            'shape': 'rect',            'shape.border.width': 1,            'shape.border.color': 'white',            'wf.visible': true,            'wf.color': 'white'        });        node.a({            vx: randMinMax(-speed, speed),            vy: randMinMax(-speed, speed),            obj: {                width: node.getWidth(),                height: node.getHeight(),                data: node            }        });                            dataModel.add(node);    }                    createShape([        {x: -d, y: d},        {x: d, y: d},        {x: d, y: -d},        {x: -d, y: -d},        {x: -d, y: d}    ]);                       quadtree = new Quadtree({ x: -d, y: -d, width: d, height: d });                                    requestAnimationFrame(update);}               function update() {       quadtree.clear();                    dataModel.each(function(data){        if(!(data instanceof ht.Shape)){            var position = data.getPosition();            var vx = data.a('vx');            var vy = data.a('vy');            var w = data.getWidth()/2;            var h = data.getHeight()/2;            var x = position.x + vx;            var y = position.y + vy;            if(x - w < -d){                data.a('vx', -vx);                x = -d + w;            }            if(x + w > d){                data.a('vx', -vx);                x = d - w;            }            if(y - h < -d){                data.a('vy', -vy);                y = -d + h;            }            if(y + h > d){                data.a('vy', -vy);                y = d - h;            }            data.setPosition(x, y);                                    var obj = data.a('obj');            obj.x = x - w;            obj.y = y - h;                        quadtree.insert(obj);            setColor(data, undefined);        }    });                    dataModel.each(function(data){        if(!(data instanceof ht.Shape)){             var obj = data.a('obj');            var objs = quadtree.retrieve(obj);            if(objs.length > 1){                                            for(var i=0; i

QuadTree四叉树从名称想到所富含的意义正是树状的数据构造,其各种节点有七个儿女节点,可将二维平面递归分…

澳门新浦京娱乐游戏 4

HT for Web提供了弹力布局(也称之为力导向布局)的效应,即依据节点之间存在互斥力,相互连接的节点间存在引力,
弹力布局运行大器晚成段时间后,全体拓扑互联网构造会逐年达到没有稳固的平衡动静。这一个效应很有趣,前几天大家就将它的魔力表现出来。

要完毕如此的效率,该从何入手呢?接下去大家就将那些标题拆解成几何个小意思来消除。

本例地址:

1. 创办三个树状结构

有询问过HT for
Web的心上人,对树状结构数据的创导应该都不面生,在那间自身就不做浓厚的探幽索隐了。树状布局数据的开创很简短,在此为了让代码更简短,笔者封装了五个点子来创建树状构造数据,具体代码如下:

/**
 * 创建连线
 * @param {ht.DataModel} dataModel - 数据容器
 * @param {ht.Node} source - 起点
 * @param {ht.Node} target - 终点
 */
function createEdge(dataModel, source, target) {
    // 创建连线,链接父亲节点及孩子节点
    var edge = new ht.Edge();
    edge.setSource(source);
    edge.setTarget(target);
    dataModel.add(edge);
}

/**
 * 创建节点对象
 * @param {ht.DataModel} dataModel - 数据容器
 * @param {ht.Node} [parent] - 父亲节点
 * @returns {ht.Node} 节点对象
 */
function createNode(dataModel, parent) {
    var node = new ht.Node();
    if (parent) {
        // 设置父亲节点
        node.setParent(parent);

        createEdge(dataModel, parent, node);
    }
    // 添加到数据容器中
    dataModel.add(node);
    return node;
}

/**
 * 创建结构树
 * @param {ht.DataModel} dataModel - 数据容器
 * @param {ht.Node} parent - 父亲节点
 * @param {Number} level - 深度
 * @param {Array} count - 每层节点个数
 * @param {function(ht.Node, Number, Number)} callback - 回调函数(节点对象,节点对应的层级,节点在层级中的编号)
 */
function createTreeNodes(dataModel, parent, level, count, callback) {
    level--;
    var num = (typeof count === 'number' ? count : count[level]);

    while (num--) {
        var node = createNode(dataModel, parent);
        // 调用回调函数,用户可以在回调里面设置节点相关属性
        callback(node, level, num);
        if (level === 0) continue;
        // 递归调用创建孩子节点
        createTreeNodes(dataModel, node, level, count, callback);
    }
}

哈哈,代码写得大概有一点复杂了,简单的做法就是嵌套几个for循环来创建树状构造数据,在此自身就非常少说了,接下去大家来切磋第2个难点。

澳门新浦京娱乐游戏 5

2. 在2D拓扑下模拟3D树状构造每层的半径总结

在3D下的树状布局体最大的标题就在于,各个节点的层系及每层节点围绕其父亲节点的半径总计。以往树状布局数据现原来就有了,那么接下去就该起来酌量半径了,大家从两层树状构造开首要推荐算:

澳门新浦京娱乐游戏 6

笔者前几天先创设了两层的树状布局,全体的子节点是一字排开,并未环绕其阿爹节点,那么我们该怎么去明确那几个子女节点的职位吗?

率先我们得明白,各样末端节点都有风姿罗曼蒂克圈归属本身的园地,不然节点与节点之间将会设有重叠的图景,所以在这里处,大家借使末端节点的世界半径为25,那么三个相邻节点之间的最短间隔将是两倍的节点领域半径,约等于50,而这个末端节点将均匀地围绕在其阿爹节点四周,那么相邻几个节点的张角就足以显著出来,有了张角,有了两点间的离开,那么节点绕其老爹节点的最短半径也就能够总结出来了,假如张角为a,两点间最小间隔为b,那么最小半径r的计算公式为:

r = b / 2 / sin(a / 2);

那就是说接下去小编么就来布局下那么些树,代码是那样写的:

/**
 * 布局树
 * @param {ht.Node} root - 根节点
 * @param {Number} [minR] - 末端节点的最小半径
 */
function layout(root, minR) {
    // 设置默认半径
    minR = (minR == null ? 25 : minR);
    // 获取到所有的孩子节点对象数组
    var children = root.getChildren().toArray();
    // 获取孩子节点个数
    var len = children.length;
    // 计算张角
    var degree = Math.PI * 2 / len;
    // 根据三角函数计算绕父亲节点的半径
    var sin = Math.sin(degree / 2),
        r = minR / sin;
    // 获取父亲节点的位置坐标
    var rootPosition = root.p();

    children.forEach(function(child, index) {
        // 根据三角函数计算每个节点相对于父亲节点的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            y = c * r;

        // 设置孩子节点的位置坐标
        child.p(x + rootPosition.x, y + rootPosition.y);
    });
}

在代码中,你会发掘自家将末端半径私下认可设置为25了,如此,大家透过调用layout(卡塔尔国方法就足以对协会树实行结构了,其结构作用如下:

澳门新浦京娱乐游戏 7

从成效图能够看得出,末端节点的暗中认可半径并非很优异,结构出来的机能连线都快看不到了,因而我们能够追加末端节点的暗中认可半径来解决布局太密的难题,如将暗中认可半径设置成40的效率图如下:

澳门新浦京娱乐游戏 8

方今两层的树状布满消除了,那么大家来寻访三层的树状布满该怎么管理。

将第二层和第三层用作三个完全,那么实际上三层的树状构造跟两层是大器晚成律的,区别的是在管理第二层节点时,应该将其当做叁个两层的树状布局来拍卖,那么像这种规律的管理用递归最佳可是了,由此大家将代码稍稍该着下,在拜谒效果怎么样:

澳门新浦京娱乐游戏 9

万分,节点都重叠在生机勃勃道了,看来简单的递归是非常的,那么具体的主题素材出在哪儿啊?

紧凑剖判了下,开掘阿爹节点的圈子半径是由其儿女节点的世界半径决定的,因而在布局时索要通晓笔者节点的小圈子半径,并且节点的职位决议于老爸节点的领域半径及职分音讯,那样一来就不能边计算半径边布局节点地点了。

那么以往一定要将半径的简政放权和布局分开来,做两步操作了,大家先来解析下节点半径的总计:

率先必要分明最要害的尺度,老爸节点的半径决议于其子女节点的半径,这几个原则告诉大家,只可以从下往上总结节点半径,由此大家规划的递归函数必得是先递归后总计,废话非常少说,大家来看下具体的代码完成:

/**
 * 就按节点领域半径
 * @param {ht.Node} root - 根节点对象
 * @param {Number} minR - 最小半径
 */
function countRadius(root, minR) {
    minR = (minR == null ? 25 : minR);

    // 若果是末端节点,则设置其半径为最小半径
    if (!root.hasChildren()) {
        root.a('radius', minR);
        return;
    }

    // 遍历孩子节点递归计算半径
    var children = root.getChildren();
    children.each(function(child) {
        countRadius(child, minR);
    });

    var child0 = root.getChildAt(0);
    // 获取孩子节点半径
    var radius = child0.a('radius');

    // 计算子节点的1/2张角
    var degree = Math.PI / children.size();
    // 计算父亲节点的半径
    var pRadius = radius / Math.sin(degree);

    // 设置父亲节点的半径及其孩子节点的布局张角
    root.a('radius', pRadius);
    root.a('degree', degree * 2);
}

OK,半径的估摸解决了,那么接下去就该解决结构难点了,构造树状布局数据要求鲜明:孩子节点的坐标地点决意于其老爸节点的坐标地点,因而结构的递归形式和估测计算半径的递归形式各异,我们须要先布局老爹节点再递归构造孩子节点,具体看看代码吧:

/**
 * 布局树
 * @param {ht.Node} root - 根节点
 */
function layout(root) {
    // 获取到所有的孩子节点对象数组
    var children = root.getChildren().toArray();
    // 获取孩子节点个数
    var len = children.length;
    // 计算张角
    var degree = root.a('degree');
    // 根据三角函数计算绕父亲节点的半径
    var r = root.a('radius');
    // 获取父亲节点的位置坐标
    var rootPosition = root.p();

    children.forEach(function(child, index) {
        // 根据三角函数计算每个节点相对于父亲节点的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            y = c * r;

        // 设置孩子节点的位置坐标
        child.p(x + rootPosition.x, y + rootPosition.y);

        // 递归调用布局孩子节点
        layout(child);
    });
}

代码写完了,接下去正是亲眼见到神跡的时刻了,我们来拜会效果图吧:

澳门新浦京娱乐游戏 10

不对呀,代码应该是没难点的呦,为何来得出来的法力照旧会重叠呢?不过精心察看大家能够发掘比较上个版本的构造会好过多,起码本次只是前边节点重叠了,那么难题出在哪个地方吧?

不知晓大家有未有开采,消释节点自个儿的深浅,尾数第二层节点与节点之间的天地是相切的,那么也正是说节点的半径不仅仅和其孩子节点的半径有关,还与其外孙子节点的半径有关,这我们把总计节点半径的办法改动下,将外甥节点的半径也考虑进去再看看效果咋样,改动后的代码如下:

/**
 * 就按节点领域半径
 * @param {ht.Node} root - 根节点对象
 * @param {Number} minR - 最小半径
 */
function countRadius(root, minR) {
   ……

    var child0 = root.getChildAt(0);
    // 获取孩子节点半径
    var radius = child0.a('radius');

    var child00 = child0.getChildAt(0);
    // 半径加上孙子节点半径,避免节点重叠
    if (child00) radius += child00.a('radius');

   ……
}

上边就来拜见效果啊~

澳门新浦京娱乐游戏 11

哈哈哈,看来大家拆解深入分析对了,果然就不再重叠了,那大家来探视再多大器晚成层节点会是何许的壮观场景吧?

澳门新浦京娱乐游戏 12

哦,NO!这不是笔者想见见的机能,又重叠了,好讨厌。

无须心急,大家再来稳重解析解析下,在前边,我们关系过二个名词——领域半径,什么是小圈子半径呢?很简短,正是能够容纳下自家及其具备孩子节点的细小半径,那么难点就来了,末端节点的领域半径为我们钦命的纤维半径,那么倒数第二层的园地半径是有一些吗?并不是大家前边总结出来的半径,而应该加上末端节点自个儿的世界半径,因为它们中间存在着满含关系,子节点的小圈子必需含有于其阿爸节点的领域中,那大家在拜会上图,是或不是以为末端节点的天地被私吞了。那么我们眼下总结出来的半径代表着什么样啊?后面总计出来的半径其实代表着子女节点的结构半径,在布局的时候是经过该半径来布局的。

OK,那大家来总括下,节点的园地半径是其下每层节点的布局半径之和,而构造半径须要遵照其子女节点个数及其领域半径协同决定。

好了,咱们以往精通难题的所在了,那么大家的代码该怎么去贯彻呢?接着往下看:

/**
 * 就按节点领域半径及布局半径
 * @param {ht.Node} root - 根节点对象
 * @param {Number} minR - 最小半径
 */
function countRadius(root, minR) {
    minR = (minR == null ? 25 : minR);

    // 若果是末端节点,则设置其布局半径及领域半径为最小半径
    if (!root.hasChildren()) {
        root.a('radius', minR);
        root.a('totalRadius', minR);
        return;
    }

    // 遍历孩子节点递归计算半径
    var children = root.getChildren();
    children.each(function(child) {
        countRadius(child, minR);
    });

    var child0 = root.getChildAt(0);
    // 获取孩子节点半径
    var radius = child0.a('radius'),
        totalRadius = child0.a('totalRadius');

    // 计算子节点的1/2张角
    var degree = Math.PI / children.size();
    // 计算父亲节点的布局半径
    var pRadius = totalRadius / Math.sin(degree);

    // 缓存父亲节点的布局半径
    root.a('radius', pRadius);
    // 缓存父亲节点的领域半径
    root.a('totalRadius', pRadius + totalRadius);
    // 缓存其孩子节点的布局张角
    root.a('degree', degree * 2);
}

在代码中我们将节点的圈子半径缓存起来,从下往上意气风发层豆蔻梢头层地叠合上去。接下来大家协同验证其不易:

澳门新浦京娱乐游戏 13

解决,正是那样子了,2D拓扑上边的布局化解了,那么接下去该出动3D拓扑啦~

应用弹力结构功能需求在引入ht.js`核心库之后,再引入一个ht-forcelayout.js `的弹力布局插件库,因为还用到了
form 表单,所以要引进 ht-form.js 的表单插件库:

3. 步入z轴坐标,显示3D下的树状布局

3D拓扑上边布局无非就是多加了八个坐标系,而且以此坐标系只是决定节点的惊人而已,并不会潜濡默化到节点之间的重叠,所以接下去我们来更动下大家的前后相继,让其能够在3D上健康结构。

也无需太大的改建,大家只必要纠正下布局器而且将2D拓扑组件改成3D拓扑组件就足以了。

/**
 * 布局树
 * @param {ht.Node} root - 根节点
 */
function layout(root) {
    // 获取到所有的孩子节点对象数组
    var children = root.getChildren().toArray();
    // 获取孩子节点个数
    var len = children.length;
    // 计算张角
    var degree = root.a('degree');
    // 根据三角函数计算绕父亲节点的半径
    var r = root.a('radius');
    // 获取父亲节点的位置坐标
    var rootPosition = root.p3();

    children.forEach(function(child, index) {
        // 根据三角函数计算每个节点相对于父亲节点的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            z = c * r;

        // 设置孩子节点的位置坐标
        child.p3(x + rootPosition[0], rootPosition[1] - 100, z + rootPosition[2]);

        // 递归调用布局孩子节点
        layout(child);
    });
}

地点是改建变成3D构造后的布局器代码,你会意识和2D的结构器代码就差贰个坐标系的的精兵简政,别的的都意气风发律,看下在3D上结构的功力:

澳门新浦京娱乐游戏 14

恩,郑重其事的了,在篇章的起始,我们能够看看每大器晚成层的节点都有两样的颜色及大小,那些都是比较轻便,在那地本人就不做深切的批注,具体的代码完结如下:

var level = 4,
    size = (level + 1) * 20;

var root = createNode(dataModel);
root.setName('root');
root.p(100, 100);

root.s('shape3d', 'sphere');
root.s('shape3d.color', randomColor());
root.s3(size, size, size);

var colors = {},
    sizes = {};
createTreeNodes(dataModel, root, level - 1, 5, function(data, level, num) {
    if (!colors[level]) {
        colors[level] = randomColor();
        sizes[level] = (level + 1) * 20;
    }

    size = sizes[level];

    data.setName('item-' + level + '-' + num);
    // 设置节点形状为球形
    data.s('shape3d', 'sphere');
    data.s('shape3d.color', colors[level]);
    data.s3(size, size, size);
});

在这里间引进了叁个自由生成颜色值的方法,对每生龙活虎层随机生成意气风发种颜色,并将节点的样子改成了球形,让页面看起来雅观些(其实非常丑)。

澳门新浦京娱乐游戏 15

提个外话,节点上得以贴上海教室片,还足以设置文字的通向,能够依据客商的理念动态调解岗位,等等生龙活虎多元的扩充,那个大家都足以去品尝,相信都能够做出一个超级美的3D树出来。

到此,整个德姆o的制作就终止了,前不久的篇幅有个别长,谢谢我们的耐烦阅读,在兼备上或则是发挥上有何提议或意见款待大家提议,点击这里能够访问HT
for Web官方网址络的手册。

<script src="../../guide/lib/core/ht.js"></script>
<script src="../../guide/lib/plugin/ht-forcelayout.js"></script>
<script src="../../guide/lib/plugin/ht-form.js"></script>

ht.layout.Force3dLayout类提供 3D弹力结构,布局函数可传入 DataModel和 Graph3dView三种参数。
暗中同意仅对未选中图元实行布局,假使布局函数参数为 Graph3dView时,则视图组件的 isMovable和 isVisible函数将震慑图元是还是不是可布局,
图元 style上的 layoutable质量也可设为 false堵住图元插足布局。

介绍完
HT
封装的弹力布局的背景之后,接下去正是援救你们也能轻易地落实这么些功能。

率先大家定义二个颜料数组变量,存款和储蓄各类弹力球的水彩,还定义了三个随机函数,用来生成数随机的数组中的颜色:

var colorList = ['#FFAFA4', '#B887C5', '#B9EA9C', '#CFD9E7', '#4590B8', '#FF9C30'], 
    colorLen = colorList.length;
var randomColor = function() {
    var ran = Math.random() * colorLen;
    return colorList[Math.floor(ran)];//随机6种颜色
};

紧接着创造弹力球,轻易生成二个3D 节点,通过设置这一个节点的 style
样式属性来调控节点的显示格局,其大校“shape3d”设置为“sphere”就能够将
ht.Node 六面体产生 3D
球人体模型型,再安装“shape3d”属性为日前定义的专擅颜色,s3 是 HT 封装的设置
3D 节点大小的 setSize3d 函数的简写,最终将以此节点增添进数据模型
dataModel 中:

var createNode = function(dm) {//创建node节点 圆
    var node = new ht.Node();
    node.s({//设置样式为 setStyle 的简写
        'shape3d': 'sphere',
        'shape3d.color': randomColor()//设置随机颜色
    });
    node.s3(40, 40, 40);
    dm.add(node);
    return node;
};

现在功效图上冒出的还也许有各类弹力球之间的连线,这么些连线大家大器晚成看就认为很有的时候,也是经过组织多个八个节点,这些节点是透过 HT
for Web
建立模型手册 setShape3dModel函数自定义的
ht.Default.createRingModel 依据 xy 平面包车型地铁曲线,环绕12日产生的 3D
环形模型,将其取名字为‘custom’:

ht.Default.setShape3dModel(//创建模型 根据xy平面的曲线,环绕一周形成3D模型。
    'custom', ht.Default.createRingModel( [0.5, 0.5, -0.2, 0, 0.5, -0.5], [1, 3] )
);

HT
将客户自定义的质量和 HT 暗中同意的质量调用方法分为 node.a 和 node.s
那样就能够将四头有效地区分开来(具体参照 HT for Web
入门手册 style
章节),我们在开创管线的时候就用了这种办法:

var updatePipeline = function(edge) {//重新设置edge的样式
    var pipeline = edge.a('pipeline');
    pipeline.s3(1, 1, 1);//设置大小
    pipeline.p3(0, 0, 0);//设置坐标

    var node1 = edge.getSourceAgent(),//获取图形上连接的起始节点
    node2 = edge.getTargetAgent();//获取图形上连接的目标节点
    pipeline.s('mat', createMatrix(node1.p3(), node2.p3(), 20));//3d整体图形矩阵变化
};

最隐衷的是什么样能做出让七个节点“若离若即”的作用?

咱们知晓,矩阵能描述放肆线性别变化换。线性别变化换保留了直线和平行线,线性别变化换保留直线的还要,其余的几何性质如长度、角度、面积和容积恐怕被退换退换了。一言以蔽之,线性别变化换大概“拉伸”坐标系,但不会“盘曲”或“卷折”坐标系。那一个函数首要是将大家的连接线在拖动掸力球后被拖拖拉拉的总是线的进行一个“变化矩阵”的操作,变化矩阵也是
HT 封装的 ht.Default.createMatrix 函数,通过将节点的 style 属性 mat
设置为叁个自定义的函数,便是将以此节点的坐标乘上在“mat”属性对应的值,也就是说如果当前那个管线的团团转角为
[Math.PI/6, 0, 0],借使我们在 createMatrix 函数中设置 r3 为
[Math.PI/3, 0, 0],那么这几个节点会旋转 90
度。特别轻便地开创下转换矩阵:

var createMatrix = function(p1, p2, width) {//createMatrix(array, matrix)将一组JSON描述的缩放、移动和旋转等操作转换成对应的变化矩阵
    var vec = [p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]],
        dist = ht.Default.getDistance(p1, p2);//获取两点之间距离,或向量长度
    return ht.Default.createMatrix({
        s3: [width, dist, width],
    r3: [Math.PI/2 - Math.asin(vec[1]/dist), Math.atan2(vec[0], vec[2]), 0],
    rotationMode: 'xyz',
    t3: [(p1[0]+p2[0])/2, (p1[1]+p2[1])/2, (p1[2]+p2[2])/2]
    });
};

底工装配零部件全部概念完成,接着正是将“shape3d”属性设置为自定义的
3D 模型“custom”
,并将“layoutable”属性设置为“false”阻止图元参加构造,并将点时期的连线通过edge.a(‘pipeline’,
node卡塔尔国重新刷新,并增加进数据模型 dataModel 中:

var createEdge = function(dm, node1, node2) {//创建‘custom’模型的edge
    var node = new ht.Node();
    node.s({
        'shape3d': 'custom',
        'shape3d.color': '#ECE0D4',
        'layoutable': false
    });
    dm.add(node);

    var edge = new ht.Edge(node1, node2);
    edge.a('pipeline', node);
    edge.s('edge.color', 'rgba(0, 0, 0, 0)');
    dm.add(edge);
    return edge;
};

插:我们还足以在工业上用
HeatMap 热图上做作品,效果照旧很炫,具体地址http://hightopo.com/guide/guide/plugin/forcelayout/examples/example_heatmap3d.html

澳门新浦京娱乐游戏 16

分界面上的图片全体制图实现,剩下的就唯有form 表单,首先将 form 表单增多进 HTML 页面,用的是 HT 封装的
ht.widget.FormPane 函数:

var formPane = new ht.widget.FormPane();
formPane.setWidth(230);
formPane.setHeight(125);
formPane.addToDOM();

铭记,form
表单要设置宽高,不然不彰显。

form
表单增添行是经过 addRow 函数,我们重点来讲一下底下的几行,Color、Range
和 Intensity,那四个名字根本是用来调整“头灯”的。在 HT 中一向通过
setHeadlightColor/setHeadlightRange/setHeadlightIntensity
四个函数来支配“头灯”的颜色、范围以至灯的强度,onValueChanged
属性,看名称就能够想到其意义属性值改换今后触发的平地风波:

['Color', 'Range', 'Intensity'].forEach(function(name) {
    var obj = { id: name },
    func = function(oV, nV) {
        g3d['setHeadlight' + name](nV);// === g3d.setHeadlightColor(nV)/g3d.setHeadlightRange(nV)/g3d.setHeadlightIntensity(nV)
    };
    if (name === 'Color')
        obj.colorPicker = {//ht.widget.ColorPicker为颜色选择框 
        instant: true,
        value: g3d['getHeadlight' + name](),// === g3d.getHeadlightColor()
        onValueChanged: func
    };
    else 
        obj.slider = {//滑动条
            min: 0,
        max: name === 'Range' ? 20000 : 3,
        step: 0.1,
        value: g3d['getHeadlight' + name](),
        onValueChanged: func
        };
    formPane.addRow([ name, obj ], [ 70, 0.1 ]);
});

slider
和 colorPicker 都以 HT 自定义的滑动条和颜色接收器,详细情形请参谋 HT for
Web
表单臂册。

假使还会有不懂的请咨询小编,也许能够一向上 HT for
Web 官方网址查阅手册。

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注