Гость
Форумы / Android [игнор отключен] [закрыт для гостей] / drawArc некорректная отрисовка / 24 сообщений из 24, страница 1 из 1
17.02.2015, 09:40
    #38881323
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Добрый день!
Рисую 2 полуокружности, но почему они не плотно прилегают друг к другу?? На рисунке нестыковка хорошо видна.
Вот код:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
rectF = new RectF(100, 100, 300, 300);
		
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(70);
paint.setColor(Color.BLACK);
paint.setAlpha(150);

int degree = 60;

canvas.drawArc(rectF, 0, -(360 - degree), false, paint);
canvas.drawArc(rectF, 0, degree, false, paint);


Может как-то иначе нужно отрисовывать чтобы получить плавно прилега?
...
Рейтинг: 0 / 0
17.02.2015, 10:13
    #38881364
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
+1 градус для обоих не предлагать?
...
Рейтинг: 0 / 0
17.02.2015, 10:17
    #38881368
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Пробовал! Не помогло...
...
Рейтинг: 0 / 0
17.02.2015, 10:28
    #38881380
Джибс
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
а в drawable circle не проще сделать ?
...
Рейтинг: 0 / 0
17.02.2015, 10:40
    #38881393
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
цвет и градусы чарта должны изменяться. Но я пробовал в drawable - всё равно криво получается.
Вопрос не в том как проще сделать, а в том как нарисовать 2 или более полукруга, так чтобы края плавно прилегали друг к другу.
...
Рейтинг: 0 / 0
17.02.2015, 10:46
    #38881406
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Сдается мне, что это второй arc накладывается таким образом. Проверь, нарисуй полный круг и затем в нем на сколько-нибудь градусов и скорее всего второй и нарисует пустоты для себя.
...
Рейтинг: 0 / 0
17.02.2015, 10:47
    #38881411
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Код: sql
1.
2.
3.
rectF = new RectF(100, 100, 300, 300);
		
Paint paint = new Paint();


Кстати, последняя студия ругается на такой код в onDraw. Говорит, что создание объектов стоит вынести за рамки этого метода. И я с ней согласен.
...
Рейтинг: 0 / 0
17.02.2015, 10:49
    #38881419
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Отрисовал полный круг внутри него полукруг - просветов не видно.
...
Рейтинг: 0 / 0
17.02.2015, 10:54
    #38881424
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
ЦиркульОтрисовал полный круг внутри него полукруг - просветов не видно.
У тебя странный метод рисования. Я не поленился его проверить но так будет лучше.

Код: sql
1.
2.
canvas.drawArc(rectF, degree, 360, false, paint);
canvas.drawArc(rectF, 0, degree, false, paint);
...
Рейтинг: 0 / 0
17.02.2015, 11:00
    #38881436
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Обрати внимание, что есть альфа paint.setAlpha(150);
И если делать в фоне полный круг, то цвета смешаются.

Нужно именно кусочками изобразить.
...
Рейтинг: 0 / 0
17.02.2015, 11:05
    #38881443
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Чего-то не понимаю тебя. Попробовал черным, белым, желтым и...
...
Рейтинг: 0 / 0
17.02.2015, 11:14
    #38881467
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Попробуй вот этот код:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
rectF = new RectF(100, 100, 300, 300);
		
Paint paint1 = new Paint();
paint1.setAntiAlias(true);
paint1.setStrokeCap(Paint.Cap.BUTT);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(70);
paint1.setColor(Color.RED);
paint1.setAlpha(150);
		
Paint paint2 = new Paint();
paint2.setAntiAlias(true);
paint2.setStrokeCap(Paint.Cap.BUTT);
paint2.setStyle(Paint.Style.STROKE);
paint2.setStrokeWidth(70);
paint2.setColor(Color.GREEN);
paint2.setAlpha(50);

int degree = 60;

