绘图基础,绘制基础

时间:2019-11-21 20:33来源:永利皇宫463手机版
Bitmap 资料来自:扔物线的工夫分享http://hencoder.com/ 线上箭头表示画线的方向。WINDING方式和ALTE福睿斯NATE情势都会填充两个密闭的L型区域,号码从1到3。三个更加小的中间区域,号码为

图片 1

Bitmap

资料来自:扔物线的工夫分享 http://hencoder.com/

线上箭头表示画线的方向。WINDING方式和ALTE福睿斯NATE情势都会填充两个密闭的L型区域,号码从1到3。三个更加小的中间区域,号码为4和5,在ALTE大切诺基NATE形式下不被填充。不过在WINDING方式下,号码5的区域会被填充,那是因为区域的内部抵达图形的外表必得高出两条相似方向的线。号码为4的区域不会被填充,因为射线必需越过两条边框线,但是这两条边框线的绘图方向相反。

UI-1 Drawing

图片 2图片 3

自定义绘制技巧点总括:

主意:重写绘制方法,此中最常用的是 onDraw()

关键: Canvas 的使用

  1, Canvas 的绘图类情势: drawXXX() (关键参数:Paint卡塔尔

  2,Canvas 的扶植类方法:范围裁切(clipXXX()卡塔尔国和几何转变

抵补:使用分裂的绘图方法来调节遮掩关系

  1 /*-------------------------------------------
  2 ALTWIND.C -- Alternate and Winding Fill Modes
  3              (c) Charles Petzold, 1998
  4 -------------------------------------------*/
  5 
  6 #include <Windows.h>
  7 
  8 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  9 
 10 int WINAPI WinMain( __in HINSTANCE hInstance
 11                     , __in_opt HINSTANCE hPrevInstance
 12                     , __in LPSTR lpCmdLine
 13                     , __in int nShowCmd )
 14 {
 15     static TCHAR szAppName[] = TEXT("AltWind");
 16     HWND hwnd;
 17     MSG msg;
 18     WNDCLASS wndclass;
 19 
 20     wndclass.style = CS_HREDRAW | CS_VREDRAW;
 21     wndclass.lpfnWndProc = WndProc;
 22     wndclass.cbClsExtra = 0;
 23     wndclass.cbWndExtra = 0;
 24     wndclass.hInstance = hInstance;
 25     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 26     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
 27     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 28     wndclass.lpszMenuName = NULL;
 29     wndclass.lpszClassName = szAppName;
 30 
 31     if (!RegisterClass(&wndclass))
 32     {
 33         MessageBox(NULL, TEXT("Program requires Windows NT!")
 34             , szAppName, MB_ICONERROR);
 35         return 0;
 36     }
 37 
 38     hwnd= CreateWindow(szAppName, TEXT("Alternate and Winding Fill Modes")
 39         , WS_OVERLAPPEDWINDOW
 40         , CW_USEDEFAULT, CW_USEDEFAULT
 41         , CW_USEDEFAULT, CW_USEDEFAULT
 42         , NULL, NULL, hInstance, NULL);
 43 
 44     ShowWindow(hwnd, nShowCmd);
 45     UpdateWindow(hwnd);
 46 
 47     while (GetMessage(&msg, NULL, 0, 0))
 48     {
 49         TranslateMessage(&msg);
 50         DispatchMessage(&msg);
 51     }
 52 
 53     return msg.wParam;
 54 }
 55 
 56 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 57 {
 58     static POINT aptFigure[10] = {10, 70
 59                                 , 50, 70
 60                                 , 50, 10
 61                                 , 90, 10
 62                                 , 90, 50
 63                                 , 30, 50
 64                                 , 30, 90
 65                                 , 70, 90
 66                                 , 70, 30
 67                                 , 10, 30};
 68     static int cxClient, cyClient;
 69     HDC hdc;
 70     int i;
 71     PAINTSTRUCT ps;
 72     POINT apt[10];
 73 
 74     switch (message)
 75     {
 76     case WM_SIZE:
 77         cxClient = LOWORD(lParam);
 78         cyClient = HIWORD(lParam);
 79         return 0;
 80 
 81     case WM_PAINT:
 82         hdc = BeginPaint(hwnd, &ps);
 83         SelectObject(hdc, GetStockObject(GRAY_BRUSH));
 84 
 85         for (i = 0; i !=10; ++i)
 86         {
 87             apt[i].x = cxClient * aptFigure[i].x / 200;
 88             apt[i].y = cyClient * aptFigure[i].y / 100;
 89         }
 90         SetPolyFillMode(hdc, ALTERNATE);
 91         Polygon(hdc, apt, 10);
 92 
 93         for (i = 0; i != 10; ++i)
 94         {
 95             apt[i].x += cxClient / 2;
 96         }
 97         SetPolyFillMode(hdc, WINDING);
 98         Polygon(hdc, apt, 10);
 99 
100         EndPaint(hwnd, &ps);
101         return 0;
102 
103     case WM_DESTROY:
104         PostQuitMessage(0);
105         return 0;
106     }
107 
108     return DefWindowProc(hwnd, message, wParam, lParam);
109 }

学习进程:

1,Canvas 的 drawXXX() 连串措施及Paint最平淡无奇的接受;

2,Paint的进级计谋;

3,Canvas对绘制的提携——范围裁切和几何转换;

4,使用不相同的绘图方法来决定绘制顺序;


ALTWIND.C

丨一切的开头:onDraw()

    别漏写了super.onDraw()。

图片的坐标(按贰个100*100单位的区域设定卡塔尔国存款和储蓄在aptFigure数组中。那个坐标会根据客商去的上升的幅度和中度按比例缩放。程序展现七个图形,三个运用ALTE汉兰达NATE填充方式,另三个运用WINDING填充格局。结果如图:

丨Canvas.drawXXX() 和 Paint 基础

    Paint.setStyle(Style style)设置绘制形式():Paint.style.FILL、STROKE、FILL_AND_STROKE

    Paint.setColor(int color)设置颜色

    Paint.setStrokeWidth(float width)设置线条宽度

    Paint.setTextSize(float textSize)设置文字大小

    Paint.setAnti阿里as(boolean aa)设置抗锯齿开关        能够在创设刻Paint paint=new Paint(Paint.ANTI_ALIAS_FLAG);


图片 4

Canvas.drawColor()、Canvas.drawRGB()、Canvas.drawARGB():

效果与利益整个绘制区域,用于绘制中期设置背景底色或绘制中期设置蒙板;


drawCircle(float centerX, float centerY, float radius, Paint paint):

xy设置圆心,以view的左顶点为坐标系原点,radius设置半径;

留心:Paint能做的早期交给Paint去做,drawXXX方法参数尽量只含有特有的特性如圆心半径;


drawRect(float left, float top, float right, float bottom, Paint paint) 

left,top,right,bottom是矩形四条边相对于xyxy轴的坐标;

三个重载方法drawRect(RectF rect, Paint paint)和drawRect(Rect rect, Paint paint),能够直接填写RectF或Rect对象来绘制矩形;


drawPoint(float x, float y, Paint paint)

点的尺寸可以经过paint.setStrokeWidth(width)来安装;

点的模样能够透过paint.setStrokeCap(cap)来安装,端点有圆头 (ROUND)、大背头(BUTT) 和方头 (SQUARE) 两种;

FILL形式下的drawCircle()和drawRect()也能达到平等功效,按偏好选拔;


drawPoints(float[] pts, Paint paint) 批量画点

drawPoints(float[] pts, int offset, int count, Paint paint) 

float[] points={0,0,50,50,50,100,100,50,100,100,150,50,150,100};// 绘制三个点:(50, 50) (50, 100) (100, 50) (100, 100)

canvas.drawPoints(points,2/* 跳过多少个数,即前五个 0 */,8/* 大器晚成共绘制 8 个数(4 个点卡塔尔国*/, paint);


drawOval(float left, float top, float right, float bottom, Paint paint) 画椭圆

重载方法drawOval(RectF rect, Paint paint),能够一贯填写RectF来绘制椭圆;


drawLine(float startX, float startY, float stopX, float stopY, Paint paint) 画线

起源终点的坐标

drawLines(float[] pts, Paint paint) 批量画线

drawLines(float[] pts, int offset, int count, Paint paint) 


drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) 圆角矩形

left,top,right,bottom是四条边的坐标,rx和ry是圆角的横向半径和纵向半径;

重载方法drawRoundRect(RectF re


ct, float rx, float ry, Paint paint),让你能够向来填写RectF来绘制圆角矩形;


drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) 绘制弧形或扇形

drawArc()是应用三个椭圆来描述弧形的。left,top,right,bottom描述的是那一个弧形所在的椭圆;

startAngle是弧形的序幕角度(x 轴的正向,即正右的主旋律,是 0 度的职分;顺时针为正角度,逆时针为负角度卡塔尔;

sweepAngle是弧形划过的角度;

useCenter代表是或不是连接到圆心,借使不连选取圆心,正是弧形,假若老是到圆心,便是扇形。

注:通过 userCenter 的 true 或 false  +  Paint 的 stroke或 fill 能够画出 空心扇形、仅描边弧形、实心扇形、封口弧形;



丨drawPath(Path path, Paint paint) 画自定义图形

当上边的办法不能够满意绘制目的时用这些;

透过陈述路线的议程来绘制图形,它的path参数正是用来描述图形路线的对象;

Path能够描述直线、二遍曲线、一回曲线、圆、椭圆、弧形、矩形、圆角矩形。把那些图片组成起来,就可以描述出过多千头万绪的图片;


帕特h 方法第生龙活虎类:直接描述路径

1,addXxx(卡塔尔加多子图形

.addCircle (float x, float y, float radius, Direction dir) 添加圆

.addOval (float left, float top, float right, float bottom, Direction dir) / addOval(RectF oval, Direction dir) 增加椭圆

.addRect (float left, float top, float right, float bottom, Direction dir) / addRect(RectF rect, Direction dir) 增多矩形

.addRoundRect (RectF rect, float rx, float ry, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Direction dir) / addRoundRect(RectF rect, float[] radii, Direction dir) / addRoundRect(float left, float top, float right, float bottom, float[] radii, Direction dir) 加多圆角矩形

.addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle) / addArc(RectF oval, float startAngle, float sweepAngle) 增加弧形

.addPath(Path path) 增添另三个 Path

2,xxxTo()——画线(直线或曲线卡塔尔

.lineTo(float x, float y) / rLineTo(float x, float y) 画直线;

从此以往时此刻职分向指标地方画一条直线,x和y是目之处的坐标。那多少个艺术的区别是,lineTo(x, y)的参数是相对坐标,而rLineTo(x, y)的参数是相持当前地点的周旋坐标(前缀 r 指的就是relatively「相对地」),也正是偏离;

.quadTo(float x1, float y1, float x2, float y2) / rQuadTo(float dx1, float dy1, float dx2, float dy2) 画一回贝塞尔曲线;

.cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) / rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 画三遍贝塞尔曲线;

.moveTo(float x, float y) / rMoveTo(float x, float y) 移动到指标地点;

.arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo) / arcTo(RectF oval, float startAngle, float sweepAngle) 画弧形

和 Canvas.drawArc()比起来,少了一个参数 useCenter,表示只用来画弧线;多了贰个参数 forceMoveTo,true表示拖着画笔到弧形的源点,false表示抬起画笔从弧形起源开首画;

addArc()相当于 forceMoveTo = true的 arcTo();

.close(卡塔尔国将绘制轨迹的终端与源点实行再而三,约等于lineTo(源点卡塔尔国;

注:当Paint设置style为fill时会自动密闭填充;


帕特h 方法第二类:支持的安装或总计

.setFillType(Path.FillType ft) 用来安装图形自相交时的填写算法,别的应用少之甚少;

FillType有4个值:WINDING(默认)、EVEN_ODD、INVERSE_WINDING、INVERSE_EVEN_ODD

WINDING是「全填充」,而EVEN_ODD是「交叉填充」:

图片 5

EVEN_ODD 和 WINDING 的切实原理

EVEN_ODD

即 even-odd rule (奇偶原则卡塔尔:对于平面中的任性一点,向自由方向射出一条射线,那条射线和图纸相交的次数(相交才算,相切不算哦卡塔 尔(英语:State of Qatar)假诺是奇数,则那一个点被感觉在图纸内部,是要被涂色的区域;要是是偶数,则这几个点被感觉在图片外部,是不被涂色的区域。还以左右会友的双圆为例:

图片 6

射线的主旋律无所谓,同贰个点射向任何方向的射线,结果都以雷同的,不相信你可以施行。

从上图能够阅览,射线每穿过图形中的一条线,内外状态就生出三遍切换,那就是为什么EVEN_ODD是八个「交叉填充」的格局。

WINDING

即 non-zero winding rule (非零环绕数原则卡塔 尔(英语:State of Qatar):首先,它须求您图形中的全体线条都以有绘制方向的:

图片 7

下一场,同样是从平面中的点向任性方向射出一条射线,但计算法规不均等:以 0 为初阶值,对于射线和图片的具备交点,蒙受种种顺时针的交点(图形从射线的左臂向右穿过卡塔 尔(英语:State of Qatar)把结果加 1,碰到每种逆时针的交点(图形从射线的右偏向左穿过卡塔 尔(阿拉伯语:قطر‎把结果减 1,最后把富有的交点都算上,得到的结果风流洒脱旦不是 0,则以为那个点在图纸内部,是要被涂色的区域;如果是 0,则认为那一个点在图纸外界,是不被涂色的区域。

图片 8

和EVEN_ODD相仿,射线的大势并不影响结果。

进而,小编这段日子的可怜「简单冷酷」的下结论,对于WINDING来讲并不完全正确:假如你有着的图片都用平等的自由化来绘制,那么WINDING确实是三个「全填充」的准则;但万大器晚成使用不一致的趋平素绘制图形,结果就不一样样了。

图表的样子:对于增添子图形类方法(如Path.addCircle()Path.addRect()卡塔 尔(阿拉伯语:قطر‎的大方向,由艺术的dir参数来决定,这么些在近期早就讲过了;而对此画线类的不二诀窍(如Path.lineTo()Path.arcTo()卡塔尔就更轻便了,线的取向正是图片的取向。

故此,完整版的EVEN_ODD和WINDING的效应应该是那般的:

图片 9

而INVERSE_EVEN_ODD和INVERSE_WINDING,只是把那二种效应举办反转而已,懂了EVEN_ODD和WINDING,自然也就懂INVETucsonSE_EVEN_ODD和INVERSE_WINDING了,扔物线就不讲了。



丨drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 绘制 Bitmap

drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)

drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)



丨drawText(String text, float x, float y, Paint paint) 绘制文字

能够使用Paint设置textSize

编辑:永利皇宫463手机版 本文来源:绘图基础,绘制基础

关键词: