2010-08-15 17 views
7

मैं एक पैनल (Line2D और Graphics2D.drawLine()) पर रेखा खींचने के लिए जावा एडब्ल्यूटी का उपयोग कर रहा हूं और मुझे आश्चर्य है कि मैं टिक अंक के साथ एक रेखा कैसे खींच सकता हूं, इसी प्रकार:जावा - एक शासक (90 डिग्री कोण पर टिक अंकों के साथ लाइन)

| ---- | ---- | ---- | ---- | ---- |

मुझे उन पदों को पता है जिन्हें मैं पहले से ही टिक बनाना चाहता हूं।

लाइनें किसी भी स्थिति में हो सकती हैं, इसलिए टिक को लाइन के कोण पर एक कोण पर खींचा जाना चाहिए।

मेरी मूल ज्यामिति & जावा में इसे लागू करने की क्षमता मुझे विफल कर रही है। :)

+0

आप मनमाने ढंग से दिशाओं में "शासक" लाइनों आकर्षित करने के लिए करना चाहते हैं? क्या निश्चित अंतराल पर टिक हैं, या आप उन्हें 0%, 33%, 66%, 100% कहने के लिए दिखाना चाहते हैं? – aioobe

+0

सामान्य रूप से ग्राफिक्स के विवरण के लिए नीचे देखें। टिक अंक समानांतर दूरी के साथ समान रूप से दूरी पर होंगे। (आईई: मुझे एक समाधान की आवश्यकता है जहां मैं एक लाइन को विभाजित कर सकता हूं और प्रत्येक खंड में इसकी लंबाई के साथ इन टिकों की मनमानी संख्या खींच सकता हूं) – Matt

+0

मुझे बताएं कि आप मेरे उत्तर के बारे में क्या सोचते हैं। – jjnguy

उत्तर

13

मैं सुझाव है कि आप

  1. लागू एक शासक-ड्राइंग-विधि है कि एक साधारण क्षैतिज मापनी ड्रॉ बाहर Math.atan2 का उपयोग कर वांछित कोण सही
  2. चित्रा बाएं से।
  3. शासक-ड्राइंग-विधि का आह्वान करने से पहले अनुवाद और रोटेशन के साथ AffineTransform लागू करें।

यहां एक पूर्ण परीक्षण कार्यक्रम है। कि तुम बस के रूप में आसानी से संख्या आकर्षित कर सकता है (Graphics.create विधि मूल ग्राफिक्स वस्तु की एक प्रति बनाने के लिए प्रयोग किया जाता है, तो हम को बदलने गंदगी नहीं मूल है।)

import java.awt.*; 

public class RulerExample { 

    public static void main(String args[]) { 
     JFrame f = new JFrame(); 
     f.add(new JComponent() { 

      private final double TICK_DIST = 20; 

      void drawRuler(Graphics g1, int x1, int y1, int x2, int y2) { 
       Graphics2D g = (Graphics2D) g1.create(); 

       double dx = x2 - x1, dy = y2 - y1; 
       double len = Math.sqrt(dx*dx + dy*dy); 
       AffineTransform at = AffineTransform.getTranslateInstance(x1, y1); 
       at.concatenate(AffineTransform.getRotateInstance(Math.atan2(dy, dx))); 
       g.transform(at); 

       // Draw horizontal ruler starting in (0, 0) 
       g.drawLine(0, 0, (int) len, 0); 
       for (double i = 0; i < len; i += TICK_DIST) 
        g.drawLine((int) i, -3, (int) i, 3); 
      } 

      public void paintComponent(Graphics g) { 
       drawRuler(g, 10, 30, 300, 150); 
       drawRuler(g, 300, 150, 100, 100); 
       drawRuler(g, 100, 100, 120, 350); 
       drawRuler(g, 50, 350, 350, 50); 
      } 
     }); 

     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setSize(400, 400); 
     f.setVisible(true); 
    } 
} 

enter image description here

ध्यान दें, टिकों के ऊपर। ड्रॉस्ट्रिंग-कॉल एक ही परिवर्तन के माध्यम से चले जाएंगे और लाइन के साथ अच्छी तरह से "झुकाव" प्राप्त करेंगे।

+0

दिलचस्प, मेरा मानना ​​है कि 'AffineTransform' वह कीवर्ड है जिसे मैं ढूंढ रहा था। Google ने इस ट्यूटोरियल को बहुत ही समान घटकों के साथ बनाया: http://www.glyphic.com/transform/applet/1intro.html अब मुझे समझना है कि इसे मेरी समस्या पर कैसे लागू करें। – Matt

