【问题标题】:Rotation of polygon by angle javascript按角度javascript旋转多边形
【发布时间】:2018-05-30 09:53:04
【问题描述】:

我想旋转一个多边形 我有这样的多边形数组 [ [-17.999999999999986, 587.25], [-14, 197.25], [544, 169.25], [554, 551.25] ]

第一步:我计算质心

function getCentroid(coord) {
    var center = coord.reduce(function (x,y) {
        return [x[0] + y[0]/coord.length, x[1] + y[1]/coord.length] 
    }, [0,0])
    return center;
}

第二步:轮换:

function rotate(CX, CY, X, Y, angle) {
    var rad = angle * (Math.PI / 180.0);
    var nx = Math.cos(rad) * (X-CX) - Math.sin(rad) * (Y-CY) + CX;
    var ny = Math.sin(rad) * (X-CX) + Math.cos(rad) * (Y-CY) + CY;
    return [nx,ny];
}

问题是每次我旋转多边形时,它都会变大。 也许我的公式有问题,但很多程序员都在使用这个。

感谢您的回答。

【问题讨论】:

  • 你能提供更多代码吗?完整的 HTML 和 JavaScript 代码,以便我们可以在 sn-p 中对其进行测试?
  • 质心计算看起来不对。与此比较:github.com/ayamflow/polygon-centroid/blob/master/index.js
  • @RobbyCornelissen 直接除以长度而不是最后做它没有错。他的功能与您的链接中的功能相同。命名只是有点偏离。我的答案使用了第二个示例中的函数,它就像一个魅力
  • @Fuzzyma 是的,你是对的。我想我对累加器和当前值的xy 命名感到困惑。
  • 我在答案的末尾添加了一个拉皮条的版本。也许那个看起来更好

标签: javascript jquery svg svg.js


【解决方案1】:

您标记了 svg.js,所以我假设您正在使用它。 所以这就是我的做法。

// assuming that you have a div with the id "canvas" here
var canvas = SVG('canvas')

var angle = 20

// draw polygon
var polygon = canvas.polygon([ [-18, 587.25], [-14, 197.25], [544, 169.25], [554, 551.25] ])
    .fill('none')
    .stroke('black')

// we clone it so we have something to compare 
var clone = polygon.clone()

// get center of polygon
var box = polygon.bbox()
var {cx, cy} = box

// get the values of the points
var rotatedPoints = polygon.array().valueOf().map((p) => {

  // transform every point
  var {x, y} = new SVG.Point(p)
    .transform(new SVG.Matrix().rotate(angle, cx, cy))

  return [x, y]
})


// update polygon with points
polygon.plot(rotatedPoints)

小提琴:https://jsfiddle.net/Fuzzy/3qzubk5y/1/

你不需要先制作一个多边形来旋转这些点。您可以直接使用我们的数组并在其上调用相同的 map 函数。但在这种情况下,您需要自己弄清楚 cx 和 cy:

function getCentroid(coord) {
    var center = coord.reduce(function (x,y) {
        return [x[0] + y[0]/coord.length, x[1] + y[1]/coord.length] 
    }, [0,0])
    return center;
}

var canvas = SVG("canvas")
var points = [ [-18, 587.25], [-14, 197.25], [544, 169.25], [554, 551.25] ]
var center = getCentroid(points)
var angle = 20

// polygon before rotation
canvas.polygon(points).fill('none').stroke('black')

// get the values of the points
var rotatedPoints = points.map((p) => {

  // transform every point
  var {x, y} = new SVG.Point(p)
    .transform(new SVG.Matrix().rotate(angle, center[0], center[1]))

  return [x, y]
})

// polygon after rotation
canvas.polygon(rotatedPoints).fill('none').stroke('black')

小提琴:https://jsfiddle.net/Fuzzy/g90w10gg/

因此,既然您的质心功能似乎可以工作,那么您的错误一定是在您的旋转功能中。但是,当我拥有这些库时,我更喜欢使用它们的功能。无需重新发明轮毂 :)

// 编辑: 我把你的质心函数拉了一点,所以变量命名更清楚一点:

function getCentroid(coord) {
    var length = coord.length
    var center = coord.reduce(function (last, current) {
        last.x += current[0] / length
        last.y += current[1] / length
        return last
    }, {x: 0, y: 0})

    return center;
}

【讨论】:

  • 当我执行你的代码时出现这个错误:Uncaught TypeError: SVG.Point is not a constructor
  • 那么你的 svg.js 版本已经过时了
  • 对,我移到了上一个版本,现在很好
  • 在这种情况下,请接受答案,以便社区知道这个问题有一个公认的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多