How can I make the image rotate depending on the direction of the finger?

I am trying to create a circular image based on a custom swipe.Now, I did, considering as two parts. one is left and the other is right. If the user moves from the right half, it means that he rotates clockwise, and the swipe counterclockwise. On the left side, I did the opposite. So, now my image will rotate perfectly only when I touch the left and right halves .. when touching the top and bottom .. it behaves differently. I even tried to calculate the radians .. it doesn’t work either Can someone suggest me better identify clockwise or counterclockwise ...

Thank you Lakshmi Jones

+5
source share
5 answers

You must approach this problem with a trignometer. Assuming you know the start point of the swipe (a1, b1) and the end point of the swipe (a2, b2) The center of the circles is at the point (x, y)

enter image description here

If we know the difference in angles created by the lines (x, y) → (a1, b1) and (x, y) → (a2, b2), we will know whether to rotate clockwise or counterclockwise, based on The above angle is positive or negative.

The line angle is calculated below. Let the red corner be red

if(a1-x==0){
    if(b1-y>0) red=pi/2
    else red = 3*pi/2
}
else{
  tan(red) = abs((b1-y)/(a1-x))
  red = tan-inverse( abs((b1-y)/(a1-x)) )
  if(a1-x<0){
    if(b1-y<=0)
        red+=pi;
    else
        red+=pi/2
  }
  else if(a1-x>0 && b1-y<0){
      red+=3*pi/2
  }
}

See here for how to calculate tan inverses.

Similarly, calculate the green value. After that, simply comparing the green and red values ​​will let you know what to do.

if(red - green == pi || red - green == 0){
    do_nothing();        
}else if(red - green > 0){
    rotate_clockwise();        
}else{
    rotate_anticlockwise();
}

/ , /.

+5

- . .

.h

#import <UIKit/UIKit.h>
#import "SMRotaryProtocol.h"

@interface SMRotaryWheel : UIControl

@property (weak) id <SMRotaryProtocol> delegate;
@property (nonatomic, strong) UIView *container;
@property int numberOfSections;
@property CGAffineTransform startTransform;
@property (nonatomic, strong) NSMutableArray *cloves;
@property int currentValue;


- (id) initWithFrame:(CGRect)frame andDelegate:(id)del withSections:(int)sectionsNumber;

.m

#import "SMRotaryWheel.h"
#import <QuartzCore/QuartzCore.h>
#import "SMCLove.h"

@interface SMRotaryWheel()
    - (void)drawWheel;
    - (float) calculateDistanceFromCenter:(CGPoint)point;
    - (void) buildClovesEven;
    - (void) buildClovesOdd;
    - (UIImageView *) getCloveByValue:(int)value;
    - (NSString *) getCloveName:(int)position;
@end

static float deltaAngle;
static float minAlphavalue = 0.6;
static float maxAlphavalue = 1.0;

@implementation SMRotaryWheel

@synthesize delegate, container, numberOfSections, startTransform, cloves, currentValue;


- (id) initWithFrame:(CGRect)frame andDelegate:(id)del withSections:(int)sectionsNumber {

    if ((self = [super initWithFrame:frame])) {

        self.currentValue = 0;
        self.numberOfSections = sectionsNumber;
        self.delegate = del;
        [self drawWheel];

    }
    return self;
}



- (void) drawWheel {

    container = [[UIView alloc] initWithFrame:self.frame];

    CGFloat angleSize = 2*M_PI/numberOfSections;

    for (int i = 0; i < numberOfSections; i++) {

        UIImageView *im = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"segment.png"]];

        im.layer.anchorPoint = CGPointMake(1.0f, 0.5f);
        im.layer.position = CGPointMake(container.bounds.size.width/2.0-container.frame.origin.x, 
                                        container.bounds.size.height/2.0-container.frame.origin.y); 
        im.transform = CGAffineTransformMakeRotation(angleSize*i);
        im.alpha = minAlphavalue;
        im.tag = i;

        if (i == 0) {
            im.alpha = maxAlphavalue;
        }

        UIImageView *cloveImage = [[UIImageView alloc] initWithFrame:CGRectMake(12, 15, 40, 40)];
        cloveImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"icon%i.png", i]];
        [im addSubview:cloveImage];

        [container addSubview:im];

    }

    container.userInteractionEnabled = NO;
    [self addSubview:container];

    cloves = [NSMutableArray arrayWithCapacity:numberOfSections];

    UIImageView *bg = [[UIImageView alloc] initWithFrame:self.frame];
    bg.image = [UIImage imageNamed:@"bg.png"];
    [self addSubview:bg];

    UIImageView *mask = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 58, 58)];
    mask.image =[UIImage imageNamed:@"centerButton.png"] ;
    mask.center = self.center;
    mask.center = CGPointMake(mask.center.x, mask.center.y+3);
    [self addSubview:mask];

    if (numberOfSections % 2 == 0) {

        [self buildClovesEven];

    } else {

        [self buildClovesOdd];

    }

    [self.delegate wheelDidChangeValue:[self getCloveName:currentValue]];


}


- (UIImageView *) getCloveByValue:(int)value {

    UIImageView *res;

    NSArray *views = [container subviews];

    for (UIImageView *im in views) {

        if (im.tag == value)
            res = im;

    }

    return res;

}