+0

आप वांछित कोण (एटान 2 (डीई, डीएक्स) द्वारा घूर्णन करके वांछित स्टार्ट-पॉइंट पर पहले अनुवाद (चलती) द्वारा इसे लागू करते हैं। AffineTransform.concatenate के साथ दो परिवर्तनों को मिलाएं। – aioobe

+1

यह बहुत अच्छा लग रहा है। मुझे ट्रांसफॉर्म सामान से खुद को और परिचित बनाने की जरूरत है। – jjnguy

1

चीज़ें है कि ध्यान देने योग्य बात की जरूरत है:

  • एक लम्ब -1 की एक ढलान है/oldslope।
  • आदेश किसी भी दिशा में पंक्तियों का समर्थन करने के लिए, आप इसे parametrically
  • इस प्रकार क्या करने की जरूरत है, तो आप मूल लाइन, कि newdx=dy; newdy=-1*dx जिसका मतलब है कि भर में डीवाई और dx की है।
  • यदि आपके पास ऐसा है कि <dx, dy> कुछ थीटा के लिए एक यूनिट वेक्टर (sqrt(dx*dx+dy+dy)==1, या dx==cos(theta); dy=sin(theta)) है, तो आपको केवल यह जानने की आवश्यकता है कि आप कितने दूर टिक अंक चाहते हैं।
  • sx, एसवाई अपने प्रारंभ x और y हैं
  • लंबाई लाइन की लंबाई है
  • seglength डैश की लंबाई
  • dx है, उप मूल लाइन
  • newdx की ढलानों है, newdy (ऊपर गणना) पार लाइनों

इस प्रकार की ढलानों कर रहे हैं,

  1. एक ड्रा <sx,sy> से लाइन <sx+dx*length,sy+dy*length>
  2. करने के लिए (एक्स, वाई शुरू) ((i = 0 के लिए लाइनों का एक सेट ड्रा; मैं < = लंबाई; i + = अंतराल) <sx+dx*i-newdx*seglength/2,sy+dy*i-newdy*seglength/2> से <sx+dx*i+newdx*seglength/2,sy+dy*i+newdy*seglength/2>
+0

मुझे यह जवाब बहुत पसंद है क्योंकि यह ज्यामिति को समझाने का प्रयास करता है। दुर्भाग्य से, मुझे इसके चारों ओर अपने सिर लपेटने में परेशानी हो रही है। मैंने आपके द्वारा वर्णित सूत्रों में प्लग किया है और मुझे newdy और newdx के लिए बहुत ही अजीब परिणाम मिल रहे हैं। (नकारात्मक मान जो मेरे पैनल पर निर्देशांक की सीमा से बाहर गिरते हैं) फिर से, मेरी ज्यामिति सबसे अच्छी है, लेकिन मुझे आश्चर्य है कि सूत्र एक कार्टेसियन समन्वय प्रणाली के लिए है या नहीं।जावा के निर्देशांक पैनल के ऊपरी बाएं कोने में 0,0 स्थान देते हैं। – Matt

1

लिए मुझे आशा है कि आप मैट्रिक्स पता गुणन। एक पंक्ति को घुमाने के लिए आपको रोटेशन मैट्रिक्स द्वारा इसे एकाधिक करने की आवश्यकता है। (मैं एक उचित मैट्रिक्स आकर्षित लेकिन दोनों लाइन मान coudln't अलग नहीं कर रहे हैं)

|x'| = |cos(an) -sin(an)| |x| 

|y`| = |sin(an) cos(an)| |y| 

वर्ष अंक एक्स, वाई कर रहे हैं और नई एक्स ', वाई' है। आइए उदाहरण के लिए हमें बताएं, मान लें कि आपके पास (0,0) से (0,1) तक लंबवत रेखा है, अब आप 90 डिग्री से घूमना चाहते हैं। (0,0) शून्य रहेगा तो बस देखते हैं क्या करने के लिए (0,1)

होता
|x'| = |cos(90) -sin(90)| |0| 

|y`| = |sin(90) cos(90)| |1| 

==

|1 0| |0| 

|0 1| |1| 

==

| 1*0 + 0*1| 

| 0*0 + 1*1| 

== |0| 

    |1| 

आप क्षैतिज रेखा के लिए मिलता है (0,0),(0,1) जैसे आप उम्मीद करेंगे।

आशा है कि यह मदद करता है,
रॉनी