2016-04-17 10 views
3

私は現在の外側の周りティックとAndroidウェアウォッチフェイス正方形の時計にウォッチフェイス「ダニ」を描くにはどうすればいいですか?

ラウンドウォッチフェイスではなく、それは次のように判明広場にもダニが発生
float innerMainTickRadius = mCenterX - 35; 
      for(int tickIndex = 0; tickIndex < 12; tickIndex++) { 
       float tickRot = (float) (tickIndex * Math.PI * 2/12); 
       float innerX = (float) Math.sin(tickRot) * innerMainTickRadius; 
       float innerY = (float) -Math.cos(tickRot) * innerMainTickRadius; 
       float outerX = (float) Math.sin(tickRot) * mCenterX; 
       float outerY = (float) -Math.cos(tickRot) * mCenterX; 
       canvas.drawLine(mCenterX + innerX, mCenterY + innerY, mCenterX + outerX, mCenterY + outerY, mTickPaint); 
      } 

を生成するこのスニペットを持っている: Round ticks on Squareが、私は思いますそれらは円形ではなく、より適切に形状に適合します。例:Square watchface

標準的な方法はありますか?私は再びトリグを使うことはできないと思っています...

答えて

3

もちろんジオメトリとトリグを使用します。例えば時計の面に置いた線は、中心を指しているので、ある部分が与えられた(x、y)になり、もう片方がarctan2(cy-y、cx-x)になります。あなたは中心に向かって持っている点(cx、cy)を返します。次に、x、yからcos(angle)* r、sin(angle)* rに線を引いて、与えられた長さrの中心の方向に線を描きます。

しかし、サンプル画像があれば、x、yからx + r、yまで線を引いてから、キャンバスを角度で回転させて、そのように数を微調整することができます。キャンバスの行列とcanvas.restore()を微調整する前にcanvas.save()を実行してください。

これは、どのような図形からでも、あなたのティックを描きたいと思っている数学の位置とその位置を残します。これはパス内で行うことができます。したがって、丸みを帯びた矩形のパスを定義し、PathMeasureクラスを使用してgetPosTan()を取得し、接線を無視して、四角形の周囲の位置を見つけるための位置を使用します。それは、決定された形状に応じて、線分またはベジェセクションのいずれかを通る位置として、それらの位置を計算することができます。例えば

:描画ルーチンで

static final int TICKS = 12; 
static final float TICKLENGTH = 20; 

float left = cx - 50; 
    float top = cy - 50; 
    float right = cx + 50; 
    float bottom = cy + 50; 
    float ry = 20; 
    float rx = 20; 
    float width = right-left; 
    float height = bottom-top; 
    Path path = new Path(); 
    path.moveTo(right, top + ry); 
    path.rQuadTo(0, -ry, -rx, -ry); 
    path.rLineTo(-(width - (2 * rx)), 0); 
    path.rQuadTo(-rx, 0, -rx, ry); 
    path.rLineTo(0, (height - (2 * ry))); 
    path.rQuadTo(0, ry, rx, ry); 
    path.rLineTo((width - (2 * rx)), 0); 
    path.rQuadTo(rx, 0, rx, -ry); 
    path.rLineTo(0, -(height - (2 * ry))); 
    path.close(); 

    PathMeasure pathMeasure = new PathMeasure(); 
    pathMeasure.setPath(path,true); 
    float length = pathMeasure.getLength(); 
    float[] pos = new float[2]; 
    float r = TICKLENGTH; 
    for (int i = 0; i < TICKS; i++) { 
     pathMeasure.getPosTan(i * (length/TICKS),pos,null); 
     double angle = Math.atan2(cy - pos[1], cx - pos[0]); //yes, y then x. 
     double cos = Math.cos(angle); 
     double sin = Math.sin(angle); 
     canvas.drawLine(pos[0], pos[1], (float)(pos[0] + cos * r), (float)(pos[1] + sin * r), paint); 
    } 

は確かに、それは次のようになります。それは得るために多くの仕事を取るので

clock picture

それはあなたのイメージのように見える。しかし、それは完全に実行可能です。パスメジャーのトリックはどんな形状でも機能します。私はLollipop +の制限のためにpath.addRoundRectの使用を避けました。あなたはその質問hereに私の答えを見ることができます。そして、丸みを帯びた矩形のエスケープな形を描く方法については、他にもたくさんの答えがあります。もしあなたがエンベロープ関数を書こうと思っているのであれば、時間の経過と共に、現在の画像を係数tに従って四角形のエンベロープにスケーリングするだけです。

+0

モックアップをベクターで使用している場合は、ベクターグラフィックを使用して、そのアイコンを描画中に大きく吹き飛ばすことができます。あなたがSVGで望むものを描き、それをアンドロイドベクターグラフィックスに変換し、drawableをキャンバスに描画すると、それはかなり小さく、あいまいではありません。 – Tatarize

+0

これは実際には悪い考えではありません。私はあなたの最初の答えを使用し、それはかなりうまくいきました。 – nuggetbram

1

角度は現在の位置の関数です。私はすぐにこのケースで閉じたフォームを取得するためのトリックを見ていない。しかし、最も一般的なケースでは、ちょうど各目盛りの位置を保存することができます。次に、その点と中心を通る線を描きます。これ第二私は

theta(i)=arctan(y_pos(i)/x_pos(i)) 

中心を想定している角度は、座標(0,0)を有しています。この場合、顔は90度ごとに周期的で、対角線についても対称であるため、連続する8ティックの位置を保存するだけで済みます。

関連する問題