2015-02-10 85 views
0

我一直在试图找出一段时间,现在我正在制作一个程序,它使用一个三角形作为箭头并试图弄清楚如何制作一个箭头两点,这意味着第一个点将在三角形底部的中点,而第二个点将在朝向远离第一点的方向的尖端处。绘制一个等腰三角形/带有两个点的箭头

这种粗漆图纸应该帮助找出什么我谈论 http://i.stack.imgur.com/f3ktz.png(会直接把图片,但没有足够的代表)

现在,我经历了,并试图找出如何计算那些其他三角形的两个端点,所以我可以制作多边形,但是我没有正确地做,因为我得到的不是等腰三角形,并且端点不会创建垂直于原始线条的直线。

什么我目前得到(对于某些图纸在其上方,显示分) http://i.stack.imgur.com/dljsn.png

我当前的代码

public class Triangle extends Shape{ 

private boolean assigned = false; 

private int[] x; 

private int[] y; 

public Triangle(Point startPoint, Point endPoint){ 
    this.startPoint = startPoint; 
    this.endPoint = endPoint; 
} 

@Override 
public void draw(Graphics g) { 
    g.setColor(Color.white); 
    if(!assigned) { 
     x = new int[3]; 
     y = new int[3]; 
     double distance = startPoint.distance(endPoint); 
     double halfDistance = distance/2; 
     double angle = getAngle(startPoint,endPoint)- Math.PI/2.0; 

     x[0] = (int)endPoint.getX(); 
     y[0] = (int)endPoint.getY(); 

     x[1] = (int)((Math.sin(angle)*halfDistance) + startPoint.getX()); 
     y[1] = (int)((Math.cos(angle)*halfDistance) + startPoint.getY()); 

     x[2] = (int)(startPoint.getX() - (Math.sin(angle)*halfDistance)); 
     y[2] = (int)(startPoint.getY() - (Math.cos(angle)*halfDistance)); 


     assigned = true; 
     if(endPoint.distance(x[1],y[1]) == (Math.sqrt(5)*halfDistance)) 
      System.out.println("DEBUG: Confirm Correct 1"); 
     if(endPoint.distance(x[1],y[1]) == endPoint.distance(x[2],y[2])) 
      System.out.println("DEBUG: Confirm Correct 2"); 
    } 
    g.fillPolygon(x,y,3); 
    g.setColor(Color.blue); 
} 

private double getAngle(Point pointOne, Point pointTwo){ 
    double angle = Math.atan2(pointTwo.getY()- pointOne.getY(),pointTwo.getX()-pointOne.getX()); 
    while(angle < 0){ 
     angle += (2.0*Math.PI); 
    } 
    return angle; 
} 

}

我在这方面的工作了几个小时,可以似乎没有弄明白,有人请帮忙。

回答

0

所以,我结束了的东西替代double angle = getAngle(startPoint,endPoint)- Math.PI/2.0;更像double angle = -Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x);

我写了这个小测试程序,它可以让你移动到分绕一大圈,并产生所产生的三角形...

