Draw Bubble Graph in iOS? [closed] - ios

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
hope you guys are doing well.
How can I draw graph similar to below image?
To be more specific, my graph will have low, normal and high risk with orange, green and red colours respectively. Each containing bubble with info in x- axis.
I wanna make exactly like above image any help would be appreciated and also please be specific while posting some third party libs and all.
How can I achieve the above graph?
Note- In X- axis (dates) and Y- axis [(values) in bubbles] are there.
EDIT
y-axis is fixed with some range by x-axis is from server took in NSMutableArray
Thanks in advance.

First step in drawing graph is to create X-Y axis layout. You can draw X and Y axis line using UIBezierPath and CAShapeLayer.
UIBezierPath *graphPath = [[UIBezierPath alloc]init];
[graphPath setLineWidth:GRAPH_LAYOUT_LINE_WIDTH];
[[UIColor blackColor] setStroke];
[graphPath moveToPoint:CGPointMake(ORIGN_X, ORIGN_Y)];
[graphPath addLineToPoint:CGPointMake((ORIGN_X + TOTAL_X_DIST),ORIGN_Y)];
[graphPath stroke]; // drawing path
//Creating graph layout
CAShapeLayer *graphLayout = [CAShapeLayer layer];
graphLayout.fillColor = [[UIColor clearColor] CGColor];
graphLayout.strokeColor = [GRAPH_LAYOUT_COLOR CGColor];
graphLayout.lineWidth = GRAPH_LAYOUT_LINE_THICKNESS;
graphLayout.path = [graphPath CGPath];
[self.layer addSublayer:graphLayout];
Repeat the above code for drawing Y axis
Second you need to create X and Y axis scale
float minX = 0;
float maxX = 10;
float minY = 0;
float maxY = 100;
float x1Unit = 1;
float y1Unit = 1;
self.spacingX = TOTAL_X_DIST/((maxX - minX)/x1Unit);
self.spacingY = TOTAL_Y_DIST/((maxY - minY+1)/y1Unit);
Now you need to get the values(cartesian coordinate) of X and Y axis in an array, here i am just hard coding the points
//Enter the co-ordinates
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(0, 50)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(1, 20)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(2, 35)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(3, 55)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(4, 80)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(5, 60)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(6, 85)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(7, 50)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(8, 30)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(9, 10)]];
[self.pointsArray addObject:[NSValue valueWithCGPoint:CGPointMake(10, 05)]];
Next we need to convert cartesian coordinate values to values of x and y with respect to parent view.
// Creating (x,y) points based on superview coordinate system
for (NSValue *point in self.pointsArray)
{
CGPoint coordinate;
coordinate.x = (STARTING_X*x1Unit + ([point CGPointValue].x * self.spacingX) + self.spacingX/1.5)/x1Unit;
coordinate.y = (STARTING_Y*y1Unit - ([point CGPointValue].y * self.spacingY))/y1Unit;
[self.coordinateArray addObject:[NSValue valueWithCGPoint:coordinate]];
}
Now it's time to add beautiful bubbles
for (int a = 0; a < [self.coordinateArray count]; a++)
{
CGPoint point = [[self.coordinateArray objectAtIndex:a] CGPointValue];
//Creating bubble for points on the graph.
UIView *bubble = [[UIView alloc] initWithFrame:BUBBLE_FRAME];
bubble.Layer.cornerRadius = BUBBLE_FRAME_WIDTH/2;
//Giving the color for the bubble based on the Y-Axis value
if (point.y <= 50)
{
bubble.backgroundColor = RED_COLOR;
}
else if (point.y > 50 && point.y <= 80)
{
bubble.backgroundColor = YELLOW_COLOR;
}
else
{
bubble.backgroundColor = GREEN_COLOR;
}
[self addSubview:bubble];
}
Hope this helps you

Related

How to cut up image based on coordinates

