Reputation: 73
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();
Upvotes: 4
Views: 402
Reputation: 51837
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();
}
Upvotes: 8