Example usage for android.graphics Path Path

List of usage examples for android.graphics Path Path

Introduction

In this page you can find the example usage for android.graphics Path Path.

Prototype

public Path() 

Source Link

Document

Create an empty path

Usage

From source file:com.larvalabs.svgandroid.SVGParser.java

/**
 * This is where the hard-to-parse paths are handled.
 * Uppercase rules are absolute positions, lowercase are relative.
 * Types of path rules://from w  w w .ja  v a  2s  . c o  m
 * <p/>
 * <ol>
 * <li>M/m - (x y)+ - Move to (without drawing)
 * <li>Z/z - (no params) - Close path (back to starting point)
 * <li>L/l - (x y)+ - Line to
 * <li>H/h - x+ - Horizontal ine to
 * <li>V/v - y+ - Vertical line to
 * <li>C/c - (x1 y1 x2 y2 x y)+ - Cubic bezier to
 * <li>S/s - (x2 y2 x y)+ - Smooth cubic bezier to (shorthand that assumes the x2, y2 from previous C/S is the x1, y1 of this bezier)
 * <li>Q/q - (x1 y1 x y)+ - Quadratic bezier to
 * <li>T/t - (x y)+ - Smooth quadratic bezier to (assumes previous control point is "reflection" of last one w.r.t. to current point)
 * </ol>
 * <p/>
 * Numbers are separate by whitespace, comma or nothing at all (!) if they are self-delimiting, (ie. begin with a - sign)
 *
 * @param s the path string from the XML
 */
private static Path doPath(String s) {
    int n = s.length();
    ParserHelper ph = new ParserHelper(s, 0);
    ph.skipWhitespace();
    Path p = new Path();
    float lastX = 0;
    float lastY = 0;
    float lastX1 = 0;
    float lastY1 = 0;
    RectF r = new RectF();
    char cmd = 'x';
    while (ph.pos < n) {
        char next = s.charAt(ph.pos);
        if (!Character.isDigit(next) && !(next == '.') && !(next == '-')) {
            cmd = next;
            ph.advance();
        } else if (cmd == 'M') { // implied command
            cmd = 'L';
        } else if (cmd == 'm') { // implied command
            cmd = 'l';
        } else { // implied command
            // Log.d(TAG, "Implied command: " + cmd);
        }
        p.computeBounds(r, true);
        // Log.d(TAG, "  " + cmd + " " + r);
        // Util.debug("* Commands remaining: '" + path + "'.");
        boolean wasCurve = false;
        switch (cmd) {
        case 'M':
        case 'm': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'm') {
                p.rMoveTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                p.moveTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'Z':
        case 'z': {
            p.close();
            break;
        }
        case 'L':
        case 'l': {
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'l') {
                p.rLineTo(x, y);
                lastX += x;
                lastY += y;
            } else {
                p.lineTo(x, y);
                lastX = x;
                lastY = y;
            }
            break;
        }
        case 'H':
        case 'h': {
            float x = ph.nextFloat();
            if (cmd == 'h') {
                p.rLineTo(x, 0);
                lastX += x;
            } else {
                p.lineTo(x, lastY);
                lastX = x;
            }
            break;
        }
        case 'V':
        case 'v': {
            float y = ph.nextFloat();
            if (cmd == 'v') {
                p.rLineTo(0, y);
                lastY += y;
            } else {
                p.lineTo(lastX, y);
                lastY = y;
            }
            break;
        }
        case 'C':
        case 'c': {
            wasCurve = true;
            float x1 = ph.nextFloat();
            float y1 = ph.nextFloat();
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'c') {
                x1 += lastX;
                x2 += lastX;
                x += lastX;
                y1 += lastY;
                y2 += lastY;
                y += lastY;
            }
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'S':
        case 's': {
            wasCurve = true;
            float x2 = ph.nextFloat();
            float y2 = ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 's') {
                x2 += lastX;
                x += lastX;
                y2 += lastY;
                y += lastY;
            }
            float x1 = 2 * lastX - lastX1;
            float y1 = 2 * lastY - lastY1;
            p.cubicTo(x1, y1, x2, y2, x, y);
            lastX1 = x2;
            lastY1 = y2;
            lastX = x;
            lastY = y;
            break;
        }
        case 'A':
        case 'a': {
            float rx = ph.nextFloat();
            float ry = ph.nextFloat();
            float theta = ph.nextFloat();
            int largeArc = (int) ph.nextFloat();
            int sweepArc = (int) ph.nextFloat();
            float x = ph.nextFloat();
            float y = ph.nextFloat();
            if (cmd == 'a') {
                x += lastX;
                y += lastY;
            }
            drawArc(p, lastX, lastY, x, y, rx, ry, theta, largeArc == 1, sweepArc == 1);
            lastX = x;
            lastY = y;
            break;
        }
        default:
            Log.d(TAG, "Invalid path command: " + cmd);
            ph.advance();
        }
        if (!wasCurve) {
            lastX1 = lastX;
            lastY1 = lastY;
        }
        ph.skipWhitespace();
    }
    return p;
}

