zoukankan      html  css  js  c++  java
  • Path相关评论的方法(一)


    以前的主要是关于Canvas的translate(平移) 、scale(缩放) 、rotate(旋转) 、skew(错切)。接下来几篇主要讲下android里的Path(封装了贝塞尔曲线)& Canvas里的drawPath(path,paint);

    非常多人听到贝塞尔曲线,就认为似乎挺高端大气上档次。后面会和大家一起揭开它的面纱,一睹真容;

    Path(路径):

    我们先看看Path类里有哪些方法



    咱们从上往下看:

    构造函数有两个。各自是

        /**
         * Create an empty path
         */
        public Path() {
            mNativePath = init1();
            mDetectSimplePaths = HardwareRenderer.isAvailable();
        }

        /**
         * Create a new path, copying the contents from the src path.
         *
         * @param src The path to copy from when initializing the new path
         */
        public Path(Path src) {
            int valNative = 0;
            if (src != null) {
                valNative = src.mNativePath;
            }
            mNativePath = init2(valNative);
            mDetectSimplePaths = HardwareRenderer.isAvailable();
        }

    这没啥好说的,另外一种就是直接复用src 里设置的属性创建一个新的Path对象。

    path.reset():清除掉path里的线条和曲线,可是不会改变它的fill-type(后面setFillType再说);

    path.rewind():清除掉path里的线条和曲线,可是会保留内部的数据结构以便重用;

    path.set(Path src);用src的内容替换原path的内容,一起看个小样例:

    创建一个path,加入一个实心圆到path里

    mEndPath = new Path();
    mEndPath.addCircle(300, 300, 100, Direction.CW);
    绘制该path:

    canvas.drawPath(mEndPath, mPaint);
    效果例如以下,无可厚非:



    此时在path里再加入一个矩形:

    mEndPath = new Path();
    mEndPath.addCircle(300, 300, 100, Direction.CW);
    mEndPath.addRect(new RectF(50, 50, 250, 200), Direction.CW);
    效果例如以下:



    做例如以下修改:

    mEndPath = new Path();
    mEndPath.addCircle(300, 300, 100, Direction.CW);
    //mEndPath.addRect(new RectF(50, 50, 250, 200), Direction.CW);
    
    mSrcPath = new Path();
    mSrcPath.addRect(new RectF(50, 50, 250, 200), Direction.CW);
    mEndPath.set(mSrcPath);
    直接执行,假设在4.0以上的机器上(4.0及以上硬件加速默认开启),会发现屏幕上什么都没有了,说明该方法会受到硬件加速的影响,关掉硬件加速,再看效果:



    以下一起来看看Path 的 FillType - 填充模式:

    android里定义了四种FillType,各自是:

     WINDING          (0),

     EVEN_ODD         (1),

     INVERSE_WINDING    (2),

     INVERSE_EVEN_ODD   (3)

    有张图能够专门用来说明这四种模式的区别:


    以上图示已经很清晰,我们还是用例如以下代码做下測试:

    mEndPath = new Path();
    mEndPath.addCircle(300, 300, 150, Direction.CW);
    mEndPath.addCircle(380, 380, 150, Direction.CW);
    mEndPath.setFillType(FillType.INVERSE_EVEN_ODD);
    
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setStyle(Style.FILL);
    mPaint.setColor(Color.RED);
    測试结果例如以下图:


    不设置FillType:

               

    setFillType(FillType.WINDING)          setFillType(FillType.EVEN_ODD): 


               

    setFillType(FillType.INVERSE_WINDING):   setFillType(FillType.INVERSE_EVEN_ODD):


    依据以上图示,Path的FillType能够总结例如以下:

    1.Path的默认FillType为 FillType.WINDING;

    2.作用的范围为绘制 Path 的 Canvas 总体。而非 path 所在区域;

    3.FillType.WINDING:取path全部所在区域;

    4.FillType.EVEN_ODD:取path所在并不相交区域;

    5.FillType.INVERSE_WINDING:取path全部未占区域;

    6.FillType.INVERSE_EVEN_ODD:取path未占或相交区域;

    以下看看和填充模式相关的几个方法:

    getFillType():不用多说。返回 Path 的填充模式;

    setFillType():设置 Path 的填充模式;

    isInverseFillType():是否是 逆 填充模式:

    WINDING 和 EVEN_ODD 返回false,INVERSE_WINDING 和 INVERSE_EVEN_ODD 返回true。

    toggleInverseFillType():切换相反的填充模式。举个小样例:

            mEndPath = new Path();
            mEndPath.addCircle(300, 300, 150, Direction.CW);
            mEndPath.addCircle(380, 380, 150, Direction.CW);
            mEndPath.setFillType(FillType.WINDING);
            mEndPath.toggleInverseFillType();
    
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setStyle(Style.FILL);
            mPaint.setColor(Color.RED);
    此时给Path设置了WINDING的填充模式,调用toggleInverseFillType()。终于的模式为:

    FillType.INVERSE_WINDING

    isEmpty():path是否为空,假设path不包括不论什么线条和曲线,则返回true,否则返回false;

    isRect(RectF rect):假设path指定的是一个rect,则返回true,否则返回false。假设返回true & rect 不为null。则将该rect设置为path 的区域;

    computeBounds(RectF bounds,boolean exact):计算path所在区域,并将结果写入bounds,假设整个path仅仅包括0或1个点,将返回(0,0,0,0):

    用例如以下代码做下測试:

            mComputeRect = new RectF();
            mEndPath = new Path();
            mEndPath.addCircle(380, 380, 150, Direction.CW);
            mEndPath.addRect(new RectF(200, 300, 500, 500), Direction.CW);
            mEndPath.computeBounds(mComputeRect, false);
            Toast.makeText(
                    mContext,
                    "" + mComputeRect.left + "," + mComputeRect.top + "," + mComputeRect.right + ","
                            + mComputeRect.bottom,
                    Toast.LENGTH_LONG).show();

    返回结果为(200,230,530,530),即path所含内容的边界区域


    incReserve(int extraPtCount):提示path将会添加extraPtCount个点。这能使path有效率的分配它的存储空间。


    好了,这篇就主要介绍这些方法。后面主要介绍 Path 里 XXXTo 和 addXXX 相关的方法,最后我们再一起用Path做个样例!














  • 相关阅读:
    Codeforces 868A Bark to Unlock
    poj 3744 Scout (Another) YYF I
    Codeforces 526F Pudding Monsters
    Codeforces 789D Weird journey
    Codeforces 827E Rusty String
    Codeforces 841D Leha and another game about graph
    bzoj 3560 DZY Loves Math V
    Codeforces 833A The Meaningless Game
    Codeforces 839D Winter is here
    Codeforces 839C Journey
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4586031.html
Copyright © 2011-2022 走看看