canvas.drawArc(rectF, degree, 360, false, paint1); // сдесь ты рисуешь полный круг
canvas.drawArc(rectF, 0, degree, false, paint2); // а сдесь зелёный полукруг - но поскольку есть альфа цвета смешались и круг отрисован не зелёного цвета


Цвета смешаны. Полукруг не зелёный.
Поэтому нужно отрисовать 2 полукруга которые плавно стыкуются друг с другом
...
Рейтинг: 0 / 0
17.02.2015, 11:15
    #38881469
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
...
Рейтинг: 0 / 0
17.02.2015, 11:32
    #38881499
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Ок, понял. С альфа-каналом такие не пройдет, да. А без него можно создать иллюзия идеального стыка.
...
Рейтинг: 0 / 0
17.02.2015, 11:35
    #38881506
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Так может кто-то знает как решить эту задачку?
Вопрос остаётся открытым
...
Рейтинг: 0 / 0
17.02.2015, 11:38
    #38881512
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
ЦиркульТак может кто-то знает как решить эту задачку?
С альфа-каналом и drawArc не получится. Из-за того, как реализован drawArc. Впрочем, он везде примерно так сделан.
...
Рейтинг: 0 / 0
17.02.2015, 11:40
    #38881517
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Или как отрисовать чарт (график) с идеальным стыком полуокружностей?
Такой как на картинке например
...
Рейтинг: 0 / 0
17.02.2015, 11:44
    #38881522
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
ЦиркульИли как отрисовать чарт (график) с идеальным стыком полуокружностей?
Еще разик: альфа-канал убрать и получается идеальный стык.
...
Рейтинг: 0 / 0
17.02.2015, 11:52
    #38881532
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Код: java
1.
2.
3.
4.
        mPaint.setColor(Color.YELLOW);
        canvas.drawArc(mRectF, degree-1, 300+2, false, mPaint);
        mPaint.setColor(Color.RED);
        canvas.drawArc(mRectF, 0, degree, false, mPaint);
...
Рейтинг: 0 / 0
17.02.2015, 12:16
    #38881569
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Я не верю, чтобы в Android не было способа отрисовать с альфа-каналом несколько полукругов с идеальным стыком.
Вопрос открыт...
...
Рейтинг: 0 / 0
17.02.2015, 13:01
    #38881642
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
ЦиркульЯ не верю, чтобы в Android не было способа отрисовать с альфа-каналом несколько полукругов с идеальным стыком.
Вот это вера

Почитай, тут и причина и альтернативное решение https://medium.com/@workingkills/the-mysterious-case-of-who-killed-arcs-on-android-9155f49166b8
...
Рейтинг: 0 / 0
17.02.2015, 13:13
    #38881659
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Кстати, рабочий вариант... Нужно сюда перенести.
Тэги: android Canvas.drawArc same start length точный

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
package com.biowink.clue;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;

import static java.lang.Math.abs;
import static java.lang.Math.ceil;
import static java.lang.Math.cos;
import static java.lang.Math.floor;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
import static java.lang.Math.toRadians;

/**
 * Collection of methods to achieve better circular arc drawing, as
 * {@link Canvas#drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint)} is unreliable.
 * <p>
 * To draw a simple arc, use
 * {@link #drawArc(android.graphics.Canvas, android.graphics.PointF, float, float, float, android.graphics.Paint)}.
 * </p>
 */
public final class ArcUtils
{
    private static final double FULL_CIRCLE_RADIANS = toRadians(360d);

    private ArcUtils() { }

    /**
     * Draws a circular arc on the given {@code Canvas}.
     *
     * @param canvas       The canvas to draw into.
     * @param circleCenter The center of the circle on which to draw the arc.
     * @param circleRadius The radius of the circle on which to draw the arc.
     * @param startAngle   Starting angle (in degrees) where the arc begins.
     * @param sweepAngle   Sweep angle (in degrees) measured clockwise.
     * @param paint        The paint to use then drawing the arc.
     *
     * @see #drawArc(android.graphics.Canvas, android.graphics.PointF, float, float, float, android.graphics.Paint, int, boolean)
     */
    public static void drawArc(Canvas canvas, PointF circleCenter, float circleRadius,
                               float startAngle, float sweepAngle, Paint paint)
    {
        drawArc(canvas, circleCenter, circleRadius, startAngle, sweepAngle, paint, 8, false);
    }