From source file:org.androfarsh.widget.DragGridLayout.java

@Override
protected void dispatchDraw(Canvas canvas) {
    if (mDebugMode) {
        mPaint.setStyle(Style.FILL_AND_STROKE);
        final Path path = new Path();

        path.reset();//from w  w  w.j a va2  s  .c  o  m
        mCellsRegion.getBoundaryPath(path);
        path.close();
        mPaint.setColor(0x660000cc);
        canvas.drawPath(path, mPaint);

        path.reset();
        mFreeCellsRegion.getBoundaryPath(path);
        path.close();
        mPaint.setColor(0x66cc0000);
        canvas.drawPath(path, mPaint);
    }

    if (mRootView == null) {
        drawCellGrid(canvas);
    }
    super.dispatchDraw(canvas);
}

From source file:com.lovejjfg.demo.TouchCircleView.java

public void drawTriangle(Canvas c, float startAngle, float sweepAngle) {
    if (mArrow == null) {
        mArrow = new Path();
        mArrow.setFillType(Path.FillType.EVEN_ODD);
    } else {/*  w w  w .  ja v  a2s . c o m*/
        mArrow.reset();
    }

    // Adjust the position of the triangle so that it is inset as
    // much as the arc, but also centered on the arc.
    //        float inset = (int) mStrokeInset / 2 * mArrowScale;
    float x = (float) (mRingCenterRadius * Math.cos(0) + innerRectf.centerX());
    float y = (float) (mRingCenterRadius * Math.sin(0) + innerRectf.centerY());

    // Update the path each time. This works around an issue in SKIA
    // where concatenating a rotation matrix to a scale matrix
    // ignored a starting negative rotation. This appears to have
    // been fixed as of API 21.
    mArrow.moveTo(0, 0);
    mArrow.lineTo(ARROW_WIDTH * mArrowScale, 0);
    mArrow.lineTo((ARROW_WIDTH * mArrowScale / 2), (ARROW_HEIGHT * mArrowScale));
    mArrow.offset(x, y);
    mArrow.close();
    // draw a triangle
    c.rotate(startAngle + sweepAngle, innerRectf.centerX(), innerRectf.centerY());
    c.drawPath(mArrow, innerPaint);

}

From source file:ingbank.com.tr.happybanking.common.ui.controls.PagerSlidingTabStrip.java

public Path getEquilateralTriangle(Rect bounds) {
    android.graphics.Point startPoint = null, p2 = null, p3 = null;
    int width = bounds.right - bounds.left - 12;
    int height = bounds.bottom - bounds.top;

    startPoint = new android.graphics.Point(bounds.left, bounds.bottom);

    p2 = new android.graphics.Point(startPoint.x + width, startPoint.y);
    //p3 = new Point(startPoint.x + (width / 2), startPoint.y - width);
    p3 = new android.graphics.Point(startPoint.x + (width / 2), startPoint.y - height);

    Path path = new Path();
    path.moveTo(startPoint.x, startPoint.y);
    path.lineTo(p2.x, p2.y);// w  ww .jav  a  2  s.co m
    path.lineTo(p3.x, p3.y);

    return path;
}

From source file:com.sinyuk.jianyimaterial.widgets.FloatingToolbar.java

