【问题标题】:How to draw an ellipse from degree and coordinates如何根据度数和坐标绘制椭圆
【发布时间】:2021-02-11 15:09:39
【问题描述】:

我正在使用 D3 图表来绘制一个椭圆。我没有 Rx、Cx、Ry、Cy,但每隔 8 度就有坐标(x0 和 y0)。

θ (°) x(θ) y(θ) 0.00 0.00 3.09 8.00 0.48 3.37 16.00 0.94 3.59 24.00 1.39 3.74 32.00 1.81 3.81 40.00 2.20 3.81 48.00 2.54 3.74 56.00 2.83 3.59 64.00 3.07 3.37 72.00 3.25 3.09 80.00 3.36 2.75 88.00 3.41 2.35 96.00 3.40 1.91 104.00 3.31 1.43 112.00 3.17 0.92 120.00 2.96 0.40 128.00 2.69 -0.13 136.00 2.37 -0.66 144.00 2.01 -1.18 152.00 1.60 -1.67 160.00 1.17 -2.14 168.00 0.71 -2.56 176.00 0.24 -2.93 184.00 -0.24 -3.24 192.00 -0.71 -3.49 200.00 -1.17 -3.67 208.00 -1.60 -3.78 216.00 -2.01 -3.82 224.00 -2.37 -3.78 232.00 -2.69 -3.67 240.00 -2.96 -3.49 248.00 -3.17 -3.24 256.00 -3.31 -2.93 264.00 -3.40 -2.56 272.00 -3.41 -2.14 280.00 -3.36 -1.67 288.00 -3.25 -1.18 296.00 -3.07 -0.66 304.00 -2.83 -0.13 312.00 -2.54 0.40 320.00 -2.20 0.92 328.00 -1.81 1.43 336.00 -1.39 1.91 344.00 -0.94 2.35 352.00 -0.48 2.75 360.00 0.00 3.09

我们如何画一个连接所有点的椭圆?举个例子会很有帮助。

