首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >六边形上的小片

六边形上的小片
EN

Stack Overflow用户
提问于 2014-12-07 03:53:07
回答 1查看 606关注 0票数 0

我想在六角上制作一张派图。对此,可能有几种解决方案。图中有我的六边形和两个想法:

  1. 我的六角(6个顶点,4个面)
  2. 它应该如何看结尾(没有灰色线)
  3. 数学:我能从对象中得到一些信息来动态计算新的顶点(从中心到每一点)来添加彩色脸吗?
  4. 裁剪:在球体上,派-图很简单,也许我可以剪辑这三个对象(没有SVG.js!)所以我只看到了有剪贴图的六角?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-07 11:24:21

在three.js中,整个剪裁的事情已经在这里解决了:Object Overflow Clipping Three JS,用一个小提琴显示它是有效的。

因此,我将选择“顶点”选项,或者更确切地说,一个函数,给定一个值列表,返回一个多边形列表,每个值一个,这是六边形的一部分,这样

  • 它们都有中心点作为顶点。
  • 他们在这一点上的角度与值成正比。
  • 它们形成六边形隔板。

让我们假设六边形被刻在半径R的圆中,并由顶点定义:

{(R sqrt(3)/2,R/2),(0,R),(-R sqrt(3)/2,R/2),(-R sqrt(3)/2,-R/2),(0,-R),(R sqrt(3)/2,-R/2)}

这很容易来自cos(Pi/6)、sin(Pi/6)和各种对称性。

得到每个多边形的中心角是相当简单的,因为它和圆是一样的。现在我们需要知道六边形上的点的位置。

注意,如果使用坐标轴的对称性,只有两种情况: 0,Pi/6和Pi/6,Pi/2,然后通过镜像得到结果。如果你用Pi/3的旋转对称性,你只有一个情况:-Pi/6,Pi/6,你通过旋转得到结果。

利用旋转对称性

因此,对于每一点,你可以考虑它的角度在- Pi/6,Pi/6之间。在这部分的六边形上的任何一点都有x=R sqrt(3)/2,这大大简化了问题:我们只需要找到它的y值。

现在我们假设我们知道我们点的极坐标角,因为它和圆是一样的。让我们称它为beta,并在-Pi/6,Pi/6中确定它的值。我们不知道它离中心有多远,因此我们有以下系统:

由于cos从来不在Pi/6,Pi/6的范围内,所以这个问题得到了很小的解决。

因此,d=R sqrt(3)/( 2 cos(alpha) )y=d sin(alpha)

所以现在我们知道

  • beta中心的角度
  • 它离中心d很远,这要归功于旋转对称

所以我们的重点是(d cos(beta), d sin(beta))

代码

是的,我很好奇,所以我最后把它编码了。如果你想自己玩的话很抱歉。它正在工作,而且最终非常难看(至少在这个数据集中是这样),请参见jsfiddle:http://jsfiddle.net/vb7on8vo/5/

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var R = 100;
var hexagon = [{x:R*Math.sqrt(3)/2, y:R/2}, {x:0, y:R}, {x:-R*Math.sqrt(3)/2, y:R/2}, {x:-R*Math.sqrt(3)/2, y:-R/2}, {x:0, y:-R}, {x:R*Math.sqrt(3)/2, y:-R/2}];
var hex_angles = [Math.PI / 6, Math.PI / 2, 5*Math.PI / 6, 7*Math.PI / 6, 3*Math.PI / 2, 11*Math.PI / 6];

function regions(values)
{
    var i, total = 0, regions = [];

    for(i=0; i<values.length; i++)
        total += values[i];

    // first (0 rad) and last (2Pi rad) points are always at x=R Math.sqrt(3)/2, y=0
    var prev_point = {x:hexagon[0].x, y:0}, last_angle = 0;

    for(i=0; i<values.length; i++)
    {
        var j, theta, p = [{x:0,y:0}, prev_point], beta = last_angle + values[i] * 2 * Math.PI / total;

        for( j=0; j<hexagon.length; j++)
        {
            theta = hex_angles[j];
            if( theta <= last_angle )
                continue;
            else if( theta >= beta )
                break;
            else
                p.push( hexagon[j] );
        }

        var alpha = beta - (Math.PI * (j % 6) / 3); // segment 6 is segment 0
        var d = hexagon[0].x / Math.cos(alpha);
        var point = {x:d*Math.cos(beta), y:d*Math.sin(beta)};

        p.push( point );
        regions.push(p.slice(0));

        last_angle = beta;
        prev_point = {x:point.x, y:point.y};
    }

    return regions;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27342339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文