如何获取新坐标系中PVector在原坐标系的坐标(Processing/p5.js)
解决方法:获取新坐标系向量的原坐标系坐标
你当前的代码中,vectorInNewCoordSys是旋转45度后的新坐标系中的向量,要将它转换回原坐标系(即pushMatrix()之前的坐标系,已执行translate(width/2, height/2))的坐标,需要应用逆变换。以下是几种实现方式:
方法1:手动计算逆旋转变换
因为当前变换只有顺时针旋转45度,可通过三角函数手动推导逆变换(等价于将向量逆时针旋转45度),适配Processing向下的y轴:
PVector originalVector; void setup() { size(400, 400); originalVector = new PVector(100, 0); } void draw() { background(220); translate(width/2, height/2); stroke(255, 0, 0); drawVector(originalVector); pushMatrix(); float theta = radians(45); rotate(theta); PVector vectorInNewCoordSys = originalVector.get(); // 转换新坐标系向量到原坐标系 PVector coordInOriginalSys = convertToOriginalCoord(vectorInNewCoordSys, theta); stroke(0, 0, 255); drawVector(vectorInNewCoordSys); popMatrix(); println("原坐标系坐标:(" + coordInOriginalSys.x + ", " + coordInOriginalSys.y + ")"); } void drawVector(PVector v) { line(0, 0, v.x, v.y); } // 新坐标系向量转原坐标系 PVector convertToOriginalCoord(PVector v, float theta) { float cosTheta = cos(theta); float sinTheta = sin(theta); float x = v.x * cosTheta - v.y * sinTheta; float y = v.x * sinTheta + v.y * cosTheta; // 若要转屏幕坐标系(左上角原点),添加translate偏移: // x += width/2; // y += height/2; return new PVector(x, y); }
如果需要得到预期结果(100,100),可调整vectorInNewCoordSys的取值,比如设置为new PVector(100*sqrt(2), 0),或修改旋转角度匹配转换逻辑。
方法2:使用PMatrix2D自动处理变换矩阵
Processing的PMatrix2D类可自动记录当前变换矩阵,并计算逆矩阵,适合多变换组合(平移+旋转+缩放)的场景:
PVector originalVector; void setup() { size(400, 400); originalVector = new PVector(100, 0); } void draw() { background(220); translate(width/2, height/2); stroke(255, 0, 0); drawVector(originalVector); pushMatrix(); rotate(radians(45)); PVector vectorInNewCoordSys = originalVector.get(); // 获取当前变换矩阵 PMatrix2D currentTransform = new PMatrix2D(); getMatrix(currentTransform); // 计算逆矩阵 PMatrix2D inverseTransform = new PMatrix2D(); currentTransform.invert(inverseTransform); // 应用逆变换得到原坐标系坐标 PVector coordInOriginalSys = new PVector(); inverseTransform.mult(vectorInNewCoordSys, coordInOriginalSys); stroke(0, 0, 255); drawVector(vectorInNewCoordSys); popMatrix(); println("原坐标系坐标:(" + coordInOriginalSys.x + ", " + coordInOriginalSys.y + ")"); } void drawVector(PVector v) { line(0, 0, v.x, v.y); }
这种方法无需手动推导公式,Processing会自动处理所有已应用的变换逻辑。
方法3:使用PVector内置变换方法
PVector提供rotate()方法,直接对向量执行逆时针旋转(对应坐标系顺时针旋转的逆变换),代码更简洁:
PVector originalVector; void setup() { size(400, 400); originalVector = new PVector(100, 0); } void draw() { background(220); translate(width/2, height/2); stroke(255, 0, 0); drawVector(originalVector); pushMatrix(); float theta = radians(45); rotate(theta); PVector vectorInNewCoordSys = originalVector.get(); // 复制向量并执行逆旋转 PVector coordInOriginalSys = vectorInNewCoordSys.get(); coordInOriginalSys.rotate(-theta); // 负角度实现逆时针旋转 stroke(0, 0, 255); drawVector(vectorInNewCoordSys); popMatrix(); println("原坐标系坐标:(" + coordInOriginalSys.x + ", " + coordInOriginalSys.y + ")"); } void drawVector(PVector v) { line(0, 0, v.x, v.y); }
内容的提问来源于stack exchange,提问作者user22305318
相关产品推荐
相关产品推荐

