【问题标题】:confusion calculating x/y coordinates based on rotation angle with D3 + svg transformation使用 D3 + svg 变换根据旋转角度计算 x/y 坐标的混淆
【发布时间】:2014-09-16 10:22:01
【问题描述】:

D3 和 SVG 的新手,我很困惑为什么我使用旋转角度 + 弧距计算 x、y 坐标(围绕圆/钟面的 SVG 元素位置)的数学...本质上:

  1. 我创建了圆圈/钟面(包括翻译):

    var face = d3.select(".chart").append("g")
        .attr("class", "clock-face")
        .attr('transform','translate(' + width/2 + ',' + (circleRadius + margin) + ')');
    
  2. 我在钟面上附加了一个“g”元素(包含数据+一些视觉内容),并对单个数据点容器应用旋转(基于线性比例以围绕圆定位元素):

    var circleScale = d3.scale.linear()
        .range([0, data.length])
        .domain([0, 60]);
    
    // data container
    var bar = face.selectAll('g')
        .data(data)
        .enter().append('g')
        .attr('transform', function(d, i) {
            return 'rotate('  + circleScale(i) + ')';
        })
        .each(function(d, i) {
            // set theta
            d.theta = circleScale(i);
    });
    
  3. 我希望能够根据它的 theta(旋转角度)值计算我的单个数据点容器的 x/y 坐标:

    function calcPosition(centerX, centerY, radius, theta) {
        var coords = {};
        var x = centerX + radius * Math.cos(theta);
        var y = centerX + radius * Math.sin(theta);
        coords.x = x;
        coords.y = y;
    
        return coords;
    };
    
    var origin = calcPosition(0, 0, circleRadius, d.theta);
    
    face.append('circle')
        .attr('cx', origin.x)
        .attr('cy', origin.y)
        .attr('r', 5)
        .attr('fill', 'yellow')
    

但是,这会产生完全错误的 x/y 坐标。我相信我的三角函数在根据旋转角度计算 x/y 坐标时是正确的,但是关于 SVG 转换的一些事情正在搞砸这一切......有什么建议吗?

非常感谢!

【问题讨论】:

  • theta 还是 弧度
  • @PaulS。好问题...原来我有这样的圆形比例: var circleScale = d3.scale.linear().range([0, data.length]).domain([0, 2 * Math.PI]);
  • 但这产生了奇怪的结果(没有正确映射到 360 度)......但是由于某种原因将圆比例更改为以下工作......我看到这可能是我的错误点.但我对 D3 比例感到困惑: var circleScale = d3.scale.linear().range([0, data.length]).domain([0, 60]);

标签: javascript svg d3.js rotation


【解决方案1】:

在您的圆圈刻度中,您似乎错误地在范围和域之间进行了交换。 范围 应该是[0,360][0,2*Math.PI]。请注意您当前如何拥有[0,60],而不是 360,这可能是一个错误。 也许域应该变成[0,data.length]——就像你目前的范围——但我不确定数据的性质以及这是否有意义。我希望域名是[0,12],一天中的几个小时。

至于您的calcPosition 三角函数,theta 必须以为弧度才能正常工作,这表明您的circleScale 应在[0,2*Math.PI] 范围内。但是,对于 SVG 变换,您需要使用度数。因此,您需要以一种或另一种方式在其中一种情况下进行一些转换。此外,您在calcPosition 中有一个错误,其中y 应该基于centerY 而不是centerX

最后,我建议在一个简单的 for 循环中预先计算所有 d.theta,而不是在渲染时在 each 函数中这样做。这主要是为了分离关注点并避免错误(例如,如果您在渲染条形之前尝试访问 d.theta 会发生什么?)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2017-04-23
    • 1970-01-01
    • 2013-04-06
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多