Draw string on ellipse
-
06-07-2021 - |
Pergunta
I'm happy with the output of my clock, however - I am not sure how to properly align my drawString
for the numbers which should appear at the tip of each tick mark on the clock.
I am hoping someone might be able show the proper method/formula for this.
private void drawTickMarks(Graphics2D g2)
{
double radius = this.faceRadius;
for (int secs = 0; secs <= 60; secs++)
{
double tickStart;
if (secs % 5 == 0)
tickStart = radius - 15;
else
tickStart = radius - 5;
tick = drawRadii(secs / 60.0, tickStart, radius);
if (secs % 5 == 0)
{
g2.setStroke(new BasicStroke(3));
g2.drawString(""+(secs/5),(int)tick.getX1()+(int)(tick.getX1()-tick.getX2()),
(int)tick.getY1()+(int)(tick.getY1()-tick.getY2()));
}
else
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.WHITE);
g2.draw(tick);
}
}
Thanks to Thinhbk for a valid and correct solution with code and Jon W for the proper steps of coming to a solution.
Solução
As a supplemental to the solution provided by Jon W, I create a method that calculate the offset, and IMO, it looks fine. (@Jon W: sorry for not adding comment to your solution as it's rather long.)
/**
* Calculate the offset *
* @param i
* @return array:
* 0: x offset
* 1: y offset
*/
private int[] calculateOffSet(int i) {
int[] val = new int[2];
int deflt = -12;
if(i == 12) {
val[0] = -15;
val[1] = 9;
}else if (i > 6) {
val[0] = deflt + i - 6 ;
val[1] = i ;
}else {
val[0] = deflt + i ;
val[1] = i + 6;
}
return val;
}
And in your code, just call this:
int xLocation = (int)tick.getX1()+(int)(tick.getX1()-tick.getX2());
int yLocation = (int)tick.getY1()+(int)(tick.getY1()-tick.getY2());
int[] offset = calculateOffSet((secs / 5));
g2.drawString(number, xLocation + offset[0], yLocation + offset[1]);
Outras dicas
If you imagine the String enclosed within a box, the x and y values you pass into drawString
specify the lower left corner of the box.
I would modify the drawString
line as such:
String number = ""+(secs/5);
int xLocation = (int)tick.getX1()+(int)(tick.getX1()-tick.getX2());
int yLocation = (int)tick.getY1()+(int)(tick.getY1()-tick.getY2());
int offsetX = /*Insert some value here to shift the position of all the strings
along the x-axis. Make this an expression that contains number.length(),
so that two-digit numbers are shifted more than one digit numbers. */
int offsetY = /*Insert some value here to shift the position of all the strings along
the y-axis.*/
g2.drawString(number, xLocation + offsetX, yLocation + offsetY);
You'll have to play around with the specific values for offsetX
and offsetY
to make it look nice.
If you want to be even fancier and make it so that drawString
will automatically adjust the location depending on what font is being used, take a look at this and the FontMetrics
class. You'll want to make offsetX
and offsetY
vary depending on width and height of the characters being drawn and whatnot.