如何在 ECMAScript 中将点转换为极坐标?
我需要将点击位置转换为极坐标。 这是我当前的算法。 Location 是画布上点击的位置 ({x:evt.clientX, y:evt.clientY}
),center 是原点距 0,0 的偏移量。例如,如果圆的中心位于 250, 250,则中心为 {x:250, y:250}
。比例尺是半径的比例尺。例如,如果圆的半径通常为 50,比例尺为 0.5,则半径变为 25。(用于放大/缩小)
this.getPolarLocation = function(location){
var unscaledFromCenter = {
x: location.x - center.x,
y: location.y - center.y
};
var angle = this.getAngleOnCircle(unscaledFromCenter);
var dist = Math.sqrt(unscaledFromCenter.x * unscaledFromCenter.x + unscaledFromCenter.y * unscaledFromCenter.y) * this.ds.scale;
return {
angle:angle,
dist:dist,
toString: function(){
return "Theta: ".concat(angle).concat("; dist: ").concat(dist);
}
};
}
this.getAngleOnCircle = function(location){
var x = location.x;
var y = location.y;
if(x == 0 && y > 0)
return Math.PI / 2;
if(x == 0 && y < 0)
return 3 * Math.PI / 2;
if(y == 0 && x > 0)
return 0;
if(y == 0 && x < 0)
return Math.PI;
var angle = Math.atan(y/x);
if(x > 0 && y > 0)
return angle;
if(x < 0)
return Math.PI + angle
return Math.PI * 2 + angle;
}
问题的屏幕截图。左边是缩小后发生的情况(并且不应该发生)。右边放大了(比例> = 1),这是应该发生的情况。
我的印象是我的中心坐标稍微偏离了。对于scale >= 1,它似乎工作得很好,但对于scale <= 1,则不行。 1
来源: circos.html:http://pastie.org/private/cowsjz7mcihy8wtv4u4ag circos.js: http://pastie.org/private/o9w3dwccmimalez9fropa datasource.js: http://pastie.org/private/iko9bqq8eztbfh8xpvnoaw 在 Firefox 中运行
所以我的问题是:为什么这不起作用?
I need to turn a click location into a polar coordinate.
This is my current algorithm. Location is the location on the canvas of the click ({x:evt.clientX, y:evt.clientY}
), center is the offset of the origin from 0,0. For example, if the circle is centered on 250, 250, center is {x:250, y:250}
. Scale is the scale of the radius. For example, if the radius of a circle from the center would normally be 50 and the scale is .5, the radius becomes 25. (it's for zooming in/out)
this.getPolarLocation = function(location){
var unscaledFromCenter = {
x: location.x - center.x,
y: location.y - center.y
};
var angle = this.getAngleOnCircle(unscaledFromCenter);
var dist = Math.sqrt(unscaledFromCenter.x * unscaledFromCenter.x + unscaledFromCenter.y * unscaledFromCenter.y) * this.ds.scale;
return {
angle:angle,
dist:dist,
toString: function(){
return "Theta: ".concat(angle).concat("; dist: ").concat(dist);
}
};
}
this.getAngleOnCircle = function(location){
var x = location.x;
var y = location.y;
if(x == 0 && y > 0)
return Math.PI / 2;
if(x == 0 && y < 0)
return 3 * Math.PI / 2;
if(y == 0 && x > 0)
return 0;
if(y == 0 && x < 0)
return Math.PI;
var angle = Math.atan(y/x);
if(x > 0 && y > 0)
return angle;
if(x < 0)
return Math.PI + angle
return Math.PI * 2 + angle;
}
Screenshots of the issue. The left is what happens zoomed out (and is not supposed to happen). The right is zoomed in (scale >= 1), and is what is supposed to happen.
I'm under the impression that my center coordinates are being shifted slightly off. It seems to work fine for scale >= 1, but not for scale < 1
Source:
circos.html: http://pastie.org/private/cowsjz7mcihy8wtv4u4ag
circos.js: http://pastie.org/private/o9w3dwccmimalez9fropa
datasource.js: http://pastie.org/private/iko9bqq8eztbfh8xpvnoaw
Run in Firefox
So my question is: why doesn't this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于某种原因,当我关闭萤火虫时,该程序会自动运行。它似乎不适用于 Firefox 5,仅适用于我的版本(在 3s 的某处)。不管怎样,我正在放弃这个项目,转而采用更面向对象的方式。当前的算法无法处理基因组。 (这正是我要映射的)
更新:
我找到了问题...我正在测量距页面左上角的距离,而不是画布左上角的距离。因此,当启用 Firebug 时,屏幕会发生移动,使问题变得更糟。解决方案是使用canvas.offsetLeft和canvas.offsetTop来计算画布上的位置。
For some reason, the program automagically works when I close firebug. It doesn't seem to work on Firefox 5, only the version I have (in the 3s somewhere). Either way, I'm scrapping the project for something more object oriented. There's no way the current algorithm could handle a genome. (which is exactly what I'm going to be mapping)
UPDATE:
I figured out the problem... I was measuring the distance from the top left of the page, not the top left of the canvas. Thus, when firebug was enabled, the screen was shifted, making the problems worse. The solution is the use canvas.offsetLeft and canvas.offsetTop to calculate the position on the canvas.