【问题讨论】:

    标签: javascript svg d3.js ellipse


    【解决方案1】:

    因为您拥有所有笛卡尔坐标,所以这里的最佳选择是使用<path> 元素而不是<ellipse>。此外,由于同样的原因,您实际上既不需要 D3 也不需要度数(您的第一列)。但是,如果你想坚持使用 D3,你只需要一个行生成器,如下所示:

    const lineGenerator = d3.line()
        .x(d => xScale(d.xPos))
        .y(d => yScale(d.yPos));
    

    在这里,我将您的 x(θ)y(θ) 重命名为 xPosyPos。另外,我使用的是比例尺(但请注意范围间隔,它们必须相同)。

    结果如下:

    const csv = `deg,xPos,yPos
    0.00,0.00,3.09
    8.00,0.48,3.37
    16.00,0.94,3.59
    24.00,1.39,3.74
    32.00,1.81,3.81
    40.00,2.20,3.81
    48.00,2.54,3.74
    56.00,2.83,3.59
    64.00,3.07,3.37
    72.00,3.25,3.09
    80.00,3.36,2.75
    88.00,3.41,2.35
    96.00,3.40,1.91
    104.00,3.31,1.43
    112.00,3.17,0.92
    120.00,2.96,0.40
    128.00,2.69,-0.13
    136.00,2.37,-0.66
    144.00,2.01,-1.18
    152.00,1.60,-1.67
    160.00,1.17,-2.14
    168.00,0.71,-2.56
    176.00,0.24,-2.93
    184.00,-0.24,-3.24
    192.00,-0.71,-3.49
    200.00,-1.17,-3.67
    208.00,-1.60,-3.78
    216.00,-2.01,-3.82
    224.00,-2.37,-3.78
    232.00,-2.69,-3.67
    240.00,-2.96,-3.49
    248.00,-3.17,-3.24
    256.00,-3.31,-2.93
    264.00,-3.40,-2.56
    272.00,-3.41,-2.14
    280.00,-3.36,-1.67
    288.00,-3.25,-1.18
    296.00,-3.07,-0.66
    304.00,-2.83,-0.13
    312.00,-2.54,0.40
    320.00,-2.20,0.92
    328.00,-1.81,1.43
    336.00,-1.39,1.91
    344.00,-0.94,2.35
    352.00,-0.48,2.75
    360.00,0.00,3.09`;
    
    const data = d3.csvParse(csv, d3.autoType);
    const svg = d3.select("svg");
    const xScale = d3.scaleLinear()
      .domain(d3.extent(data, d => d.xPos))
      .range([85, 215]);
    const yScale = d3.scaleLinear()
      .domain(d3.extent(data, d => d.yPos))
      .range([10, 140]);
    const lineGenerator = d3.line()
      .x(d => xScale(d.xPos))
      .y(d => yScale(d.yPos));
    const ellipse = svg.append("path")
      .datum(data)
      .attr("d", lineGenerator);
    path {
      fill: none;
      stroke-width: 3px;
      stroke: steelblue;
    }
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <svg></svg>

    因为你有这么多点,所以椭圆看起来不错,特别是在像这样的小型 SVG 中。但是你也可以通过在点之间进行插值来改善它的外观,例如:

    const lineGenerator = d3.line()
        .x(d => xScale(d.xPos))
        .y(d => yScale(d.yPos))
        .curve(d3.curveCatmullRom);
    

    这是一个并排的大 SVG 的结果(插值路径是红色的):

    const csv = `deg,xPos,yPos
    0.00,0.00,3.09
    8.00,0.48,3.37
    16.00,0.94,3.59
    24.00,1.39,3.74
    32.00,1.81,3.81
    40.00,2.20,3.81
    48.00,2.54,3.74
    56.00,2.83,3.59
    64.00,3.07,3.37
    72.00,3.25,3.09
    80.00,3.36,2.75
    88.00,3.41,2.35
    96.00,3.40,1.91
    104.00,3.31,1.43
    112.00,3.17,0.92
    120.00,2.96,0.40
    128.00,2.69,-0.13
    136.00,2.37,-0.66
    144.00,2.01,-1.18
    152.00,1.60,-1.67
    160.00,1.17,-2.14
    168.00,0.71,-2.56
    176.00,0.24,-2.93
    184.00,-0.24,-3.24
    192.00,-0.71,-3.49
    200.00,-1.17,-3.67
    208.00,-1.60,-3.78
    216.00,-2.01,-3.82
    224.00,-2.37,-3.78
    232.00,-2.69,-3.67
    240.00,-2.96,-3.49
    248.00,-3.17,-3.24
    256.00,-3.31,-2.93
    264.00,-3.40,-2.56
    272.00,-3.41,-2.14
    280.00,-3.36,-1.67
    288.00,-3.25,-1.18
    296.00,-3.07,-0.66
    304.00,-2.83,-0.13
    312.00,-2.54,0.40
    320.00,-2.20,0.92
    328.00,-1.81,1.43
    336.00,-1.39,1.91
    344.00,-0.94,2.35
    352.00,-0.48,2.75
    360.00,0.00,3.09`;
    
    const data = d3.csvParse(csv, d3.autoType);
    const svg = d3.select("svg");
    const xScale = d3.scaleLinear()
      .domain(d3.extent(data, d => d.xPos))
      .range([10, 490]);
    const yScale = d3.scaleLinear()
      .domain(d3.extent(data, d => d.yPos))
      .range([10, 490]);
    const lineGenerator = d3.line()
      .x(d => xScale(d.xPos))
      .y(d => yScale(d.yPos));
    const ellipse = svg.append("path")
      .datum(data)
      .attr("d", lineGenerator);
    
    const ellipse2 = svg.append("path")
      .attr("class", "path2")
      .attr("transform", "translate(500,0)")
      .datum(data)
      .attr("d", d => lineGenerator.curve(d3.curveCatmullRom)(d));
    path {
      fill: none;
      stroke-width: 3px;
      stroke: steelblue;
    }
    
    .path2 {
      stroke: orangered;
    }
    <script src="https://d3js.org/d3.v6.min.js"></script>
    <svg width="1000" height="500"></svg>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多