@TargetApi(21)
private void hideLollipopImpl() {
    int rootWidth = mRoot.getWidth();

    float controlX;

    if (mFabOriginalX > rootWidth / 2f) {
        controlX = mFabOriginalX * 0.98f;
    } else {//  www. j a  v  a 2s.  c  o  m
        controlX = mFabOriginalX * 1.02f;
    }

    final Path path = new Path();
    path.moveTo(mFab.getX(), mFab.getY());
    final float x2 = controlX;
    final float y2 = getY();
    path.quadTo(x2, y2, mFabOriginalX, mFabOriginalY + getTranslationY());
    ObjectAnimator anim = ObjectAnimator.ofFloat(mFab, View.X, View.Y, path);
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.setDuration(FAB_UNMORPH_DURATION);
    anim.setStartDelay(FAB_UNMORPH_DELAY);
    anim.start();

    /**
     * Animate FAB elevation back to 6dp
     */
    anim = ObjectAnimator.ofFloat(mFab, View.TRANSLATION_Z, 0);
    anim.setInterpolator(new AccelerateDecelerateInterpolator());
    anim.setDuration(FAB_UNMORPH_DURATION);
    anim.setStartDelay(FAB_UNMORPH_DELAY);
    anim.start();

    /**
     * Restore alpha of FAB drawable
     */
    Drawable drawable = mFab.getDrawable();
    if (drawable != null) {
        anim = ObjectAnimator.ofPropertyValuesHolder(drawable, PropertyValuesHolder.ofInt("alpha", 255));
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        anim.setDuration(FAB_UNMORPH_DURATION);
        anim.setStartDelay(FAB_UNMORPH_DELAY);
        anim.start();
    }

    Animator toolbarReveal = ViewAnimationUtils.createCircularReveal(this, getWidth() / 2, getHeight() / 2,
            (float) (Math.hypot(getWidth() / 2, getHeight() / 2)), (float) mFab.getWidth() / 2f);

    toolbarReveal.setTarget(this);
    toolbarReveal.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            setVisibility(View.INVISIBLE);
            mFab.setVisibility(View.VISIBLE);
            mMorphing = false;
        }
    });
    toolbarReveal.setDuration(CIRCULAR_UNREVEAL_DURATION);
    toolbarReveal.setInterpolator(new AccelerateInterpolator());
    toolbarReveal.setStartDelay(CIRCULAR_UNREVEAL_DELAY);
    toolbarReveal.start();

    /**
     * Animate FloatingToolbar animation back to 6dp
     */
    anim = ObjectAnimator.ofFloat(this, View.TRANSLATION_Z, 0);
    anim.setDuration(CIRCULAR_UNREVEAL_DURATION);
    anim.setStartDelay(CIRCULAR_UNREVEAL_DELAY);
    anim.start();
}

From source file:com.chrynan.guitarchords.view.GuitarChordView.java

