概要

AffineTransformを使用して時計盤の上半分と下半分で異なる回転でアラビア数字を配置します。

スクリーンショット

Swing/ArabicClockFace.png

サンプルコード

for (String txt : arabicNumerals) {
  double m00 = at.getScaleX();
  double d = m00 > 0d || Math.abs(m00) < 0.0001 ? 1d : -1d;
  AffineTransform si = AffineTransform.getScaleInstance(d, d);
  Shape s = getTextLayout(txt, font, frc).getOutline(si);
  Rectangle2D r = s.getBounds2D();
  double tx = r.getCenterX();
  double ty = radius - hourMarkerLen - r.getHeight() + r.getCenterY();
  Shape t = AffineTransform.getTranslateInstance(-tx, -ty)
      .createTransformedShape(s);
  g2.fill(at.createTransformedShape(t));
  at.rotate(Math.PI / 6d);
}
View in GitHub: Java, Kotlin

解説

  • 時計盤の上半分(9, 10, 11, 12, 1, 2, 3)
    • アラビア数字文字列からFontTextLayoutを使用して文字図形を取得
    • 時計盤の中央から12時の位置まで文字図形を移動
    • 時計盤の中央を原点にプラス30°回転をAffineTransformに追加して文字図形を回転
  • 時計盤の下半分(4, 5, 6, 7, 8)
    • 3x3アフィン変換行列のX座標スケーリング要素m00が負かつ0ではない場合時計盤の下半分と判断し、アラビア数字文字列からFontTextLayoutを使用して上下左右反転した文字図形を取得
      • 0かどうかはm00の絶対値が誤差0.0001以下かどうかで計算(Math.abs(m00) < 0.0001)
    • 時計の中心から12時の位置まで文字図形を移動
    • 時計の中心を原点にプラス30°回転をAffineTransformに追加して文字図形を回転

参考リンク

コメント