java - Move a point toward the mouse
问题描述
(I'm using processing for this but it is not necessarily relevant.)
I'm looking for an algorithm that would take the point A and the point B (B being the mouse cursor position) and use them so that every frame the point A moves a little bit towards B (from -1px to 1px left/right up/down)
I tried x1 += cos(atan((mouseY-y1)/(mouseX-x1))) and the same with sin for y1, but I doesn't seem to work.
If someone has an idea I would appreciate it.
I'm not looking for a built-in function that would do the job, I'd like to understand the math behind it.
Thank you for your time.
解决方案
It is important that the point coordinates are floating point values:
float x = 0.0, y= 0.0;
For the computation of the movement of the point, I recommend to use PVector
.
Setup 2 vectors, for the point and the mouse position:
PVector Pt = new PVector(x, y);
PVector Pm = new PVector(mouseX, mouseY);
Calculate the Unit vector from Pt
to Pm
:
PVector D = PVector.sub(Pm, Pt);
D.normalize();
Calculate the new point by newPt = Pt + D * min(speed, dist)
, but ensure that the point moves not further than the Euclidean distance to the mouse:
float speed = 3;
float movelen = min(PVector.dist(Pt, Pm), speed);
PVector newPt = PVector.add(Pt, D.mult(movelen));
The same can be achieved by arithmetic operations
float dx = mouseX - x;
float dy = mouseY - y;
float dist = sqrt(dx*dx + dy*dy);
if (dist > 0) {
float movelen = min(dist, speed);
x += dx/dist * movelen;
y += dy/dist * movelen;
}
(dx
,dy
) is the vector from the point to the mouse and dist
ist the Euclidean distance between the 2 points. A Unit vector can be calculated by dividing a vector by its magnitude, so (dx/dist
, dy/dist
) is the unit direction vector.
Finally (dx/dist * movelen
, dx/dist * movelen
) is the same as D * movelen
.
See the example:
(the code works for any speed
, even below 1.0)
float x = 0.0, y= 0.0;
void setup() {
size(300, 300);
x = (float)random(width);
y = (float)random(height);
}
void draw() {
float speed = 3;
/*
//setup points
PVector Pt = new PVector(x, y);
PVector Pm = new PVector(mouseX, mouseY);
// calcualte normalized direction
PVector D = PVector.sub(Pm, Pt);
D.normalize();
// calcualte new point
float movelen = min(PVector.dist(Pt, Pm), speed);
PVector newPt = PVector.add(Pt, D.mult(movelen));
x = newPt.x;
y = newPt.y;
*/
float dx = mouseX - x;
float dy = mouseY - y;
float dist = sqrt(dx*dx + dy*dy);
if (dist > 0) {
float movelen = min(dist, speed);
x += dx/dist * movelen;
y += dy/dist * movelen;
}
background(196);
stroke(0);
fill(255, 0, 0);
ellipse((int)x, (int)y, 10, 10);
fill(0, 255, 0);
ellipse(mouseX, mouseY, 10, 10);
}
推荐阅读
- ubuntu - cgi3.2.9 make install 在 ubuntu 18.4 中失败
- ruby-on-rails - Autoprefixer 不支持 Node v0.10.37 错误
- c# - 卡在重新加载相关实体以从外部进行新更改?
- c# - Asp .net MVC 5 Route Attribute with id between route
- html - CSS编辑不起作用
- python - 1005x132589 像素的图像尺寸太大。每个方向必须小于 2^16
- jgroups - 尝试使用 probe.sh 监控 JGroups
- html - jquery验证表单隐藏显示不起作用
- java - 我的 Firebase 数据库为每个成员属性返回 null
- python - 无法使用 TableauServerClient 连接到 Tableau Server 10.5