    /**
     * Draws a circular arc on the given {@code Canvas}.
     *
     * @param canvas             The canvas to draw into.
     * @param circleCenter       The center of the circle on which to draw the arc.
     * @param circleRadius       The radius of the circle on which to draw the arc.
     * @param startAngle         Starting angle (in degrees) where the arc begins.
     * @param sweepAngle         Sweep angle (in degrees) measured clockwise.
     * @param paint              The paint to use then drawing the arc.
     * @param arcsPointsOnCircle See {@link #createBezierArcDegrees(android.graphics.PointF, float, float, float, int, boolean, android.graphics.Path)}.
     * @param arcsOverlayPoints  See {@link #createBezierArcDegrees(android.graphics.PointF, float, float, float, int, boolean, android.graphics.Path)}.
     *
     * @see #drawArc(android.graphics.Canvas, android.graphics.PointF, float, float, float, android.graphics.Paint)
     */
    public static void drawArc( Canvas canvas, PointF circleCenter, float circleRadius,
                               float startAngle, float sweepAngle, Paint paint,
                               int arcsPointsOnCircle, boolean arcsOverlayPoints)
    {
        if (sweepAngle == 0f)
        {
            final PointF p = pointFromAngleDegrees(circleCenter, circleRadius, startAngle);
            canvas.drawPoint(p.x, p.y, paint);
        }
        else
        {
            canvas.drawPath(createBezierArcDegrees(
                    circleCenter, circleRadius, startAngle, sweepAngle,
                    arcsPointsOnCircle, arcsOverlayPoints, null), paint);
        }
    }

    /**
     * Normalize the input radians in the range 360° > x >= 0°.
     *
     * @param radians The angle to normalize (in radians).
     *
     * @return The angle normalized in the range 360° > x >= 0°.
     */
    public static double normalizeRadians(double radians)
    {
        radians %= FULL_CIRCLE_RADIANS;
        if (radians < 0d) { radians += FULL_CIRCLE_RADIANS; }
        if (radians == FULL_CIRCLE_RADIANS) { radians = 0d; }
        return radians;
    }


    /**
     * Returns the point of a given angle (in radians) on a circle.
     *
     * @param center       The center of the circle.
     * @param radius       The radius of the circle.
     * @param angleRadians The angle (in radians).
     *
     * @return The point of the given angle on the specified circle.
     *
     * @see #pointFromAngleDegrees(android.graphics.PointF, float, float)
     */

    public static PointF pointFromAngleRadians(PointF center, float radius, double angleRadians)
    {
        return new PointF((float)(center.x + radius * cos(angleRadians)),
                (float)(center.y + radius * sin(angleRadians)));
    }

    /**
     * Returns the point of a given angle (in degrees) on a circle.
     *
     * @param center       The center of the circle.
     * @param radius       The radius of the circle.
     * @param angleDegrees The angle (in degrees).
     *
     * @return The point of the given angle on the specified circle.
     *
     * @see #pointFromAngleRadians(android.graphics.PointF, float, double)
     */

    public static PointF pointFromAngleDegrees(PointF center, float radius, float angleDegrees)
    {
        return pointFromAngleRadians(center, radius, toRadians(angleDegrees));
    }