@Override
protected void onDraw(Canvas canvas) {
    //This method handles a lot of work, possibly too much for an onDraw method, but since I'm not animating
    //or updating the view often, it should be capable of performing the tasks without too much effort.
    //I can optimize this later.

    //First draw the strings and fret markers
    //Fret markers; not worrying about whether or not to show the bridge nut now (since that wasn't calculated
    //in to the drawing size)
    //TODO need to take into account whether or not to show bridgeNut
    int fretCount = chord.getFretCount();
    fretCount = (fretCount < 4) ? 4 : fretCount;
    for (int i = 0; i < fretCount + 1; i++) {
        canvas.drawLine(drawingBounds.left + fretNumberBounds.width(),
                (drawingBounds.top + stringMarkerBounds.height()) + (i * fretSize) + (i * fretMarkerSize),
                drawingBounds.right - stringSize,
                (drawingBounds.top + stringMarkerBounds.height()) + (i * fretSize) + (i * fretMarkerSize),
                fretMarkerPaint);//from   w w  w  .ja v  a2  s. c o m
    }
    //Strings
    for (int i = 0; i < stringCount; i++) {
        canvas.drawLine((stringMarkerBounds.left) + (i * stringDistance) + (i * stringSize),
                drawingBounds.top + stringMarkerBounds.height(),
                (stringMarkerBounds.left) + (i * stringDistance) + (i * stringSize),
                drawingBounds.bottom - fretMarkerSize, stringPaint);
    }
    //Next draw the fret numbers and string markers
    //Fret numbers; check if we are showing them or not
    if (showFretNumbers) {
        for (int i = 0; i < fretCount; i++) {
            canvas.drawText(String.valueOf(i + 1), drawingBounds.left + fretNumberBounds.width() / 2,
                    getVerticalCenterTextPosition(
                            stringMarkerBounds.bottom + (i * fretMarkerSize) + (i * fretSize) + (fretSize / 2),
                            String.valueOf(i + 1), fretNumberPaint),
                    fretNumberPaint);
        }
    }
    //String markers
    for (int i : chord.getMutedStrings()) {
        canvas.drawText(mutedText,
                (drawingBounds.left + fretNumberBounds.width()) + ((stringCount - i) * stringDistance)
                        + ((stringCount - i) * stringSize),
                getVerticalCenterTextPosition(drawingBounds.top + (stringMarkerBounds.height() / 2), mutedText,
                        stringMarkerPaint),
                stringMarkerPaint);
    }
    for (int i : chord.getOpenStrings()) {
        canvas.drawText(openStringText,
                (drawingBounds.left + fretNumberBounds.width()) + ((stringCount - i) * stringDistance)
                        + ((stringCount - i) * stringSize),
                getVerticalCenterTextPosition(drawingBounds.top + (stringMarkerBounds.height() / 2),
                        openStringText, stringMarkerPaint),
                stringMarkerPaint);
    }
    //Finally, draw all the notes and the note text
    //Bars
    float startCenterX;
    float startCenterY;
    for (ChordMarker cm : chord.getBars()) {
        startCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getStartString()) * stringDistance)
                + ((stringCount - cm.getStartString()) * stringSize);
        startCenterY = stringMarkerBounds.bottom
                + (((cm.getFret() * fretSize) + (cm.getFret() * fretMarkerSize)) - (fretSize / 2));
        float endCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getEndString()) * stringDistance)
                + ((stringCount - cm.getEndString()) * stringSize);
        float endCenterY = startCenterY;
        canvas.drawCircle(startCenterX, startCenterY, noteSize / 2, notePaint);
        canvas.drawCircle(endCenterX, endCenterY, noteSize / 2, notePaint);
        if (showFingerNumbers) {
            canvas.drawText(String.valueOf(cm.getFinger()), startCenterX, getVerticalCenterTextPosition(
                    startCenterY, String.valueOf(cm.getFinger()), noteNumberPaint), noteNumberPaint);
            canvas.drawText(String.valueOf(cm.getFinger()), endCenterX,
                    getVerticalCenterTextPosition(endCenterY, String.valueOf(cm.getFinger()), noteNumberPaint),
                    noteNumberPaint);
        }
        barLinePath = new Path();
        barLinePath.moveTo(startCenterX, startCenterY - (noteSize / 2));
        barLinePath.quadTo((startCenterX + endCenterX) / 2, (startCenterY + endCenterY - (noteSize / 2)) / 4,
                endCenterX, endCenterY - (noteSize / 2));
        canvas.drawPath(barLinePath, barLinePaint);
    }
    //Individual notes
    for (ChordMarker cm : chord.getIndividualNotes()) {
        startCenterX = (drawingBounds.left + fretNumberBounds.width())
                + ((stringCount - cm.getStartString()) * stringDistance)
                + ((stringCount - cm.getStartString()) * stringSize);
        startCenterY = stringMarkerBounds.bottom
                + (((cm.getFret() * fretSize) + (cm.getFret() * fretMarkerSize)) - (fretSize / 2));
        canvas.drawCircle(startCenterX, startCenterY, noteSize / 2, notePaint);
        if (showFingerNumbers) {
            canvas.drawText(String.valueOf(cm.getFinger()), startCenterX, getVerticalCenterTextPosition(
                    startCenterY, String.valueOf(cm.getFinger()), noteNumberPaint), noteNumberPaint);
        }
    }
}

From source file:com.wanikani.androidnotifier.graph.HistogramPlot.java

