0

0

在Processing中实现基于鼠标输入的2D图形独立旋转与拖动

碧海醫心

碧海醫心

发布时间:2025-11-17 16:29:12

|

993人浏览过

|

来源于php中文网

原创

在Processing中实现基于鼠标输入的2D图形独立旋转与拖动

本教程详细介绍了如何在processing中利用2d变换矩阵(translate、rotate、pushmatrix、popmatrix)和鼠标事件(mousedragged)实现多个图形的独立旋转和整体拖动。文章强调了使用相对坐标定义图形的重要性,并提供了示例代码,帮助开发者创建交互式的动态图形效果。

Processing 2D图形变换基础

Processing提供了一套强大的2D变换函数,允许我们对图形进行平移、旋转和缩放,而无需手动修改每个顶点的坐标。这些变换基于一个内部的变换矩阵,它定义了当前绘图环境的坐标系统。理解这些变换的关键在于它们是累积的,并且会影响其之后的所有绘图操作。

  • translate(x, y): 将坐标系的当前原点移动到新的位置(x, y)。在此之后绘制的所有图形都将相对于这个新原点进行定位。
  • rotate(angle): 围绕当前坐标系的原点旋转绘图环境。angle通常以弧度表示。
  • scale(s) 或 scale(sx, sy): 改变绘图环境的尺寸。

实现图形的静态旋转与拖动

当我们需要让图形在屏幕上保持其“中心”位置旋转,或者通过鼠标拖动来移动它们时,需要巧妙地结合translate()和rotate()。

1. 避免图形“飞出”屏幕

初学者在使用rotate()时常遇到的问题是图形会围绕画布的左上角(默认原点(0,0))旋转,导致图形移出可见区域。要解决这个问题,我们需要:

  • 将坐标系原点移动到图形的中心:在调用rotate()之前,先使用translate(centerX, centerY)将坐标系原点移动到图形的旋转中心。
  • 使用相对坐标定义图形:图形的所有顶点坐标都应该相对于其旋转中心来定义。例如,如果图形的中心是(0,0),那么其顶点坐标应是相对于(0,0)的偏移量。

2. 鼠标拖动平移功能

为了实现通过鼠标拖动来移动整个图形组,我们可以利用mouseDragged()事件。这个函数会在鼠标被按下并拖动时持续触发。

float offsetX = 0; // 用于存储整体平移的X偏移量
float offsetY = 0; // 用于存储整体平移的Y偏移量

void setup() {
  size(1800, 1000);
}

void draw() {
  background(0); // 每帧清空背景

  // 应用整体平移
  translate(offsetX, offsetY);

  // ... 在这里绘制所有图形 ...
}

void mouseDragged() {
  // 更新偏移量,使图形跟随鼠标移动
  offsetX = mouseX;
  offsetY = mouseY;
}

在上述代码中,offsetX和offsetY跟踪鼠标的当前位置,并通过translate(offsetX, offsetY)将整个绘图环境的原点移动到鼠标位置。这意味着所有后续绘制的图形都会以鼠标位置为新的(0,0)点进行绘制。

甲骨文AI协同平台
甲骨文AI协同平台

专门用于甲骨文研究的革命性平台

下载

独立图形的旋转:pushMatrix()与popMatrix()

要让多个图形独立地旋转,例如一个顺时针旋转,另一个逆时针旋转,同时保持它们各自的中心,就需要使用pushMatrix()和popMatrix()。

  • pushMatrix(): 保存当前的变换矩阵状态。它将当前坐标系的状态(包括平移、旋转、缩放)压入一个中。
  • popMatrix(): 恢复到最近一次pushMatrix()保存的变换矩阵状态。它从栈中弹出上一个状态,并将其设为当前坐标系状态。

通过在每个独立图形的绘制代码块前后分别调用pushMatrix()和popMatrix(),我们可以为每个图形创建独立的变换环境,互不干扰。

示例:两颗星形图形的独立旋转

以下示例展示了如何在Processing中创建两个星形图形,它们围绕各自的中心独立旋转(一个顺时针,一个逆时针),并且整个图形组可以通过鼠标拖动进行平移。图形的顶点坐标已调整为相对于其自身中心(0,0)的相对坐标。

float offsetX = 0; // 整体平移X
float offsetY = 0; // 整体平移Y

void setup() {
  size(1800, 1000);
  // 初始时将整体平移中心设置在画布中央
  offsetX = width / 2;
  offsetY = height / 2;
}

void draw() {
  background(0); // 每帧清空背景

  // 1. 应用整体平移,将所有图形的逻辑中心移动到鼠标拖动的位置
  translate(offsetX, offsetY);

  // --- 第一个星形 (顺时针旋转) ---
  pushMatrix(); // 保存当前变换状态 (包括整体平移)
    // 2. 围绕当前原点 (即星形的中心) 旋转
    rotate(frameCount * 0.01); // frameCount是一个内置变量,提供连续的动画值

    // 3. 绘制第一个星形 (使用相对于其中心的坐标)
    fill(139, 19, 191);
    triangle( 100,  100,    0,  350, -100,  100);
    fill(20, 134, 245);
    triangle( 200, -100,  350,  100,  100,  100);
    fill(191, 8, 8);
    triangle(-100,  100, -350,  100, -200, -100);
    fill(86, 165, 3);
    triangle(-200, -100, -350, -400,    0, -150);
    fill(167, 167, 166);
    triangle(   0, -150,  350, -400,  200, -100);
  popMatrix(); // 恢复到pushMatrix()时的变换状态 (取消了第一个星形的旋转)

  // --- 第二个星形 (逆时针旋转) ---
  pushMatrix(); // 再次保存当前变换状态 (包括整体平移)
    // 2. 围绕当前原点 (即星形的中心) 逆时针旋转
    rotate(frameCount * -0.01);

    // 3. 绘制第二个星形 (使用相对于其中心的坐标)
    fill(139, 19, 191);
    triangle(-100, -150,    0, -400,  100, -150);
    fill(86, 165, 3);
    triangle( 100, -150,  350, -150,  200,   50);
    fill(167, 167, 166);
    triangle(-200,   50, -350, -150, -100, -150);
    fill(20, 134, 245);
    triangle(-200,   50, -350,  350,    0,  150);
    fill(191, 8, 8);
    triangle( 200,  50, 350, 350,   0, 150);
  popMatrix(); // 恢复到pushMatrix()时的变换状态 (取消了第二个星形的旋转)

  // 绘制中心圆 (相对于当前原点,即整体平移后的中心)
  fill(0, 0, 0);
  // 注意:Processing内置的圆形绘制函数是ellipse,这里为了兼容原代码,使用自定义的circle函数
  circle(0, 0, 425);
}

// 鼠标拖动时更新整体平移偏移量
void mouseDragged() {
  offsetX = mouseX;
  offsetY = mouseY;
}

// 自定义circle函数,实际调用ellipse
void circle(float x, float y, float r) {
  ellipse(

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

61

2026.01.19

java用途介绍
java用途介绍

本专题整合了java用途功能相关介绍,阅读专题下面的文章了解更多详细内容。

87

2026.01.19

java输出数组相关教程
java输出数组相关教程

本专题整合了java输出数组相关教程,阅读专题下面的文章了解更多详细内容。

39

2026.01.19

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

10

2026.01.19

xml格式相关教程
xml格式相关教程

本专题整合了xml格式相关教程汇总,阅读专题下面的文章了解更多详细内容。

13

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

19

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号