在 p5.js 中将多边形旋转给定度数
给定一个表示多边形每个顶点的向量数组,我们必须将多边形旋转中点给定的度数(例如 n)。请注意,问题要求我们不要绘制旋转的多边形,而是旋转多边形。这意味着内置的转换对象在这种情况下是无用的。简而言之,我们需要旋转多边形本身,而不是整个坐标系。
基本思想是将多边形中的每个顶点旋转 n 度。以下公式旋转给定点在笛卡尔平面上:
我们将从基本代码开始在迭代中解决问题:
- 基本代码:我们将为此使用 p5.js 以使其更具交互性。这是我们的基本index.html文件
代码:
Rotating a Polygon - 旋转多边形:这是旋转多边形的函数。请注意,我们将角度转换为弧度,因为输入将以度为单位。但在 p5.js 中,
cos
和sin
默认情况下需要以弧度表示的值。另外,请注意 JavaScript 中的列表是通过引用传递的,因此如果我们修改传递的参数,那么也会对原始列表产生影响。代码:
function rotatePolygon(vertices,degree){ // Converting degree to radians! degree = radians(degree); for(let i = 0; i < vertices.length; ++i){ // Storing the previous values so // they don't get overwritten let x = vertices[i].x, y = vertices[i].y; vertices[i].x = x*cos(degree)-y*sin(degree); vertices[i].y = x*sin(degree)+y*cos(degree); } }
- 计算中点:现在我们可以旋转多边形,但问题要求我们相对于它的中点旋转它,所以首先我们需要计算它。要通过中点旋转多边形,我们首先需要计算它的中点。多边形的中点只是所有坐标的平均值。这是计算中点的函数。
代码:
function calcMidpoint(vertices){ let midpoint = createVector(0, 0) for (let i = 0; i < vertices.length; i++) midpoint.add(vertices[i]); return midpoint.div(vertices.length) }
- 平移中点:围绕中点旋转多边形的过程将涉及一些平移。希望这一步非常直观和自我声明。
代码:
function translatePolygon(vertices, x, y) { for (let i = 0; i < vertices.length; i++) { vertices[i].x += x; vertices[i].y += y; } }
上述迭代的最终程序组合:这是我们基于上述迭代的最终sketch.js文件:
- 代码:
var starPolygon = [] function setup() { // Init the HTML5 Canvas of given size createCanvas(800, 600); /* Vertices for a star-polygon (decagon) */ let x = [440, 468, 534, 486, 498, 440, 382, 394, 346, 412]; let y = [230, 290, 300, 344, 410, 380, 410, 344, 300, 290]; /* Converting given vertices to an array of vectors */ for (let i = 0; i < x.length; ++i) starPolygon.push(createVector(x[i], y[i])); } function rotatePolygon(vertices, degree){ // Converting degree to radians! degree = radians(degree); for(let i = 0; i < vertices.length; ++i) { // Storing the previous values so they // don't get overwritten let x = vertices[i].x, y = vertices[i].y; vertices[i].x = x*cos(degree)-y*sin(degree); vertices[i].y = x*sin(degree)+y*cos(degree); } } function calcMidpoint(vertices) { let midpoint = createVector(0, 0) for (let i = 0; i < vertices.length; i++) midpoint.add(vertices[i]); return midpoint.div(vertices.length) } function translatePolygon(vertices, x, y) { for(let i = 0; i < vertices.length; i++){ vertices[i].x += x; vertices[i].y += y; } } function draw() { // Clear everything with grey background background(255); rotatePolygon(starPolygon,1); drawPolygon(starPolygon); let a = calcMidpoint(starPolygon); // Origin the polygon to center // and draw it at (400, 300) translatePolygon(starPolygon, 400-a.x, 300-a.y) } // This is how you draw a polygon in p5.js function drawPolygon(vertices) { beginShape(); for (let i = 0; i < vertices.length; ++i) vertex(vertices[i].x, vertices[i].y); fill(255, 217, 0); // If you don't close it then it'd // draw a chained line-segment endShape(CLOSE); }
- 输出:
本文讨论的简单原理可用于解决与计算机图形相关的各种问题。虽然我们不谈论它,但我们可以很容易地以类似的方式缩放多边形,一种平移多边形(只需按相同的因子缩放每个顶点)。中点查找算法可用于查找链式线段的中点,而不仅仅是多边形。另外,请注意,相同的原则适用于转换整个坐标系,p5.js 本身提供了内置的转换对象,但我们没有使用它们,因为我们被要求旋转多边形而不是坐标系。