2016-04-23 23 views
4

我試圖在OSX上繪製使用核心圖形的速度表的元素。我幾乎可以得到它,但需要一些關於儀表內部中心刻度的幫助。這裏是我想要做的圖像:在NSX中在OSX上繪製帶有核心圖形的車速表

enter image description here

這裏是什麼,我這麼遠的圖像:

enter image description here

我知道如何繪製圓環以及如何繪製圍繞量表中心的線段,如下所示:

- (void)drawOuterGaugeRingsInRect:(CGContextRef)contextRef rect:(NSRect)rect { 


    CGContextSetLineWidth(contextRef,self.gaugeRingWidth); 

    CGContextSetStrokeColorWithColor(contextRef, [MyColors SpeedGaugeOuterRingGray].CGColor); 
    CGFloat startRadians = 0; 
    CGFloat endRadians = M_PI*2; 
    CGFloat radius = self.bounds.size.width/2 - 5; 

    CGContextAddArc(contextRef, CGRectGetMidX(rect),CGRectGetMidY(rect),radius,startRadians,endRadians,YES); 
    //Render the outer gauge 
    CGContextStrokePath(contextRef); 

    //Draw the inner gauge ring. 
    radius -= self.gaugeRingWidth; 
    CGContextSetStrokeColorWithColor(contextRef, [MyColors SpeedGaugeInnerRingGray].CGColor); 
    CGContextAddArc(contextRef, CGRectGetMidX(rect),CGRectGetMidY(rect),radius,startRadians,endRadians,YES); 

    //Render the inner gauge 
    CGContextStrokePath(contextRef); 

    radius -= self.gaugeRingWidth; 

    //Draw and fill the gauge background 

    CGContextSetFillColorWithColor(contextRef, [MyColors SpeedGaugeCenterFillBlack ].CGColor); 
    CGContextSetStrokeColorWithColor(contextRef, [MyColors SpeedGaugeCenterFillBlack].CGColor); 
    CGContextAddArc(contextRef, CGRectGetMidX(rect),CGRectGetMidY(rect),radius,startRadians,endRadians,YES); 

    //Render and fill the gauge background 
    CGContextDrawPath(contextRef, kCGPathFillStroke); 


    /*BLUE CIRCULAR DIAL */ 
    //Prepare to draw the blue circular dial. 
    radius -= self.gaugeRingWidth/2; 

    //Adjust gauge ring width 
    CGContextSetLineWidth(contextRef,self.gaugeRingWidth/2); 

    CGContextSetStrokeColorWithColor(contextRef, [MyColors SpeedGaugeBlue].CGColor); 

    CGFloat startingRadians = [MyMathHelper degressToRadians:135]; 
    CGFloat endingRadians = [MyMathHelper degressToRadians:45]; 


    CGContextAddArc(contextRef, CGRectGetMidX(rect),CGRectGetMidY(rect),radius,startingRadians,endingRadians,NO); 

    //Render the blue gauge line 
    CGContextStrokePath(contextRef); 
} 

上面的代碼在中調用在我NSView

的關鍵部分方法是代碼在這裏:

- (void)drawInnerDividerLines:(CGContextRef)context rect:(NSRect)rect { 

    CGFloat centerX = CGRectGetMidX(rect); 
    CGFloat centerY = CGRectGetMidY(rect); 


    CGContextSetLineWidth  (context, 3.0); 
    CGContextSetRGBStrokeColor (context, 37.0/255.0, 204.0/255.0, 227.0/255.0, 0.5); 



    CGFloat destinationX = centerX + (centerY * (cos((135)*(M_PI/180)))); 
    CGFloat destinationY = centerY + (centerX * (sin((135)*(M_PI/180)))); 

    NSPoint destinationPoint = NSMakePoint(destinationX, destinationY); 


    CGContextMoveToPoint(context, centerX, centerY); 

    CGContextAddLineToPoint(context, destinationPoint.x, destinationPoint.y); 

    CGContextStrokePath(context); 

} 

我明白是怎麼回事,但我試圖解決的是繪製小線的問題,關內的藍線延伸到視圖的中心點,但不會一直畫到中心。我有點不確定如何修改數學和繪圖邏輯來實現這一點。這裏是單位圓我基於核心圖形繪製的角度。

enter image description here

我試圖解決的主要問題是:

  1. 如何定義適當的起點切斷淺藍色內線作爲起始點爲每個規蜱的。現在,我正在繪製從中心到邊緣的整條線。

  2. 如何控制滴答指示器的長度,因爲它在藍線上指向中心,偏離它的原點。

任何提示或建議,將指向我在正確的方向來解決這個問題將不勝感激。

回答

2

我推薦使用載體。您可以通過計算髮現一行對給定的角度圈中的任何一點:

dirX = cos(angle); 
dirY = sin(angle); 
startPt.x = center.x + innerRadius * dirX; 
startPt.y = center.y + innerRadius * dirY; 
endPt.x = center.x + outerRadius * dirX; 
endPt.y = center.y + outerRadius * dirY; 

然後,您可以繪製startPtendPt之間的一條線。

+0

正是我所需要的,感謝您對本! – zic10

1

任何提示或建議,將指向我在正確的方向來解決這一點,將不勝感激。

在周圍可以形成一個直角三角形中心的一定的角度考慮在您的圓的圓周上的點,半徑爲斜邊,與另外兩個邊於x & y軸平行(忽略點在0,90,180或270度的退化情況)。鑑於與罪的公式(記住學校SOHCAHTOA)和一些基本的數學,你可以計算點的座標,並使用從中心到點繪製一個半徑。

「勾號」標記的終點只是位於不同半徑的圓上,所以相同的數學計算會給出終點,您可以繪製標記。您只需要確定這些圓的半徑,即沿原始半徑的距離應該是刻度的終點。

HTH

0

的另一種方法,以避免三角是旋轉變換矩陣,只是繪製一個垂直或水平線。

// A vertical "line" of width "width" along the y axis at x==0. 
NSRect tick = NSMakeRect(-width/2.0, innerRadius, width, outerRadius - innerRadius); 
NSAffineTransform* xform = [NSAffineTransform transform]; 
// Move the x and y axes to the center of your speedometer so rotation happens around it 
[xform translateXBy:center.x yBy:center.y]; 
// Rotate the coordinate system so that straight up is actually at your speedometer's 0 
[xform rotateByDegrees:135]; 
[xform concat]; 
// Create a new transform to rotate back around for each tick. 
xform = [NSAffineTransform transform]; 
[xform rotateByDegrees:-270.0/numTicks]; 
for (int i = 0; i < numTicks; i++) 
{ 
    NSRectFill(tick); 
    [xform concat]; 
} 

你可能想在[NSGraphicsContext saveGraphicsState][NSGraphicsContext restoreGraphicsState]所以當你完成變換矩陣恢復到這個包起來。

如果你希望兩個不同類型的刻度線(主要和次要),則有兩種不同的rects並選擇基於i % 10 == 0或任何一個。也許還可以切換顏色。等