I have a question related to cutting up an image to know which part is tapped by the user. It's a rather simple exercise for some, I think, but I've been cracking my head over this and can't find a proper way.
What I would like to do is tap a body part on this image and have the device tell me what body part it is:
But I have absolutely no clue on how to program this.
I've been thinking on setting an array of outline CGPoints for every body part, but how to get those? Photoshop coordinates? And then calculate the touched point onto the closest CGPoint?
Somebody gave me the idea to cut up the image in the different zones, different images for every body part. But here the problem is that every image is a rectangle, which makes it very hard to know what exactly got touched. Would also need an array of points, especially for the overlapping images.
Another person told me this would only be possible using SpriteKit.
Let me know, smart peeps :)
UPDATE:
I figured it out! I'm making a lot of arrays that contain the points to the hand, the legs, ... An example:
CGPoint p1 = CGPointMake(x + 432, y + 200);
CGPoint p2 = CGPointMake(x + 523, y + 188);
CGPoint p3 = CGPointMake(x + 530, y + 277);
CGPoint p4 = CGPointMake(x + 432, y + 277);
CGPoint p5 = CGPointMake(x + 523, y + 367);
CGPoint p6 = CGPointMake(x + 432, y + 354);
CGPoint p7 = CGPointMake(x + 325, y + 355);
CGPoint p8 = CGPointMake(x + 296, y + 362);
NSArray *handL = [NSArray arrayWithObjects:
[NSValue valueWithCGPoint:p1],
[NSValue valueWithCGPoint:p2],
[NSValue valueWithCGPoint:p3],
[NSValue valueWithCGPoint:p4], nil];
[shapes addObject:#{#"name":NSLocalizedString(#"Left Hand", #""), #"points":handL}];
NSArray *handR = [NSArray arrayWithObjects:
[NSValue valueWithCGPoint:p5],
[NSValue valueWithCGPoint:p6],
[NSValue valueWithCGPoint:p7],
[NSValue valueWithCGPoint:p8], nil];
[shapes addObject:#{#"name":NSLocalizedString(#"Right Hand", #""), #"points": handR}];
Afterwards in I read these values and layer them:
NSArray *shapes = [[NumbersHelper sharedNumbersHelper] getScreenThreeShapes];
for (int outside = 0; outside < [shapes count]; outside++) {
CAShapeLayer *shape = [[CAShapeLayer alloc] init];
[self.scrollView.layer addSublayer:shape];
shape.opacity = 0.5;
shape.lineWidth = 2;
shape.lineJoin = kCALineJoinRound;
NSArray *points = [[[shapes valueForKey:#"points"] allObjects] objectAtIndex:outside];
UIBezierPath *path = [[UIBezierPath alloc] init];
for (int inside = 0; inside < points.count; inside++) {
if (inside == 0) {
[path moveToPoint:[[points objectAtIndex:inside] CGPointValue]];
} else {
[path addLineToPoint:[[points objectAtIndex:inside] CGPointValue]];
}
}
[path closePath];
shape.path = [path CGPath];
shape.name = [[[shapes valueForKey:#"name"] allObjects] objectAtIndex:outside];
}
When the user taps the view I do this:
- (void)tappedOnView:(UITapGestureRecognizer *)sender
{
if ([sender locationInView:self.scrollView].x > 2048 && [sender locationInView:self.scrollView].x < 3072) {
screenTwoTouchedPoint = [sender locationInView:self.scrollView];
CGPoint touchPoint = [sender locationInView:self.scrollView];
NSString *name;
for (id sublayers in self.scrollView.layer.sublayers) {
if ([sublayers isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shape = sublayers;
if (CGPathContainsPoint(shape.path, 0, touchPoint, YES)) {
name = shape.name;
break;
}
}
}
[self tappedBody:sender onPart:name];
}
}
A crude but simple way would be to have transparent buttons over various body parts. In case a body part is not covered properly by a single button, add multiple smaller buttons.
You can add tag to the buttons to identify which button/body part got tapped or connect them to unique Actions.
A solution that worked for me. Create a 2d array for the entire size of the image. If the image is 250x250, your array would be the same.
Fill this array with NSObjects, having and int bodyInteger
Then drag your finger on the hand of the image, and in your touchesMoved take the co-ordinates from location, and pick the object from your 2d array by using the co-ordinates and setting its bodyInteger to 1.
Now when someone puts finger on hand, you take the respective object from 2d array and see what bodyInteger it has.
If you have memory constraints, you can create a structure instead of an NSObject and save only for the points that are within the body.
Alternatively, you can create a boundary for each body part and save it. When user touches with finger, you can see if the point is within a saved polygon or not.

text labels drawn in CGRect form an elliptical arc when images drawn using the same coordinates form a circular arc

I am new to Core Graphics and trying to understand why text labels I draw in CGRect form an elliptical arc when images I draw using the same coordinates form a circular arc.
The original code by Arthur Knopper creates circles wherever the screen is touched. By removing the touches method, I have been able to generate a series of small circles (dots) along a circular arc (uber circle). Each dot is centred on the perimeter of the uber circle (as shown below).
In order to label each dot I use the same point coordinates I used for placing the dot. However text labels form an elliptical arc even though dots form a circular arc (as shown below). Labels are also hidden by the dots when dots are filled. The reason for this is a complete mystery.
As a novice I am probably missing something basic in Core Graphics. If anyone could explain what that is and what I need to do to make both arcs circular and place labels on top of the dots I’d be most grateful.
Thanks.
Here is the code.
circleView.h
NSMutableArray *totalCircles;
int dotCount, limit;
float uberX, uberY, uberRadius, uberAngle, labelX,
labelY,dotRadius, dotsFilled, sectors, x, y;
CGPoint dotPosition;
CGRect boxBoundary;
CGContextRef context;
}
- (void)demo;
#end
And ...
-#implementation iOSCircleView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
totalCircles = [[NSMutableArray alloc] init];
// Set background color
self.backgroundColor = [UIColor whiteColor];
}
return self;
} // frame a view for drawing
- (void)drawRect:(CGRect)rect {
[self demo];
}
- (void)demo {
context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5);
uberX = 120;
uberY = 160;
uberRadius = 30;
sectors = 16;
uberAngle = (2.0 * PI) / sectors;
dotRadius = 20;
dotsFilled = FALSE;
for (dotCount = 1; dotCount <= sectors; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // make new point for each dot
dotPosition = CGPointMake(x,y); // create each dot
NSLog(#"Circle%i: %#", dotCount, NSStringFromCGPoint(dotPosition));
[self autoLabel]; // text hides behind the dots
newCircle.circleCentre = dotPosition; // place each dot on the frame
[totalCircles addObject:newCircle];
[self setNeedsDisplay];
}
CGContextSetShadowWithColor(context, CGSizeMake(-3 , 2), 4.0, [UIColor clearColor].CGColor);
dotCount = 1;
for (iOSCircle *circle in totalCircles) {
CGContextAddArc(context, circle.circleCentre.x, circle.circleCentre.y, circle.circleRadius, 0.0, M_PI * 2.0, YES); // draw the circles
NSLog(#"Dot %i Filled %i ", dotCount, dotsFilled);
switch (dotsFilled) {
case 1:
CGContextSetFillColorWithColor(context, [[UIColor cyanColor] CGColor]);
//CGContextDrawPath(context, kCGPathFillStroke);
break;
default:
//CGContextStrokePath(context); // draw dot outline
break;
}
dotCount++;
}
} // draw circular dots in circular patterns
- (void)setSectorDotCoordinates {
x = uberX + (uberRadius * cos(uberAngle *dotCount) * 2);
y = uberY + (uberRadius * sin(uberAngle *dotCount) * 2);
} // calculate dot coordinates along a circular arc
- (void)autoLabel {
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
boxBoundary = CGRectMake(x-dotRadius, y-dotRadius, x+dotRadius, y+dotRadius);
[[NSString stringWithFormat:#"%i",dotCount] drawInRect:boxBoundary withFont:[UIFont systemFontOfSize:24] lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter];
}
Change the boxBoundary in autoLabel, CGRectMake creates a rectangle with one point coordinates and width and height, not two points:
(void)autoLabel {
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
boxBoundary = CGRectMake(x-dotRadius, y-dotRadius, dotRadius*2, dotRadius*2);
[[NSString stringWithFormat:#"%i",dotCount] drawInRect:boxBoundary
withFont:[UIFont systemFontOfSize:24]
lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter];
}
In your code the "boxes" containing the texts where bigger and bigger when you where going to the right. (the width and height were not fixed)
My updated code show labels that match the drawing order but text is still hidden when dots are filled.
I suspect I need to construct a path to write text in front of the dots and it’s already apparent that something like CGPathMoveToPoint is needed to start drawing from the 12 O'clock position.
Here’s the updated code. The first part draws and renders the dots
context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 0.5);
uberX = 160;
uberY = 240;
uberRadius = 52;
sectors = 16;
uberAngle = ((2.0 * PI) / sectors);
NSLog(#"%f %f %f %f", uberX, uberY, uberRadius, uberAngle);
dotRadius = 20;
dotsFilled = FALSE;
textOffset = 4; // add to y to centre the label
for (dotCount = 1; dotCount <= 4 /*sectors*/; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // create a new point for each dot
dotPosition = CGPointMake(x,y); // create each dot
NSLog(#"Circle%i: %#", dotCount, NSStringFromCGPoint(dotPosition));
newCircle.circleCentre = dotPosition; // place each dot on the frame
[totalCircles addObject:newCircle];
[self setNeedsDisplay];
}
CGContextSetShadowWithColor(context, CGSizeMake(-3 , 2), 4.0, [UIColor clearColor].CGColor);
dotCount = 1;
for (iOSCircle *circle in totalCircles) {
CGContextAddArc(context, circle.circleCentre.x, circle.circleCentre.y, circle.circleRadius, 0.0, M_PI * 2.0, YES);
// draw the circles
NSLog(#"Dot %i Filled %i ", dotCount, dotsFilled);
switch (dotsFilled) {
case 1:
CGContextSetFillColorWithColor(context, [[UIColor cyanColor] CGColor]);
CGContextDrawPath(context, kCGPathFillStroke);
break;
default:
CGContextStrokePath(context); // draw dot outline
break;
}
[self setSectorDotCoordinates]; // find point coordinates for each dot
dotCount++;
}
The code that draws the labels follow immediately afterwards.
// draw labels
for (dotCount = 1; dotCount <= sectors; dotCount++)
{
// Create a new iOSCircle Object
iOSCircle *newCircle = [[iOSCircle alloc] init];
newCircle.circleRadius = dotRadius;
[self setSectorDotCoordinates]; // find point coordinates for each dot
dotPosition = CGPointMake(x,y); // use point coordinates for label
[self autoLabel]; // THIS SHOWS TEXT BEHIND THE DOTS
}

Dashed lines with CGContextStrokePath

I am developing an app where the user should be able to draw lines with the finger. The user can enable dashed lines, but I am having a strange problem when trying to do so. If the user drags the finger slowly a solid line appears, but when doing it fast the dashes appears. I would like the dashes to appear no matter what when enabled. The problem is shown on the gif below:
I am collecting the touch points with a UIPanGestureRecognizer:
-(void)dragGestureCaptured:(UIPanGestureRecognizer *)gesture
{
NSValue* touchPoint = [NSValue valueWithCGPoint:[gesture locationInView:self.drawingView]];
if(gesture.state == UIGestureRecognizerStateBegan)
{
[self initializePreviousPointValues:[touchPoint CGPointValue]];
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
EBLog(#"Dragging ends..");
return;
}
previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [touchPoint CGPointValue];
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
[self.drawingView addDrawColor:self.currentDrawColor];
[self.drawingView.controlPoints addObject:[NSValue valueWithCGPoint:previousPoint1]];
[self.drawingView.points addObject:[NSValue valueWithCGPoint:mid2]];
[self.drawingView.movePoints addObject:[NSValue valueWithCGPoint:mid1]];
[self.drawingView setNeedsDisplay];
}
The drawingView uses the controlsPoints, points and movePoints to draw the lines:
- (void)drawLinesInContext:(CGContextRef)context
{
for (int i = 0; i < [self.points count]; i++)
{
CGPoint movePoint = [[self.movePoints objectAtIndex:i] CGPointValue];
CGPoint controlPoint = [[self.controlPoints objectAtIndex:i] CGPointValue];
CGPoint point = [[self.points objectAtIndex:i] CGPointValue];
CGContextMoveToPoint(context, movePoint.x, movePoint.y);
CGContextAddQuadCurveToPoint(context, controlPoint.x, controlPoint.y, point.x, point.y);
NSNumber* colorHash = [self.colorHashes objectAtIndex:i];
UIColor* col = [self.colorsForHashValue objectForKey:colorHash];
CGFloat red = 0.0f, blue = 0.0f, green = 0.0f, alpha = 1.0f;
[col getRed:&red green:&green blue:&blue alpha:&alpha];
if (alpha == 0.0f)
{
penWidth = 15.0f;
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeClear);
}
else
{
penWidth = 5.0f;
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeNormal);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, alpha);
}
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, penWidth);
CGContextSetShouldAntialias(context, false);
CGContextSetAllowsAntialiasing(context, false);
if (self.drawDashedLines)
{
CGFloat dashLengths[] = {10.0f, 10.0f};
CGContextSetLineDash(context, 0.0f, dashLengths, 2);
}
CGContextStrokePath(context);
}
}
drawLinesInContext: is invoked in drawRect:.
What am I doing wrong, since the dashes don't appear when dragging slowly?
I have already seen the Drawing a dashed line with CGContextSetLineDash and tried the CGPathAddLineToPoint to see if it makes a difference, but it didn't. I was experiencing the exact same problem.
The problem is that you draw separate paths between each subsequent points, and
each path starts with a new dash pattern. If the finger is moved slowly, you draw
lots of very short path. It the path is shorter than 10 points (the first
dash length which is drawn) then no dash pattern is seen at all.
The following pseudo-code hopefully shows the idea how to solve this. Instead of
for i = 1 ... N {
move to point[i-1]
curve to point[i]
set line dash
stroke path
}
it should be
move to point[0]
for i = 1 ... N {
curve to point[i]
}
set line dash
stroke path

Cocos2D & ccDrawLine - Drawing smooth lines

I have some troubles when I try to draw lines with cocos2d! I store points, got from touchMoved method, in a NSMutableArray, and pass that array to a subclass of CCNode called Lines that I use to draw the lines from the array of points. The problem is that the line is not smooth when I swipe slowly, but when I swipe faster, the line is way much smoother. See the pictures below :
Slow Swipe :
Fast Swipe :
I tried to solve the problem with ccpDistance, which calculate the distance between the last saved point and if it's not far enough I don't save it. I also tried to draw little circles at each saved positions, but this isn't really nice neither. Here's my code :
In my GameScene :
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (ccpDistance(lastPoint, location) > 10) {
//SAVE THE POINT
[linePoints addObject:[NSValue valueWithCGPoint:location]];
[line updatePoints:linePoints];
lastPoint = location;
}
}
And my Line Class :
- (void) updatePoints:(NSMutableArray *)_point
{
points = _point;
}
- (void) draw
{
if ([points count] > 0) {
ccGLEnable(GL_LINE_STRIP);
ccDrawColor4B(209, 75, 75, 255);
float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();
glLineWidth(lineWidth);
int count = [points count];
for (int i = 0; i < (count - 1); i++){
CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];
ccDrawLine(pos1, pos2);
ccDrawSolidCircle(pos2, 2.5, 20);
}
}
}
Also, is there something in my code that could be done better to improve performance? Right now I don't have any problems even with 1000+ points, but just in case...
Any help will be greatly appreciated! Thanks in advance!
Ok, I found a website explaining really clearly how to do smooth lines, and it worked wonderfully! There's still anti-aliasing that's left to do, but maybe I will never do, since it looks really great on retina devices. Here's the website : Drawing Smooth Lines with Cocos2D
And here's the result :
Also, for those interested in the finished code, here it is :
Line.m
- (void) drawCurPoint:(CGPoint)curPoint PrevPoint:(CGPoint)prevPoint
{
float lineWidth = 6.0;
ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);
//These lines will calculate 4 new points, depending on the width of the line and the saved points
CGPoint dir = ccpSub(curPoint, prevPoint);
CGPoint perpendicular = ccpNormalize(ccpPerp(dir));
CGPoint A = ccpAdd(prevPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint B = ccpSub(prevPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint C = ccpAdd(curPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint D = ccpSub(curPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint poly[4] = {A, C, D, B};
//Then draw the poly, and a circle at the curPoint to get smooth corners
ccDrawSolidPoly(poly, 4, red);
ccDrawSolidCircle(curPoint, lineWidth/2.0, 20);
}
- (void) draw
{
if ([points count] > 0) {
ccGLEnable(GL_LINE_STRIP);
ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);
ccDrawColor4F(red.r, red.g, red.b, red.a);
float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();
glLineWidth(lineWidth);
int count = [points count];
for (int i = 0; i < (count - 1); i++){
CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];
[self drawCurPoint:pos2 PrevPoint:pos1];
}
}
}
As for the GameScene, nothing changed there (See the question for the code)! Note that you can change the line if (ccpDistance(lastPoint, location) > X), where X is the minimum distance between two points before the game saves another one. The lower X is, the smoother the line will be, but you will have way more points in your array, which could affect performance!
Anyway, thank you guys for your suggestions and your help, it helped me to get in the right way!
I think that you could smooth up your line drawing with some averaging.
- (void) updatePoints:(NSMutableArray *)_point
{
points = _point;
int count = [points count];
for (int i = 3; i < (count - 4); i++) {
CGPoint pos1 = [[points objectAtIndex:i - 2] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i - 1] CGPointValue];
CGPoint pos3 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos4 = [[points objectAtIndex:i + 1] CGPointValue];
CGPoint pos5 = [[points objectAtIndex:i + 2] CGPointValue];
CGFloat xpos = (pos1.x + pos2.x + 2 * pos3.x + pos4.x + pos5.x)/6;
...
(now calcuclate ypos similarly and store the point into an array)
}
}

Draw shape of land on view by taking latitude and longitude in iOS?

I want to draw shape of small land on view by taking latitude and longitude at the corner of land.
I have wrote following code. For now I took hard core values.
- (void)drawRect:(CGRect)rect {
CGSize screenSize = [UIScreen mainScreen].applicationFrame.size;
SCALE = MIN(screenSize.width, screenSize.height) / (2.0 * EARTH_RADIUS);
OFFSET = MIN(screenSize.width, screenSize.height) / 2.0;
CGPoint latLong1 = {18.626103, 73.805023};
CGPoint latLong2 = {18.626444, 73.804884};
CGPoint latLong3 = {18.626226, 73.804969};
CGPoint latLong4 = {18.626103, 73.805023};
NSMutableArray *points=[NSMutableArray arrayWithObjects:[NSValue valueWithCGPoint:[self convertLatLongCoord:latLong1]],[NSValue valueWithCGPoint:[self convertLatLongCoord:latLong2]], [NSValue valueWithCGPoint:[self convertLatLongCoord:latLong3]],[NSValue valueWithCGPoint:[self convertLatLongCoord:latLong4]],nil];
CGContextRef ctx = UIGraphicsGetCurrentContext();
for(int i=0;i<points.count;i++)
{
// CGPoint newCoord = [self convertLatLongCoord:latLong];
NSValue *val = [points objectAtIndex:i];
CGPoint newCoord = [val CGPointValue];
if(i == 0)
{
// move to the first point
CGContextMoveToPoint(ctx, newCoord.x, newCoord.y);
}
else
{
CGContextAddLineToPoint(ctx, newCoord.x, newCoord.y);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
CGContextSetStrokeColorWithColor(ctx, [[UIColor redColor] CGColor]);
}
}
CGContextStrokePath(ctx);
}
Below is method which converts lat long into x,y co-ordinates.
- (CGPoint)convertLatLongCoord:(CGPoint)latLong
{
CGFloat x = EARTH_RADIUS * cos(latLong.x) * cos(latLong.y) * SCALE + OFFSET;
CGFloat y = EARTH_RADIUS * cos(latLong.x) * sin(latLong.y) * SCALE + OFFSET;
return CGPointMake(x, y);
}
My problem is when I took small land(e.g house land) area lat long its shape is not visible on view after draw. How I can show maximise shape of land on view.
Thanks in advance.

Resources