protected void drawBar(Canvas canvas, Samples bar, float left, float right) {
    long base, height;
    float top, tbl;
    Paint lpaint;//from  www . j  a  va 2  s  .  c om
    Paint paint;
    Path path;
    RectF rect;

    top = vp.getY(vp.yMax);
    base = 0;
    for (Sample sample : bar.samples) {
        if (sample.value > 0) {
            height = sample.value;

            if (base > vp.yMax)
                ;
            else if (base + height > vp.yMax) {
                path = new Path();
                path.moveTo(left, vp.getY(base));
                path.lineTo(left, top);
                path.lineTo(left + (right - left) / 3, top - 10);
                path.lineTo(left + (right - left) * 2 / 3, top + 5);
                path.lineTo(right, top);
                path.lineTo(right, vp.getY(base));
                path.close();
                canvas.drawPath(path, pas.series.get(sample.series));
            } else {
                rect = new RectF(left, vp.getY(base + height), right, vp.getY(base));
                rect.intersect(meas.plotArea);
                paint = pas.series.get(sample.series);
                paint.setStyle(Style.FILL);
                canvas.drawRect(rect, paint);
                paint.setStyle(Style.STROKE);
                canvas.drawRect(rect, paint);
            }
            base += height;
        }
    }

    if (base <= vp.yMax) {
        lpaint = pas.levelupPaint;
        tbl = vp.getY(base) - meas.headroom / 2;
    } else {
        lpaint = pas.levelupPaintInside;
        tbl = vp.getY(vp.yMax) + meas.margin;
    }

    if (base > 0 && drawTotal)
        canvas.drawText(Long.toString(base), (left + right) / 2, tbl, lpaint);
}

From source file:com.acceleratedio.pac_n_zoom.AnimActivity.java

