2016-04-17 4 views
3

Ich habe diese Schnipsel zur Zeit die Zecken um die Außenseite und Android Wear Zifferblatt ErzeugungWie zeichne Watchface "Ticks" auf einer quadratischen Uhr?

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); 
      } 

, die die Zecken gut auf einem runden Zifferblatt erzeugt aber auf einem Platz es stellt sich heraus, wie folgt aus: Round ticks on Square aber ich würde wie sie nicht kreisförmig sein sollen, sondern die Form etwas passender anpassen, zB: Square watchface

Gibt es einen Standard Weg dies zu tun? Ich schätze, ich kann Trig nicht wieder verwenden ...

Antwort

3

Natürlich verwenden Sie Geometrie und Trig. Zum Beispiel jede Linie, die Sie auf die Uhrfläche legen, die Sie auf die Mitte zeigen möchten, so dass ein Teil der gegebene (x, y) und der andere arctan2 (cy-y, cx-x) ist, was Ihnen den Winkel von der Punkt, den Sie auf das Zentrum (cx, cy) haben, dann zeichnen Sie einfach die Linie in Richtung des Mittelpunkts einer gegebenen Länge r, indem Sie die Linie von x, y nach cos (Winkel) * r, sin (Winkel) * r zeichnen .

Wenn Sie jedoch Ihr Beispielbild verwenden, möchten Sie vielleicht die Linie von x, y nach x + r, y zeichnen und dann die Leinwand um den Winkel drehen, so dass Sie die gezählten Zahlen zeichnen können. Stellen Sie sicher, dass Sie canvas.save() ausführen, bevor Sie die canvas-Matrix und canvas.restore() nach der Optimierung optimieren.

Dies lässt die Mathematik der Form, aus der Sie Ihre Ticks zeichnen möchten, und die Positionen dazu. Sie können dies innerhalb eines Pfades tun. Definieren Sie den Pfad für ein abgerundetes Rechteck und verwenden Sie dann die PathMeasure-Klasse, um getPosTan() zu erhalten. Ignorieren Sie dann die Tangente und verwenden Sie einfach die Position, in der Sie Ihre Position um ein abgerundetes Rechteck finden. Dies oder einfach diese Positionen als die Positionen entweder durch ein Liniensegment oder einen Bezierabschnitt in Abhängigkeit von der bestimmten Form berechnen.

Zum Beispiel:

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

In der Auslosung Routine

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); 
    } 

Zwar sieht es so aus:

clock picture

So würde es viel mehr Arbeit nehmen, um Es sieht aus wie dein Bild. Aber es ist absolut machbar. Die Pfadmaß-Trick-Sache wird für jede Form funktionieren. Ich habe vermieden, path.addRoundRect wegen der Lollipop + Beschränkung zu verwenden. Sie können meine Antwort auf diese Frage here sehen. Und die anderen Antworten, die reichlich sind, um eine abgerundete rechteckige Form zu zeichnen. Sie können, wenn Sie eine Hüllkurvenfunktion schreiben möchten, einfach Ihr aktuelles Bild entsprechend dem Faktor t auf die Hüllkurve des Rechtecks ​​skalieren, während es rund um die Uhr läuft.

+0

Wenn Sie dieses Modell in Vektor haben, könnten Sie einfach Vektorgrafiken verwenden und dieses Symbol während der Ziehung so groß aufblasen.Zeichnen Sie, was Sie in einem SVG möchten, konvertieren Sie es in Android-Vektorgrafiken und zeichnen Sie einfach das Zeichen auf der Leinwand, es wäre ziemlich klein und nicht mehrdeutig. – Tatarize

+0

Das ist eigentlich keine schlechte Idee. Ich habe deine erste Antwort benutzt und es hat am Ende ziemlich gut funktioniert – nuggetbram

1

Der Winkel ist eine Funktion der Position jetzt. Ich sehe nicht sofort den Trick, um in diesem Fall eine geschlossene Form zu bekommen. Aber im allgemeinsten Fall könnten Sie am Ende nur die Position jedes Häkchens speichern, dann zeichnen Sie nur die Linie, die durch diesen Punkt und das Zentrum verläuft. so ist der Winkel bei Sekunde i nur

unter der Annahme, dass das Zentrum Koordinaten (0,0) hat. In diesem Fall müssen Sie die Positionen nur für 8 aufeinander folgende Ticks speichern, da die Fläche alle 90 Grad periodisch und symmetrisch um die Diagonalen ist.

Verwandte Themen