2011-09-28 24 views
5

में मिनट का हाथ ले जाएं मैं अवधारणा ऐप का एक सरल सबूत लिखने की कोशिश कर रहा हूं जो उपयोगकर्ता को घड़ी के मिनट के घूमने की अनुमति देता है। मुझे OnTouchEvent के लिए सही तर्क के साथ आने में कठिनाई हो रही है।Android घड़ी

अब तक मैं निम्नलिखित कोड है:

public boolean onTouchEvent(MotionEvent e) { 

     float x = e.getX(); 
     float y = e.getY(); 

    switch (e.getAction()) { 
    case MotionEvent.ACTION_MOVE: 
     //find an approximate angle between them. 

     float dx = x-cx; 
     float dy = y-cy; 
     double a=Math.atan2(dy,dx); 

     this.degree = Math.toDegrees(a); 
     this.invalidate(); 
    } 
    return true; 
    } 


protected void onDraw(Canvas canvas) { 
    super .onDraw(canvas); 

    boolean changed = mChanged; 
    if (changed) { 
     mChanged = false; 
    } 

    int availableWidth = getRight() - getLeft(); 
    int availableHeight = getBottom() - getTop(); 

    int x = availableWidth/2; 
    int y = availableHeight/2; 

    cx = x; 
    cy = y; 

    final Drawable dial = mDial; 

    int w = dial.getIntrinsicWidth() + 100; 
    int h = dial.getIntrinsicHeight() + 100; 

    boolean scaled = false; 

    if (availableWidth < w || availableHeight < h) { 
     scaled = true; 

     float scale = Math.min((float) availableWidth/(float) w, (float) availableHeight/(float) h); 

     canvas.save(); 
     canvas.scale(scale, scale, x, y); 
    } 

    if (changed) 
    { 
     dial.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
    } 

    dial.draw(canvas); 

    canvas.save(); 
    float hour = mHour/12.0f * 360.0f; 

    canvas.rotate(hour, x, y); 

    final Drawable hourHand = mHourHand; 

    if (changed) { 

     w = hourHand.getIntrinsicWidth() + 30; 
     h = hourHand.getIntrinsicHeight() + 30; 

     hourHand.setBounds(x - (w/2), y - (h/2), x + (w/2), y + (h/2)); 
    } 

    hourHand.draw(canvas); 
    canvas.restore(); 

    canvas.save(); 
    float minute = mMinutes/60.0f * 360.0f; 

    if (bearing == 0) 
    { 
     canvas.rotate(minute, x, y); 
    } 
    else 
    { 
     canvas.rotate((float)bearing, x, y); 
    } 

    final Drawable minuteHand = mMinuteHand; 

    if (changed) { 

     w = minuteHand.getIntrinsicWidth() + 30; 
     h = minuteHand.getIntrinsicHeight() + 30; 

     minuteHand.setBounds(x - w, y - h, x + w, y + h); 
    } 

    minuteHand.draw(canvas); 
    canvas.restore(); 

    if (scaled) { 
     canvas.restore(); 
    } 
} 

फिर उस आधार पर, मेरे OnDraw विधि निर्दिष्ट "this.degree" (सिर्फ canvas.rotate कॉल) के लिए सूई घूमता है। मुझे लगता है कि मेरा गणित यहां बंद है। मैंने यहां उदाहरण का पालन करने की कोशिश की: Calculate angle for rotation in Pie Chart, लेकिन यह अभी भी मिनट के हाथ को सही ढंग से घूर्णन नहीं कर रहा है। किसी भी सहायता की सराहना की जाएगी।

उत्तर

2

गणित सही दिखता है। आपकी गणना आपको टच इवेंट का कोण देनी चाहिए, जहां केंद्र बिंदु के सटीक दाएं कोने वाला स्पर्श आपको 0 डिग्री देना चाहिए।

