Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何计算旋转椭圆上的点_Javascript_Canvas_Ellipse - Fatal编程技术网

Javascript 如何计算旋转椭圆上的点

Javascript 如何计算旋转椭圆上的点,javascript,canvas,ellipse,Javascript,Canvas,Ellipse,我有一个工作代码,可以找到椭圆上给定角度的x,y: getPointOnEllipse(origin_x, origin_y, radius_x, radius_y, angle) { var r_end_angle = end_angle / 360 * 2 * Math.PI; var x = origin_x + Math.cos(r_end_angle) * radius_x; var y = origin_y + Math.sin(r_end_

我有一个工作代码,可以找到椭圆上给定角度的x,y:

getPointOnEllipse(origin_x, origin_y, radius_x, radius_y, angle) {

  var r_end_angle = end_angle / 360 * 2 * Math.PI;
  var x        = origin_x + Math.cos(r_end_angle) * radius_x;
  var y        = origin_y + Math.sin(r_end_angle) * radius_y;

  return {x: x, y: y}

我的问题是,如果椭圆以r角旋转,我该如何进行此计算,就像是由以下因素创建的:

ellipse(origin_x, origin_y, radius_x, radius_y, r);
更新:我尝试了下面的建议,但效果不太好。以下是原始(0)旋转:

这是大约90度旋转后的结果:

以下是我尝试的代码:

/* 
* origin_x - Center of the Ellipse X
* origin_y - Center of the Ellipse Y
* radius_x - Radius X
* radius_y - Radius Y
* angle    - angle along the ellipse on which to place the handle
* rotation - Angle which the ellipse is rotated
*/
getPointOnEllipse(origin_x, origin_y, radius_x, radius_y, angle, rotation) {
 var r_end_angle = (angle + rotation) / 360 * 2 * Math.PI;
 var endX        = origin_x + Math.cos(r_end_angle) * radius_x;
 var endY        = origin_y + Math.sin(r_end_angle) * radius_y;

 var cosA  = Math.cos(rotation);
 var sinA  = Math.sin(rotation);
 var dx    = endX - origin_x;
 var dy    = endY - origin_y;

 rotated_x = origin_x + dx * cosA - dy * sinA;
 rotated_y = origin_y + dx * sinA + dy * cosA;
以下是一些日志记录:

X 369,Y 233,半径X 104,半径Y 17,端部角0,旋转0,端部473,端部233,cosA 1,sinA 0,dx 104,dy 0,旋转角X 473,旋转角Y 233

X 369,Y 233,半径X 104,半径Y 17,末端角度90,旋转0,末端X 369,末端Y 250,cosA 1,sinA 0,dx 0,dy 17,旋转X 369,旋转Y 250

X 369,Y 233,半径X 104,半径Y 17,端角180,旋转0,端X 265,端Y 233,cosA 1,sinA 0,dx-104,dy 0,旋转的端X 265,旋转的端Y 233

X 369,Y 233,半径X 104,半径Y 17,端部角270,旋转0,端部369,端部216,cosA 1,sinA 0,dx 0,dy-17,旋转X 369,旋转Y 216

在这里,旋转90度后,点似乎不会在椭圆上结束:

X 369,Y 233,半径X 104,半径Y 17,端部角0,旋转96.40608527543233,端部357.396254311691,端部249.89385326910204,cosA-0.5542897094655916,sinA 0.8323238059676955,dx-11.60374568830904,dy 16.89385326910204,旋转361.370680558866,旋转213.9737204053

X 369,Y 233,半径X 104,半径Y 17,端部角90,旋转96.40608527543233,端部265.6493682360816,端部231.10323387787258,cosA-0.5542897094655916,sinA 0.8323238059676955,dx-103.35063176391839,dy-1.896766127417,旋转122U X 427.86491525130737,旋转148.030166784783

X 369,Y 233,半径X 104,半径Y 17,端部角180,旋转96.40608527543233,端部380.603745688309,端部216.1061467089796,cosA-0.5542897094655916,sinA 0.8323238059676955,dx 11.60374568830904,dy-16.89385326910204,旋转X 376.6293194241134,旋转252.022162795047

X 369,Y 233,半径X 104,半径Y 17,端部角270,旋转96.40608527543233,端部472.35063176391833,端部234.89676612212745,cosA-0.5542897094655916,sinA 0.8323238059676955,dx 103.35063176391833,dy 1.8967661221224454,旋转310.1350847486927,旋转317.969833236


我肯定这里有什么地方出错了-有什么想法吗?

只需将函数得到的点绕椭圆中心旋转即可:

函数旋转点(x,y,原点,原点,旋转){
常数cosA=数学cos(旋转);
const sinA=Math.sin(旋转);
常数dx=x-原点;
常数dy=y-初始值;
返回{
x:originX+dx*cosA-dy*sinA,
y:originY+dx*sinA+dy*cosA
}
}

请注意,您的函数
getPointOnEllipse
不返回与中心角对应的点。

您实际上可能不需要计算此位置

canvas API提供了控制上下文当前转换矩阵的方法。
在许多情况下,接受这个方法比自己计算所有事情更方便

例如,您的示例相对于椭圆自身的变换放置四个正方形。所以你需要做的是,首先将变换矩阵设置为椭圆的位置,然后只移动每个正方形的相对位置

下面是一个快速编写的示例:

const ctx=canvas.getContext('2d');
阶级形态{
构造函数(cx、cy、父级){
这个.cx=cx;
this.cy=cy;
this.parent=parent;
this.path=new Path2D();
这个角度=0;
this.color=“black”;
}
applyTransform(){
如果(this.parent){//递归地应用所有转换
this.parent.applyTransform();
}
变换(1,0,0,1,this.cx,this.cy);
ctx.旋转(此角度);
}
}
const rad_x=(canvas.width/1.3)/2;
const rad_y=(canvas.height/1.3)/2;
类Rect扩展了形状{
构造函数(dx、dy、父级){
超级(rad_x*dx,rad_y*dy,父级);
this.path.rect(-5,-5,10,10);
Object.defineProperty(此“角度”{
得到(){
//因此,正方形不会旋转
返回parent.angle*-1;
}
})
}
}
const椭圆=新形状(canvas.width/2,canvas.height/2);
椭圆(0,0,rad_x,rad_y,0,0,Math.PI*2);
常量形状=[ellipse].concat(
[
新矩形(0,-1,椭圆),
新矩形(1,0,椭圆),
新矩形(0,1,椭圆),
新矩形(-1,0,椭圆)
]
);
常数鼠标={x:0,y:0};
canvas.onmousemove=({offsetX,offsetY})=>{
鼠标.x=偏移量x;
mouse.y=offsetY;
};
draw();
函数clearTransform(){
setTransform(1,0,0,1,0,0);
}
函数绘图(){
//更新椭圆的角度
椭圆角度=(椭圆角度+数学PI/180)%(数学PI*2);
//清楚的
clearTransform();
clearRect(0,0,canvas.width,canvas.height)
//画形状
shapes.forEach(shape=>{
clearTransform();//完全清除变换矩阵
shape.applyTransform();//也将应用其父级的转换
//检查是否悬停此形状
shape.color=ctx.isPointInPath(shape.path,mouse.x,mouse.y)?“红色”:“黑色”;
ctx.strokeStyle=shape.color;
笔划(形状、路径);
});
//再做一次
请求动画帧(绘制);
}

谢谢,但它没有像预期的那样工作-请参见上面我的编辑,我无法在评论中获得所有信息:-(x不应该是x:originX+dx*cosA+dy*sinA而不是x:originX+dx*cosA-dy*sinA,同样地,y应该是y:originY+dx*sinA-dy*cosA吗?@BalchandarReddy,这取决于旋转方向。我的答案是逆时针旋转-右手坐标系。你能指定什么是
end\u角度
,以及你为什么使用它吗?)
end\u angle+rotation
计算椭圆上的点?函数参数名称为
an会让人困惑