how to shift the slider image knot outside - iphone

i have difficulties understanding the math behind on how to calculate the circumference of the knots to the center of the circle. i hope you guys can give me some pointer.
the current calculation set the knot img in the middle of pie, will like to shift it nearer to the outer circle like in img 2
thank you for viewing and commenting, any comments are appreciated.
how i wan to it to be.
/** Draw a white knob over the circle **/
-(void) drawTheHandle:(CGContextRef)ctx{
CGContextSaveGState(ctx);
NSLog(#"handleCenterA.x %f",handleCenterA.x);
NSLog(#" handleCenterA.y %f", handleCenterA.y);
[[UIColor colorWithWhite:1.0 alpha:1.0]set];
UIImage *myImage = [UIImage imageNamed:#"clock-marker.png"];
//this will give me the result of image 1
[myImage drawInRect:CGRectMake(handleCenterA.x-35, handleCenterA.y-40, TB_BUTTON_WIDTH, TB_BUTTON_WIDTH)];
//this will give me the result of image 2
[myImage drawInRect:CGRectMake(handleCenterA.x-35, handleCenterA.y-40, TB_BUTTON_WIDTH, TB_BUTTON_WIDTH)];
CGContextRestoreGState(ctx);
}
#pragma mark - Math -
/** Move the Handle **/
-(void)movehandle:(CGPoint)lastPoint{
//Get the center
CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
//Calculate the direction from a center point and a arbitrary position.
//float currentAngle = AngleFromNorth(centerPoint, lastPoint, NO);
//int angleInt = floor(currentAngle);
//Calculate the direction from the center point to an arbitrary position.
float currentAngle = AngleFromNorth(centerPoint, lastPoint, NO);
int angleInt = 360 - floor(currentAngle);
if (sliderLock == SliderLockedStart) {
self.startAngle = angleInt;
}
//Redraw
[self setNeedsDisplay];
}
- (CGPoint)centerPointFromAngel:(int)angleInt {
CGPoint point = [self pointFromAngle:angleInt];
point.x += TB_BUTTON_WIDTH/2;
point.y += TB_BUTTON_WIDTH/2;
return point;
}
- (CGFloat)distanceBetween:(CGPoint)p1 and:(CGPoint)p2 {
CGFloat xDist = (p2.x - p1.x);
CGFloat yDist = (p2.y - p1.y);
return sqrt((xDist * xDist) + (yDist * yDist));
}
/** Given the angle, get the point position on circumference **/
-(CGPoint)pointFromAngle:(int)angleInt{
//Circle center
CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - (TB_BUTTON_WIDTH/2), self.frame.size.height/2 - (TB_BUTTON_WIDTH/2));
//The point position on the circumference
CGPoint result;
result.y = round(centerPoint.y + radius * sin(ToRad(-angleInt))) ;
result.x = round(centerPoint.x + radius * cos(ToRad(-angleInt)));
return result;
}
//Sourcecode from Apple example clockControl
//Calculate the direction in degrees from a center point to an arbitrary position.
static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) {
CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y);
float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0;
v.x /= vmag;
v.y /= vmag;
double radians = atan2(v.y,v.x);
result = ToDeg(radians);
return (result >=0 ? result : result + 360.0);
}