private void mainAnmLoop() {

    AnimationSet anmSet = null;/*from  w ww.  ja v  a 2s.  co  m*/

    if (onClickFlg == 1) {

        if (anmSet != null) {
            anmSet.cancel();
            anmSet.reset();
        }

        return;
    }

    // --- Loop through the frames
    int frm_nmbr = svg_data.frm.size();

    if (++frm_mbr >= frm_nmbr)
        frm_mbr = 0;

    // -- You need to turn the sprites on and off for the current frame
    LoadSVG.frame crt_frm = svg_data.frm.get(frm_mbr);
    String crt_frm_ordr = crt_frm.frm_ordr;
    ArrayList<String> sprt_ordr = svg_data.svg.ordr;
    int crt_dur = crt_frm.end - crt_frm.bgn;

    // - Loop through the sprites 
    int sprt_nmbr = sprt_ordr.size();
    int frm_sprt_mbr = 0;

    for (int sprt_mbr = 0; sprt_mbr < sprt_nmbr; sprt_mbr += 1) {

        String sprt_id = sprt_ordr.get(sprt_mbr);
        int sym_mbr = Integer.parseInt(sprt_id.substring(1, sprt_id.indexOf('_'))) - 2;

        if (sym_mbr >= 0) { // not g1 which is not loaded

            LoadSVG.symbol crt_sym = svg_data.symbl.get(sym_mbr);

            if (crt_frm_ordr.indexOf(sprt_id) >= 0) { // Sprite is present

                if (crt_sym.aud_id != null && !crt_sym.aud_id.equals("")) { // The sprite is audio

                    SoundPool mSoundPool = loadSVG.getMSoundPool();
                    int streamId = mSoundPool.play(svg_data.soundId[sym_mbr], 1.0f, 1.0f, 1, 0, 1.0f);
                    mSoundPool.setLoop(streamId, -1);
                } else { // The sprite is graphic
                    anim_view = anmViews.get(sprt_mbr);
                    anim_view.setAlpha(1f);
                    int xfm_idx = crt_frm.xfm_idx[frm_sprt_mbr];

                    if (xfm_idx >= 0) { // An animation tag is present

                        anmSet = new AnimationSet(false);
                        LoadSVG.xfrm crt_xfm = svg_data.xfm.get(xfm_idx);
                        ArrayList<Integer[]> pnts = crt_xfm.mov_path;
                        int init_scl = (int) (initScl[sprt_mbr] * 100);

                        if (pnts.size() > 0) {

                            final Path path = new Path();
                            ld_scl_pth_pnts(pnts, path);
                            PathAnimation pthAnm = new PathAnimation(path);
                            pthAnm.setDuration(crt_dur);
                            pthAnm.setInterpolator(new LinearInterpolator());
                            pthAnm.setFillAfter(true); // Needed to keep the result of the animation
                            anmSet.addAnimation(pthAnm);
                        }

                        if (crt_xfm.scl_bgn != init_scl) {

                            float crt_scl = crt_xfm.scl_bgn / init_scl;
                            float end_scl = crt_scl;

                            if (crt_xfm.scl_end != crt_xfm.scl_bgn)
                                end_scl = crt_xfm.scl_end / init_scl;

                            ScaleAnimation sclAnm = new ScaleAnimation(crt_scl, end_scl, crt_scl, end_scl,
                                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

                            sclAnm.setDuration(crt_dur);
                            anmSet.addAnimation(sclAnm);
                        }

                        if (crt_xfm.rot_bgn != 0) {

                            float crt_rot = crt_xfm.rot_bgn;
                            float end_rot = crt_rot;

                            if (crt_xfm.rot_end != crt_xfm.rot_bgn)
                                end_rot = crt_xfm.rot_end;

                            RotateAnimation rotAnm = new RotateAnimation(crt_rot, end_rot,
                                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

                            rotAnm.setDuration(crt_dur);
                            anmSet.addAnimation(rotAnm);
                        }

                        anim_view.startAnimation(anmSet); //start animation
                    }
                }

                frm_sprt_mbr++;
            } else { // The sprite is not present
                if (!(crt_sym.aud_id != null && !crt_sym.aud_id.equals(""))) { // The sprite is graphic
                    anim_view = anmViews.get(sprt_mbr);
                    anim_view.setAlpha(0f);
                }
            }
        } else { // g1

            if (crt_frm_ordr.indexOf(sprt_id) >= 0)
                frm_sprt_mbr++;
        }
    }

    waitDur(crt_dur);
}

From source file:com.blestep.sportsbracelet.view.TimelineChartView.java

private void drawTargetLine(Canvas c) {
    if (mIsShowTargetDashedLine && mTargetValue > 0) {
        if (mTargetValue > mMaxValue) {
            Path path = new Path();
            path.moveTo(0, mTopSpaceHeight);
            path.lineTo(mGraphArea.width(), mTopSpaceHeight);
            c.drawPath(path, mGraphTargetDashedLinePaint);
        } else {/*ww  w.j  av a  2s .  c  o  m*/
            float height = mGraphArea.height();
            float y = (float) (height - (height * ((mTargetValue * 100) / mMaxValue)) / 100) + mTopSpaceHeight;
            Path path = new Path();
            path.moveTo(0, y);
            path.lineTo(mGraphArea.width(), y);
            c.drawPath(path, mGraphTargetDashedLinePaint);
        }
    }
}

From source file:de.telekom.pde.codelibrary.ui.layout.PDESwipeRefreshLayout.java

/**
 * @brief Draw Circle Path//from w  ww  .j ava  2  s  .c o  m
 */
private void drawCirclePath() {
    int width = mBounds.width();
    int height = mBounds.height();
    int cx = width / 2;
    int cy = height / 2;

    float innerRadius = 0.7f * PDEBuildingUnits.BU();
    float outerRadius = 0.9f * PDEBuildingUnits.BU();

    mCirclePath = new Path();
    mCirclePath.moveTo(cx, cy - innerRadius);
    mCirclePath.lineTo(cx, cy - outerRadius);

    mCirclePath.arcTo(new RectF(cx - outerRadius, cy - outerRadius, cx + outerRadius, cy + outerRadius), -90.0f,
            ARC_RADIUS);

    mCirclePath.lineTo((float) (cx + Math.sin(degreesToRadians(ARC_RADIUS)) * innerRadius),
            (float) (cy - Math.cos(degreesToRadians(ARC_RADIUS)) * innerRadius));

    mCirclePath.arcTo(new RectF(cx - innerRadius, cy - innerRadius, cx + innerRadius, cy + innerRadius),
            -90.0f + ARC_RADIUS, -ARC_RADIUS);
}