Sunday, May 30, 2004
兩點間畫有箭頭的線
不知道有沒有更好的作法~
//畫箭頭 double x1 = fromPoint.getX(); double y1 = fromPoint.getY(); double x2 = toPoint.getX(); double y2 = toPoint.getY(); double distance = fromPoint.distance(toPoint); double cita = Math.toDegrees(Math.asin(Math.abs(y1 - y2) / distance)); double subCitaSin = ARROW_LENGTH * Math.sin(Math.toRadians(cita - 30)); double subCitaCos = ARROW_LENGTH * Math.cos(Math.toRadians(cita - 30)); double addCitaSin = ARROW_LENGTH * Math.sin(Math.toRadians(cita + 30)); double addCitaCos = ARROW_LENGTH * Math.cos(Math.toRadians(cita + 30)); double up1, down1, up2, down2; if(x1 > x2){ //箭頭在第二象限 if(y1 > y2){ up1 = x2 + subCitaCos; down1 = y2 + subCitaSin; up2 = x2 + addCitaCos; down2 = y2 + addCitaSin; } //箭頭在第三象限 else{ up1 = x2 + subCitaCos; down1 = y2 - subCitaSin; up2 = x2 + addCitaCos; down2 = y2 - addCitaSin; } } else{ //箭頭在第一象限 if(y1 > y2){ up1 = x2 - subCitaCos; down1 = y2 + subCitaSin; up2 = x2 - addCitaCos; down2 = y2 + addCitaSin; } //箭頭在第四象限 else{ up1 = x2 - subCitaCos; down1 = y2 - subCitaSin; up2 = x2 - addCitaCos; down2 = y2 - addCitaSin; } } g2d.draw(new Line2D.Double(new Point2D.Double(up1, down1), toPoint)); g2d.draw(new Line2D.Double(new Point2D.Double(up2, down2), toPoint));由 swanky 發表於 May 30, 2004 11:56 PM
剛好路過, 覺得您的做法太繁瑣...
多多利用平移,旋轉將會讓您輕鬆許多.
野人獻曝,請多包含.
Here is my example:
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
/**
* @author T55555
* @version 1.0.0 2004-06-30
*/
public class DrawArrow extends JComponent {
public static void main(String[] args) {
JFrame f = new JFrame("DrawArrow ----- by T55555");
f.getContentPane().add(new DrawArrow());
f.setSize(275, 150);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
double p = 10.0;
double q = 100.0;
double m = (p + q) / 2;
ciyawasay_drawArrow(g2d, new Point2D.Double(p, p), new Point2D.Double(q, q));
ciyawasay_drawArrow(g2d, new Point2D.Double(q, q), new Point2D.Double(p, p));
ciyawasay_drawArrow(g2d, new Point2D.Double(p, q), new Point2D.Double(q, p));
ciyawasay_drawArrow(g2d, new Point2D.Double(q, p), new Point2D.Double(p, q));
ciyawasay_drawArrow(g2d, new Point2D.Double(m, p), new Point2D.Double(m, q));
ciyawasay_drawArrow(g2d, new Point2D.Double(m, q), new Point2D.Double(m, p));
ciyawasay_drawArrow(g2d, new Point2D.Double(p, m), new Point2D.Double(q, m));
ciyawasay_drawArrow(g2d, new Point2D.Double(q, m), new Point2D.Double(p, m));
g2d.translate(150.0, 0.0);
t55555_drawArrow(g2d, new Point2D.Double(p, p), new Point2D.Double(q, q));
t55555_drawArrow(g2d, new Point2D.Double(q, q), new Point2D.Double(p, p));
t55555_drawArrow(g2d, new Point2D.Double(p, q), new Point2D.Double(q, p));
t55555_drawArrow(g2d, new Point2D.Double(q, p), new Point2D.Double(p, q));
t55555_drawArrow(g2d, new Point2D.Double(m, p), new Point2D.Double(m, q));
t55555_drawArrow(g2d, new Point2D.Double(m, q), new Point2D.Double(m, p));
t55555_drawArrow(g2d, new Point2D.Double(p, m), new Point2D.Double(q, m));
t55555_drawArrow(g2d, new Point2D.Double(q, m), new Point2D.Double(p, m));
g2d.translate(-150.0, 0.0);
}
public void ciyawasay_drawArrow(Graphics2D g2d, Point2D fromPoint, Point2D toPoint) {
double ARROW_LENGTH = 10.0;
double x1 = fromPoint.getX();
double y1 = fromPoint.getY();
double x2 = toPoint.getX();
double y2 = toPoint.getY();
double distance = fromPoint.distance(toPoint);
double cita = Math.toDegrees(Math.asin(Math.abs(y1 - y2) / distance));
double subCitaSin = ARROW_LENGTH * Math.sin(Math.toRadians(cita - 30));
double subCitaCos = ARROW_LENGTH * Math.cos(Math.toRadians(cita - 30));
double addCitaSin = ARROW_LENGTH * Math.sin(Math.toRadians(cita + 30));
double addCitaCos = ARROW_LENGTH * Math.cos(Math.toRadians(cita + 30));
double up1, down1, up2, down2;
if(x1 > x2){
if(y1 > y2){
up1 = x2 + subCitaCos;
down1 = y2 + subCitaSin;
up2 = x2 + addCitaCos;
down2 = y2 + addCitaSin;
}
else{
up1 = x2 + subCitaCos;
down1 = y2 - subCitaSin;
up2 = x2 + addCitaCos;
down2 = y2 - addCitaSin;
}
}
else{
if(y1 > y2){
up1 = x2 - subCitaCos;
down1 = y2 + subCitaSin;
up2 = x2 - addCitaCos;
down2 = y2 + addCitaSin;
}
else{
up1 = x2 - subCitaCos;
down1 = y2 - subCitaSin;
up2 = x2 - addCitaCos;
down2 = y2 - addCitaSin;
}
}
g2d.draw(new Line2D.Double(new Point2D.Double(up1, down1), toPoint));
g2d.draw(new Line2D.Double(new Point2D.Double(up2, down2), toPoint));
g2d.draw(new Line2D.Double(fromPoint, toPoint));
}
// Note: pre-condition: toPoint != fromPoint
// ( if the 2 points are the same ===> distance == 0 and angle is indeterminate )
public void t55555_drawArrow(Graphics2D g2d, Point2D fromPoint, Point2D toPoint) {
double ARROW_LENGTH = 10.0;
double ARROW_ANGLE = Math.toRadians(30);
double ax = ARROW_LENGTH * Math.cos(ARROW_ANGLE);
double ay = ARROW_LENGTH * Math.sin(ARROW_ANGLE);
AffineTransform originTransform = g2d.getTransform();
g2d.translate(toPoint.getX(), toPoint.getY());
g2d.rotate((fromPoint.getY() > toPoint.getY() ? -1 : 1) * Math.acos((toPoint.getX() - fromPoint.getX()) / fromPoint.distance(toPoint)));
g2d.draw(new Line2D.Double(0, 0, -ax, -ay));
g2d.draw(new Line2D.Double(0, 0, -ax, ay));
g2d.setTransform(originTransform);
g2d.draw(new Line2D.Double(fromPoint, toPoint));
}
}
The main idea is translate the origin to the toPoint,
and rotate to make the axe X parallel to the vector (fromPoint, toPoint).
For the rotate angle, the "classic" way is try to using atan like:
if (x1 > x2) {
g2d.rotate(Math.PI + Math.atan((y1 - y2) / (x1 - x2)));
} else if (x1 y2) {
g2d.rotate( -Math.PI / 2 );
} else if (y1
g2d.rotate( Math.PI / 2);
} else {
return;
}
As you can see, there are many checking to do.
The example I show you do not using the atan.
I am using vector dot product formula.
A . B = |A| |B| cos(theda)
with A = vector (fromPoint, toPoint),
B = (1, 0) (axe X, unit vector)
In case if you want fill the arrow, with
3rd point that can define by the distance from the toPoint, the method I used will even simpler(compare to yours).
Oops, it seems the atan checking have trouble to layout...
(my post code is not the same as showing on the page, bug on the post text re-formating ?)
Anyway, I do not know how to layout to post it correctly. And this is real simple algebra formula.
太感謝了~
您的方法真是比我的好很多~ ^^"
把顏色"存"起來
為了讓設計者可以更改
Concept
的顏色所以多了一個可以選擇顏色的功能
不過要怎麼把這個顏色很方便地從一般文字檔案中存取呢?
在
Color
類別中可以找到答案喔~存:
使用
Color
類別中的getRGB()
方法取得型態為int
的RGB值,再轉成字串
Color color = Color.BLUE; String colorRGBText = "" + color.getRGB();
讀:
把RGB值丟給
Color
的建構子
Color color = new Color(Integer.parseInt(colorRGBText));由 swanky 發表於 May 30, 2004 12:58 PM
Wednesday, May 26, 2004
SOMEWHERE OUT THERE
很久以前的一部卡通--美國鼠譚
這是裡面我最愛的一首歌--SOMEWHERE OUT THERE
小時後看的 劇情已經忘的差不多了 但這首歌一直記得
不知道大家有沒有看過~
《歌詞中英對照》
SOMEWHERE OUT THERE
外面那裡的某一個地方
(Barry Mann, Cynthia Weil, and James Horner)
Somewhere out there beneath the pale moonlight
外面那裡的某一個地方 在那蒼白的月光下
Someone\'s thinking of me and loving me tonight
今晚有個人正在想念著我 愛著我
Somewhere out there someone\'s saying a prayer
外面那裡的某一個地方 有個人正在祈禱
That we\'ll find one another in that dream somewhere out there
但願我們會找到彼此 在外面某一個地方的美夢裡
And even though I know how very far apart we are
而即使我知道我們相隔多麼遙遠
It helps to think we might be wishin\' on the same bright star
想到我們或許\正在對著同一顆星星許\願 就可以讓我好過許\多
And when the night wind starts to sing a lonesome lullaby
而當夜風開始唱一首寂寞的搖籃曲
It helps to think we\'re sleeping underneath the same big sky
想到我們睡在同一片寬闊的天空下 就可以讓我好過許\多
Somewhere out there if love can see us through
外面那裡的某一個地方 如果愛可以讓我們堅強
Then we\'ll be together somewhere out there
那麼我們將會團聚 在外面那裡的某一個地方
Out where dreams come true
某一個夢想可以成真的地方
能不能唱給我聽呢? ^^
Posted by: swanky 發表於 2004-05-26 11:59 PM這部卡通不久前迪士尼有撥過
可能還會重播
我看ㄌ好幾遍
什么时候再听都是一首很好听很好听的歌,尤其是电影版的原曲。真的很感激一楼的shumi。Thank you!
Posted by: Pasu 發表於 2004-09-05 08:25 PM我都好鍾意呢首歌~! 記得套卡通片係叫"老鼠也移民"~
Posted by: 招仔 發表於 2004-11-07 04:23 PM我也喜欢这首歌,可是在哪里可以下载它的mp3呢?
Posted by: traycy 發表於 2005-03-21 12:50 PM我也不知道呢~
Posted by: swanky 發表於 2005-03-21 06:54 PMMonday, May 17, 2004
Sorts比較
比較各Sorts:
時間複雜度
in-place or not in-place
stable or unstable
《Sorts比較》
比較表 | Time Complexity | Space Complexity | Stable/Unstable | ||
---|---|---|---|---|---|
Best Case | Worst Case | Average Case | |||
Insertion Sort | O(n) |
O(n2) |
O(n2) |
O(1) |
Stable |
Selection Sort | O(n2) |
O(n2) |
O(n2) |
O(1) |
Unstable |
Bubble Sort | O(n) |
O(n2) |
O(n2) |
O(1) |
Stable |
Shell Sort | O(n3/2) |
O(n2) |
O(n2) |
O(1) |
Unstable |
Quick Sort | O(nlogn) |
O(n2) |
O(nlogn) |
O(logn)~O(n) |
Unstable |
Merge Sort | O(nlogn) |
O(nlogn) |
O(nlogn) |
O(n) |
Stable |
Heap Sort | O(nlogn) |
O(nlogn) |
O(nlogn) |
O(1) |
Unstable |
LSD Radix Sort |
O(d*(n+r))
|
O(n*r) |
Stable |
Sorts總整理5--Bubble Sort
《Bubble Sort》
Algorithm :for i←1 to length[A] do for j←length[A] downto i+1 do if A[j]<A[j-1] then exchange A[j]←→A[j-1]
void bubbleSort(int[] Array) { int temp; for (int i = 0; i < Array.length; i++) { for (int j = 0; j < (Array.length - i - 1); j++) { if (Array[j].score > Array[j + 1].score) { temp = Array[j].score; Array[j].score = Array[j + 1].score; Array[j + 1].score = temp; } } } }java code:字串排序
void bubbleSort(String[] Array) { String temp; for (int i = 0; i < Array.length; i++) { for (int j = 0; j < (Array.length - i - 1); j++) { if (Array[j].name.compareTo(Array[j + 1].name) > 0) { temp = Array[j].name; Array[j].name = Array[j + 1].name; Array[j + 1].name = temp; } } } }由 shumi 發表於 May 17, 2004 08:41 AM
Sorts總整理4--Quick Sort
《Quick Sort》
Algorithm :if p<r then q←Partition(A,p,r) Quicksort(A,p,q-1) Quicksort(A,q+1,r)Partition(A,p,r)
x←A[r] i←p-1 for j←p to r-1 do if A[j]≦x then i←i+1 exchange A[i]←→A[j] exchange A[i+1]←→A[r] return i+1
void quickSort(int[] Array, int p, int r){ if(p < r){ int q = partition(Array, p, r); quickSort(Array, p, q - 1); quickSort(Array, q + 1, r); } } int partition(int[] Array, int p, int r){ int x = Array[r]; int i = p - 1; for(int j = p; j <= r - 1; j++){ if(Array[j] <= x){ i++; int t1 = Array[i]; Array[i] = Array[j]; Array[j] = t1; } } int t2 = Array[i+1]; Array[i+1] = Array[r]; Array[r] = t2; return i + 1; }java code:字串排序
int partition(String[] Array, int p, int r) { String x = Array[r].name; int i = p - 1; for (int j = p; j <= (r - 1); j++) { if (Array[j].name.compareTo(x) <= 0) { i++; String t1 = Array[i].name; Array[i].name = Array[j].name; Array[j].name = t1; } } String t2 = Array[i + 1].name; Array[i + 1].name = Array[r].name; Array[r].name = t2; return i + 1; } void quickSort(String[] Array) { quickSort(Array,0,Array.length-1); } void quickSort(String[] Array, int p, int r) { if (p < r) { int q = partition(Array, p, r); quickSort(Array, p, q - 1); quickSort(Array, q + 1, r); } }由 shumi 發表於 May 17, 2004 08:28 AM
Sorts總整理3--Heap Sort
《Heap Sort》
Algorithm :return └i/2┘Left(i)
return 2iRight(i)
return 2i+1Max-Heapify(A,i)
l←Left(i) r←Right(i) if l≦heap-size[A] and A[l]>A[i] then largest←l else largest←i if r≦heap-size[A] and A[r]>A[largest] then largest←r if largest≠i then exchange A[i]←→A[largest] Max-Heapify(A,largest)Build-Max-Heap(A)
heap-size[A]←length[A]
for i←└length[A]/2┘ downto 1
do Max-Heapify(A,i)
Heapsort(A)
Build-Max-Heap(A) for i ←length[A] downto 2 do exchange A[1]←→A[i] heap-size[A]←heap-size[A]-1 Max-Heapify(A,1)
int parent(int i){ return (i - 1)/2; } int left(int i){ return 2 * i + 1; } int right(int i){ return 2 * i + 2; } void heapSort(int[] Array){ buildMaxHeap( Array ); for(int i = Array.length - 1; i >= 1; i--){ int temp = Array[0]; Array[0] = Array[i]; Array[i] = temp; heapSize--; maxHeapify(Array, 0); } } void buildMaxHeap(int[] Array){ heapSize = Array.length; for(int i = (int)( (Array.length/2) - 1 ); i >= 0; i--){ maxHeapify(Array, i); } } void maxHeapify(int[] Array, int i){ int L = left(i); int R = right(i); int largest; if( (L < heapSize) && (Array[L] > Array[i]) ) largest = L; else largest = i; if( (R < heapSize) && (Array[R] > Array[largest]) ) largest = R; if(largest != i){ int temp = Array[i]; Array[i] = Array[largest]; Array[largest] = temp; maxHeapify(Array, largest); } }java code:字串排序
int parent(int i){ return (i - 1)/2; } int left(int i){ return 2 * i + 1; } int right(int i){ return 2 * i + 2; } void buildMaxHeap(String[] Array) { heapSize = Array.length; for (int i = (int) ((Array.length / 2) - 1); i >= 0; i--) { maxHeapify(Array, i); } } void maxHeapify(String[] Array, int i) { int L = left(i); int R = right(i); int largest; if ((L < heapSize) && (Array[L].name.compareTo(Array[i].name) > 0)) { largest = L; } else { largest = i; } if ((R < heapSize) && (Array[R].name.compareTo(Array[largest].name) > 0)) { largest = R; } if (largest != i) { String temp = Array[i].name; Array[i].name = Array[largest].name; Array[largest].name = temp; maxHeapify(Array, largest); } } void heapSort(String[] Array) { buildMaxHeap(Array); for (int i = Array.length - 1; i >= 1; i--) { String temp = Array[0].name; Array[0].name = Array[i].name; Array[i].name = temp; heapSize--; maxHeapify(Array, 0); } }由 shumi 發表於 May 17, 2004 12:23 AM
Sorts總整理2--Merge Sort
《Merge Sort》
Algorithm :n1←q-p+1 n2←r-q △cerate arrays L(1..n1+1) and R(1..n2+1) for i←1 to n1 do L[i]←A[p+i-1] for j←1 to n2 do R[j]←A[q+j] L[n1+1]←∞ R[n2+1]←∞ i←1 j←1 for k←p to r do if L[i]≦R[j] then A[k]←L[i] i←i+1 else A[k]←R[j] j←j+1Merge-Sort(A,p,r)
if p<r then q←└(p+r)/2┘ Merge-Sort(A,p,q) Merge-Sort(A,q+1,r) Merge(A,p,q,r)
void mergeSort(int[] Array, int p, int r){ if( p < r ){ int q = ( p + r )/2; mergeSort(Array, p, q); mergeSort(Array, q + 1, r); merge(Array, p, q, r); } } void merge(int[] Array, int p, int q, int r){ int n1 = q - p + 1; int n2 = r - q; int[] L = new int[n1 + 1], R = new int[n2 + 1]; int i, j; for(i = 0; i < n1; i++){ L[i] = Array[p + i]; } for(j = 0; j < n2; j++){ R[j] = Array[q + j + 1]; } L[n1] = R[n2] = Integer.MAX_VALUE; i = j = 0; for(int k = p; k <= r; k++){ if(L[i] <= R[j]){ Array[k] = L[i]; i++; } else{ Array[k] = R[j]; j++; } } }java code:字串排序
void mergeSort(String[] Array){ mergeSort(Array,0,Array.length-1); } void mergeSort(String[] Array, int p, int r) { if (p < r) { int q = (p + r) / 2; mergeSort(Array, p, q); mergeSort(Array, q + 1, r); merge(Array, p, q, r); } } void merge(String[] Array, int p, int q, int r) { int n1 = q - p + 1; int n2 = r - q; String[] L = new String[n1 + 1]; String[] R = new String[n2 + 1]; int i; int j; for (i = 0; i < n1; i++) { L[i] = Array[p + i].name; } for (j = 0; j < n2; j++) { R[j] = Array[q + j + 1].name; } L[n1] = R[n2] = new String(new char[]{Character.MAX_VALUE}); i = j = 0; for (int k = p; k <= r; k++) { if (L[i].compareTo(R[j])<= 0) { Array[k].name = L[i]; i++; } else { Array[k].name = R[j]; j++; } } }由 shumi 發表於 May 17, 2004 12:01 AM
Sunday, May 16, 2004
Sorts總整理1--Insertion Sort
不過還是要把Sorts 整理整理
希望有需要的人也可以參考看看
《Insertion Sort》
Algorithm :
for j←2 for length[A]
do key←A[j]
△Insert A[j] into the sorted sequence A[1..j-1]
i←j-1
while i>0 and A[i]>key
do A[i+1]←A[i]
i←i-1
A[i+1]←key
void insertionSort(int[] Array){ for(int j = 1; j < Array.length; j++){ int key = Array[j]; int i = j - 1; while( (i >= 0) && (Array[i] > key) ){ Array[i+1] = Array[i]; i--; } Array[i+1] = key; } }java code:字串排序
void insertionSort(String[] Array) { for (int j = 1; j < Array.length; j++) { String key = Array[j].name; int i = j - 1; while ((i >= 0) && (Array[i].name.compareTo(key)> 0)) { Array[i + 1].name = Array[i].name; i--; } Array[i + 1].name = key; } }由 shumi 發表於 May 16, 2004 11:30 PM
Thursday, May 06, 2004
wiki?
但我還是不知道它確切的功能是什麼
用"好狗"查了一下資料~
wiki可以定義為網上協作寫作系統,屬於“可寫web”的一種。wiki好比軟體發展中的cvs一樣,也屬於協作開發系統。在wiki中,每一頁都是可以編輯的。wiki比起論壇和新聞系統來,能提供效果更好的知識庫。
wikiwiki是夏威夷語“快速”的意思。在這裏指能快速編輯網頁並快速建立新網頁、快速建立鏈結。
在一般的網站上,網頁都是唯讀的,而wiki網頁不但能閱讀,而且能直接修改。能發揮網路互動的優勢,使wiki頁面總是鮮活的。wiki 網站不象一般網站那樣區分讀者和編者,每個讀者都可以作為編者,都可以是網站的主人,一個wiki網站上的內容常常是多個人共同的心血,每個人可以隨時加 入網站的建設。wiki能聚集很多人的智慧,而不是只展示幾個人的智慧。
wiki和論壇相比,論壇只能發消息,wiki不但能發消息,而且能把消息用超鏈結有效的組織起來。wiki還能使多個人共同編輯同一篇文章,使一個文章能像軟體一樣隨時間不斷完善。
- 最基本的是結構化文本功能
- 用戶註冊功能
- 版本歷史功能
- 版本間的比較功能
- 最新更改功能
- 多wiki功能,就是運行一個wiki系統,能夠在“鏈結字”、“最近更動”方面區分為不相干的多個系統。不要本來無關的主題,在同一個最近更動裏出現。最好管理和授權工作也是能分開的。如果能選擇搜索層次更好
- 有完善的wiki管理功能。強大的授權管理功能。最好是web方式的管理。如果從管理上來說zope上的zwiki是比較理想的
- 鎖頁功能
- 頁面監視功能。頁面改變後能email通知監視人
我也想做一ㄍ屬於自己ㄉblog...
要怎ㄇ起頭ㄋ??
自己架一個比較麻煩
要架server、灌軟體
最難的是還要去維護
現在很多國內的BBS
像是
無名小站
telnet://wretch.twbbs.org/
http://www.wretch.twbbs.org/blog/
狂狷年少
telnet://kgbbs.net/
http://blog.kgbbs.net/
都可以在BBS上註冊後有免費的blog、相簿、留言版
可以去試試囉~ ^^
(妳會不會上BBS啊? @.@)
Posted by: swanky 發表於 2004-05-12 11:15 PM