之前遇到一個公司讓畫價格曲線圖,除了用OpenGL就是用Quartz2D,OpenGL還是傾向去底層的api這個比較低級。大家如果不是做游戲還是用一些封裝比較好的東西。Quartz2D就可以滿足你的要求,基本的曲線,各種圖形的繪制,橡皮擦等等。Quartz2D還有一個corepolt的開源庫應該是基於Quartz2D的。以下是官方網站的文檔譯文:
Paths中的幾個重要元素Pointsvoid CGContextMoveToPoint ( CGContextRef c, CGFloat x, CGFloat y);指定一個點成為current pointQuartz會跟蹤current point一般執行完一個相關函數后,current point都會相應的改變.Lines相關的幾個函數void CGContextAddLineToPoint ( CGContextRef c, CGFloat x, CGFloat y);創建一條直線,從current point到 (x,y)然后current point會變成(x,y)void CGContextAddLines ( CGContextRef c, const CGPoint points[], size_t count);創建多條直線,比如points有兩個點,那么會畫兩條直線 從current point到 (x1,y1),然后是(x1,y1)到(x2,y2)
然后current point會變成points中的最后一個點
Arcs兩種方法創建弧度 第一種void CGContextAddArc ( CGContextRef c, CGFloat x, //圓心的x坐標 CGFloat y, //圓心的x坐標 CGFloat radius, //圓的半徑 CGFloat startAngle, //開始弧度 CGFloat endAngle, //結束弧度 int clockwise //0表示順時針,1表示逆時針);假如想創建一個完整的圓圈,那么 開始弧度就是0 結束弧度是 2pi, 因為圓周長是 2*pi*r.最后,函數執行完后,current point就被重置為(x,y).還有一點要注意的是,假如當前path已經存在一個subpath,那么這個函數執行的另外一個效果是會有一條直線,從current point到弧的起點 第二種void CGContextAddArcToPoint ( CGContextRef c, CGFloat x1,//端點1的x坐標 CGFloat y1,//端點1的y坐標 CGFloat x2,//端點2的x坐標 CGFloat y2,//端點2的y坐標 CGFloat radius//半徑);原理:首先畫兩條線,這兩條線分別是 current point to (x1,y1) 和(x1,y1) to (x2,y2).這樣就是出現一個以(x1,y1)為頂點的兩條射線,然后定義半徑長度,這個半徑是垂直於兩條射線的,這樣就能決定一個圓了,更好的理解看下圖,不過個人認為下圖所標的 tangent point 1的位置是錯誤的。最后,函數執行完后,current point就被重置為(x2,y2).還有一點要注意的是,假如當前path已經存在一個subpath,那么這個函數執行的另外一個效果是
會有一條直線,從current point到(x1,y1)
Curves畫曲線,一般是一條直線,然后定義幾個控制點,使直線變彎曲。三次曲線函數void CGContextAddCurveToPoint ( CGContextRef c, CGFloat cp1x,//控制點1 x坐標 CGFloat cp1y,//控制點1 y坐標 CGFloat cp2x,//控制點2 x坐標 CGFloat cp2y,//控制點2 y坐標 CGFloat x,//直線的終點 x坐標 CGFloat y//直線的終點 y坐標);
假如第二個控制點(cp2x,cp2y)比(cp1x,cp1y) 更接近current point,那么會形成一個封閉的曲線
二次曲線函數void CGContextAddQuadCurveToPoint ( CGContextRef c, CGFloat cpx,//控制點 x坐標 CGFloat cpy,//控制點 y坐標 CGFloat x,//直線的終點 x坐標 CGFloat y//直線的終點 y坐標);執行完函數貌似current point不會變化,沒有具體測試過Ellipsesvoid CGContextAddEllipseInRect ( CGContextRef context, CGRect rect//一矩形);如果矩形是一個正方形,那么畫出來就是一個圓執行完函數貌似current point不會變化,沒有具體測試過Rectanglesvoid CGContextAddRect ( CGContextRef c, CGRect rect);一次性畫出多個矩形void CGContextAddRects ( CGContextRef c, const CGRect rects[], size_t count);需要注意的是,畫矩形有一些特別,current point沒有發生變化
Creating a Path調用函數 CGContextBeginPath 開始創建路徑,線調用函數CGContextMoveToPoint設置起點然后開始畫自己想畫的路徑,注意一下幾點:1.Lines, arcs, and curves,是從current point開始的2.假如想封閉一條路徑,那么調用函數 CGContextClosePath 把當前點和起點連接起來3.當在畫 arcs的時候,Quartz會畫一條線從current point 到 starting point4.畫矩形的時候不會有第三條那這樣的的一條直線5.創建完路徑后,必須調用 painting 函數 fill or stroke the path,不然不會畫上面東東在相應的設備上】6.開始創建一個新的路徑的時候,使用函數 CGContextBeginPath。重復利用路徑的相關函數和數據類型CGPathCreateMutable 類似於 CGContextBeginPathCGPathMoveToPoint 類似於 CGContextMoveToPointCGPathAddLineToPoint 類似於 CGContextAddLineToPointCGPathAddCurveToPoint 類似於 CGContextAddCurveToPointCGPathAddEllipseInRect 類似於 CGContextAddEllipseInRectCGPathAddArc 類似於 CGContextAddArcCGPathAddRect 類似於 CGContextAddRectCGPathCloseSubpath 類似於 CGContextClosePathCGPathRefCGMutablePathRef用CGContextAddPath函數把一個路徑添加到graphics context中void CGContextAddPath ( CGContextRef context, CGPathRef path);
Painting a PathStroking :畫出路徑Filling :填充路徑的封閉區域影響Stroking的參數Line widthvoid CGContextSetLineWidth ( CGContextRef c, CGFloat width);Line join:線轉彎的時候的樣式,比如圓滑的方式void CGContextSetLineJoin ( CGContextRef c, CGLineJoin join);
Line cap:線的兩端的樣式,比如兩端變的圓滑void CGContextSetLineCap ( CGContextRef c, CGLineCap cap);
Miter limit:當Line join的模式是Miter join的時候,這個參數會有影響void CGContextSetMiterLimit ( CGContextRef c, CGFloat limit);Line dash pattern:虛線相關void CGContextSetLineDash ( CGContextRef c, CGFloat phase, const CGFloat lengths[], size_t count);
Stroke color spacevoid CGContextSetStrokeColorSpace ( CGContextRef c, CGColorSpaceRef colorspace);Stroke colorvoid CGContextSetStrokeColor ( CGContextRef c, const CGFloat components[]);void CGContextSetStrokeColorWithColor ( CGContextRef c, CGColorRef color);Stroke pattern(和透明度相關)void CGContextSetStrokePattern ( CGContextRef c, CGPatternRef pattern, const CGFloat components[]);
Stroking的相關函數Strokes當前path.void CGContextStrokePath ( CGContextRef c);Strokes 指定的 矩形.void CGContextStrokeRect ( CGContextRef c, CGRect rect);Strokes 指定的 矩形, 使用指定的寬度.void CGContextStrokeRectWithWidth ( CGContextRef c, CGRect rect, CGFloat width);Strokes 指定的橢圓.void CGContextStrokeEllipseInRect ( CGContextRef context, CGRect rect);Strokes 一些直線.void CGContextStrokeLineSegments ( CGContextRef c, const CGPoint points[], size_t count);決定是Stroking 還是Fillingvoid CGContextDrawPath ( CGContextRef c, CGPathDrawingMode mode);