finally solved it.
/** Given the angle, get the point position on circumference **/
-(CGPoint)pointFromAngle:(int)angleInt{
//Circle center//TB_BUTTON_WIDTH
CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - (TB_BUTTON_WIDTH/2), self.frame.size.height/2 - (TB_BUTTON_WIDTH/2));
//The point position on the circumference radius
CGPoint result;
result.y = round(centerPoint.y + 120 * sin(ToRad(-angleInt))) ;
result.x = round(centerPoint.x + 120 * cos(ToRad(-angleInt)));
NSLog(#"centerPoint %#",NSStringFromCGPoint(centerPoint));
NSLog(#"result %#",NSStringFromCGPoint(result));
return result;
}

Related

How to Pass Locations From CLLocationManager

How to Pass latitude and Longitude values form CLLocation Manager to My CustomView. I have A ViewController With CLLocationManger where iam getting the Locations, I have Another UIView Class with drawRect Where i have Divided the View with Coordinates as
#define EARTH_RADIUS 6371
- (void)drawRect:(CGRect)rect
{
CGPoint latLong = {41.998035, -116.012215};
CGPoint newCoord = [self convertLatLongCoord:latLong];
NSLog(#"Cartesian Coordinate: (%f, %f)",newCoord.x, newCoord.y);
//Draw dot at coordinate
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0
green:92.0/255.0
blue:136.0/255.0
alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(newCoord.x, newCoord.y, 100, 100));
}
-(CGPoint)convertLatLongCoord:(CGPoint)latLong
{
CGFloat x = EARTH_RADIUS * cos(latLong.x) * cos(latLong.y);
CGFloat y = EARTH_RADIUS * cos(latLong.x) * sin(latLong.y);
return CGPointMake(x, y);
}
I have Took the CGPoint latLong = {41.998035, -116.012215} static.
Can you say me How to Pass A ViewController Values to UIView Class
You would generally have a property in you UIView subclass for your coordinate (either using your CGPoint or perhaps a CLLocationCoordinate2D) and then call setNeedsDisplay so that the device knows that it needs to call your drawRect method.
Thus, have a property:
#property (nonatomic) CLLocationCoordinate2D coordinate;
And then update the implementation of your view as such:
- (void)setCoordinate:(CLLocationCoordinate2D)coordinate
{
_coordinate = coordinate;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
CGPoint newCoord = [self convertLatLongCoord:self.coordinate];
NSLog(#"Cartesian Coordinate: (%f, %f)",newCoord.x, newCoord.y);
//Draw dot at coordinate
CGColorRef darkColor = [[UIColor colorWithRed:21.0/255.0
green:92.0/255.0
blue:136.0/255.0
alpha:1.0] CGColor];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, darkColor);
CGContextSetStrokeColorWithColor(context, darkColor);
CGContextFillRect(context, CGRectMake(newCoord.x, newCoord.y, 100.0, 100.0));
}
// I assume you're using the algorithm from here: https://stackoverflow.com/a/1185413/1271826
- (CGPoint)convertLatLongCoord:(CLLocationCoordinate2D)coordinate
{
CGFloat x = EARTH_RADIUS * cos(coordinate.latitude * M_PI / 180.0) * cos(coordinate.longitude * M_PI / 180.0);
CGFloat y = EARTH_RADIUS * cos(coordinate.latitude * M_PI / 180.0) * sin(coordinate.longitude * M_PI / 180.0);
// TODO: The above calculates x and y values from -EARTH_RADIUS to EARTH_RADIUS.
// You presumably want to scale this appropriately for your view. The
// specifics will vary based upon your desired user interface.
return CGPointMake(x, y);
}
Then, when you want to update your view, you can do something like:
myCustomView.coordinate = CLLocationCoordinate2DMake(41.998035, -116.012215);
While I've tried to remedy some flaws in convertLatLongCoord, it's still not perfect, as it will yield values ranging from -EARTH_RADIUS to EARTH_RADIUS (which obviously won't work for a CGRect of a UIView, which is expecting values between zero and the width/height of the view).
I assume the underlying algorithm is one like discussed here: Converting from longitude\latitude to Cartesian coordinates. I've tried to fix the degrees to radians conversion needed by cos and sin, you still need to scale this and translate it to values appropriate for what portion of the map/radar you're intending to show.
Based on the comment that you want to "find your boat" it sounds like you want the heading from your current location to a specified location (your boat). That calculation is this
+ (float)getHeadingForDirectionFromCoordinate:(CLLocationCoordinate2D)fromLoc toCoordinate:(CLLocationCoordinate2D)toLoc
{
float fLat = degreesToRadians(fromLoc.latitude);
float fLng = degreesToRadians(fromLoc.longitude);
float tLat = degreesToRadians(toLoc.latitude);
float tLng = degreesToRadians(toLoc.longitude);
float degree = radiansToDegrees(atan2(sin(tLng-fLng)*cos(tLat), cos(fLat)*sin(tLat)-sin(fLat)*cos(tLat)*cos(tLng-fLng)));
if (degree >= 0) {
return degree;
} else {
return 360+degree;
}
}

"Ghost rectangle" affecting program?

Yesterday there was a rectangle stuck in the top corner of my program, and for some reason no matter what I did I could not get it out of there. Today I re-ran the program, and it disappeared, but I believe it's memory is still stuck because it's affecting my code.
I'm trying to detect when rectangle A (motioned by accelerometer) contacts rectangle B (randomly placed; motionless). Nothing happens when A contacts B, however when I move A into the top corner where the ghost rectangle was all of yesterday it runs my if statement continuously until I move it away.
Here is the code just incase it's needed
#synthesize Button;
#synthesize Rand;
//Awaking the accelerometer
-(void) awakeaccelerometer
{
[[UIAccelerometer sharedAccelerometer]setUpdateInterval:1.0/50.0];//<---Sensitivity
[[UIAccelerometer sharedAccelerometer]setDelegate:self];
NSLog(#"Accelerometer is awake");
float randX = arc4random() % 320;
float randY = arc4random() % 548;
CGPoint randNewPlace = CGPointMake(randX, randY);
Rand.center = randNewPlace;
}
//Controlling the accelerometer
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
#define MovingObjectRadius 4
//Acceleration for player
valueX = acceleration.x * 10; //speeds
valueY = acceleration.y * -10; //speeds
//Create new integers
int newX = (int)(Button.center.x + valueX);
int newY = (int)(Button.center.y + valueY);
//Position Validate...This stops the movements from going past the screen; 320 pixels
//For X
if (newX > (320 - MovingObjectRadius))
{
newX = (320 - MovingObjectRadius);
}
if (newX < (0 + MovingObjectRadius))
{
newX = (0 + MovingObjectRadius);
}
//For Y
if (newY > (548 - MovingObjectRadius))
{
newY = (548 - MovingObjectRadius);
}
if (newY < (0 + MovingObjectRadius))
{
newY = (0 + MovingObjectRadius);
}
//Make the new point
CGPoint buttonNewCenter = CGPointMake(newX,newY);
Button.center = buttonNewCenter;
CGRect blockRect = CGRectMake(newX, newY, 20, 20);
CGRect targetRect = CGRectMake(randX, randY, 20, 20);
if (CGRectIntersectsRect(blockRect, targetRect))
{
float tnewX = arc4random() % 320;
float tnewY = arc4random() % 548;
CGPoint randNewPl = CGPointMake(tnewX, tnewY);
Rand.center = randNewPl;
}
}

How to draw polygons in cocoa touch using UIBezierPath

I want to draw polygon of different sides (4-12). What is the logic for drawing a polygon. For e.g. if user selects 6 side, it should draw a hexagon, if user enters 8 sides it should draw a octagon. I have found the following code but i also want to resize the UIView in which i am drawing a polygon so that the shape inside of the view also grows along with the view. Any body can help me please. Following is the code i am using currently but it is not positioned at the center also when i resize the view that shape moves to another position in the view.
int radius = MINIMUM(widht, height)*0.4 ;
for (int i = 0; i < _numberOFsides; i++){
CGPoint point = CGPointMake(widht/2+radius *cosf(i*2*M_PI/_numberOFsides), widht/2+radius*sinf(i*2*M_PI/_numberOFsides));
if (i==0) {
[_shapePath moveToPoint:point];
}
else{
[_shapePath addLineToPoint:point];
[_shapePath stroke];
}
}
now to resize ur UIBazierPath you can add below code,
CGRect bazierRect = CGPathGetBoundingBox(bezierpath.CGPath)
CGFloat scaleX = view.frame.size.width / bazierRect.frame.size.width;
CGFloat scaleY = view.frame.size.height / bazierRect.frame.size.height;
CGAffineTransform transform = CGAffineTransformMakeScale(scaleX, scaleY);
CGPathRef newPath = CGPathCreateCopyByTransformingPath(bezierpath.CGPath, &transform);
bezierPath.CGPath = newPath;
CFRelease(newPath);
If you want to make a regular polygon with any number of sides the following code will give you the vertices of each edge and it is easy to rescale in size and number of sides:
int n = 10; //number of edges
float j = 20; //length of each edge
float x = 130;
float y = 250;//the point 130,250 will be at the bottom of the figure
float angle = 2*M_PI;
for (int i = 0; i < n; i++) {
CGRect frame = CGRectMake(x, y, 2, 2);//put a dot on x,y
NSLog(#"%f | %f, %f", angle, x, y);
x = x + j*cosf(angle);
y = y + j*sinf(angle); //move to the next point
angle = angle - 2*M_PI/n; //update the angle
//display the dot
UIView *rect = [[UIView alloc] initWithFrame:frame];
rect.backgroundColor = [UIColor blueColor];
[self.view addSubview:rect];
}
Hope this helps. If you have any questions feel free to ask and have a great day!
~Deadly Porcupine

Cocos2D and iPhone's accelerometer

good afternoon!
Today I've started to develop a game and I got a trouble. So, first at all I would like to say that I have no experience developing games...
So, I've a CCSprite in the layer and I want to move this between the scene with a margin (top, bottom, left and right).
The minimum X should be -0.8 (in X-axis using the accelerometer) and the maximum 8. The minimun Y should be -1 (in Y-axis) or 0 in Z-axis and the maximum 0 (in Y-axis) or -1 (in Z-axis).
Ok, knowing this, I've tried to do this using the range between minimum and maximum space and accelerometer value but I haven't getting this working vertically (Y-axis on the iPhone). Then I got a done code in the web but this don't works when I want to move the object to back (the object only goes).
Did someone know how to fix this?
My actual code:
- (void)updatePosition:(ccTime)dt {
CGSize winSize = [[CCDirector sharedDirector] winSize];
float maxY = winSize.height - car.contentSize.height/2 - 20;
float minY = car.contentSize.height/2 + 20;
float newY = car.position.y + (carPointsPerSecY * dt);
newY = MIN(MAX(newY, minY), maxY);
float maxX = winSize.width - car.contentSize.width/2 - 40;
float minX = car.contentSize.width/2 + 40;
float newX = car.position.x + (carPointsPerSecX * dt);
newX = MIN(MAX(newX, minX), maxX);
car.position = ccp(newX, newY);
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
float speedY = acceleration.y * 500;
if(carPointsPerSecY < speedY) {
carPointsPerSecY = MIN(carPointsPerSecY + 10, speedY);
} else {
carPointsPerSecY = MAX(carPointsPerSecY - 2, speedY);
}
float speedX = acceleration.x * 200;
if(carPointsPerSecX < speedX) {
carPointsPerSecX = MIN(carPointsPerSecX + 10, speedX);
} else {
carPointsPerSecX = MAX(carPointsPerSecX - 10, speedX);
}
NSLog(#"Acceleration: X (%f) - Y (%f) - Z (%f)", acceleration.x, acceleration.y, acceleration.z);
}
I'm not sure I completely understand what you want but I hope this helps you with your end goal:
-(void)updatePosition:(ccTime)dt {
CGSize size = [[CCDirector sharedDirector] winSize];
int margin = 20;
float speed = 15;
float maxX = size.width - car.contentSize.width / 2 - margin;
float minX = car.contentSize.width / 2 + margin;
float maxY = size.height - car.contentSize.height / 2 - margin;
float minY = car.contentSize.height / 2 + margin;
float newX = MIN(MAX(car.position.x + xAccel * speed, minX), maxX);
float newY = MIN(MAX(car.position.y + yAccel * speed, minY), maxY);
car.position = ccp(newX, newY);
}
//define in header: float xAccel, yAccel;
- (void)accelerometer: (UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration {
yAccel = acceleration.x;
xAccel = -acceleration.y;
}

Scaling image anchored at cetain point

Is it possible to scale an image by using a specified point as the anchor, i.e. the image "grows" out from this point?
Scaling isn't based on a point. What you want to do is move it so that the the corresponding point on the new and original images is at the same point. To do this, just adjust the (x,y) position of the image. Use the proportional distance to the edge multiplied by the difference in size.
You could do something like this (based on solution using UIPinchGesureRecognize, but you can get the idea...).
This is the selector called for the gestureRecognizer:
CGPoint newDistanceFromCenter;
CGPoint distanceFromCenter;
- (void) scale:(id)sender
{
UIPinchGestureRecognizer *recognizer = (UIPinchGestureRecognizer*)sender;
if(recognizer.state == UIGestureRecognizerStateBegan)
{
CGPoint pinchPoint = [recognizer locationInView:self];
distanceFromCenter.x = self.center.x - pinchPoint.x;
distanceFromCenter.y = self.center.y - pinchPoint.y;
}
else if(recognizer.state == UIGestureRecognizerStateChanged)
{
CGAffineTransform currentTransform = self.transform;
CGFloat scale = recognizer.scale;
newDistanceFromCenter.x = (distanceFromCenter.x * scale);
newDistanceFromCenter.y = (distanceFromCenter.y * scale);
CGPoint center = scalingImage_.center;
center.x -= (distanceFromCenter.x - newDistanceFromCenter.x);
center.y -= (distanceFromCenter.y - newDistanceFromCenter.y);
self.center = center;
distanceFromCenter = newDistanceFromCenter;
self.transform = CGAffineTransformScale(currentTransform, scale, scale);
recognizer.scale = 1;
}
}