我正在使用Java AWT在面板上繪製線條(Line2D
和Graphics2D.drawLine()
),我想知道如何繪製刻度線,類似於:Java - 繪製標尺(在90度角刻有刻度線)
| ---- | ---- | ---- | ---- | ---- |
我知道我希望提前打勾的位置。
這些線可以在任何位置,所以蜱必須以與線本身相關的角度繪製。
我的基本幾何&在Java中應用它的能力讓我失望。 :)
我正在使用Java AWT在面板上繪製線條(Line2D
和Graphics2D.drawLine()
),我想知道如何繪製刻度線,類似於:Java - 繪製標尺(在90度角刻有刻度線)
| ---- | ---- | ---- | ---- | ---- |
我知道我希望提前打勾的位置。
這些線可以在任何位置,所以蜱必須以與線本身相關的角度繪製。
我的基本幾何&在Java中應用它的能力讓我失望。 :)
我建議
Math.atan2
所需的角度,吸引了一個簡單的水平標尺。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);
}
}
注意,你可以很容易地得出的數字在蜱之上。 drawString調用將經歷相同的轉換,並沿着該線很好地「傾斜」。
有趣的是,我相信'AffineTransform'是我一直在尋找的關鍵詞。 Google使用非常相似的組件製作了本教程: http://www.glyphic.com/transform/applet/1intro.html 現在我只需瞭解如何將其應用於我的問題。 – Matt 2010-08-15 17:43:34
通過首先平移(移動)到所需起點,然後旋轉所需角度(atan2(dy,dx))來應用它。將兩個轉換與AffineTransform.concatenate結合在一起。 – aioobe 2010-08-15 19:26:15
看起來不錯。我需要讓自己更熟悉Transform的東西。 – jjnguy 2010-08-15 19:30:27
事情需要指出的是:
newdx=dy; newdy=-1*dx
。<dx, dy>
是一個單位矢量(sqrt(dx*dx+dy+dy)==1
或dx==cos(theta); dy=sin(theta)
爲某些theta),然後你只需要知道你想要多大的分隔符。因此的(上文計算的)的斜率,
<sx,sy>
線(啓動x,y)提供到<sx+dx*length,sy+dy*length>
<sx+dx*i-newdx*seglength/2,sy+dy*i-newdy*seglength/2>
到<sx+dx*i+newdx*seglength/2,sy+dy*i+newdy*seglength/2>
我非常喜歡這個答案,因爲它試圖解釋幾何。不幸的是,我無法繞過它。我插入你描述的公式,我得到了newdy&newdx非常奇怪的結果。 (負值遠遠超出我面板上的座標範圍) 同樣,我的幾何圖形是最好的,但我想知道該公式是否爲笛卡爾座標系。Java的座標將0,0放置在面板的左上角。 – Matt 2010-08-15 18:30:04
我希望你知道矩陣乘法。爲了旋轉一條線,你需要通過旋轉矩陣來多重旋轉一條線。 (I coudln't繪製一個適當的矩陣,但假設這兩個線不分離)
|x'| = |cos(an) -sin(an)| |x|
|y`| = |sin(an) cos(an)| |y|
舊點是x,y和新的是X「 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)
就像你所期望的那樣。
希望它能幫助,
羅尼
你想畫任意方向的「尺子」行?蜱是以固定的時間間隔出現,還是希望它們出現,例如0%,33%,66%,100%? – aioobe 2010-08-15 17:32:32
請參閱下面有關圖形的一般說明。刻度線將以任意間距均勻間隔。 (IE:我需要一個解決方案,我可以將線劃分並在每個線段沿其長度繪製任意數量的這些刻度) – Matt 2010-08-15 17:40:13
讓我知道您對我的答案的看法。 – jjnguy 2010-08-15 19:00:12