英文:
Rotating text not the position of the text in processing
问题
我正在尝试制作一个时钟,并且希望所有的数字都处于正确的位置,但它们都被旋转了,例如6被倒置,而12是正确的。有没有办法只旋转文本,而不改变文本的位置?
我的代码是:
push();
textSize(48);
for (int i = 1; i < 13; i++) {
int offset = -15;
if (str(i).length() == 2) {
offset -= 14.5;
}
rotate(radians(30));
text(i, offset, -350);
//println(i*30);
}
pop();
英文:
i am trying to make a clock and have all the numbers in the correct place but they are all rotated e.g. 6 is upside down whereas 12 is correct. is there anyway to rotate just the text not the position of the text?
my code is
push();
textSize(48);
for (int i = 1; i < 13; i++) {
int offset = -15;
if (str(i).length() == 2) {
offset -= 14.5;
}
rotate(radians(30));
text(i, offset, -350);
//println(i*30);
}
pop();
答案1
得分: 8
未看代码,我的直觉是你使用了 rotate()
函数,但可能你没有使用 pushMatrix()
/popMatrix();
来将坐标空间隔离到本地空间,以便可以临时旋转。
我建议阅读 2D 变换教程。
正如教程所提到的,变换的顺序很重要:
size(300, 300);
background(0);
stroke(255);
// 文本居中对齐
textAlign(CENTER);
// 将全局坐标原点移动到画布中心
translate(width / 2, height / 2);
int hours = 12;
// 每个小时的角度部分(360/12 = 30 度),但以弧度表示
float angleIncrement = TWO_PI / hours;
// 距中心的距离
float radius = 100;
for (int i = 0; i < hours; i++) {
// 计算每个小时的角度,减去一些角度,因为角度 0 指向右侧,而不是顶部(12 点钟)
// 记住这个偏移量:在绘制时钟指针时可能会有帮助 ;)
float angle = (angleIncrement * i) - (QUARTER_PI * 4/3);
// 隔离坐标空间
pushMatrix();
// 以全局中心为基准,按照每小时的角度旋转
rotate(angle);
// 从局部旋转后的中心位置平移,基于半径
translate(radius, 0);
// 撤销局部旋转,使文本保持水平
rotate(-angle);
// 绘制文本
text(i+1, 0, 0);
// 退出局部坐标系统,回到全局坐标
popMatrix();
}
下面是一个带有帮助函数的示例,用于可视化坐标系统:
void setup() {
// ...(略去部分代码,与上面的示例相似)
}
void drawCoordinateSystem(String label, float size, float alpha) {
// ...(略去部分代码,与上面的示例相似)
}
请注意,对于 pushMatrix()
/popMatrix()
,不需要缩进,这只是一种视觉提示,有助于在阅读代码时记住坐标系统的嵌套。
这部分以下的代码是一些过于复杂的演示,您可能不需要,但希望它能够提供一些有趣的可视化效果。
注:此处省略了一些代码,仅返回翻译内容。
英文:
Without seeing the code my hunch is you use rotate()
, but probably you don't use pushMatrix()
/popMatrix();
to isolate the coordinate space to local one that can be temporarily rotated.
I recommend reading the 2D Transformations tutorial
As the tutorial mentions, the order of transformations matters:
size(300, 300);
background(0);
stroke(255);
// center align text
textAlign(CENTER);
// global translation to center
translate(width / 2, height / 2);
int hours = 12;
// an angle section (360/12 = 30 degrees), but in radians
float angleIncrement = TWO_PI / hours;
// distance from center
float radius = 100;
for(int i = 0 ; i < hours; i++){
// calculate the angle for each hour, subtracting a bit because angle 0 points to the right, not top (12 o'clock)
// remember this offset: it may come in handy when drawing clock handles ;)
float angle = (angleIncrement * i) - (QUARTER_PI * 4/3);
// isolate coordinate space
pushMatrix();
// rotate from global center by each hour angle
rotate(angle);
// translate from locally rotated center based on radius
translate(radius, 0);
// undo local rotation so text is straight
rotate(-angle);
// render text
text(i+1,0,0);
// exit local coordinate system, back to global coordinates after this
popMatrix();
}
Here is the same example with a helper function to help visualise the coordinate systems:
void setup() {
size(300, 300);
background(0);
stroke(255);
// center align text
textAlign(CENTER);
drawCoordinateSystem("1.original cooordinates",60, 255);
// global translation to center
translate(width / 2, height / 2);
drawCoordinateSystem("2.global center",60, 64);
int hours = 12;
// an angle section (360/12 = 30 degrees), but in radians
float angleIncrement = TWO_PI / hours;
// distance from center
float radius = 100;
for (int i = 0; i < hours; i++) {
// calculate the angle for each hour, subtracting a bit because angle 0 points to the right, not top (12 o'clock)
// remember this offset: it may come in handy when drawing clock handles ;)
float angle = (angleIncrement * i) - (QUARTER_PI * 4/3);
// isolate coordinate space
pushMatrix();
// rotate from global center by each hour angle
rotate(angle);
if(i == 0){
drawCoordinateSystem("3.local+rotation",60, 127);
}
// translate from locally rotated center based on radius
translate(radius, 0);
if(i == 0){
drawCoordinateSystem("4.local+rot.+\ntrans.",60, 192);
}
// undo local rotation so text is straight
rotate(-angle);
if(i == 0){
drawCoordinateSystem("\n5.prev.\n-rot.",60, 255);
}
// render text
text(i+1, 0, 0);
// exit local coordinate system, back to global coordinates after this
popMatrix();
}
}
void drawCoordinateSystem(String label, float size, float alpha){
pushStyle();
textAlign(LEFT);
strokeWeight(3);
// x axis
stroke(192, 0, 0, alpha);
line(0, 0, size, 0);
// y axis
stroke(0, 192, 0, alpha);
line(0, 0, 0, size);
text(label, 10, 15);
popStyle();
}
Note that the indent is not required for pushMatrix()
/popMatrix()
, it's more of a visual cue to aid when you read code to remember coordinate system nesting.
This is over the top and you won't need the code bellow, but hopefully it's a fun visualisation:
PImage screenshot;
String[] labels = {"1.original cooordinates","2.global center\ntranslate(width / 2, height / 2)",
"3.local+rotation\npushMatrix();\nrotate(angle)",
"4.local+rot.+\ntrans.\ntranslate(radius, 0)","5.previous-rot.\nrotate(-angle)",""};
PMatrix2D[] systems = new PMatrix2D[labels.length];
PMatrix2D lerpMatrix = new PMatrix2D();
void setup() {
size(300, 300);
background(0);
stroke(255);
// center align text
textAlign(CENTER);
// "1.original cooordinates"
systems[0] = new PMatrix2D();
// global translation to center
translate(width / 2, height / 2);
// "2.global center"
systems[1] = systems[0].get();
systems[1].translate(width / 2, height / 2);
int hours = 12;
// an angle section (360/12 = 30 degrees), but in radians
float angleIncrement = TWO_PI / hours;
// distance from center
float radius = 100;
for (int i = 0; i < hours; i++) {
// calculate the angle for each hour, subtracting a bit because angle 0 points to the right, not top (12 o'clock)
// remember this offset: it may come in handy when drawing clock handles ;)
float angle = (angleIncrement * i) - (QUARTER_PI * 4/3);
// isolate coordinate space
pushMatrix();
// rotate from global center by each hour angle
rotate(angle);
if(i == 0){
// "3.local+rotation"
PMatrix2D local = new PMatrix2D();
local.apply(systems[1]);
local.rotate(angle);
systems[2] = local.get();
}
// translate from locally rotated center based on radius
translate(radius, 0);
if(i == 0){
// "4.local+rot.+\ntrans."
systems[3] = systems[2].get();
systems[3].translate(radius,0);
}
// undo local rotation so text is straight
rotate(-angle);
if(i == 0){
// "\n5.prev.\n-rot."
systems[4] = systems[3].get();
systems[4].rotate(-angle);
systems[5] = systems[4];
}
// render text
text(i+1, 0, 0);
// exit local coordinate system, back to global coordinates after this
popMatrix();
}
screenshot = get();
}
void draw(){
image(screenshot,0, 0);
animateCoordinateSystems();
text("mouse mouse on X axis", width / 2, height - 12);
}
void animateCoordinateSystems(){
float mapping = map(constrain(mouseX, 0, width), 0, width, 0.0, 1.0);
float globalT = (float)(labels.length -1) * mapping;
int index = (int)globalT;
float localT = globalT - index;
lerpMatrix(systems[index], systems[index+1], localT, lerpMatrix);
pushMatrix();
applyMatrix(lerpMatrix);
drawCoordinateSystem(labels[index] + (labels[index+1].length() > 0 ? "\ntransitions to\n" + labels[index+1] : ""),60, 255);
popMatrix();
}
void lerpMatrix(PMatrix2D from, PMatrix2D to, float t, PMatrix2D result){
result.m00 = lerp(from.m00, to.m00, t);
result.m01 = lerp(from.m01, to.m01, t);
result.m02 = lerp(from.m02, to.m02, t);
result.m10 = lerp(from.m10, to.m10, t);
result.m11 = lerp(from.m11, to.m11, t);
result.m12 = lerp(from.m12, to.m12, t);
}
void drawCoordinateSystem(String label, float size, float alpha){
pushStyle();
textAlign(LEFT);
strokeWeight(3);
// x axis
stroke(192, 0, 0, alpha);
line(0, 0, size, 0);
// y axis
stroke(0, 192, 0, alpha);
line(0, 0, 0, size);
text(label, 10, 15);
popStyle();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论