कुछ बातों के लिए

  • बाहर देखने के लिए सुनिश्चित करें कि आप सही दिशा में घूमना कर रहे हैं। इसे सीधे रखना मुश्किल है, और इस प्रकार इसे पेंच करना आसान है
  • सुनिश्चित करें कि आप ध्यान में रखते हैं कि 0 का मान यह है कि मिनट का हाथ दाईं ओर इंगित करना चाहिए। उदाहरण के लिए, यदि आप ऊपर की ओर इशारा करते हुए एक मिनट के हाथ से शुरू करते हैं, तो आपको अपनी गणना के परिणामस्वरूप 90 डिग्री जोड़ना/घटा देना होगा (घूर्णन की दिशा के आधार पर - सुनिश्चित नहीं है कि कौन सा सही है)
  • बनाएं सुनिश्चित करें कि (सीएक्स, साइ) केंद्र बिंदु है जिसके आस-पास कोण
  • घूर्णन करते समय, आपको या तो 3 arg Canvas.rotate(float, float, float) विधि का उपयोग करने की आवश्यकता होगी, या यह सुनिश्चित करने के लिए एक अतिरिक्त अनुवाद अलग-अलग जोड़ना होगा, ताकि आप यह सुनिश्चित कर सकें कि आप सही बिंदु के चारों ओर घूर्णन कर रहे हैं। किसी भी अनुवाद के बिना, यह चारों ओर घूमने जाएगा (0,0) (दृश्य के ऊपर बाईं ओर)

अधिक रोटेशन पर: रोटेशन हमेशा "वर्तमान" (0,0) बिंदु के आसपास होता है। "वर्तमान" से, मेरा मतलब है कि वर्तमान मैट्रिक्स लागू होने के बाद (0,0) बिंदु। जब आप पहली बार ड्रॉ में प्रवेश करते हैं, तो (0,0) बिंदु दृश्य के ऊपरी-बाएं कोने होना चाहिए। जब भी आप एक अनुवाद/स्केलिंग/आदि लागू करते हैं, तो आप संभावित रूप से बदल जाएंगे (0,0) बिंदु, दृश्य के सापेक्ष।

मुझे लगता है कि निम्नलिखित की तरह कुछ रोटेशन की सही केंद्र स्थापित करने के लिए काम करना चाहिए, के संबंध में:

//first we save the initial matrix, so we can easily get 
//back to this state after we're done rotating 
canvas.save(); 
//I *think* you need to negate the center offsets here, 
//because you are conceptually moving the canvas, rather 
//than moving the center directly 
canvas.translate(-cx, -cy); 
//<perform the rotation and draw the clock hand> 
//... 

//and now restore the matrix back to the initial state 
canvas.restore(); 
+0

धन्यवाद। मैं अपने केंद्र बिंदु को दोबारा जांचूंगा। मुझे लगता है कि मुद्दा यह है कि केंद्र बिंदु पूरी स्क्रीन के सापेक्ष है, न कि घड़ी। तो यह 240, 240 की तरह कुछ है। यह असली मुद्दा हो सकता है। विचार? – bek

+0

@ user968322 मैंने रोटेशन – JesusFreke

+0

के केंद्र के बारे में कुछ अतिरिक्त विवरण जोड़े हैं, अभी भी कोई भाग्य नहीं है। यह यादृच्छिक दिशाओं में जाने शुरू होता है। मेरी पोस्ट में मूल कोड अपडेट किया गया। – bek

0

आपका गणना मिनट हाथ के लिए कोण को मापने के लिए अच्छा है इसी अनुरूप में चतुर्थ भाग में बारी बारी से घड़ी ... यहां बिट परिवर्तन स्पर्श स्थिति पर घूमने के लिए मिनट या घंटे का हाथ बना सकते हैं .... कार्रवाई विधि

पर डाउन टच() विधि में नीचे दी गई विधि को कॉल करें
public float getRotationAngle(float x, float y) { 
     float dx = x - cx; 
     float dy = y - cy; 
     double a = Math.atan2(dy, dx); 

     double degree = Math.toDegrees(a)+90; 
     if(angle<0){ 
      degree=degree+360; 
     } 
     return (float) degree; 
} 

मैं के रूप में कोण की गणना के लिए अवधारणा वैक्टर के साथ इस दृष्टिकोण है, लेकिन यू चाहते हैं, तो थोड़ा सा अपने कोड की तुलना में अधिक मैं उस तर्क दे देंगे ....