I'm drawing lines in an app by connecting two points, what I want to do next is to display a label at the middle of the line displaying its length. This is what I'm using for the length calculation:
CGFloat dx = point2.x - point1.x;
CGFloat dy = point2.y - point1.y;
return sqrt(dx*dx + dy*dy );
How could I display the distance in in or cm and how would I place the label in the middle of the line.
Thanks
EDIT: Here's my drawRect method, with what I've tried:
- (void)drawRect:(CGRect)rect
{
// Drawing code
if ([_pointsArray count] > 0) {
int i;
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 7.0f);
CGContextSetLineCap(c, kCGLineCapRound);
CGContextSetStrokeColorWithColor(c, [UIColor blueColor].CGColor);
for (i = 0; i < ([_pointsArray count]-1); i++) {
CGPoint p1 = [[self.pointsArray objectAtIndex:i]CGPointValue];
CGPoint p2 = [[self.pointsArray objectAtIndex:i+1]CGPointValue];
CGContextMoveToPoint(c, p1.x, p1.y);
CGContextAddLineToPoint(c, p2.x, p2.y);
UILabel *lengthLabel = [[UILabel alloc]init];
CGFloat dx = p2.x - p1.x;
CGFloat dy = p2.y - p1.y;
CGFloat result = sqrt(dx*dx + dy*dy);
lengthLabel.text = [NSString stringWithFormat:#"%f", result];
CGContextStrokePath(c);
}
}
}
The first thing you need to do is find where to put the text. Start by finding the center of the line. This is simple geometry based on the two points you have:
CGPoint p1 = [[self.pointsArray objectAtIndex:i]CGPointValue];
CGPoint p2 = [[self.pointsArray objectAtIndex:i+1]CGPointValue];
CGPoint lineCenter = CGPointMake((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0);
Now you need to calculate the rectangle to draw the text.
NSString *text = [NSString stringWithFormat:#"%f", result];
UIFont *font = [UIFont systemFontWithSize:14]; // pick a size
NSDictionary *attrs = #{ NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor blueColor] }; // pick a color
CGSize *textSize = [text sizeWithAttributes:attrs];
Now you have the line center and the text size you need to calculate the text rectangle:
CGRect textRect = CGRectMake(lineCenter.x - (textSize.width / 2.0), lineCenter.y - (textSize.height / 2.0), textSize.width, textSize.height);
And now you can draw the text:
[text drawInRect:textRect withAttributes:attrs];
All together with your code:
UIFont *font = [UIFont systemFontWithSize:14]; // pick a size
NSDictionary *attrs = #{ NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor blueColor] }; // pick a color
for (i = 0; i < ([_pointsArray count]-1); i++) {
CGPoint p1 = [[self.pointsArray objectAtIndex:i]CGPointValue];
CGPoint p2 = [[self.pointsArray objectAtIndex:i+1]CGPointValue];
CGContextMoveToPoint(c, p1.x, p1.y);
CGContextAddLineToPoint(c, p2.x, p2.y);
CGFloat dx = p2.x - p1.x;
CGFloat dy = p2.y - p1.y;
CGFloat result = sqrt(dx*dx + dy*dy);
NSString *text = [NSString stringWithFormat:#"%f pts", result];
CGPoint lineCenter = CGPointMake((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0);
CGSize *textSize = [text sizeWithAttributes:attrs];
CGRect textRect = CGRectMake(lineCenter.x - (textSize.width / 2.0), lineCenter.y - (textSize.height / 2.0), textSize.width, textSize.height);
[text drawInRect:textRect withAttributes:attrs];
CGContextStrokePath(c);
}
Notes:
This is untested. There could be typos.
This draws the line length in points. You need to find your own way to convert to other units.
Related
How to make UI with round image and round text, also add ratting icon on same circle. in iOS application
Import roundImageView.h class in your view class and set background image on your UIButton. Please change button type Custom.
After Following these steps try this code .
CGRect frame = CGRectMake(0, 0, 200, 200);
roundImageView *roudImage = [[roundImageView alloc]init];
UIImage *image1 = [roudImage createMenuRingWithFrame:frame :#"Your Title" labelBgColor:[UIColor colorWithRed:(191/255.f) green:(251/255.f) blue:(158/255.f) alpha:1] ringBgColor:[UIColor colorWithRed:(214/255.f) green:(214/255.f) blue:(214/255.f) alpha:1] levelUnlockShow:1 buttonObj:yourButtonObj];
[yourButtonObj setImage:image1 forState:UIControlStateNormal];
Note :- In this you can see we set only Image not background image ..
Create a class roundImageView UIImage Type and paste this code
in roundImageView.h file code
#import <UIKit/UIKit.h>
#interface roundImageView : UIImage
- (UIImage*) createMenuRingWithFrame:(CGRect)frame : (NSString*) sectionTitle labelBgColor : (UIColor*)labelBgColor ringBgColor : (UIColor *)ringBgColor levelUnlockShow: (NSInteger) levelUnloackNm buttonObj : (UIButton *)buttonObj;
Paste code in roundImageView.m file
#import "roundImageView.h"
#implementation roundImageView
#define DegreesToRadians(x) (M_PI * x / 180.0)
- (void) drawStringAtContext:(CGContextRef) context string:(NSString*) text atAngle:(float) angle withRadius:(float) radius
{
CGSize textSize = [text sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:18]}];
float perimeter = 2 * M_PI * radius;
float textAngle = textSize.width / perimeter * 2 * M_PI;
angle += textAngle / 2;
for (int index = 0; index < [text length]; index++)
{
NSRange range = {index, 1};
NSString* letter = [text substringWithRange:range];
char* c = (char*)[letter cStringUsingEncoding:NSASCIIStringEncoding];
CGSize charSize = [letter sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:18]}];
NSLog(#"Char %# with size: %f x %f", letter, charSize.width, charSize.height);
float x = radius * cos(angle);
float y = radius * sin(angle);
float letterAngle = (charSize.width / perimeter * -2 * M_PI);
CGContextSaveGState(context);
CGContextTranslateCTM(context, x, y);
CGContextRotateCTM(context, (angle - 0.5 * M_PI));
CGContextShowTextAtPoint(context, 0, 0, c, strlen(c));
CGContextRestoreGState(context);
angle += letterAngle;
}
}
- (void)drawRect:(CGRect)rect contextData:(CGContextRef) context {
CGContextSetLineWidth(context, 30);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 50);
CGContextAddCurveToPoint(context, 0, 180, 0, 0, -80, 0);
CGContextStrokePath(context);
}
- (UIImage*) createMenuRingWithFrame:(CGRect)frame : (NSString*) sectionTitle labelBgColor : (UIColor*)labelBgColor ringBgColor : (UIColor *)ringBgColor levelUnlockShow: (NSInteger) levelUnloackNm buttonObj : (UIButton *)buttonObj
{
CAShapeLayer *circle = [CAShapeLayer layer];
// Make a circular shape
UIBezierPath *circularPath=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, buttonObj.frame.size.width, buttonObj.frame.size.height) cornerRadius:MAX(buttonObj.frame.size.width, buttonObj.frame.size.height)];
circle.path = circularPath.CGPath;
// Configure the apperence of the circle
circle.fillColor = [UIColor blackColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 0;
buttonObj.layer.mask = circle;
CGPoint centerPoint = CGPointMake(frame.size.width / 2, frame.size.height / 2);
char* fontName = (char*)[[UIFont fontWithName:#"Helvetica" size:18].fontName cStringUsingEncoding:NSASCIIStringEncoding];
const CGFloat* ringColorComponents = CGColorGetComponents([ringBgColor CGColor]);
// const CGFloat* textBGColorComponents = CGColorGetComponents([[UIColor colorWithRed:80/255.0 green:160/255.0 blue:15/255.0 alpha:1] CGColor]) ;
const CGFloat* textColorComponents = CGColorGetComponents([[UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:1] CGColor]);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, frame.size.width, frame.size.height, 8, 4 * frame.size.width, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextSelectFont(context, fontName, 18, kCGEncodingMacRoman);
CGContextSetRGBStrokeColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
CGContextSetLineWidth(context, 25);
CGContextStrokeEllipseInRect(context, CGRectMake(10, 10, frame.size.width - (10 * 2), frame.size.height - (10 * 2)));
CGContextSetRGBFillColor(context, textColorComponents[0], textColorComponents[1], textColorComponents[2], 1.0);
CGContextSaveGState(context);
CGContextTranslateCTM(context, centerPoint.x, centerPoint.y);
// float angleStep = 2 * M_PI ;
float angle = DegreesToRadians(135);
float textRadius = 95;
textRadius = textRadius - 12;
// [self drawImageAtContext:context string:text atAngle:angle withRadius:textRadius];
[self drawLblBackGroundAtContext:context string:sectionTitle atAngle:angle withRadius:textRadius withLabelBackgroudColor:labelBgColor ];
//angle -= angleStep;
CGContextSetRGBStrokeColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
CGContextSetLineWidth(context, 25);
[self drawStringAtContext:context string:sectionTitle atAngle:angle withRadius:textRadius];
//angle -= angleStep;
angle = DegreesToRadians(315);
// [self drawImageAtContext:context string:text atAngle:angle withRadius:textRadius];
[self drawImageAtContext:context atAngle:angle withRadius:textRadius levelUnlock: levelUnloackNm];
//angle -= angleStep;
CGContextRestoreGState(context);
CGImageRef contextImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
//[self saveImage:[UIImage imageWithCGImage:contextImage] withName:#"test.png"];
return [UIImage imageWithCGImage:contextImage];
}
- (void) drawImageAtContext:(CGContextRef) context atAngle:(float) angle withRadius:(float) radius levelUnlock:(NSInteger )levelUnlock
{
CGSize textSize = [#"MMMMMM" sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:18]}];
float perimeter = 2 * M_PI * radius;
float textAngle = (textSize.width+1) / perimeter * 2 * M_PI;
angle += textAngle / 2;
// UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(angle, 0, 20, 20)];
if (levelUnlock != 0) {
for (int index = 0; index < 6; index++)
{
NSRange range = {index, 1};
NSString* letter = [#"MMMMMM" substringWithRange:range];
CGSize charSize = [letter sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:18]}];
NSLog(#"Char %# with size: %f x %f", letter, charSize.width, charSize.height);
float x = radius * cos(angle);
float y = radius * sin(angle);
float letterAngle = ((charSize.width+1) / perimeter * -2 * M_PI);
CGContextSaveGState(context);
CGContextTranslateCTM(context, x, y);
CGContextRotateCTM(context, (angle - 0.5 * M_PI));
// CGContextShowTextAtPoint(context, 0, 0, c, strlen(c));
const CGFloat* ringColorComponents;
NSInteger raiting = 6 - levelUnlock ;
if (index + 1 > raiting) {
ringColorComponents = CGColorGetComponents([[UIColor colorWithRed:0/255.0 green:170/255.0 blue:216/255.0 alpha:1] CGColor]);
}else{
ringColorComponents = CGColorGetComponents([[UIColor colorWithRed:150/255.0 green:150/255.0 blue:150/255.0 alpha:1] CGColor]);
}
CGContextSetRGBStrokeColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
CGContextSetRGBFillColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
CGContextSetLineWidth(context, 8);
//Line Changed for border
CGContextStrokeEllipseInRect(context, CGRectMake(2, 1, 8, 8));
CGContextRestoreGState(context);
angle += letterAngle;
}
}
}
- (void) drawLblBackGroundAtContext:(CGContextRef) context string:(NSString*) text atAngle:(float) angle withRadius:(float) radius withLabelBackgroudColor: (UIColor *)labelBgColor
{
// text = [NSString stringWithFormat:#"%#sdsad",text];
CGSize textSize = [text sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:20]}];//[text sizeWithFont:[UIFont fontWithName:#"Helvetica" size:20]];
float perimeter = 2 * M_PI * radius;
float textAngle = textSize.width / perimeter * 2 * M_PI;
angle += textAngle / 2;
for (int index = 0; index < [text length]; index++)
{
NSRange range = {index, 1};
NSString* letter = [text substringWithRange:range];
// char* c = (char*)[letter cStringUsingEncoding:NSASCIIStringEncoding];
CGSize charSize = [letter sizeWithAttributes:#{NSFontAttributeName: [UIFont fontWithName:#"Helvetica" size:18]}];
NSLog(#"Char %# with size: %f x %f", letter, charSize.width, charSize.height);
float x = radius * cos(angle);
float y = radius * sin(angle);
float letterAngle = ((charSize.width+1) / perimeter * -2 * M_PI);
CGContextSaveGState(context);
CGContextTranslateCTM(context, x, y);
CGContextRotateCTM(context, (angle - 0.5 * M_PI));
const CGFloat* ringColorComponents = CGColorGetComponents([ labelBgColor CGColor]);
CGContextSetRGBStrokeColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
CGContextSetRGBFillColor(context, ringColorComponents[0], ringColorComponents[1], ringColorComponents[2], 1.0);
if (index + 1 == [text length]){
CGContextSetLineWidth(context, 15);
CGContextStrokeRect(context, CGRectMake(0, 2, 15, 15));
}else{
CGContextSetLineWidth(context, 15);
CGContextStrokeRect(context, CGRectMake(0, 2, 15, 15));
}
CGContextRestoreGState(context);
if (index +1 == [text length]) {
angle += letterAngle ;
}else{
angle += letterAngle;
}
}
}
#end
Try this code its working fine ...
Well,i didnt got your question completely..,if u want ur image view to be a proper circle,then use layer property.
Add QuartzCore framework to your project
#import <QuartzCore/QuartzCore.h>
then,in viewDidLoad ,add the following code.
myImageView.layer.cornerRadius = (myImageView.bounds.size.height/2);
myImageView.layer.masksToBounds = YES;
The rest is upto you,use your logic to do the remaining.
EDIT
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CALayer_class/index.html go through these.
You can take a look on WWDC2014 videos: "What's new in interface builder."
They are creating class similar to what you need.
https://developer.apple.com/videos/wwdc/2014/
okie i am using a PieChart i got from github Astrokin Piechart
But in this piechart label has not been added to different slices and i want something as shown below
I have looked up on stackoverflow already and am trying to draw text in draw rect but doesnt seem to work. code is below
for (int i = 0; i < slicesCount; i++)
{
double value = [self.datasource pieChartView:self valueForSliceAtIndex:i];
NSString *title = [self.datasource pieChartView:self titleForSliceAtIndex:i];
endAngle = startAngle + M_PI*2*value/sum;
/*CGFloat x = centerX + (radius+10) * (cos((startAngle-90)*M_PI/180.0) + cos((endAngle-90)*M_PI/180.0)) / 2;
CGFloat y = centerY + (radius+10) * (sin((startAngle-90)*M_PI/180.0) + sin((endAngle-90)*M_PI/180.0)) / 2;
[title drawAtPoint:CGPointMake(x, y) withFont:[UIFont fontWithName:FONT_HELVETICA size:12.0]];*/
CGFloat x = centerX + ((radius + 10) * cos(startAngle));
CGFloat y = centerY + ((radius + 10) * sin(endAngle));
// NSLog(#"X Y: %f %f %f", x, y, degree);
NSString *text = #"Test";
[text drawInRect:CGRectMake(x, y, 50, 44) withFont:[UIFont systemFontOfSize:14.0f]];
CGContextAddArc(context, centerX, centerY, radius, startAngle, endAngle, false);
UIColor *drawColor = [self.datasource pieChartView:self colorForSliceAtIndex:i];
CGContextSetStrokeColorWithColor(context, drawColor.CGColor);
CGContextSetLineWidth(context, lineWidth);
CGContextStrokePath(context);
startAngle += M_PI*2*value/sum;
}
right now it looks like this
What am i possibly doing wrong?
You draw text with
[text drawInRect:CGRectMake(x, y, 50, 44) withFont:[UIFont systemFontOfSize:14.0f]];
That makes your text's top left corner to appear at point (x,y). As I can see, you want text's center to appear at point (x,y). What you need to do is to subtract half of the text's width from x and the same for y, so that it becomes:
CGFloat height = 50.0;
CGFloat width = 44.0;
[text drawInRect:CGRectMake(x - width / 2.0, y - height / 2.0, width, height) withFont:[UIFont systemFontOfSize:14.0f]];
Also you'll need to dynamically get text's width based on the string you have, "95%" is wider than "5%", yeah? So you'll need something like:
UIFont *font = [UIFont systemFontOfSize:14.0f];
CGSize textSize = [text sizeWithFont:font]; // -sizeWithFont is deprecated in iOS7, you'll need something else
CGFloat height = textSize.height;
CGFloat width = textSize.width;
[text drawInRect:CGRectMake(x - width / 2.0, y - height / 2.0, width, height) withFont:font];
I have an issue with drawing the following diagram.
First I draw the grid lines with CGContextMoveToPoint, CGContextAddLineToPoint and CGContextStrokePath. Afterwards, I draw the diagram bars with CGContextFillRect.
Why are the lines drawn above the diagram bars?
Here is the requested code. A bit more complex, because I want to support a couple of diagram configurations.
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rectHistView = self.bounds;
CGFloat red, green, blue, alpha;
NSUInteger valueIndex = 0;
CGFloat histX, histY, histHeight;
CGFloat gridX, gridY, gridHeight;
NSString *txt;
CGSize txtSize;
// Initialize font color and set font drawing mode
CGContextSetTextDrawingMode(context, kCGTextFill);
NSDictionary *attrDictAxisValues = #{NSFontAttributeName:[UIFont systemFontOfSize:cfgAxisValuesFontSize],
NSForegroundColorAttributeName:cfgColorAxisValues};
NSDictionary *attrDictBarValues = #{NSFontAttributeName:[UIFont systemFontOfSize:cfgAxisValuesFontSize],
NSForegroundColorAttributeName:cfgColorBarValues};
// Calculate bar width and gap offset
CGFloat histWidth = rectHistView.size.width / [histValues count];
CGFloat histMaxViewHeight = bCfgShowXAxisValues ? rectHistView.size.height - cfgAxisValuesFontSize : rectHistView.size.height;
CGFloat gapOffset = histWidth * cfgBarGapPercentage / 2;
//--------------------------------------------------------
// Draw y-grid
//--------------------------------------------------------
if (bCfgShowYGrid) {
CGContextSetStrokeColorWithColor(context, HIST_CFG_UICOLOR_GRID.CGColor);
CGContextSetLineWidth(context, HIST_CFG_LINE_WIDTH_GRID);
gridHeight = bCfgShowBarValues ? histMaxViewHeight - cfgAxisValuesFontSize - HIST_CFG_FONT_GAP: histMaxViewHeight;
for (int y = 1; y <= histValueMax; y++) {
gridY = bCfgShowXAxisValues ? rectHistView.origin.y + rectHistView.size.height - (gridHeight * y / histValueMax) - cfgAxisValuesFontSize
: rectHistView.origin.y + rectHistView.size.height - (gridHeight * y / histValueMax);
CGContextMoveToPoint(context, rectHistView.origin.x, gridY);
CGContextAddLineToPoint(context, rectHistView.origin.x + rectHistView.size.width, gridY);
}
CGContextStrokePath(context);
}
//--------------------------------------------------------
// Draw histogram
//--------------------------------------------------------
for (NSString *val in histValues) {
histX = rectHistView.origin.x + (valueIndex * histWidth);
histHeight = bCfgShowBarValues ? (histMaxViewHeight - cfgAxisValuesFontSize - HIST_CFG_FONT_GAP) * [val floatValue] / histValueMax
: histMaxViewHeight * [val floatValue] / histValueMax;
histY = bCfgShowXAxisValues ? rectHistView.origin.y + rectHistView.size.height - histHeight - cfgAxisValuesFontSize
: rectHistView.origin.y + rectHistView.size.height - histHeight;
// draw x-grid
if (bCfgShowXGrid) {
gridX = rectHistView.origin.x + ((valueIndex+1) * histWidth);
gridY = bCfgShowXAxisValues ? rectHistView.origin.y + rectHistView.size.height - cfgAxisValuesFontSize
: rectHistView.origin.y + rectHistView.size.height;
CGContextSetStrokeColorWithColor(context, HIST_CFG_UICOLOR_GRID.CGColor);
CGContextSetLineWidth(context, HIST_CFG_LINE_WIDTH_GRID);
CGContextMoveToPoint(context, gridX, bCfgShowBarValues ? rectHistView.origin.y + cfgAxisValuesFontSize + HIST_CFG_FONT_GAP
: rectHistView.origin.y);
CGContextAddLineToPoint(context, gridX, gridY);
CGContextStrokePath(context);
}
// draw x-axis values
if (bCfgShowXAxisValues) {
txt = [NSString stringWithFormat:#"%lu", (unsigned long)valueIndex];
txtSize = [txt sizeWithAttributes:attrDictAxisValues];
[txt drawAtPoint:CGPointMake(rectHistView.origin.x + (valueIndex * histWidth) + (histWidth / 2.0f - txtSize.width / 2.0f),
rectHistView.origin.y + rectHistView.size.height - cfgAxisValuesFontSize)
withAttributes:attrDictAxisValues];
}
// get color from array
UIColor *color = [histColor objectAtIndex:valueIndex];
[color getRed:&red green:&green blue:&blue alpha:&alpha];
// draw histogram bar
CGContextSetRGBFillColor(context, red, green, blue, alpha);
CGContextFillRect(context, CGRectMake(histX+gapOffset, histY, histWidth-(2*gapOffset), histHeight));
// draw histogram bar values
if (bCfgShowBarValues) {
if (bCfgShowZeroBarValues || [val intValue] > 0) { // skip zero values if configured
txt = [NSString stringWithFormat:#"%d", [val intValue]];
CGSize txtSize = [txt sizeWithAttributes:attrDictBarValues];
[txt drawAtPoint:CGPointMake(rectHistView.origin.x + (valueIndex * histWidth) + (histWidth / 2.0f - txtSize.width / 2.0f),
histY - cfgAxisValuesFontSize - HIST_CFG_FONT_GAP)
withAttributes:attrDictBarValues];
}
}
valueIndex++;
}
//--------------------------------------------------------
// Draw diagram axis
//--------------------------------------------------------
CGContextSetStrokeColorWithColor(context, HIST_CFG_UICOLOR_AXIS.CGColor);
CGContextSetLineWidth(context, HIST_CFG_LINE_WIDTH_AXIS);
// draw y-axis
if (bCfgShowYAxis) {
CGContextMoveToPoint(context, rectHistView.origin.x,
bCfgShowBarValues ? rectHistView.origin.y + cfgAxisValuesFontSize + HIST_CFG_FONT_GAP: rectHistView.origin.y);
CGContextAddLineToPoint(context, rectHistView.origin.x, rectHistView.origin.y + histMaxViewHeight);
CGContextStrokePath(context);
}
// draw x-axis
if (bCfgShowXAxis) {
histY = bCfgShowXAxisValues ? rectHistView.origin.y + rectHistView.size.height - cfgAxisValuesFontSize
: rectHistView.origin.y + rectHistView.size.height;
CGContextMoveToPoint(context, rectHistView.origin.x, histY);
CGContextAddLineToPoint(context, rectHistView.origin.x + rectHistView.size.width, histY);
CGContextStrokePath(context);
}
}
I am trying to create the circles below in my iOS app. I know how to make the circles but am not entirely sure on how to get the points along the arc. It has to be in code not an image. Below is also the code I currently have.
- (void)drawRect:(CGRect)rect
{
CGPoint point;
point.x = self.bounds.origin.x + self.bounds.size.width/2;
point.y = self.bounds.origin.y + self.bounds.size.height/2;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect circle = CGRectMake(point.x/2,point.y-point.x/2,point.x,point.x);
CGContextAddEllipseInRect(context, circle);
CGContextStrokePath(context);
for (int i = 0; i<8; i++) {
CGRect circleMini = CGRectMake(??????,??????,point.x/4,point.x/4);
CGContextAddEllipseInRect(context, circleMini);
CGContextStrokePath(context);
}
}
UPDATED TO ANSWER
float cita = 0;
for (int i = 0; i<8; i++) {
CGPoint pointCir = CGPointMake(point.x/2 + radius * cos(cita) , (point.y-point.x/2) + radius * sin(cita) );
CGRect circleMini = CGRectMake(pointCir.x,pointCir.y,radius/4,radius/4);
CGContextAddEllipseInRect(context, circleMini);
CGContextStrokePath(context);
cita += M_PI / 4.0;
}
If (x,y) is the center and r is the radius of your big circle, the center of the i-th external circle will be:
center(i) = ( x + r * cos(cita) , y + r * sin(cita) )
Start cita in 0 and increment it PI/4 radians for the next circle (or 45 degrees)
Working implementation
CGFloat cita = 0;
CGFloat bigCircleRadius = point.x / 2.0;
CGFloat smallCircleRadius = bigCircleRadius / 4.0;
for (int i = 0; i < 8; i++) {
CGPoint smallCircleCenter = CGPointMake(point.x + bigCircleRadius * cos(cita) - smallCircleRadius/2.0 , point.y + bigCircleRadius * sin(cita) - smallCircleRadius / 2.0 );
CGRect smallCircleRect = CGRectMake(smallCircleCenter.x,smallCircleCenter.y,smallCircleRadius,smallCircleRadius);
CGContextAddEllipseInRect(context, smallCircleRect);
CGContextStrokePath(context);
cita += M_PI / 4.0;
}
Edit: Added implementation and renamed variables.
- (void)drawRect:(CGRect)rect
{
const NSUInteger kNumCircles = 8u;
CGFloat height = CGRectGetHeight(rect);
CGFloat smallCircleRadius = height / 10.0f;
CGRect bigCircleRect = CGRectInset(rect, smallCircleRadius / 2.0f, smallCircleRadius / 2.0f);
CGFloat bigCircleRadius = CGRectGetHeight(bigCircleRect) / 2.0f;
CGPoint rectCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0f);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextAddEllipseInRect(context, bigCircleRect);
CGContextStrokePath(context);
CGFloat alpha = 0;
for (NSUInteger i = 0; i < kNumCircles; i++)
{
CGPoint smallCircleCenter = CGPointMake(rectCenter.x + bigCircleRadius * cos(alpha) - smallCircleRadius/2.0f , rectCenter.y + bigCircleRadius * sin(alpha) - smallCircleRadius / 2.0f );
CGRect smallCircleRect = CGRectMake(smallCircleCenter.x,smallCircleCenter.y,smallCircleRadius,smallCircleRadius);
CGContextAddEllipseInRect(context, smallCircleRect);
CGContextStrokePath(context);
alpha += M_PI / (kNumCircles / 2.0f);
}
}
I'm new to objective-c and am trying to draw a line between moveable circles in Objective-c. I already have code that generates circles. Here is an image that I'd like to create in my app.
http://images.sciencedaily.com/2004/04/040407083832.jpg
Here's my code.
CircleViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
for (int i=0; i<5; i++) {
CGRect circleFrame = CGRectMake(arc4random() % 500, arc4random() % 500, (arc4random() % 200)+50 , (arc4random() % 200)+50);
CircleView *cirleView = [[CircleView alloc] initWithFrame: circleFrame];
cirleView.backgroundColor = [UIColor clearColor];
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
cirleView.circleColor = color;
[self.view addSubview:cirleView];
}
}
CircleView.m
-(void) drawCircle:(CGPoint)p withRadius:(CGFloat)radius inContext:(CGContextRef)contex
{
UIGraphicsPushContext(contex);
CGContextBeginPath(contex);
CGContextAddArc(contex, p.x, p.y, radius, 0, 2*M_PI, YES);
CGContextSetLineWidth(contex, 2.0);
CGContextAddLineToPoint(contex, p.x, p.y);
CGContextDrawPath(contex, kCGPathFillStroke);
UIGraphicsPopContext();
}
- (void)drawRect:(CGRect)rect
{
CGFloat size = self.bounds.size.width/2;
if(self.bounds.size.height < self.bounds.size.width) size = self.bounds.size.height / 2;
size *= 0.90;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 5.0);
[_circleColor setStroke];
[_circleColor setFill];
CGPoint point1;
point1.x = self.bounds.origin.x + self.bounds.size.width/2;
point1.y = self.bounds.origin.y + self.bounds.size.height/2;
[self drawCircle:point1 withRadius:size inContext:context];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[self addGestureRecognizer:singleFingerTap];
}
Thank you for your help.
Drawing a line:
-(void) drawLine (CGRect circleViewRect1, CGRect circleViewRect2)
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
//line width
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, circleViewRect1.center.x + circleViewRect1.bounds.width/2,circleViewRect1.center.y + circleViewRect1.bounds.height/2); //start from first circle radius
CGContextAddLineToPoint(context, circleViewRect2.center.x + circleViewRect2.bounds.width/2,circleViewRect2.center.y + circleViewRect2.bounds.height/2); //draw to this point
// and now draw the Path!
CGContextStrokePath(context);
}
Note:This is only useful if two circle's centers fall in horizontal line. Also, assume that circleViewRect1 is at the left of circleViewRect2. You must figure out the values for other use cases ie if they are at positioned at different angles etc.