    /**
     * Adds a circular arc to the given path by approximating it through a cubic B&#233;zier curve.
     * <p/>
     * <p>
     * Note that this <strong>does not</strong> split the arc to better approximate it, for that see either:
     * <ul>
     * <li>{@link #createBezierArcDegrees(android.graphics.PointF, float, float, float, int, boolean,
     * android.graphics.Path)}</li>
     * <li>{@link #createBezierArcRadians(android.graphics.PointF, float, double, double, int, boolean,
     * android.graphics.Path)}</li>
     * </ul>
     * </p>
     * <p/>
     * For a technical explanation:
     * <a href="http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html">
     * http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html
     * </a>
     *
     * @param path        The path to add the arc to.
     * @param center      The center of the circle.
     * @param start       The starting point of the arc on the circle.
     * @param end         The ending point of the arc on the circle.
     * @param moveToStart If {@code true}, move to the starting point of the arc
     *                    (see: {@link android.graphics.Path#moveTo(float, float)}).
     *
     * @see #createBezierArcDegrees(android.graphics.PointF, float, float, float, int, boolean, android.graphics.Path)
     * @see #createBezierArcRadians(android.graphics.PointF, float, double, double, int, boolean, android.graphics.Path)
     */
    public static void addBezierArcToPath( Path path,  PointF center,
                                           PointF start,  PointF end, boolean moveToStart)
    {
        if (moveToStart) { path.moveTo(start.x, start.y); }
        if (start.equals(end)) { return; }

        final double ax = start.x - center.x;
        final double ay = start.y - center.y;
        final double bx = end.x - center.x;
        final double by = end.y - center.y;
        final double q1 = ax * ax + ay * ay;
        final double q2 = q1 + ax * bx + ay * by;
        final double k2 = 4d / 3d * (sqrt(2d * q1 * q2) - q2) / (ax * by - ay * bx);
        final float x2 = (float)(center.x + ax - k2 * ay);
        final float y2 = (float)(center.y + ay + k2 * ax);
        final float x3 = (float)(center.x + bx + k2 * by);
        final float y3 = (float)(center.y + by - k2 * bx);

        path.cubicTo(x2, y2, x3, y3, end.x, end.y);
    }

    /**
     * Adds a circular arc to the given path by approximating it through a cubic B&#233;zier curve, splitting it if
     * necessary. The precision of the approximation can be adjusted through {@code pointsOnCircle} and
     * {@code overlapPoints} parameters.
     * <p>
     * <strong>Example:</strong> imagine an arc starting from 0° and sweeping 100° with a value of
     * {@code pointsOnCircle} equal to 12 (threshold -> 360° / 12 = 30°):
     * <ul>
     * <li>if {@code overlapPoints} is {@code true}, it will be split as following:
     * <ul>
     * <li>from 0° to 30° (sweep 30°)</li>
     * <li>from 30° to 60° (sweep 30°)</li>
     * <li>from 60° to 90° (sweep 30°)</li>
     * <li>from 90° to 100° (sweep 10°)</li>
     * </ul>
     * </li>
     * <li>if {@code overlapPoints} is {@code false}, it will be split into 4 equal arcs:
     * <ul>
     * <li>from 0° to 25° (sweep 25°)</li>
     * <li>from 25° to 50° (sweep 25°)</li>
     * <li>from 50° to 75° (sweep 25°)</li>
     * <li>from 75° to 100° (sweep 25°)</li>
     * </ul>
     * </li>
     * </ul>
     * </p>
     * <p/>
     * For a technical explanation:
     * <a href="http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html">
     * http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html
     * </a>
     *
     * @param center            The center of the circle.
     * @param radius            The radius of the circle.
     * @param startAngleRadians The starting angle on the circle (in radians).
     * @param sweepAngleRadians How long to make the total arc (in radians).
     * @param pointsOnCircle    Defines a <i>threshold</i> (360° /{@code pointsOnCircle}) to split the B&#233;zier arc to
     *                          better approximate a circular arc, depending also on the value of {@code overlapPoints}.
     *                          The suggested number to have a reasonable approximation of a circle is at least 4 (90°).
     *                          Less than 1 will be ignored (the arc will not be split).
     * @param overlapPoints     Given the <i>threshold</i> defined through {@code pointsOnCircle}:
     *                          <ul>
     *                          <li>if {@code true}, split the arc on every angle which is a multiple of the
     *                          <i>threshold</i> (yields better results if drawing precision is required,
     *                          especially when stacking multiple arcs, but can potentially use more points)</li>
     *                          <li>if {@code false}, split the arc equally so that each part is shorter than
     *                          the <i>threshold</i></li>
     *                          </ul>
     * @param addToPath         An existing path where to add the arc to, or {@code null} to create a new path.
     *
     * @return {@code addToPath} if it's not {@code null}, otherwise a new path.
     *
     * @see #createBezierArcDegrees(android.graphics.PointF, float, float, float, int, boolean, android.graphics.Path)
     */

