You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取新坐标系中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:05:04