我想放大到处理草图中鼠标光标下的点。问题的规模部分非常简单;这是我搞不懂的翻译部分。其想法是能够放大到处理草图,同时保持草图中对象之间的相对距离。
如有任何帮助,我们将不胜感激。一个放大但不保持相对距离的基本草图如下:
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 = mouseX
、my = mouseY
、d = 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);
}