Javascript 给定正多边形的一侧,找到其余的边

Javascript 给定正多边形的一侧,找到其余的边,javascript,algorithm,math,geometry,turtle-graphics,Javascript,Algorithm,Math,Geometry,Turtle Graphics,我们得到: 正多边形的边数 由坐标(x1,y1)和(x2,y2)定义的一侧 我必须找出剩下的坐标。我该怎么做呢?假设我们有一个a,它通过从x1,y1移动到x2,y2绘制了一段n边正多边形。要绘制其余的边,我们将执行以下操作n-1次: 转一个角度 向前移动一段距离 我们必须转动的角度是360度。例如,如果我们画一个三角形,海龟在每一段后必须旋转120度。如果我们顺时针画三角形,我们从海龟的当前方向减去120度。如果我们逆时针画,我们加120度 向前移动的距离是第一段的长度。我们可以使用。在

我们得到:

  • 正多边形的边数
  • 由坐标(x1,y1)和(x2,y2)定义的一侧
我必须找出剩下的坐标。我该怎么做呢?

假设我们有一个a,它通过从
x1,y1
移动到
x2,y2
绘制了一段
n
边正多边形。要绘制其余的边,我们将执行以下操作
n-1
次:

  • 转一个角度
  • 向前移动一段距离
我们必须转动的角度是360度。例如,如果我们画一个三角形,海龟在每一段后必须旋转120度。如果我们顺时针画三角形,我们从海龟的当前方向减去120度。如果我们逆时针画,我们加120度

向前移动的距离是第一段的长度。我们可以使用。在JavaScript中,我们可以这样实现它:

var dx = x2-x1,
    dy = y2-y1,
    length = Math.sqrt(dx*dx + dy*dy);
海龟的初始方向与第一条线段的角度相同,我们可以通过取
dx/length
的反余弦来计算:

var angle = Math.acos(dx/length);
if (dy < 0) {
  angle = 2*Math.PI - angle;
}
要在当前方向上向前移动海龟
距离
单位,我们使用基本三角学:

turtle.x += Math.cos(turtle.angle) * distance;
turtle.y += Math.sin(turtle.angle) * distance;
请注意,JavaScript中的三角函数使用弧度而不是度。圆中有2π弧度,因此半圆形中有π弧度。如果我们有一个以弧度表示的角度
r
,那么以度表示的等价物是
r/Math.PI*180

当我们从海龟方向加上或减去一个值时,有可能以小于零或大于2π的角度结束。这不会影响我们的三角计算,但会使程序难以调试。为了确保角度始终在[0,2π]范围内,我们可以在
turtle.angle
修改时执行以下操作:

turtle.angle -= Math.floor(turtle.angle / (2*Math.PI)) * 2*Math.PI;
我已经编写了一个代码片段来演示海龟方法。通过单击下面的蓝色按钮运行代码,然后单击并拖动以绘制多边形的第一段。您可以通过单击加号和减号来更改边数

var多边形={
颜色:{
轴:“#ccc”,
双方:{
悬停:{plain:'#dddfa4',special:'#9d9c64'},
期末:{普通:'#b0c598',特别:'#4f7337'}
}
}
};
Polygon.turtle={x:0,y:0,角度:0};
Polygon.turtle.setPosition=函数(x,y){
var g=多边形,
海龟,
context=g.context,
原点=g原点;
海龟.x=x;
海龟。y=y;
context.moveTo(origin.left+turtle.x,origin.top-turtle.y);
};
Polygon.turtle.setAngle=函数(角度){
var g=多边形,
海龟=g.海龟;
角度=角度;
};
Polygon.turtle.left=函数(增量){
var g=多边形,
海龟=g.海龟;
turtle.angle=g.normalizeAngle(turtle.angle+delta);
};
Polygon.turtle.right=函数(增量){
var g=多边形,
海龟=g.海龟;
turtle.angle=g.normalizeAngle(turtle.angle-delta);
};     
Polygon.normalizeAngle=函数(角度){
角度-=数学地板(角度/(2*Math.PI))*2*Math.PI;
返回角;
};
Polygon.turtle.forward=函数(距离){
var g=多边形,
海龟,
canvas=g.canvas,
context=g.context,
原点=g原点;
海龟.x+=数学cos(海龟角度)*距离;
turtle.y+=数学sin(turtle.angle)*距离;
lineTo(origin.left+turtle.x,origin.top-turtle.y);
};
Polygon.resizeCanvas=函数(){
var g=多边形,
canvas=g.canvas,
context=g.context,
宽度=画布。宽度=窗口。内部宽度,
高度=canvas.height=window.innerHeight;
g、 原点={left:Math.floor(宽度/2),top:Math.floor(高度/2)};
g、 牵引轴();
};
Polygon.drawAxes=函数(){
var g=多边形,
canvas=g.canvas,
context=g.context,
原点=g原点,
颜色=g.color;
context.lineWidth=2;
context.strokeStyle=color.axes;
context.beginPath();
context.moveTo(origin.left,0);
context.lineTo(origin.left,canvas.height);
context.moveTo(0,origin.top);
lineTo(canvas.width,origin.top);
stroke();
};
Polygon.drawPolygon=函数(情况){
var g=多边形,
canvas=g.canvas,
context=g.context,
海龟,
颜色=g.color,
n=parseInt(document.getElementById('numSides').innerHTML,10),
转动=2*Math.PI/n,
x1=g.x1,y1=g.y1,x2=g.x2,y2=g.y2,
dx=x2-x1,
dy=y2-y1,
长度=数学sqrt(dx*dx+dy*dy);
变量角度=数学acos(dx/长度);
if(dy<0){
角度=2*Math.PI-角度;
}
clearRect(0,0,canvas.width,canvas.height);
g、 牵引轴();
context.lineWidth=4;
context.lineCap='round';
context.beginPath();
context.strokeStyle=color.sides[situation].plain;
乌龟。设置位置(x1,y1);
乌龟。设置角度(角度);
对于(变量i=0;iturtle.angle -= Math.floor(turtle.angle / (2*Math.PI)) * 2*Math.PI;
(mx, my) = ((x1+x2)/2, (y1+y2)/2)
(px, py) = (-(y2-y1), x2-x1)
(nx, ny) = (px/Len, py/Len), where Len = Sqrt(px*px + py*py)
  ApoLen = Len / (2*Tan(Pi/N))
(ax, ay) = ApoLen * (nx, ny) = (px / (2 * Tan(Pi/N)), py / (2 * Tan(Pi/N)))
(cx, cy) = (mx, my) + (ax, ay)
  R = ApoLen / Cos(Pi/N)
  BaseAngle = ArcTan2(y1 - cy, x1 - cy)
 Ai = BaseAngle + (i - 1) * 2 * Pi / N
  (xi, yi) = (cx + R * Cos(Ai), cy + R * Sin(Ai))