如何放大鼠标光标下的点(处理)



我想放大到处理草图中鼠标光标下的点。问题的规模部分非常简单;这是我搞不懂的翻译部分。其想法是能够放大到处理草图,同时保持草图中对象之间的相对距离。

如有任何帮助,我们将不胜感激。一个放大但不保持相对距离的基本草图如下:

float scaleFactor;
void setup()
{
    size(300, 300);
    scaleFactor = 1;
}
void draw()
{
    background(255);
    fill(128);
    noStroke();
    pushMatrix();
    scale(scaleFactor);
    rect(0, 0, 100, 100);
    popMatrix();
}
void keyPressed()
{
    if (key == 'r')
    {
        scaleFactor = 1;
    }
}
void mouseWheel(MouseEvent e)
{
    scaleFactor += e.getAmount() / 100;
}

前面的回答没有完全符合要求的行为。例如,如果你想要与用户在谷歌地图中滚动鼠标所期望的相同风格的缩放,我认为你想要这样的:

float scaleFactor = 1.0;
float translateX = 0.0;
float translateY = 0.0;
void setup() {
    size(300, 300);
}
void draw() {
    background(255);
    fill(128);
    noStroke();
    pushMatrix();
    translate(translateX,translateY);
    scale(scaleFactor);
    rect(0, 0, 100, 100);
    rect(width-100, height-100, 100, 100);
    popMatrix();
}
void keyPressed() {
    if (key == 'r') {
        scaleFactor = 1;
        translateX = 0.0;
        translateY = 0.0;
    }
}
void mouseDragged(MouseEvent e) {
    translateX += mouseX - pmouseX;
    translateY += mouseY - pmouseY;
}
void mouseWheel(MouseEvent e) {
    translateX -= mouseX;
    translateY -= mouseY;
    float delta = e.getCount() > 0 ? 1.05 : e.getCount() < 0 ? 1.0/1.05 : 1.0;
    scaleFactor *= delta;
    translateX *= delta;
    translateY *= delta;
    translateX += mouseX;
    translateY += mouseY;
}

试试这个。。。

float scaleFactor;
float translateX;
float translateY;
void setup()
{
  size(300, 300);
  scaleFactor = 1;
}
void draw()
{
  background(255);
  fill(128);
  noStroke();
  pushMatrix();
  translate(translateX,translateY);
  scale(scaleFactor);
  rect(0, 0, 100, 100);
  rect(width-100, height-100, 100, 100);
  popMatrix();
}
void keyPressed()
{
  if (key == 'r')
  {
    scaleFactor = 1;
  }
}
void mouseWheel(MouseEvent e)
{
  translateX = translateX-e.getAmount()*(mouseX)/100;
  translateY = translateY-e.getAmount()*(mouseY)/100;
  scaleFactor += e.getAmount() / 100;
}

实际上这样做更顺利:

float e = -event.getCount()/100.0;
float delta = pow(2, e);

而不是:

float delta = e.getCount() > 0 ? 1.05 : e.getCount() < 0 ? 1.0/1.05 : 1.0;

添加RandomEtc答案有效的详细答案。

他们答案的关键部分是:

void mouseWheel(MouseEvent e) {
    translateX -= mouseX;
    translateY -= mouseY;
    float delta = e.getCount() > 0 ? 1.05 : e.getCount() < 0 ? 1.0/1.05 : 1.0;
    scaleFactor *= delta;
    translateX *= delta;
    translateY *= delta;
    translateX += mouseX;
    translateY += mouseY;
}

这是因为我们做了3个转换:通过[-mouseX,-moseY]平移,通过[delta,delta]缩放,通过[+mouseX和+mouseY]翻译。

平移很重要,因为缩放比例"围绕原点"(即原点保持不变,所有其他点都会改变)。所以我们平移来移动原点,然后在最后平移回来。

就矩阵变换而言,我们可以将其表示为以下(其中mx = mouseXmy = mouseYd = delta):

 -        -    -        -    -          -
| 1  0  mx |  |  d  0  0 |  |  1  0  -mx |
| 0  1  mY |  |  0  d  0 |  |  0  1  -my |
| 0  0  1  |  |  0  0  1 |  |  0  0  1   |
 -        -    -        -    -          -

此外,注意阶数很重要,因为矩阵运算不是交换的。虽然顺序可能看起来不直观(它们的顺序相反!),但这是因为我们会在变换矩阵的右端写一个点,并从右向左应用。无论如何

如果你进行矩阵乘法,你最终会得到:

 -               -
|  d  0  mx*(1-d) |
|  0  d  my*(1-d) |
|  0  0  1        |
 -               -

或者,按delta缩放并按mouseX * (1 - delta)平移。相当于mouseX - mouseX * delta。这正是RandomEtc所做的。一个等效的功能是:

void mouseWheel(MouseEvent e) {
    float delta = e.getCount() > 0 ? 1.05 : e.getCount() < 0 ? 1.0/1.05 : 1.0;
    scaleFactor *= delta;
    translateX = (delta*translateX) + mouseX * (1 - delta);
    translateY = (delta*translateY) + mouseY * (1 - delta);
}

最新更新