精华内容
下载资源
问答
  • 圆形Imagview有几种方法,这里我列举两种方法出来仅供大家参考,当然还有其它几种方法,我就不一一赘述了 1.重写onDraw(Canvas canvas)通过Canvas来画圆,传入带bitmapShaper画笔 public class ...

    圆形Imagview有几种方法,这里我列举两种方法出来仅供大家参考,当然还有其它的几种方法,我就不一一赘述了



    1.重写onDraw(Canvas canvas)通过Canvas来画圆,传入带bitmapShaper的画笔

    public class CircleImageView extends ImageView {
    
    
        public CircleImageView(Context context) {
            super(context);
            init();
        }
    
        public CircleImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
    
        private void init(){
            //创建画笔
            paint = new Paint();
            paint.setAntiAlias(true); // 防止边缘的锯齿
            paint.setColor(Color.WHITE); // 这里的颜色决定了边缘的颜色
    
            mShaderMatrix=new Matrix();
    
        }
        /**
         * 位图对象
         * */
        private Bitmap mbitmap;
        Paint paint;
    
        protected void onDraw(Canvas canvas) {
            Drawable drawable = getDrawable();
            if (drawable == null) {
                return;
            }
            if (getWidth() == 0 || getHeight() == 0) {
                return;
            }
            if(mbitmap==null){
                mbitmap=DrawableToBitmap(drawable);
               setBitmapsharder();
            }
           if(mbitmap==null)
            return;
    
            int radius=getWidth()> getHeight()?getHeight()/2:getWidth()/2;
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
        }
    
        BitmapShader mBitmapShader=null;
        private void setBitmapsharder(){
            if (mbitmap!=null&&paint!=null&&width!=0&&height!=0){
                mBitmapShader=new BitmapShader(mbitmap, Shader.TileMode.CLAMP,Shader.TileMode.CLAMP);
                paint.setShader(mBitmapShader);
    
                float scale=0;
    
                mBitmapHeight = mbitmap.getHeight();
                mBitmapWidth = mbitmap.getWidth();
                mShaderMatrix.set(null);
    
                if (width>height) {
                    if(mBitmapWidth>mBitmapHeight)
                        scale=((float)height)/mBitmapHeight;
                    else
                        scale=((float)height)/mBitmapWidth;
                } else {
                    if(mBitmapWidth>mBitmapHeight)
                        scale=((float)width)/mBitmapHeight;
                    else
                        scale=((float)width)/mBitmapWidth;
                }
                //设置图片缩放
                mShaderMatrix.setScale(scale, scale);
               //设置图片平移显示
                if(mBitmapWidth>mBitmapHeight){
                    mShaderMatrix.postTranslate(-(mBitmapWidth-mBitmapHeight)*scale/2,0);
                }else{
                    mShaderMatrix.postTranslate(0,-(mBitmapHeight-mBitmapWidth)*scale/2);
                }
                mBitmapShader.setLocalMatrix(mShaderMatrix);
    
            }
        }
        Matrix mShaderMatrix;
        private int mBitmapWidth;
        private int mBitmapHeight;
        private int height;
        private int width;
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            height=getHeight();
            width=getWidth();
            setBitmapsharder();
        }
    
    
        @Override
        public void setImageBitmap(Bitmap bm) {
            super.setImageBitmap(bm);
            mbitmap=bm;
            setBitmapsharder();
        }
        @Override
        public void setImageDrawable(Drawable drawable) {
            super.setImageDrawable(drawable);
            mbitmap=DrawableToBitmap(drawable);
            setBitmapsharder();
    
        }
    
        @Override
        public void setImageResource(int resId) {
            super.setImageResource(resId);
            mbitmap=DrawableToBitmap(getContext(),resId);
            setBitmapsharder();
        }
        @Override
        public void setImageURI(Uri uri) {
            super.setImageURI(uri);
            mbitmap=DrawableToBitmap(getDrawable());
            setBitmapsharder();
        }
    
        /**
         * Drawable转换为Bitmap
         * */
        public static  Bitmap DrawableToBitmap(Drawable drawable){
            if(drawable==null)
                return null;
            if(drawable instanceof  BitmapDrawable)
                return ((BitmapDrawable)drawable).getBitmap();
    
            Bitmap bitmap=null;
            //如果是ColorDrawable随便给一个宽高
            if(drawable instanceof  ColorDrawable)
                bitmap=Bitmap.createBitmap(2,2,Bitmap.Config.ARGB_8888);
            else
            bitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);
    
            Canvas canvas=new Canvas(bitmap);
            //设置绘制的矩形区域
            drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        }
        /**
         * Drawable转换为Bitmap
         * */
        public static  Bitmap DrawableToBitmap(Context mContext,int ResId){
            Bitmap bitmap= BitmapFactory.decodeResource(mContext.getResources(),ResId);
            return bitmap;
        }
    
    
    }

    这里的有几个核心的点有

    第一个就是ondraw里面画圆,注意圆心的坐标以及圆的半径(半径为最小)

    第二点通过setBitmapSharder方法,里面t通过Martix设置位图的缩放比例以及位图的偏移量

    关于Martix的操作

    Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在 Android的API里都提供了set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。

    set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。

    post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。

    具体怎么用的可以去参考一下片文章Android Matrix详解






    2.通过绘制圆形的Bitmap,绘制Imagvivew

    public class CircleImageView extends ImageView {
    
    
        public CircleImageView(Context context) {
            super(context);
            init();
        }
    
        public CircleImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init(){
    
            mScaleType=getScaleType();
            //创建画笔
            paint = new Paint();
            paint.setAntiAlias(true); // 防止边缘的锯齿
            paint.setColor(Color.BLACK); // 这里的颜色决定了边缘的颜色
        }
        /**
         * 位图对象
         * */
        private Bitmap mbitmap;
        Paint paint;
        private Rect rect=new Rect();
    
        ScaleType mScaleType;
        protected void onDraw(Canvas canvas) {
            Drawable drawable = getDrawable();
            if (drawable == null) {
                return;
            }
            if (getWidth() == 0 || getHeight() == 0) {
                return;
            }
            if(mbitmap==null){
                mbitmap=DrawableToBitmap(drawable);
            }
           if(mbitmap==null)
            return;
    
            int radius=getWidth()> getHeight()?getHeight()/2:getWidth()/2;
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint);
            //把圆形bitmap居中对齐
            canvas.drawBitmap(drawCircleBitmap(mbitmap, radius),  getWidth() / 2-radius,getHeight() / 2-radius, paint);
        }
    
        /*
        *画圆形的bitmap
        *
         */
        public static Bitmap drawCircleBitmap(Bitmap bmp, int radius){
            if (bmp.getWidth() != radius || bmp.getHeight() != radius){
                /**
                 * 把图片进行缩放,以宽高最小的一方为准,缩放图片比例
                 * */
               double diameter=radius*2;//获取直径
              
                if(bmp.getWidth()> bmp.getHeight()){
                    bmp = Bitmap.createScaledBitmap(bmp, (int)( diameter*bmp.getWidth()/bmp.getHeight()),  (int)diameter, false);
                }else  if(bmp.getWidth()< bmp.getHeight()){
                    bmp = Bitmap.createScaledBitmap(bmp,  (int)(diameter/bmp.getWidth()*bmp.getHeight()), (int) diameter, false);
                }else{
                    bmp = Bitmap.createScaledBitmap(bmp,  (int)diameter,  (int)diameter, false);
                }
            }
            Bitmap output = Bitmap.createBitmap(radius*2, radius*2, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
            //设置画笔全透明
            canvas.drawARGB(0, 0, 0, 0);
            Paint paints = new Paint();
            paints.setColor(Color.WHITE);
            paints.setAntiAlias(true);//去锯齿
            paints.setFilterBitmap(true);
            //防抖动
            paints.setDither(true);
    
            //把图片圆形绘制在面部中心
            canvas.drawCircle(radius, radius, radius, paints);
    
            // 取两层绘制交集。显示前景色。
            paints.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            Rect rect=new Rect();
            if(bmp.getWidth()>=bmp.getHeight()){
                rect.set(bmp.getWidth()/2-radius,0,bmp.getWidth()/2+radius,radius*2);
            }else{
                rect.set(0,bmp.getHeight()/2-radius,radius*2,bmp.getHeight()/2+radius);
            }
            Rect rect2=new Rect(0,0,radius*2,radius*2);
            //第一个rect 针对bmp的绘制区域,rect2表示绘制到上面位置
            canvas.drawBitmap(bmp, rect, rect2, paints);
            bmp.recycle();
            return output;
        }
    
        /**
         * 设置显示类型
         * */
        @Override
        public void setScaleType(ScaleType scaleType) {
            super.setScaleType(scaleType);
            mScaleType=scaleType;
        }
    
        @Override
        public void setImageBitmap(Bitmap bm) {
            super.setImageBitmap(bm);
            mbitmap=bm;
        }
        @Override
        public void setImageDrawable(Drawable drawable) {
            super.setImageDrawable(drawable);
            mbitmap=DrawableToBitmap(drawable);
        }
    
        @Override
        public void setImageResource(int resId) {
            super.setImageResource(resId);
            mbitmap=DrawableToBitmap(getContext(),resId);
        }
        @Override
        public void setImageURI(Uri uri) {
            super.setImageURI(uri);
            mbitmap=DrawableToBitmap(getDrawable());
        }
    
    
    
    
    
        /**
         * Drawable转换为Bitmap
         * */
        public static  Bitmap DrawableToBitmap(Drawable drawable){
            if(drawable==null)
                return null;
            if(drawable instanceof  BitmapDrawable)
                return ((BitmapDrawable)drawable).getBitmap();
    
            Bitmap bitmap=null;
            //如果是ColorDrawable随便给一个宽高
            if(drawable instanceof  ColorDrawable)
                bitmap=Bitmap.createBitmap(2,2,Bitmap.Config.ARGB_8888);
            else
            bitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),Bitmap.Config.ARGB_8888);
    
            Canvas canvas=new Canvas(bitmap);
            //设置绘制的矩形区域
            drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        }
        /**
         * Drawable转换为Bitmap
         * */
        public static  Bitmap DrawableToBitmap(Context mContext,int ResId){
            Bitmap bitmap= BitmapFactory.decodeResource(mContext.getResources(),ResId);
            return bitmap;
        }
    
    }
    

    这个中绘制方法更简单我觉得可以不用重新Imagview就可以实现,把drawCircleBitmap方法就行封装一下得到圆形的bitmap然后在设置给Imageveiw就可以实现了绘制好之后记得把之前的的bitmap给reclye了

    这里画圆形view使用是在画布上面画一个圆,然后把bitmap也画上去,然后去交叉前景图

    具体paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN))

    这里面的几种交叉取景可以参考Android Paint之 setXfermode PorterDuffXfermode 讲解这篇文字



    3.还要其他的几种方式,比如画一个中间透明的圆形遮盖在上面等等



    展开全文
  • 2.4 圆的生成—Bresenham算法 57 2.5 椭圆的生成 64 2.6 一般函数的光栅化 69 2.7 扫描转换—显示的生成 71 2.7.1 实时扫描转换 71 2.7.2 使用指针的简单活化边表 72 2.7.3 排序活化边表 72 2.7.4 使用链表...
  • 2D绘图基础

    2017-12-25 16:53:00
    它提供了各种绘制图形API,如drawPoint(点)、drawLine(线)、drawRect(矩形)、drawVertices(多边形)、drawArc(弧)、drawCircle(),等等。通过它们名字,基本上可以大致了解他们功能。当然,Paint作为一个非常...

            系统通过提供Canvas对象来提供绘图方法。它提供了各种绘制图形的API,如drawPoint(点)、drawLine(线)、drawRect(矩形)、drawVertices(多边形)、drawArc(弧)、drawCircle(圆),等等。通过它们的名字,基本上可以大致了解他们的功能。当然,Paint作为一个非常重要的元素,功能也是很强大的,这里简单地列举了一些它的属性和对象的功能。

    • setAntiAlias();    //设置画笔的锯齿效果
    • setColor();         //设置画笔的颜色
    • setARGB();        //设置画笔的A、R、G、B值
    • setAlpha();         //设置画笔的Aplha值
    • setTextSize();    //设置字体尺寸
    • setStyle();          //设置画笔的风格
    • setStrokeWidth();//设置空心边框的宽度

            正式由于画笔的功能的不一样,再结合各种不同的绘图API。这样任意组合就可以实现不同的绘图效果,如果同样是矩形,设置Paint的Style,就可以画出是空心还是实心的矩形。

            如下图,就是使用如下代码绘制出来的效果。

    paint.setStyle(Paint.Style.STROKE);

            同样的参数如果使用如下代码来设置Paint的属性。那么绘制出来的效果如下图所示。

    paint.setStyle(Paint.Style.FILL);


            上面我们初步了解了绘制不同图形的基本方法,下面来重点看看Canvas家族的各个成员们。

    • DrawPoint,绘制点。
    canvas.drawPoint(x,y,paint);

    • DrawLine,绘制直线
    canvas.drawLine(startX,startY,endX,endY,paint);

    • DrawLines,绘制多条直线
    float[] pts = {
        startX1,startY1,endX1,endY1,
        ...
        startXN,startYN,endXN,endYN
    };
    canvas.drawLine(pts,paint);

    • DrawRect,绘制矩形,效果如图6.6所示。
    canvas.drawRect(left,top,right,bottom,paint,paint);

    • DrawRoundRect,绘制圆角矩形
    canvas.drawRoundRect(left,top,right,bottom,radiusX,radiusY,paint);

    • DrawCircle,绘制圆
    canvas.drawCircle(circleX,circleY,radois,paint);

    • DrawArc,绘制弧线、扇形,其中startAngle为开始的弧度,sweepAngle为圆弧的角度,注释如下所示。
    paint.setStyle(Paint.Style.STROKE);
    canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);

           

            这里需要注意下,绘制弧形与扇形的区分就是倒数第二个参数useCenter的区别,如下图所示,即为使用不同的Paint.Style和useCenter属性产生的不同效果

    Paint.Style.STROKE 和 useCenter为true
    Paint.Style.STROKE 和 useCenter为false


    Paint.Style.FILL 和 useCenter为true
    Paint.Style.FILL 和 useCenter为false


    • DrawOval,绘制椭圆
    //通过椭圆的外接矩形来绘制椭圆
    canvas.drawOval(left,top,right,bottom,paint);


    • DrawText,绘制文本。
    canvas.drawText(text,startX,startY,paint);


    • DrawPosText,在指定位置绘制文本。
    canvas.drawPosText(text,
            new float[]{X1,Y1,
                            X2,Y2
                            ......
                            Xn,Yn},
             paint);


      

    • DrawPath,绘制路径
    Path path = new Path();
    path.moveTo(50,50);
    path.lineTo(100,100);
    path.lineTo(100,300);
    path.lineTo(300,500);
    canvas.drawPath(path,paint);





















    展开全文
  • 实例006 绘制指定角度填充扇形 8 实例007 绘制多边形 9 实例008 绘制二次曲线 10 实例009 绘制三次曲线 12 实例010 绘制文本 13 实例011 设置文本字体 14 实例012 设置文本和图形颜色 15 1.2 笔画和图形处理 ...
  • 实例212 重写父类中的方法 实例213 计算几何图形的面积 实例214 简单的汽车销售商场 实例215 利用拷贝构造函数简化实例创建 实例216 访问类中私有成员的函数 实例217 实现类的加法运算 实例218 在类中实现...
  • 实例212 重写父类中的方法 实例213 计算几何图形的面积 实例214 简单的汽车销售商场 实例215 利用拷贝构造函数简化实例创建 实例216 访问类中私有成员的函数 实例217 实现类的加法运算 实例218 在类中实现...
  • 分析了直线、、圆弧和样条曲线向多段线的转化,提供了一些常用的多段线操作,提出制图法解决问题的新思路,编写了根据起点、终点和弧长创建圆弧的函数,最后又给出绘制放样展开图的方法。 第4章包含了两个有用的...
  • Microsoft C# Windows程序设计(上下册)

    热门讨论 2011-08-05 10:28:13
    13.4 使用贝塞尔曲线绘制圆和弧 13.5 贝塞尔艺术作品 13.6 数学推导 13.7 标准样条曲线 13.8 标准样条曲线公式推导 第十四章 菜单 14.1 菜单和菜单项 14.2 菜单快捷键 14.3 第一个菜单 14.4 非...
  • 22 操作图像中像素的方法二:用迭代器操作像素 5.1.5、5.1.6 23 操作图像中像素的方法三:动态地址计算 5.1.5、5.1.6 24 遍历图像中像素的14种方法 5.1.6 25 初级图像混合 5.2.4 26 多通道图像混合 5.3.3 27 ...
  • Delphi7应用编程150例

    2018-04-05 15:23:33
    使用本书最好的方法是通过学习掌握实例中的技术或技巧,然后使用这些技术尝试实现更复杂的功能并应用到更多方面。 本书内容丰富、结构合理,可以作为广大编程爱好者提高编程水平的自学教材,也可以供程序开发人员和...
  • EXCEL 2007 宝典 附光盘文件

    热门讨论 2010-04-02 14:43:05
    depreciation.xlsx:一个演示计算资产折旧的方法的工作簿。 investment calculations.xlsx:一个演示计算投资利润的公式的工作簿。 irregular payments.xlsx:一个演示不规则还款的贷款计算的工作簿。 loan ...
  • 实例144 Object类中线程相关的方法 187 实例145 哲学家就餐问题 189 实例146 使用信号量实现线程同步 190 实例147 使用原子变量实现线程同步 191 实例148 使用事件分配线程更新Swing控件 193 实例149 使用...
  • 实例144 Object类中线程相关的方法 187 实例145 哲学家就餐问题 189 实例146 使用信号量实现线程同步 190 实例147 使用原子变量实现线程同步 191 实例148 使用事件分配线程更新Swing控件 193 实例149 使用...
  • 实例068 列举SQL Server数据库中数据表 实例069 列举MySQL数据库中数据表 实例070 查看数据表结构 实例071 动态维护投票数据库 实例072 SQL Server数据库备份 实例073 SQL Server数据库恢复 实例074 MySQL...
  • 实例144 Object类中线程相关的方法 实例145 哲学家就餐问题 实例146 使用信号量实现线程同步 实例147 使用原子变量实现线程同步 实例148 使用事件分配线程更新Swing控件 实例149 使用SwingWorker类完成耗时...
  • 实例144 Object类中线程相关的方法 实例145 哲学家就餐问题 实例146 使用信号量实现线程同步 实例147 使用原子变量实现线程同步 实例148 使用事件分配线程更新Swing控件 实例149 使用SwingWorker类完成耗时...
  • 实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 图像...
  • C#程序开发范例宝典(第2版).part02

    热门讨论 2012-11-12 07:55:11
    实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ...
  • C#程序开发范例宝典(第2版).part13

    热门讨论 2012-11-12 20:17:14
    实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ...
  • 实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ...
  • 实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 185 4.3 ...
  • 程序开发范例宝典>>

    2012-10-24 10:41:28
    实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换...
  • 实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 ...
  • 实例121 波形图的绘制 179 4.2 图形转换 180 实例122 BMP转换成JPG格式 181 实例123 JPG转换成BMP格式 182 实例124 位图转化为WMF格式 183 实例125 ICO文件转化为位图 184 实例126 图片批量转换工具 ...
  • Java开发实战1200例.第2卷.part3

    热门讨论 2013-05-08 22:46:34
    实例068 列举SQL Server数据库中数据表 133 实例069 列举MySQL数据库中数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库备份 139 实例073 SQL Server数据库...
  • Java开发实战1200例.第2卷.part2

    热门讨论 2013-05-08 22:45:35
    实例068 列举SQL Server数据库中数据表 133 实例069 列举MySQL数据库中数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库备份 139 实例073 SQL Server数据库...
  • Java开发实战1200例.第2卷.part1

    热门讨论 2013-05-08 22:44:13
    实例068 列举SQL Server数据库中数据表 133 实例069 列举MySQL数据库中数据表 134 实例070 查看数据表结构 135 实例071 动态维护投票数据库 136 实例072 SQL Server数据库备份 139 实例073 SQL Server数据库...
  • 看到网上有个方案说:主项目负责加载组件,由于主项目和组件之间是隔离,那么主项目如何调用组件ApplicationLike生命周期方法呢,目前采用是基于编译期字节码插入方式,扫描所有ApplicationLike类(其有一...
  • C#.net_经典编程例子400个

    热门讨论 2013-05-17 09:25:30
    165 实例113 波形图的绘制 166 4.2 图形转换 168 实例114 BMP转换成JPG格式 168 实例115 JPG转换成BMP格式 170 实例116 位图转化为WMF 171 实例117 Ico文件转化为位图 172 实例118...
  • C#编程经验技巧宝典

    热门讨论 2008-06-01 08:59:33
    C#编程经验技巧宝典源代码,目录如下: 第1章 开发环境 1 <br>1.1 Visual Studio开发环境安装与配置 2 <br>0001 安装Visual Studio 2005开发环境须知 2 <br>0002 配置合适Visual Studio 2005...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

列举绘制圆的方法