- (void) buildClovesEven {

    CGFloat fanWidth = M_PI*2/numberOfSections;
    CGFloat mid = 0;

    for (int i = 0; i < numberOfSections; i++) {

        SMClove *clove = [[SMClove alloc] init];
        clove.midValue = mid;
        clove.minValue = mid - (fanWidth/2);
        clove.maxValue = mid + (fanWidth/2);
        clove.value = i;


        if (clove.maxValue-fanWidth < - M_PI) {

            mid = M_PI;
            clove.midValue = mid;
            clove.minValue = fabsf(clove.maxValue);

        }

        mid -= fanWidth;


        NSLog(@"cl is %@", clove);

        [cloves addObject:clove];

    }

}


- (void) buildClovesOdd {

    CGFloat fanWidth = M_PI*2/numberOfSections;
    CGFloat mid = 0;

    for (int i = 0; i < numberOfSections; i++) {

        SMClove *clove = [[SMClove alloc] init];
        clove.midValue = mid;
        clove.minValue = mid - (fanWidth/2);
        clove.maxValue = mid + (fanWidth/2);
        clove.value = i;

        mid -= fanWidth;

        if (clove.minValue < - M_PI) {

            mid = -mid;
            mid -= fanWidth; 

        }


        [cloves addObject:clove];

        NSLog(@"cl is %@", clove);

    }

}

- (float) calculateDistanceFromCenter:(CGPoint)point {

    CGPoint center = CGPointMake(self.bounds.size.width/2.0f, self.bounds.size.height/2.0f);
    float dx = point.x - center.x;
    float dy = point.y - center.y;
    return sqrt(dx*dx + dy*dy);

}

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint touchPoint = [touch locationInView:self];
    float dist = [self calculateDistanceFromCenter:touchPoint];

    if (dist < 40 || dist > 100) 
    {
        // forcing a tap to be on the ferrule
        NSLog(@"ignoring tap (%f,%f)", touchPoint.x, touchPoint.y);
        return NO;
    }

    float dx = touchPoint.x - container.center.x;
    float dy = touchPoint.y - container.center.y;
    deltaAngle = atan2(dy,dx); 

    startTransform = container.transform;

    UIImageView *im = [self getCloveByValue:currentValue];
    im.alpha = minAlphavalue;

    return YES;

}

- (BOOL)continueTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
{

    CGPoint pt = [touch locationInView:self];

    float dist = [self calculateDistanceFromCenter:pt];

    if (dist < 40 || dist > 100) 
    {
        // a drag path too close to the center
        NSLog(@"drag path too close to the center (%f,%f)", pt.x, pt.y);

        // here you might want to implement your solution when the drag 
        // is too close to the center
        // You might go back to the clove previously selected
        // or you might calculate the clove corresponding to
        // the "exit point" of the drag.

    }

    float dx = pt.x  - container.center.x;
    float dy = pt.y  - container.center.y;
    float ang = atan2(dy,dx);

    float angleDifference = deltaAngle - ang;

    container.transform = CGAffineTransformRotate(startTransform, -angleDifference);

    return YES;

}

- (void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event
{

    CGFloat radians = atan2f(container.transform.b, container.transform.a);

    CGFloat newVal = 0.0;

    for (SMClove *c in cloves) {

        if (c.minValue > 0 && c.maxValue < 0) { // anomalous case

            if (c.maxValue > radians || c.minValue < radians) {

                if (radians > 0) { // we are in the positive quadrant

                    newVal = radians - M_PI;

                } else { // we are in the negative one

                    newVal = M_PI + radians;                    

                }
                currentValue = c.value;

            }

        }

        else if (radians > c.minValue && radians < c.maxValue) {

            newVal = radians - c.midValue;
            currentValue = c.value;

        }

    }

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.2];

    CGAffineTransform t = CGAffineTransformRotate(container.transform, -newVal);
    container.transform = t;

    [UIView commitAnimations];

    [self.delegate wheelDidChangeValue:[self getCloveName:currentValue]];

    UIImageView *im = [self getCloveByValue:currentValue];
    im.alpha = maxAlphavalue;

}

- (NSString *) getCloveName:(int)position {

    NSString *res = @"";

    switch (position) {
        case 0:
            res = @"Circles";
            break;

        case 1:
            res = @"Flower";
            break;

        case 2:
            res = @"Monster";
            break;

        case 3:
            res = @"Person";
            break;

        case 4:
            res = @"Smile";
            break;

        case 5:
            res = @"Sun";
            break;

        case 6:
            res = @"Swirl";
            break;

        case 7:
            res = @"3 circles";
            break;

        case 8:
            res = @"Triangle";
            break;

        default:
            break;
    }

    return res;
}



@end

, ,

- (float) calculateDistanceFromCenter:(CGPoint)point

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

- (BOOL)continueTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event

- (void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent*)event

:)

+1

, .

:

enter image description here

, , C.

A " " , , . B A, s= B - .

s, C, A. C. .

. r= A - C. "r perp", "thumbtack" . (-y, x), x y - r.

p perp (r) :

enter image description here

, , C, - . . , .

, s, sx sy, C cx cy. :

r_perp_x = cy - ay; r_perp_y = ax - cx;
signed_length_p = (sx * r_perp_x + sy * r_perp_y) / sqrt(r_perp_x ^ 2 + r_perp_y ^ 2)

signed_length_p.

- A, C. . . r , .

0

" " - ... : starting swipe areas

, - ( A)
- ( B)
- ( D)
- ( C)

.... else - .

0

- Xamarin.iOS, , #, , , GitHub :

https://github.com/hollance/MHRotaryKnob

0

All Articles