Поворот многоугольника на угол javascript - PullRequest
0 голосов
/ 30 мая 2018

Я хотел бы повернуть многоугольник У меня есть массив многоугольников, подобный этому [[-17.999999999999986, 587.25], [-14, 197.25], [544, 169.25], [554, 551.25]]

Первый шаг: я вычисляю Centroid

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];
}

проблема заключается в том, что каждый раз, когда я поворачиваюПолигон стал больше.Возможно, у меня есть проблема с формулой, но она используется многими программистами.

Спасибо за ваши ответы.

1 Ответ

0 голосов
/ 31 мая 2018

Вы отметили 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)

Fiddle: https://jsfiddle.net/Fuzzy/3qzubk5y/1/

Ofc Вам не нужно сначала создавать многоугольник, чтобы вращать точки.Вы можете перейти прямо к нашему массиву и вызвать ту же функцию карты на нем.Но в этом случае вам нужно выяснить 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')

Fiddle: https://jsfiddle.net/Fuzzy/g90w10gg/

Так как ваша функция центроида, кажется, работает, ваша ошибка должна быть где-тов вашей функции поворота.Однако я предпочитаю использовать возможности библиотек, когда они у меня есть.Не нужно заново изобретать weel:)

// РЕДАКТИРОВАТЬ: я немного увеличил вашу функцию центроида, чтобы именование переменных было более четким:

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;
}
...