    public static Path createBezierArcRadians( PointF center, float radius, double startAngleRadians,
                                              double sweepAngleRadians, int pointsOnCircle, boolean overlapPoints,
                                               Path addToPath)
    {
        final Path path = addToPath != null ? addToPath : new Path();
        if (sweepAngleRadians == 0d) { return path; }

        if (pointsOnCircle >= 1)
        {
            final double threshold = FULL_CIRCLE_RADIANS / pointsOnCircle;
            if (abs(sweepAngleRadians) > threshold)
            {
                double angle = normalizeRadians(startAngleRadians);
                PointF end, start = pointFromAngleRadians(center, radius, angle);
                path.moveTo(start.x, start.y);
                if (overlapPoints)
                {
                    final boolean cw = sweepAngleRadians > 0; // clockwise?
                    final double angleEnd = angle + sweepAngleRadians;
                    while (true)
                    {
                        double next = (cw ? ceil(angle / threshold) : floor(angle / threshold)) * threshold;
                        if (angle == next) { next += threshold * (cw ? 1d : -1d); }
                        final boolean isEnd = cw ? angleEnd <= next : angleEnd >= next;
                        end = pointFromAngleRadians(center, radius, isEnd ? angleEnd : next);
                        addBezierArcToPath(path, center, start, end, false);
                        if (isEnd) { break; }
                        angle = next;
                        start = end;
                    }
                }
                else
                {
                    final int n = abs((int)ceil(sweepAngleRadians / threshold));
                    final double sweep = sweepAngleRadians / n;
                    for (int i = 0;
                         i < n;
                         i++, start = end)
                    {
                        angle += sweep;
                        end = pointFromAngleRadians(center, radius, angle);
                        addBezierArcToPath(path, center, start, end, false);
                    }
                }
                return path;
            }
        }

        final PointF start = pointFromAngleRadians(center, radius, startAngleRadians);
        final PointF end = pointFromAngleRadians(center, radius, startAngleRadians + sweepAngleRadians);
        addBezierArcToPath(path, center, start, end, true);
        return path;
    }

