绘制倒圆弧改变圆心坐标 [英] Draw reversed circle arc changes circle center coordinates

查看:35
本文介绍了绘制倒圆弧改变圆心坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用这段代码来绘制弧线,到目前为止效果很好,但是我遇到过我无法弄清楚 textPath 的问题.

请运行以下代码段.

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {var angleInRadians = (angleInDegrees-90) * Math.PI/180.0;返回 {x: centerX + (radius * Math.cos(angleInRadians)),y: centerY + (radius * Math.sin(angleInRadians))};}函数描述弧(x,y,半径,startAngle,endAngle){var start = polarToCartesian(x, y, radius, endAngle);var end = polarToCartesian(x, y, radius, startAngle);var largeArcFlag = endAngle - startAngle <= 180 ?0":1";无功d = ["M", start.x, start.y,"A", 半径, 半径, 0, largeArcFlag, 0, end.x, end.y].加入(" ");返回d;}var CorrectPath = document.getElementById('correctPath'),不正确路径 = document.getElementById('incorrectPath'),expectedPath = document.getElementById('expectedPath');rightPath.setAttribute('d', describeArc(24,24,20,0,90));不正确的Path.setAttribute('d', describeArc(24,24,20,90,0));expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');

.col {width: 32%;向左飘浮;填充:0.5%}

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="correctPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="green" font-size="3.2"><textPath xlink:href="#correctPath">correct</textPath></svg>

<div class="col"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="incorrectPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="red" font-size="3.2"><textPath xlink:href="#incorrectPath">不正确</textPath></svg>

<div class="col"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="expectedPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="blue" font-size="3.2"><textPath xlink:href="#expectedPath">expected</textPath></svg>

所以使用

correctPath.setAttribute('d', describeArc(24,24,20,0,90));

它似乎做了应该做的事情,但在这种情况下,我需要将文本颠倒过来,所以我试图用 endAngle 反转 startAngle代码>

incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));

你看到的结果是不正确的,它基本上是将圆弧中心坐标重新定位到另一个位置,而不是给我我期望的坐标.

我该如何调整这两个函数来处理 startAngleendAngle 的反转来产生预期的结果?

解决方案

arc 命令的结构如下:

rx ry x-axis-rotation large-arc-flag sweep-flag x y

最后一个标志,sweep-flag,描述了弧绕圆的方向.如果在极坐标中交换开始角度和结束角度,您也会交换方向:endAngle > startAngle 表示顺时针,startAngle > endAngle 表示逆时针.您的函数绘制了从 endAngle 到 startAngle 的弧线,因此反之亦然.

一个简单的解决方案是实现这个规则:

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {var angleInRadians = (angleInDegrees-90) * Math.PI/180.0;返回 {x: centerX + (radius * Math.cos(angleInRadians)),y: centerY + (radius * Math.sin(angleInRadians))};}函数描述弧(x,y,半径,startAngle,endAngle){var start = polarToCartesian(x, y, radius, endAngle);var end = polarToCartesian(x, y, radius, startAngle);var largeArcFlag = endAngle - startAngle <= 180 ?0":1";var scanFlag = endAngle >起始角?0 : 1;//原文如此无功d = ["M", start.x, start.y,A",半径,半径,0,largeArcFlag,sweetFlag,end.x,end.y].加入(" ");返回d;}var CorrectPath = document.getElementById('correctPath'),不正确路径 = document.getElementById('incorrectPath'),expectedPath = document.getElementById('expectedPath');rightPath.setAttribute('d', describeArc(24,24,20,0,90));不正确的Path.setAttribute('d', describeArc(24,24,20,90,0));expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');

.col {width: 32%;向左飘浮;填充:0.5%}

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="correctPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="green" font-size="3.2"><textPath xlink:href="#correctPath">逆时针</textPath></svg>

<div class="col"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="incorrectPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="red" font-size="3.2"><textPath xlink:href="#incorrectPath">顺时针</textPath></svg>

<div class="col"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><定义><path d="" id="expectedPath"></path></defs><circle r="24" cx="24" cy="24" fill="#eee"></circle><text id="nameText" fill="blue" font-size="3.2"><textPath xlink:href="#expectedPath">expected</textPath></svg>

但请注意,一旦您想真正越过圆的末端(以度为单位),此规则就会失效.比方说,从顺时针 300 度到 90 度.如果这是您的意图,您必须明确说明并将旋转方向作为参数传递给您的函数.

(您的参考路径M24 2.75 a 1 1 1 1 1 0 42.8无法绘制并自动重写为M 24,2.75 a 21.4,21.4 1 1 1 0 42.8代码>.请参阅这些注释,了解有关此替换的规则.)

I'm using this piece of code to draw arcs and so far it's been great, however I've encountered an issue with textPath that I cannot figure out.

Please run the following snippet.

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
    ].join(" ");

    return d;       
}