Tri

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.Point; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       TestPane tp = new TestPane(); 
       JPanel control = new JPanel(new BorderLayout()); 
       control.add(tp); 

       final JSlider startAngel = new JSlider(0, 359); 
       final JSlider endAngel = new JSlider(0, 359); 

       JPanel sliders = new JPanel(new GridLayout(1, 2)); 
       sliders.add(startAngel); 
       sliders.add(endAngel); 

       startAngel.addChangeListener(new ChangeListener() { 
        @Override 
        public void stateChanged(ChangeEvent e) { 
         tp.setStartAngle(startAngel.getValue()); 
        } 
       }); 
       endAngel.addChangeListener(new ChangeListener() { 
        @Override 
        public void stateChanged(ChangeEvent e) { 
         tp.setEndAngle(endAngel.getValue()); 
        } 
       }); 

       startAngel.setValue(0); 
       endAngel.setValue(180); 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(control); 
       frame.add(sliders, BorderLayout.SOUTH); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Point startPoint, endPoint; 
     private float startAngle = 0; 
     private float endAngle = 180; 

     public TestPane() { 
     } 

     @Override 
     public void invalidate() { 
      super.invalidate(); 
      recalculate(); 
     } 

     protected void recalculate() { 

      int dim = Math.min(getWidth(), getHeight()); 
      dim -= 50; 
      float radius = dim/2f; 

      startPoint = getPointOnCircle(startAngle, radius); 
      endPoint = getPointOnCircle(endAngle, radius); 

      repaint(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     protected Point getPointOnCircle(float degress, float radius) { 

      int x = Math.round(getWidth()/2); 
      int y = Math.round(getHeight()/2); 

      double rads = Math.toRadians(degress - 90); // 0 becomes the top 

      // Calculate the outter point of the line 
      int xPosy = Math.round((float) (x + Math.cos(rads) * radius)); 
      int yPosy = Math.round((float) (y + Math.sin(rads) * radius)); 

      return new Point(xPosy, yPosy); 

     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 

      int[] x = new int[3]; 
      int[] y = new int[3]; 
      double distance = startPoint.distance(endPoint); 
      double halfDistance = distance/2; 
      double angle = -Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x); 

      System.out.println(angle); 

      x[0] = (int) endPoint.getX(); 
      y[0] = (int) endPoint.getY(); 

      x[1] = (int) ((Math.sin(angle) * halfDistance) + startPoint.getX()); 
      y[1] = (int) ((Math.cos(angle) * halfDistance) + startPoint.getY()); 

      x[2] = (int) (startPoint.getX() - (Math.sin(angle) * halfDistance)); 
      y[2] = (int) (startPoint.getY() - (Math.cos(angle) * halfDistance)); 

      g2d.setColor(Color.RED); 
      g2d.fillPolygon(x, y, 3); 

      g2d.setColor(Color.BLUE); 
      g2d.fillOval(startPoint.x - 5, startPoint.y - 5, 10, 10); 
      g2d.setColor(Color.GREEN); 
      g2d.fillOval(endPoint.x - 5, endPoint.y - 5, 10, 10); 

      g2d.dispose(); 
     } 

     public void setStartAngle(float value) { 
      startAngle = value; 
      recalculate(); 
     } 

     public void setEndAngle(float value) { 
      endAngle = value; 
      recalculate(); 
     } 

    } 

} 

如果仍然给你一些奇怪的结果,除了分享一些测试数据,我可能会考虑使用类似Math.atan2(Math.abs(endPoint.y - startPoint.y), Math.abs(endPoint.x - startPoint.x))或S imular

+0

差不多,我在某个时候也得到了这个,但它只能在角度很好的情况下工作,而且会出现一个“怪异”的角度,产生这个http://i.imgur.com/HILpcgr.png – 2015-02-10 00:34:45

+0

好吧,停止放入怪异的角度:P – MadProgrammer 2015-02-10 00:40:04

+0

Lol,k。或者,如果您向下倾斜(负向度为btwn角度),则会产生一些尴尬的三角形 – 2015-02-10 00:40:18

0

根本不需要计算角度。

double startX = 40; 
    double startY = 120; 
    double endX = 110; 
    double endY = 15; 

    double deltaX = (startY - endY)/2; 
    double deltaY = (endX - startX)/2; 

    double[] polygonX = new double[3]; 
    double[] polygonY = new double[3]; 

    polygonX[0] = endX; 
    polygonY[0] = endY; 

    polygonX[1] = startX - deltaX; 
    polygonY[1] = startY - deltaY; 

    polygonX[2] = startX + deltaX; 
    polygonY[2] = startY + deltaY; 

Same angle

该图是非常糟糕:d,但问题是:

cos(ang) = 'distance'/(startY - endY)cod(ang) = ('distance'/2)/deltaX 所以 deltaX = (startY - endY)/2

同样aplies到deltaY = (endX - startX)/2

所以三角形的另外两个点将是startPoint减去加上那些三角形。

+0

这是不正确的,我必须考虑一下,但使用这种方法很像我的原始错误,它保持startPoint的距离相同,但不保证你会得到垂直于原始点“路径”,甚至用你自己的数字,我得到这个http://i.imgur.com/QQTMCDh.png,这不是我正在寻找的。你的只能在45度角(及其对应物,45度+ 90度* n度)的情况下工作。不过谢谢,让我试着重新思考没有角度:D – 2015-02-10 02:59:55

+0

对不起。代码中有一个错误,你应该在X开始时使用deltaX,反之亦然。我编辑它,现在尝试;) – Netto 2015-02-10 07:50:26

+0

哦,好的,我现在看。是的,它很多原来没有意义,但是,这也适用(可能快一点,因为它不需要进行角度计算)。谢谢! – 2015-02-10 17:40:00