    /**
     * Adds a circular arc to the given path by approximating it through a cubic B&#233;zier curve, splitting it if
     * necessary. The precision of the approximation can be adjusted through {@code pointsOnCircle} and
     * {@code overlapPoints} parameters.
     * <p>
     * <strong>Example:</strong> imagine an arc starting from 0° and sweeping 100° with a value of
     * {@code pointsOnCircle} equal to 12 (threshold -> 360° / 12 = 30°):
     * <ul>
     * <li>if {@code overlapPoints} is {@code true}, it will be split as following:
     * <ul>
     * <li>from 0° to 30° (sweep 30°)</li>
     * <li>from 30° to 60° (sweep 30°)</li>
     * <li>from 60° to 90° (sweep 30°)</li>
     * <li>from 90° to 100° (sweep 10°)</li>
     * </ul>
     * </li>
     * <li>if {@code overlapPoints} is {@code false}, it will be split into 4 equal arcs:
     * <ul>
     * <li>from 0° to 25° (sweep 25°)</li>
     * <li>from 25° to 50° (sweep 25°)</li>
     * <li>from 50° to 75° (sweep 25°)</li>
     * <li>from 75° to 100° (sweep 25°)</li>
     * </ul>
     * </li>
     * </ul>
     * </p>
     * <p/>
     * For a technical explanation:
     * <a href="http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html">
     * http://hansmuller-flex.blogspot.de/2011/10/more-about-approximating-circular-arcs.html
     * </a>
     *
     * @param center            The center of the circle.
     * @param radius            The radius of the circle.
     * @param startAngleDegrees The starting angle on the circle (in degrees).
     * @param sweepAngleDegrees How long to make the total arc (in degrees).
     * @param pointsOnCircle    Defines a <i>threshold</i> (360° /{@code pointsOnCircle}) to split the B&#233;zier arc to
     *                          better approximate a circular arc, depending also on the value of {@code overlapPoints}.
     *                          The suggested number to have a reasonable approximation of a circle is at least 4 (90°).
     *                          Less than 1 will ignored (the arc will not be split).
     * @param overlapPoints     Given the <i>threshold</i> defined through {@code pointsOnCircle}:
     *                          <ul>
     *                          <li>if {@code true}, split the arc on every angle which is a multiple of the
     *                          <i>threshold</i> (yields better results if drawing precision is required,
     *                          especially when stacking multiple arcs, but can potentially use more points)</li>
     *                          <li>if {@code false}, split the arc equally so that each part is shorter than
     *                          the <i>threshold</i></li>
     *                          </ul>
     * @param addToPath         An existing path where to add the arc to, or {@code null} to create a new path.
     *
     * @return {@code addToPath} if it's not {@code null}, otherwise a new path.
     *
     * @see #createBezierArcRadians(android.graphics.PointF, float, double, double, int, boolean, android.graphics.Path)
     */

    public static Path createBezierArcDegrees( PointF center, float radius, float startAngleDegrees,
                                              float sweepAngleDegrees, int pointsOnCircle, boolean overlapPoints,
                                               Path addToPath)
    {
        return createBezierArcRadians(center, radius, toRadians(startAngleDegrees), toRadians(sweepAngleDegrees),
                pointsOnCircle, overlapPoints, addToPath);
    }
}



Пример использования:
MainActivity.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
package wadman.ru.myapplication;

import android.app.Activity;
import android.os.Bundle;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyView m = new MyView(this);
        setContentView(m);
    }

}


MyView.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
package wadman.ru.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import static wadman.ru.myapplication.ArcUtils.drawArc;

/**
 * Created by wadman on 17.02.2015.
 */
public class MyView extends View implements View.OnTouchListener {

    private Paint mPaint;
    //private RectF mRectF;
    private PointF mPointF;

    public MyView(Context context) {
        super(context);
        setOnTouchListener(this);
        //mRectF = new RectF(100, 100, 300, 300);

        mPointF = new PointF(200, 200);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(70);
        mPaint.setAlpha(150);

    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnTouchListener(this);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        int degree = 60;

        mPaint.setColor(Color.YELLOW);
        //canvas.drawArc(mRectF, degree-1, 300+2, false, mPaint);
        drawArc(canvas, mPointF, 100, degree, 300, mPaint);
        mPaint.setColor(Color.RED);
        //canvas.drawArc(mRectF, 0, degree, false, mPaint);
        drawArc(canvas, mPointF, 100, 0, degree, mPaint);
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
}



Выделенный импорт нужно заменить на правильный (или свой, как сделано у меня :).
...
Рейтинг: 0 / 0
17.02.2015, 13:51
    #38881718
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Все таки не идеал, но видимо лучшее решение для альфа-канала. :)

Как вариант, можно рисовать увеличенное в два раза изображение и затем уменьшать.
...
Рейтинг: 0 / 0
17.02.2015, 15:15
    #38881837
Циркуль
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
drawArc некорректная отрисовка
Спасибо! Исчерпывающий ответ!
...
Рейтинг: 0 / 0
Форумы / Android [игнор отключен] [закрыт для гостей] / drawArc некорректная отрисовка / 24 сообщений из 24, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]