سؤال

لقد كتبت بعض برامج الرسوم البيانية الأساسية في Clojure/Java باستخدام drawLine() على سياق الرسومات من JPanel المعدل. إن التخطيط نفسه يعمل بشكل جيد ، لكنني وصلت إلى طريق مسدود أثناء محاولة تحويل بكسل تم النقر فوقه إلى أقرب نقطة بيانات.

لديّ أعمدة بسيطة بين قائمة جميع وحدات البكسل التي تحدد نقاط نهاية خطوطي وبياناتي الأولية الفعلية. ما أحتاجه هو شكوك من جميع وحدات البكسل (على سبيل المثال ، 1200 × 600 بكسل2) من نافذة الرسم البياني الخاص بي إلى وحدات البكسل في قائمة البكسل الخاصة بي ، مما يمنحني رسم خرائط تافهة من ذلك إلى نقاط البيانات الفعلية.

على سبيل المثال

<x,y>(px) ----> <~x,~y>(pixel points) ----> <x,y>(data)

هذا هو الموقف لأنني أتخيله الآن:

  • يتم النقر على بكسل في نافذة الرسم البياني الرئيسي ، ويمسك Mouselistener بهذا الحدث ويعطيني <x,y> إحداثيات العمل.

  • يتم تمرير هذه المعلومات إلى وظيفة تُرجع مسندًا يحدد ما إذا كانت القيمة التي تم تمريرها "جيدة بما يكفي" ، وتصفية على الرغم من القائمة مع ذلك ، واتخذ القيمة الأولى التي تتمتع بها.

    • ربما ، بدلاً من المسند ، يعيد وظيفة يتم تمرير قائمة نقاط البكسل ، وتُرجع قائمة من tuples (x index) الذي يشير إلى مدى جودة النقطة مع حجم x, ، وحيث تكون هذه النقطة مع index. سأفعل هذا مع كل من النقاط X ونقاط Y. ثم أقوم بتصفية ذلك وأجد الشخص مع Max X ، وأخذ تلك النقطة التي من المرجح أن تكون المستخدمة التي يعنيها المستخدم.

هل هذه حلول معقولة لهذه المشكلة؟ يبدو أن الحل الذي يتضمن تصنيفات الثقة (المسافة من PIX-PT ، ربما) قد يكون ثقيلًا للغاية ، وذاكرة ثقيلة قليلاً إذا كنت أحمل جميع النقاط في الذاكرة مرة أخرى. الحل الآخر ، باستخدام المسند فقط ، لا يبدو أنه سيكون دقيقًا دائمًا.

هذا ال تم حلها المشكلة ، كما أظهرت مكتبات الرسوم البيانية الأخرى ، ولكن من الصعب العثور على معلومات عنها بخلاف مصدر بعض هذه البرامج ، ويجب أن تكون هناك طريقة أفضل للحفر عبر آلاف الخطوط من Java لمعرفة ذلك .

أبحث عن حلول أفضل ، أو مجرد مؤشرات عامة ونصائح حول تلك التي قدمتها ، إن أمكن.

هل كانت مفيدة؟

المحلول

لذلك أنا أظن شيئًا مثل Jfreechart فقط لم يكن قطعه لتطبيقك؟ إذا لم تكن قد قطعت هذا الطريق حتى الآن ، أقترح التحقق من ذلك قبل محاولة لفلك.

على أي حال ، إذا كنت تبحث عن أقرب نقطة إلى حدث الماوس ، فحصل على النقطة بالحد الأدنى المسافة الإقليدية (إذا كان أقل من بعض العتبة) وتقديمه من شأنه أن يعطي السلوك الأكثر تنبؤًا للمستخدم. الجانب السلبي هو أن المسافة الإقليدية بطيئة نسبيًا لمجموعات البيانات الكبيرة. يمكنك استخدام الحيل مثل تجاهل الجذر التربيعي أو أشجار BSP لتسريعها قليلا. ولكن إذا كانت هذه التحسينات ضرورية تعتمد حقًا على عدد نقاط البيانات التي تعمل معها. ملف تعريف حل ساذج إلى حد ما في حالة نموذجية قبل الذهاب إلى وضع التحسين.

نصائح أخرى

أعتقد أن نهجك لائق. لا يتطلب هذا بشكل أساسي سوى تكرار واحد من خلال صفيف البيانات الخاص بك ، والرياضيات البسيطة قليلاً ولا توجد تخصيصات في كل خطوة ، لذا يجب أن تكون سريعة جدًا.

من المحتمل أن يكون الأمر جيدًا كما ستحصل إلا إذا بدأت في استخدام شكل من أشكال نظام التقسيم المكاني مثل Quadtree ، وهو أمر منطقي حقًا إذا كانت مجموعة البيانات الخاصة بك كبيرة جدًا.

بعض رمز clojure الذي قد يساعد:

(defn squared-distance [x y point]
  (let [dx (- x (.x point))
        dy (- y (.y point))]
     (+ (* dx dx) (* dy dy))))

(defn closest 
  ([x y points]
    (let [v (first points)] 
      (closest x y (rest points) (squared-distance x y v) v)))
  ([x y points bestdist best]
    (if (empty? points)
      best
      (let [v (first points)
            dist (squared-distance x y v)] 
        (if (< dist bestdist)
          (recur x y (rest points) dist v)
          (recur x y (rest points) bestdist best))))))
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top