2010-09-21 20 views
5

की दिशा के आधार पर घूमने के लिए एक छवि कैसे बना सकता हूं, मैं उपयोगकर्ता स्वाइप के आधार पर एक सर्कल छवि को स्पिन करने की कोशिश कर रहा हूं.अब मैंने दो भागों के रूप में विचार करके किया है। एक बाएं तरफ है और दूसरा सही पक्ष है। यदि उपयोगकर्ता दाएं आधे से नीचे स्वाइप करता है तो इसका मतलब है कि यह घड़ी की दिशा में घूमता है और स्वाइप करने का मतलब विरोधी घड़ी के अनुसार होता है। बाईं तरफ मैंने इसके विपरीत किया है। तो अब मेरी छवि केवल तभी घूमती है जब मैं बाएं और दाएं आधा स्पर्श करता हूं .. ऊपर और नीचे स्पर्श करने पर .. यह अलग-अलग व्यवहार करता है। मैं भी रेडियंस की गणना ny की कोशिश की है .. इसकी भी काम नहीं कर किसी भी एक सुझाव दे सकते हैं मुझे घड़ी की पहचान या एक बेहतर तरीके से बुद्धिमान anticlock करने के लिए ...मैं अपनी अंगुली स्वाइप

यू धन्यवाद, लक्ष्मी jones

उत्तर

1

Have आपने कभी भी अपनी समस्या के लिए this ट्यूटोरियल की कोशिश की है। इससे आपको निश्चित रूप से मदद मिलेगी।

कड़ी चोट

#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 

यह आपकी मदद करेगा :)

5

आपको इस समस्या को ट्राइनोमेट्री के साथ संपर्क करना चाहिए। मान लें कि आप कड़ी चोट का प्रारंभिक बिंदु (A1, B1) और कड़ी चोट के अंत बिंदु पता (A2, बी 2) हलकों केंद्र (एक्स, वाई)

enter image description here

पर है हम के अंतर पता है रेखाओं (एक्स, वाई) -> (ए 1, बी 1) और (एक्स, वाई) -> (ए 2, बी 2) -> (ए 2, बी 2) - हम जानते हैं कि ऊपर उल्लिखित कोण सकारात्मक या नकारात्मक है या नहीं, हम जानते हैं कि घड़ी की दिशा में घुमाएं या anticlockwise घुमाएंगे या नहीं।

रेखा से बने कोण को नीचे गणना की जाती है।

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 
    } 
} 

देखें here पता है कि कैसे तन-उलटा गणना करने के लिए लाल कोण लाल बनें।

इसी प्रकार कोण हरे रंग के मूल्य की गणना करें। ऐसा करने के बाद कि हरे और लाल के मूल्य की तुलना करने से आपको पता चल जाएगा कि क्या करना है।

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

कड़ी चोट के त्वरण/वेग डेटा का उपयोग कर आप एक ही त्वरण/वेग के साथ चक्र बारी बारी से कर सकते हैं।

0

हालांकि त्रिकोणमिति गणित के लिए एक दृष्टिकोण है, लेकिन यह आसान है और वैक्टरों के साथ ऐसा करने के लिए बहुत कम प्रोसेसर शक्ति की आवश्यकता होती है।

संदर्भ के लिए एक तस्वीर:

enter image description here

डायल आप स्पिन करना चाहते हैं के केंद्र बिंदु सी है।

यूजर इंटरफेस से आप एक कड़ी चोट प्रारंभ बिंदु मिल चाहिए एक और "स्वाइप वेक्टर" रों पता चलता है कि कैसे उपयोगकर्ता की उंगली बढ़ रहा है। ओएस केवल एक दूसरे बिंदु बी प्रदान करता है तो कुछ समय के के बाद एक, तो गणना रों = बी - एक

आप रोंस्पर्श चक्र सी पर केन्द्रित एक के माध्यम से गुजर रहा है कि के घटक गणना करने के लिए चाहते हैं। यह उपयोगकर्ता को अपने स्वाइप को कहीं भी शुरू करने की अनुमति देगा और इसे सी के बारे में टोक़ के रूप में माना जाएगा। यह अंतर्ज्ञानी होना चाहिए।

यह मुश्किल नहीं है। सर्कल का त्रिज्या वेक्टर आर = - सी के रूप में दिखाया गया है। इस वेक्टर के लंबवत को "आर पेप" कहा जाता है जिसे चित्र में "थंबटैक" प्रतीक के साथ दिखाया गया है। यह सिर्फ बिंदु (-y, x) है जहां x और y r के घटक हैं।

पी का प्रक्षेपण perp (आर) पर हस्ताक्षर किए की लंबाई सिर्फ एक सामान्यीकृत डॉट उत्पाद है:

enter image description here

यह एक अदिश कि सकारात्मक है है अगर रोटेशन चारों ओर काउंटर दक्षिणावर्त है सी और घड़ी की दिशा में ऋणात्मक। तो संकेत आपको घूर्णन की दिशा बताता है। पूर्ण मूल्य आपको बताता है कि घूमने के लिए कितना तेज़ या कितना तेज़ है।

मान लीजिए हम पहले से ही वेक्टर स्वाइप है रों संग्रहीत sx और sy और केंद्र सी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 है।

केवल चेतावनी छूता एक कि सी के करीब हैं अनदेखी करने के लिए है। वे शून्य से बहुत बड़े आउटपुट मान या विभाजन का उत्पादन कर सकते हैं। इसे ठीक करना आसान है। बस r की लंबाई की जांच करें और यदि यह कुछ उचित मान से कम है तो छोड़ दें।

0

यदि आपका वर्तमान समाधान आपके लिए "लगभग ठीक" है - करने के लिए सबसे सरल बात होगी ...बस दो और क्षेत्रों के साथ यह फिक्सिंग: starting swipe areas

अब आप अपनी छवि घड़ी की स्पिन जब भी उपयोगकर्ता स्वाइप
- (क्षेत्र एक में शुरू किया था)
सही है या ऊपर - दाएं या नीचे (क्षेत्र बी में शुरू किया था)
- छोड़ दिया है या नीचे (क्षेत्र विकास में शुरू किया था)
- बाएं या ऊपर (क्षेत्र सी में शुरू किया था)

.... बाकी - यह घड़ी की विपरीत दिशा स्पिन।

0

मैं Xamarin.iOS के साथ इसी तरह कुछ किया है लेकिन मुझे शक है आप सी # कोड देखना चाहते हैं तो हो सकता है यह GitHub परियोजना आप आवश्यक जानकारी दे देंगे:

https://github.com/hollance/MHRotaryKnob

संबंधित मुद्दे