var correctPath = document.getElementById('correctPath'),
    incorrectPath = document.getElementById('incorrectPath'),
    expectedPath = document.getElementById('expectedPath');
    
correctPath.setAttribute('d', describeArc(24,24,20,0,90));
incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));
expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');

.col {width: 32%; float: left; padding: 0.5%}

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="correctPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="green" font-size="3.2">
      <textPath xlink:href="#correctPath">correct</textPath>
    </text>    
  </svg>
</div>

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="incorrectPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="red" font-size="3.2">
      <textPath xlink:href="#incorrectPath">incorrect</textPath>
    </text>    
  </svg>
</div>

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="expectedPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="blue" font-size="3.2">
      <textPath xlink:href="#expectedPath">expected</textPath>
    </text>    
  </svg>
</div>

So using

correctPath.setAttribute('d', describeArc(24,24,20,0,90));

it seems to do the thing that is supposed to do, but in this case I would need to turn the text upside down so I'm trying to reverse startAngle with endAngle

incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));

and you see the result which is incorrect, it basically relocates the arc center coordinates to another position, instead of giving me the coordinates that I was expecting.

How can I adjust these two functions to be able to handle the reverse of the startAngle and endAngleto produce the expected outcome?

解决方案

The arc command is structered like this:

rx ry x-axis-rotation large-arc-flag sweep-flag x y

The last flag, sweep-flag, describes the direction an arc goes around a circle. If you swap the start angle and end angle in polar coordinates, you also swap the direction: endAngle > startAngle means clockwise, startAngle > endAngle counterclockwise. Your function draws the arc from endAngle to startAngle, so the reverse applies.

A simple solution would be to implement this rule:

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){

    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);

    var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
    var sweepFlag = endAngle > startAngle ? 0 : 1; //sic

    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y
    ].join(" ");

    return d;       
}

var correctPath = document.getElementById('correctPath'),
    incorrectPath = document.getElementById('incorrectPath'),
    expectedPath = document.getElementById('expectedPath');
    
correctPath.setAttribute('d', describeArc(24,24,20,0,90));
incorrectPath.setAttribute('d', describeArc(24,24,20,90,0));
expectedPath.setAttribute('d', 'M24 2.75 a 1 1 1 1 1 0 42.8');

.col {width: 32%; float: left; padding: 0.5%}

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="correctPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="green" font-size="3.2">
      <textPath xlink:href="#correctPath">counterclockwise</textPath>
    </text>    
  </svg>
</div>

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="incorrectPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="red" font-size="3.2">
      <textPath xlink:href="#incorrectPath">clockwise</textPath>
    </text>    
  </svg>
</div>

<div class="col">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
    <defs>
      <path d="" id="expectedPath"></path>
    </defs>
    <circle r="24" cx="24" cy="24" fill="#eee"></circle>
    <text id="nameText" fill="blue" font-size="3.2">
      <textPath xlink:href="#expectedPath">expected</textPath>
    </text>    
  </svg>
</div>

But note that this rule will fail as soon as you want to really go past the end of the circle in degrees. Lets say, from 300 degrees to 90 degrees clockwise. If that is your intention, you must state it explicitely and pass the rotation direction as a parameter to your function.

(Your reference path M24 2.75 a 1 1 1 1 1 0 42.8 is impossible to draw and automatically rewritten as M 24,2.75 a 21.4,21.4 1 1 1 0 42.8. See these notes for the rules governing this substitution.)

这篇关于绘制倒圆弧改变圆心坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