Search code examples
javaswingawtellipsedrawstring

Draw string on ellipse


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.


Solution

  • 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]);