真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java2D高級繪圖-創(chuàng)新互聯(lián)

知識要點:

第一節(jié) Java 2D的增強功能

概述、AWT圖形能力的不足、Java 2D API

第二節(jié) 圖形繪制的基本方法

轉(zhuǎn)換Graphics2D對象、Graphics 類特性、繪圖的屬性和基本編程方法

第三節(jié) 曲線問題的高級應(yīng)用開發(fā)

直線問題深入研究、貝塞爾(Bezier)曲線、自定義樣條曲線編程、

用戶數(shù)據(jù)的曲線顯示、曲線用Applet顯示的數(shù)據(jù)來源問題

第四節(jié) 字符串的高級處理

TextLayout類、LineMetrics類

第五節(jié) 構(gòu)造幾何形狀

2D幾何形狀的設(shè)計、構(gòu)造型區(qū)域幾何形狀、變換、緩沖的圖像

第六節(jié) 三維圖形處理的設(shè)計技術(shù)

透視投影、透視圖形的顯示、隱蔽面消除問題

第七節(jié) 同環(huán)境交互

GraphicsEnvironment類、GraphicsDevice類、GraphicsConfiguration類

第一節(jié) Java 2D的增強功能

一、概述:

由Sun公司與Adobe系統(tǒng)公司合作推出的Java 2D API,提供了一個功能強大而且非常靈活的二維圖形框架。Java 2D API擴展了java.awt包中定義的Graphics類和Image類,提供了高性能的二維圖形、圖像和文字,同時又維持了對現(xiàn)有AWT應(yīng)用的兼容。

二、AWT圖形能力的不足:

在 AWT 的初始實現(xiàn)中,圖形能力并不十分完善。因為開發(fā) JDK 是打算將其作為平臺中立的實現(xiàn)平臺,所以其原始的功能被限制于“最少公共功能”上,所有被支持的操作系統(tǒng)上保證提供這些公共功能;

在 Java 2D 出現(xiàn)之前,對繪制能力、字體操作和圖像控制的支持非常少。而對諸如用圖案進行著色、形狀操作以及圖形變換之類的重要操作的支持則完全沒有。

Java 2D 滿足了跨平臺實現(xiàn)中對這些功能以及其它功能的需求。

三、Java 2D API:

它是JFC (Java Fundation Classes)的一員,加強了傳統(tǒng)AWT( Abstract Windowing Toolkit )的描繪功能。在 JDK1.2中已經(jīng)支援 Java 2D 的使用。透過Java 2D API ,程序員可以輕松地描繪出任意的幾何圖形、運用不同的填色效果、對圖形做旋轉(zhuǎn)( rotate)、縮放( scale)、扭曲( shear)等。如圖所示,程序員透過2D API所提供的功能,簡單地利用不同類型的線或是填色效果繪出統(tǒng)計圖,以區(qū)分出不同的資料。

它們是基于Graphics2D類的繪圖功能,是對AWT中的Graphics類的進一步的擴展和增強。主要體現(xiàn)在:

1。對渲染質(zhì)量的控制:消除鋸齒以平滑繪制對象的邊緣

2.裁剪、合成和透明度:它們允許使用任意形狀來限定繪制操作的邊界。它們還提供對圖形進行分層以及控制透明度和不透明度的能力。

3.控制和填充簡單及復(fù)雜的形狀:這種功能提供了一個 Stroke 代理和一個 Paint 代理,前者定義用來繪制形狀輪廓的筆(定義繪制的筆的寬度和樣式),后者允許用純色、漸變色和圖案來填充形狀。

4。圖像處理和變換:Java 2D 同 Java 高級圖像 API(Java Advanced Imaging API (JAI))協(xié)作,支持用大量圖形格式處理復(fù)雜的圖像。Java 2D 還為您提供了修改圖像、形狀和字體字符的變換能力。

5。特殊的填充方式,如梯度或者圖案

6.高級字體處理和字符串格式化:允許象操作任何其它圖形形狀一樣操作字體字符。除此以外,可以象文字處理程序一樣,通過為 String 中的字符應(yīng)用屬性和樣式信息來創(chuàng)建格式化文本。

java.awt.geom 包中的Areas類支援聯(lián)集( union)、交集( intersection)、差集(subtraction )、Exclusive OR (XOR)等布爾運算。最後, AffineTransform 類別則提供圖形物件做Scale(比例)、Shear(剪裁) 、Rotate(旋轉(zhuǎn))等座標(biāo)上的轉(zhuǎn)換。

第二節(jié) 圖形繪制的基本方法

一、轉(zhuǎn)換Graphics2D對象

繪制圖形時,可以在Graphics對象或者Graphics2D對象上進行,它們都代表了需要繪圖的區(qū)域,選擇那個取決于是否要使用所增加的Java2D的圖形功能。但要注意的是,所有的Java2D圖形操作都必須在Graphics2D對象上調(diào)用。Graphics2D是Graphics的子類,同樣包含在java.awt包中。

public void paintComponent(Graphics comp)

{ Graphics2D comp2D=(Graphics2D)comp;

}

或者

public void paint (Graphics comp)

{ Graphics2D comp2D=(Graphics2D)comp;

}

二、Graphics 類特性

Graphics 類支持幾種確定圖形環(huán)境狀態(tài)的特性。以下列出了部分特性:

1)Color:當(dāng)前繪制顏色,它屬于 java.awt.Color 類型。所有的繪制、著色和純文本輸出都將以指定的顏色顯示。

2)Font:當(dāng)前字體,它屬于 java.awt.Font 類型。它是將用于所有純文本輸出的字體。

3)Clip:java.awt.Shape 類型的對象,它充當(dāng)用來定義幾何形狀的接口。該特性包含的形狀定義了圖形環(huán)境的區(qū)域,繪制將作用于該區(qū)域。通常情況下,這一形狀與整個圖形環(huán)境相同,但也并不一定如此。

4)ClipBounds:java.awt.Rectangle 對象,它表示將包圍由 Clip 特性定義的 Shape 的最小矩形。它是只讀特性。

5)FontMetrics:java.awt.FontMetrics 類型的只讀特性。該對象含有關(guān)于圖形環(huán)境中當(dāng)前起作用的 Font 的信息。如同我們將看到的那樣,獲取此信息的這種機制已被 LineMetrics 類所取代

6)Paint Mode:該特性控制環(huán)境使用當(dāng)前顏色的方式。如果調(diào)用了 setPaintMode() 方法,那么所有繪制操作都將使用當(dāng)前顏色。如果調(diào)用了 setXORMode() 方法(該方法獲取一個 Color 類型的參數(shù)),那么就用指定的顏色對像素做“XOR”操作。XOR 具有在重新繪制時恢復(fù)初始位模式的特性,因此它被用作橡皮擦除和動畫操作。

三、繪圖的屬性和基本編程方法

1)顏色Color類:沒有變化。

2)填充方式:

Paint(油漆桶) 接口有幾個具體的實現(xiàn),它們允許用純色、漸變色或圖案來填充形狀。

1,純色填充(Color類):對 java.awt.Color 類做了一些調(diào)整以實現(xiàn) Paint,并且可以用于純色填充。

2,漸變色來填充(梯度填充GradientPaint類):java.awt.GradientPaint 類允許用線性顏色漸變色來填充形狀,線性顏色漸變色允許在兩個指定的 Color 對象之間創(chuàng)建過渡??梢詫u變色設(shè)置成“周期性的”,這將導(dǎo)致漸變色圖案重復(fù)出現(xiàn)。

3,圖案填充(紋理TexturePaint類):提供了 java.awt.TexturePaint 類,它可以用由 BufferedImage 描述的圖案填充形狀

編程方法:

使用Graphics2D類中的setPaint()方法并使用Paint對象作為其參數(shù),但由于任何可以作為填充的類如GradientPaint、TexturePaint和Color都實現(xiàn)了Paint接口(該接口注意定義了在Graphics2D下的顏色填充方式),因此可以將它們作為參數(shù)。如:

public void paintComponent(Graphics comp)

{ Graphics2D comp2D=(Graphics2D)comp;

GradientPaint pat=new GradientPaint(0f,0f,Color.white,100f,45f,Color.blue);

comp2D.setPaint(pat);

}

3)設(shè)置筆的形狀:

Stroke 接口由 java.awt.BasicStroke 類實現(xiàn)。該類允許進行大量的選擇以修改線的繪制細節(jié)??梢跃幊讨付?BasicStroke 寬度,也可以指定對名為柱頭和交點的路徑上端點和交點的“裝飾”?,F(xiàn)在也可以繪制點劃線了,只須設(shè)置 BasicStroke 的破折號屬性即可。

在Graphics類中線條是一個點寬,而在Graphics2D中可以通過BasicStoke類中的setStroke()方法來設(shè)置。其構(gòu)造函數(shù)是BasicStroke(float width, int cap, int join)

其中width指示線寬(缺省時為1.0)

cap指示線的末端(包頭,在BasicStroke類中定義出三個static 類型的常量如CAP_BUTT沒有包頭( )、CAP_ROUND圓包頭( )、CAP_SQUARE方包頭( )的樣式

join指示線段之間的拐角(在BasicStroke類中定義出三個static 類型的常量如JOIN_BEVEL( )、JOIN_MITER( )、 JOIN_ROUND( )樣式。

4)編程方法:

public void paintComponent(Graphics comp)

{ Graphics2D comp2D=(Graphics2D)comp;

BasicStroke pen

=new BasicStroke(2.0f, BasicStroke .CAP_BUTT, BasicStroke .JOIN_ROUND);

comp2D.setStroke (pen);

}

代碼示例:

float thick = 0.5f; //設(shè)置畫刷的粗細為 0.5

BufferedImage bi = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);

Graphics2D g = (Graphics2D)bi.getGraphics();

Stroke stroke = g.getStroke(); //得到當(dāng)前的畫刷

g.setStroke(new BasicStroke(thick, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));

g.draw(new Line2D.Float(x1, y1, x2, y2)); 畫線

g.setStroke( stroke ); //將畫刷復(fù)原

5)創(chuàng)建要繪制的形狀對象

在Java2D中進行繪圖時,不是采用對應(yīng)的方法來實現(xiàn),而是為要實現(xiàn)某中形狀創(chuàng)建出相應(yīng)的形狀對象。這可以通過使用java.awt.geom包中的類來定義所要創(chuàng)建的形狀。如線條Line2D.Float類、距形Rectangle2D.Float或者Rectangle2D.Double類、橢圓Ellipes2D.Float、圓弧Arc2D.Float類等。

6)繪制對象:

1,可以使用Graphics2D類中的方法draw()用于繪制輪廓,而fill()方法用于填充。它們都以前面所創(chuàng)建的圖形對象作為參數(shù)。

2,Java2D中的字符串的繪制仍然采用drawString()方法,但有drawString(String s, float x, float y)和drawString(String str, int x, int y)。

3,繪制輪廓:draw(Shape s)其中的Shape接口在Graphics2D中被定義

新的 Java 2D Shape 類都有“2D”后綴。這些新的形狀使用浮點值(而不是整數(shù))來描述其幾何形狀。

Polygon類(int[] xpoints, int[] ypoints, int npoints)

RectangularShape(抽象類,其子類有Arc2D, Ellipse2D, Rectangle2D, RoundRectangle2D), Rectangle(距形)

QuadCurve2D(二次貝塞爾樣條曲線,貝塞爾曲線由兩個端點以及一個或兩個控制點指定。貝塞爾曲線創(chuàng)建了適合于大多數(shù)表示的曲線。)

CubicCurve2D(三次貝塞爾樣條曲線)

Area(區(qū)域)

GeneralPath(由直線、二次樣條曲線、三次樣條曲線所構(gòu)成)

Line2D

8)基本步驟

繪圖的第一個步驟是產(chǎn)生 Graphics2D 對象。 然后設(shè)定所要的狀態(tài)屬性。例如你想要對一物件做漸層式的填色,可以設(shè)定屬性 Paint為 GradientPaint。最後再調(diào)用Graphics2D所提供的方法fill或是draw,完成整個繪圖的程序。

9)程序?qū)嵗?br />
例一:

這是一個最簡單的例子,也可以認為是繪圖的一個最簡單的框架。

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class Map extends JFrame

{ public Map()

{ super("Map");

setSize(350,350);

MapPane map=new MapPane();

getContentPane().add(map);

}

public static void main(String [] arg)

{ Map frame=new Map();

frame.show();

}

}

class MapPane extends JPanel

{ public void paintComponent(Graphics comp)

{ Graphics2D comp2D=(Graphics2D)comp;

comp2D.drawString("sbcd",200,200);

Line2D.Float line=new Line2D.Float(1.0f,2.0f,200.0f,200.0f);

comp2D.draw(line);

}

}

例二:

下面是在Graphics2D模式下的基本繪圖框架。我們可以看到,利用:

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

通過該方法的設(shè)置,使圖形去除鋸齒狀,可以得到多么細膩的圖形。

樣例:

import java.awt.*;

import java.awt.event.*;

import java.awt.geom.*;

public class DrawDemo extends JFrame {

public DrawDemo(){

//設(shè)置窗口的大小、標(biāo)題

this.setSize(new Dimension(600, 400));

//創(chuàng)建繪制各種形狀的容器

ShapesPanel shapesPanel = new ShapesPanel();

//將該容器加入窗口

getContentPane().add(shapesPanel, BorderLayout.CENTER);

}

public static void main(String[] args) {

DrawDemo frame = new DrawDemo();

frame.setVisible(true);

//當(dāng)窗口關(guān)閉時清空內(nèi)存

frame.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

});

}

}

//創(chuàng)建各種容器的類

class ShapesPanel extends JPanel {

final int maxCharHeight = 15;

final Color bg = Color.white; //聲明背景顏色為灰色

final Color fg = Color.blue; //聲明前景顏色為藍色

public ShapesPanel() {

setBackground(bg); //設(shè)置背景顏色

setForeground(fg); //設(shè)置前景顏色

//創(chuàng)建組合邊框

setBorder(BorderFactory.createCompoundBorder(

BorderFactory.createRaisedBevelBorder(),

BorderFactory.createLoweredBevelBorder()));

}

public void paintComponent(Graphics g1) {

super.paintComponent(g1); //清空背景顏色

float thick = 0.5f; //設(shè)置畫刷的粗細為 0.5

Graphics2D g = (Graphics2D)g1;

Stroke stroke = g.getStroke(); //得到當(dāng)前的畫刷

g.setStroke(new BasicStroke(thick, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));

//通過該方法使圖形去除鋸齒狀

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

String txt= "我的文章";

int style=2;//0普通1粗體2斜體3粗斜

g.setFont(new Font("宋體", 2, 15)); //15為字大小

//設(shè)置筆刷為黑色

g.setPaint(Color.black);

g.drawString(txt,200,150);

g.setPaint(Color.red);

g.draw(new Line2D.Float(0,0,200,150)); //畫線

g.setPaint(Color.blue);

g.draw(new Rectangle2D.Float(200,150,100,100));

g.setStroke(stroke); //將畫刷復(fù)原

}

}

例三:圖形靈活的顯示

在上面的例子中,是使用一個繼承于JPanel的類,覆蓋它的void paintComponent(Graphics g1)事件方法,實現(xiàn)繪圖的,這樣雖然方便,但顯得靈活性不高。

實際上,通過JPanel對象直接賦值給Graphics2D對象,往往可以使程序具有很大的靈活性。程序可以這樣來寫。

JPanel contentPane= (JPanel) this.getContentPane();

public Graphics2D comp2D=(Graphics2D)contentPane .getGraphics();

樣例:

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class DrawDemo1 extends JFrame

{

public JPanel contentPane; //繪圖窗口

public Graphics2D comp2D; //繪圖對象

JPanel jPanel1 = new JPanel();//控件容器

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

//構(gòu)造函數(shù)

public DrawDemo1() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//控件的初始化

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(new BorderLayout());

this.setSize(new Dimension(400, 300));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

jPanel1.setLayout(null);

jButton1.setBounds(new Rectangle(30, 235, 100, 31));

jButton1.setText("畫線保留");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(150, 235, 100, 30));

jButton2.setText("畫線刪除");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(jButton1, null);

jPanel1.add(jButton2, null);

}

public static void main(String[] args) {

DrawDemo1 frame=new DrawDemo1();

frame.show();

frame.comp2D=(Graphics2D)frame.contentPane .getGraphics();

frame.comp2D.setBackground(Color.white);

frame.comp2D.clearRect(0,0,401,221);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

void jButton1_actionPerformed(ActionEvent e){

comp2D.setPaint(Color.red);

Line2D.Float line=new Line2D.Float(1.0f,2.0f,200.0f,220.0f);

comp2D.draw(line);

}

void jButton2_actionPerformed(ActionEvent e) {

comp2D.clearRect(0,0,401,221);

comp2D.setPaint(Color.blue);

Line2D.Float line=new Line2D.Float(1.0f,100.0f,300.0f,220.0f);

comp2D.draw(line);

}

}

例四:剪裁

圖形處理問題中,剪裁由的時候是非常難處理的,所謂剪裁是指超過繪圖取得內(nèi)容不顯示,看起來這是個簡單問題,但由于所有的線條必須計算與邊界的交點,而且邊界有四個方向,這就使問題變得很復(fù)雜。java 2D很好的解決了這個問題,請看下面的例子。

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class DrawDemo2 extends JFrame

{

public JPanel contentPane; //繪圖窗口

public Graphics2D comp2D; //繪圖對象

JPanel jPanel1 = new JPanel();//控件容器

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

//構(gòu)造函數(shù)

public DrawDemo2() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//控件初始化

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(new BorderLayout());

this.setSize(new Dimension(400, 300));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

jPanel1.setLayout(null);

jButton1.setBounds(new Rectangle(30, 235, 100, 31));

jButton1.setText("畫線保留");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(150, 235, 100, 30));

jButton2.setText("畫線刪除");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(jButton1, null);

jPanel1.add(jButton2, null);

}

public static void main(String[] args) {

DrawDemo2 frame=new DrawDemo2();

frame.show();

frame.comp2D=(Graphics2D)frame.contentPane .getGraphics();

frame.comp2D.setBackground(Color.white);

frame.comp2D.clearRect(0,0,401,221);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

void jButton1_actionPerformed(ActionEvent e){

comp2D.setPaint(Color.red);

Line2D.Float line=new Line2D.Float(1.0f,2.0f,200.0f,220.0f);

comp2D.draw(line);

}

void jButton2_actionPerformed(ActionEvent e) {

comp2D.clearRect(0,0,401,221);

//剪裁

comp2D.setClip(50,50,300,150);

comp2D.setPaint(Color.blue);

Line2D.Float line=new Line2D.Float(1.0f,100.0f,300.0f,220.0f);

comp2D.draw(line);

}

}

第三節(jié) 曲線問題的高級應(yīng)用開發(fā)

在jdk尚未支援 2D圖形之前,只可以畫出直的、相同粗細的線條?,F(xiàn)在可以通過2D API繪出不同粗細的線條及圓滑的曲線。在java.awt.geom包中提供了Line2D、 QuadCurve2D(二次貝塞爾曲線)及 CubicCurve2D(三次貝塞爾曲線)等相關(guān)的類,讓程序員能夠輕松地繪出想要的線條。

其實繪圖的核心是畫線,下面通過一些實例對一些問題進行深入的討論。

一、直線問題深入研究

樣例:

我們通過一個例子,深入的研究一下繪制直線和折線需要掌握哪些內(nèi)容。

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class DrawDemo1 extends JFrame

{

public JPanel contentPane; //繪圖窗口

public Graphics2D comp2D; //繪圖對象

JPanel jPanel1 = new JPanel();//控件容器

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

JButton jButton3 = new JButton();

//構(gòu)造函數(shù)

public DrawDemo1() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//控件初始化

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(new BorderLayout());

this.setSize(new Dimension(400, 300));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

jPanel1.setLayout(null);

jButton1.setBounds(new Rectangle(30, 235, 100, 31));

jButton1.setText("園頭");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(150, 235, 100, 30));

jButton2.setText("方頭");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

jButton3.setBounds(new Rectangle(270, 235, 100, 30));

jButton3.setText("封閉");

jButton3.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton3_actionPerformed(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(jButton1, null);

jPanel1.add(jButton2, null);

jPanel1.add(jButton3, null);

}

public static void main(String[] args) {

DrawDemo1 frame=new DrawDemo1();

frame.show();

frame.comp2D=(Graphics2D)frame.contentPane .getGraphics();

frame.comp2D.setBackground(Color.white);

frame.comp2D.clearRect(0,0,401,221);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

int Xs1[]={10,60,120,200,260,340};

int Ys1[]={10,200,120,180,60,130};

void jButton1_actionPerformed(ActionEvent e){

comp2D.clearRect(0,0,401,221);

//筆寬度

float thick = 10f;

//設(shè)置筆刷

//園頭園連接

comp2D.setStroke(new BasicStroke(thick,

BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

comp2D.setPaint(Color.red);

//通過該方法使圖形去除鋸齒狀

comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

comp2D.drawPolyline(Xs1,Ys1,Xs1.length);

}

void jButton2_actionPerformed(ActionEvent e) {

comp2D.clearRect(0,0,401,221);

//筆寬度

float thick = 10f;

//設(shè)置筆刷

//方頭方連接

comp2D.setStroke(new BasicStroke(thick,

BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE));

comp2D.setPaint(Color.blue);

//通過該方法使圖形去除鋸齒狀

//comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

// RenderingHints.VALUE_ANTIALIAS_ON);

comp2D.drawPolyline(Xs1,Ys1,Xs1.length);

}

void jButton3_actionPerformed(ActionEvent e) {

comp2D.clearRect(0,0,401,221);

//筆寬度

float thick = 1f;

//設(shè)置筆刷

//方頭方連接

comp2D.setStroke(new BasicStroke(thick,

BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE));

comp2D.setPaint(Color.blue);

//通過該方法使圖形去除鋸齒狀

//comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

// RenderingHints.VALUE_ANTIALIAS_ON);

//畫封閉線

comp2D.drawPolygon(Xs1,Ys1,Xs1.length);

}

}

二、貝塞爾(Bezier)曲線

java 2D提供的QuadCurve2D(二次貝塞爾曲線)及 CubicCurve2D(三次貝塞爾曲線)等相關(guān)的類,可以很容易的畫出貝賽爾曲線。

QuadCurve2D為三個數(shù)據(jù),中間一個為控制點。

CubicCurve2D為四個數(shù)據(jù),中間兩個為控制點。

樣例:

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class DrawDemo1 extends JFrame

{

public JPanel contentPane; //繪圖窗口

public Graphics2D comp2D; //繪圖對象

JPanel jPanel1 = new JPanel();//控件容器

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

//構(gòu)造函數(shù)

public DrawDemo1() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//控件初始化

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(new BorderLayout());

this.setSize(new Dimension(400, 300));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

jPanel1.setLayout(null);

jButton1.setBounds(new Rectangle(30, 235, 150, 31));

jButton1.setText("二階貝塞爾");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(200, 235, 150, 30));

jButton2.setText("三階貝塞爾");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(jButton1, null);

jPanel1.add(jButton2, null);

}

public static void main(String[] args) {

DrawDemo1 frame=new DrawDemo1();

frame.show();

frame.comp2D=(Graphics2D)frame.contentPane .getGraphics();

frame.comp2D.setBackground(Color.white);

frame.comp2D.clearRect(0,0,401,221);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

void jButton1_actionPerformed(ActionEvent e){

double[] x1={50,180,300};

double[] y1={100,190,100};

comp2D.clearRect(0,0,401,221);

//筆寬度

float thick = 1f;

comp2D.setPaint(Color.red);

QuadCurve2D.Double qc=new QuadCurve2D.Double();

qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2]);

comp2D.draw(qc);

comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]);

comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5);

comp2D.setPaint(Color.blue);

x1[1]=180;

y1[1]=30;

qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2]);

comp2D.draw(qc);

comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]);

comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5);

}

void jButton2_actionPerformed(ActionEvent e) {

double[] x1={50,80,200,300};

double[] y1={100,70,190,100};

comp2D.clearRect(0,0,401,221);

//筆寬度

float thick = 1f;

comp2D.setPaint(Color.red);

CubicCurve2D.Double qc=new CubicCurve2D.Double();

qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2],x1[3],y1[3]);

comp2D.draw(qc);

comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]);

comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5);

comp2D.drawLine((int)x1[2]-5,(int)y1[2],(int)x1[2]+5,(int)y1[2]);

comp2D.drawLine((int)x1[2],(int)y1[2]-5,(int)x1[2],(int)y1[2]+5);

float dash1[] = {10.0f};

//畫虛線

BasicStroke dashed = new BasicStroke(1.0f,

BasicStroke.CAP_BUTT,

BasicStroke.JOIN_MITER,

10.0f, dash1, 0.0f);

comp2D.setStroke(dashed);

comp2D.setPaint(Color.darkGray);

comp2D.drawLine((int)x1[1],(int)y1[1],(int)x1[2],(int)y1[2]);

//畫實線

BasicStroke stroke = new BasicStroke(1.0f);

comp2D.setStroke(stroke);

comp2D.setPaint(Color.blue);

x1[1]=180;

y1[1]=70;

x1[2]=80;

y1[2]=190;

qc.setCurve(x1[0],y1[0],x1[1],y1[1],x1[2],y1[2],x1[3],y1[3]);

comp2D.draw(qc);

comp2D.drawLine((int)x1[1]-5,(int)y1[1],(int)x1[1]+5,(int)y1[1]);

comp2D.drawLine((int)x1[1],(int)y1[1]-5,(int)x1[1],(int)y1[1]+5);

comp2D.drawLine((int)x1[2]-5,(int)y1[2],(int)x1[2]+5,(int)y1[2]);

comp2D.drawLine((int)x1[2],(int)y1[2]-5,(int)x1[2],(int)y1[2]+5);

comp2D.setStroke(dashed);

comp2D.setPaint(Color.darkGray);

comp2D.drawLine((int)x1[1],(int)y1[1],(int)x1[2],(int)y1[2]);

comp2D.setStroke(stroke);

}

}

三、自定義樣條曲線編程

當(dāng)我們需要平滑多個數(shù)據(jù)樣本點的時候,貝塞爾曲線就不能滿足要求了,為此,可以采用最早由美國“波音”飛機制造公司提出來的樣條曲線來完成,這種曲線所以稱之為樣條,是因為它模擬了造船業(yè)中的放樣原理。

樣條曲線的數(shù)學(xué)原理請參考計算機圖形學(xué),這里給出的是由java編寫的三次樣條曲線的例子。曲線平滑的原則是,必須通過所有的樣本點,另外,不論有多少樣本點,曲線的階次大為三次,所以是穩(wěn)定的。

這里我們可以看出來,程序設(shè)計的生命是什么呢?數(shù)學(xué)!這是程序設(shè)計著的生命所在。語言只是一種規(guī)范或者是一個工具,要真正寫出好的程序,沒有深厚的數(shù)學(xué)功底,是萬萬不可能的。

樣例:

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import java.awt.geom.*;

public class DrawCurve extends JFrame

{

public JPanel contentPane; //繪圖窗口

JPanel jPanel1 = new JPanel();//控件容器

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

JButton jButton3 = new JButton();

GraphicsCurve gracu;

//構(gòu)造函數(shù)

public DrawCurve() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//控件初始化

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(new BorderLayout());

this.setSize(new Dimension(500,400));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

jPanel1.setLayout(null);

jButton1.setBounds(new Rectangle(30, 310, 100, 31));

jButton1.setText("直線");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(150, 310, 100, 30));

jButton2.setText("樣條曲線");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

jButton3.setBounds(new Rectangle(270, 310, 100, 30));

jButton3.setText("粗線條");

jButton3.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton3_actionPerformed(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(jButton1, null);

jPanel1.add(jButton2, null);

jPanel1.add(jButton3, null);

gracu=new GraphicsCurve();

}

public static void main(String[] args) {

DrawCurve frame=new DrawCurve();

frame.show();

frame.gracu.myGraphics=(Graphics2D)frame.contentPane .getGraphics();

frame.gracu.myGraphics.setBackground(Color.white);

frame.gracu.myGraphics.clearRect(0,0,500,300);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

int Xs1[]={10,60,120,200,260,340};

int Ys1[]={10,200,120,180,60,130};

//畫折線

void jButton1_actionPerformed(ActionEvent e){

gracu.myGraphics.setPaint(Color.blue);

gracu.myGraphics.drawPolyline(Xs1,Ys1,Xs1.length);

}

//畫樣條

void jButton2_actionPerformed(ActionEvent e) {

gracu.myGraphics.setPaint(Color.red);

gracu.DrawCurves(Xs1,Ys1);

}

//畫粗線

void jButton3_actionPerformed(ActionEvent e) {

//筆寬度

float thick = 10f;

//設(shè)置筆刷

//方頭園連接

//gracu.myGraphics.setStroke(new BasicStroke(thick, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));

//園頭園連接

gracu.myGraphics.setStroke(new BasicStroke(thick, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

gracu.myGraphics.setPaint(Color.blue);

//通過該方法使圖形去除鋸齒狀

gracu.myGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

gracu.myGraphics.drawPolyline(Xs1,Ys1,Xs1.length);

}

}

class GraphicsCurve

{

//繪圖對象

public Graphics2D myGraphics;

public GraphicsCurve()

{

}

public GraphicsCurve(Graphics2D graphics)

{

this.myGraphics=graphics;

}

//參數(shù)表

//x數(shù)組,y數(shù)組,筆刷

public void DrawCurves(int[] xa,int[] ya)

{

int[] x, y;

double[] a, b, c;

double[] px, py, qx, qy, tt;

double[] dx, dy;

int px1,py1,px2,py2;

x=xa;

y=ya;

px1=x[0];

py1=y[0];

int n=x.length;

a=new double[n];

b=new double[n];

c=new double[n];

px=new double[n];

py=new double[n];

qx=new double[n];

qy=new double[n];

tt=new double[n];

dx=new double[n];

dy=new double[n];

int i, t, es;

double bx3, bx4, by3, by4, cx, cy;

bx4 = 0;

by3 = 0;

es = 3;

px[0] = 1;

py[0] = 1;

px[n-1] = 1;

py[n-1] = 1;

if (n>1)

{

for (i = 1;i
tt[i] = Math.sqrt((x[i] - x[i - 1]) * (x[i] - x[i - 1]) + (y[i] - y[i - 1]) * (y[i] - y[i - 1]));

switch(n)

{

case 2:

break;

case 3:

for (i = 1;i
{

a[i] = 2 * (tt[i] + tt[i + 1]);

b[i] = tt[i + 1];

c[i] = tt[i];

dx[i] = 3 * (tt[i] * (x[i + 1] - x[i]) / tt[i + 1] + tt[i + 1] * (x[i] - x[i - 1]) / tt[i]);

dy[i] = 3 * (tt[i] * (y[i + 1] - y[i]) / tt[i + 1] + tt[i + 1] * (y[i] - y[i - 1]) / tt[i]);

}

dx[1] = dx[1] - tt[2] * px[0];

dx[n - 2] = dx[n - 2] - tt[n - 2] * px[n-1];

dy[1] = dy[1] - tt[2] * py[0];

dy[n - 2] = dy[n - 2] - tt[n - 2] * py[n-1];

//注意,這是n=3的情況專有計算

px[1] = dx[1] / a[1];

py[1] = dy[1] / a[1];

break;

default:

for (i = 1;i
{

a[i] = 2 * (tt[i] + tt[i + 1]);

b[i] = tt[i + 1];

c[i] = tt[i];

dx[i] = 3 * (tt[i] * (x[i + 1] - x[i]) / tt[i + 1] + tt[i + 1] * (x[i] - x[i - 1]) / tt[i]);

dy[i] = 3 * (tt[i] * (y[i + 1] - y[i]) / tt[i + 1] + tt[i + 1] * (y[i] - y[i - 1]) / tt[i]);

}

dx[1] = dx[1] - tt[2] * px[0];

dx[n - 2] = dx[n - 2] - tt[n - 2] * px[n-1];

dy[1] = dy[1] - tt[2] * py[0];

dy[n - 2] = dy[n - 2] - tt[n - 2] * py[n-1];

c[1] = c[1]/ a[1];

for (i = 2 ;i< n - 1;i++)

{

a[i] = a[i] - b[i] * c[i - 1];

c[i] = c[i] / a[i];

}

qx[1] = dx[1] / a[1];

qy[1] = dy[1] / a[1];

for (i = 2 ;i< n - 1;i++)

{

qx[i] = (dx[i] - b[i] * qx[i - 1]) / a[i];

qy[i] = (dy[i] - b[i] * qy[i - 1]) / a[i];

}

px[n - 2] = qx[n - 2];

py[n - 2] = qy[n - 2];

for (i = n - 3;i>=1;i--)

{

px[i] = qx[i] - c[i] * px[i + 1];

py[i] = qy[i] - c[i] * py[i + 1];

}

break;

}

for (i = 0 ;i< n - 1;i++)

{

bx3 = (3 * (x[i + 1] - x[i]) / tt[i + 1] - 2 * px[i] - px[i + 1]) / tt[i + 1];

bx4 = ((2 * (x[i] - x[i + 1]) / tt[i + 1] + px[i] + px[i + 1]) / tt[i + 1]) / tt[i + 1];

by3 = (3 * (y[i + 1] - y[i]) / tt[i + 1] - 2 * py[i] - py[i + 1]) / tt[i + 1];

by4 = ((2 * (y[i] - y[i + 1]) / tt[i + 1] + py[i] + py[i + 1]) / tt[i + 1]) / tt[i + 1];

t = 0;

while (t < tt[i + 1])

{

t = t + es;

cx = x[i] + (px[i] + (bx3 + bx4 * t) * t) * t;

cy = y[i] + (py[i] + (by3 + by4 * t) * t) * t;

px2 = (int)cx;

py2 = (int)cy;

myGraphics.drawLine(px1,py1,px2,py2);

px1 = px2;

py1 = py2;

}

}

}

}

}

四、用戶數(shù)據(jù)的曲線顯示

當(dāng)需要用曲線表達數(shù)據(jù)的時候,我們雖然可以使用由廠家提供的“圖表”組件,但更多的還是需要自己編寫的,請仔細研究下面的程序,當(dāng)對圖表設(shè)計有更深入的理解。

下面的例子,我們構(gòu)造一個專門處理用戶數(shù)據(jù)的類,在這個類里,實現(xiàn)了用戶坐標(biāo)和屏幕坐標(biāo)的轉(zhuǎn)換,同時給出了一個自動繪制坐標(biāo)的方法。我們也直接使用了上面我們討論過的樣條曲線的類實現(xiàn)數(shù)據(jù)平滑。例子中的數(shù)據(jù)可以來自于數(shù)據(jù)庫或其它任何地方,仔細的研究這個例子,可以看出只要我們開動腦筋,把java強大的功能和我們對問題的理解結(jié)合在一起,就可以寫出多么靈活多變的程序來呀!

樣例:

package myDrawDemo;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

import java.awt.geom.*;

public class DataDrawDemo extends JFrame

{

public JPanel contentPane; //控件容器

JPanel jPanel1 = new JPanel();//繪圖控件

JButton jButton1 = new JButton();

JButton jButton2 = new JButton();

JButton jButton3 = new JButton();

JButton jButton4 = new JButton();

JButton jButton5 = new JButton();

JButton jButton6 = new JButton();

JButton jButton7 = new JButton();

JButton jButton8 = new JButton();

JButton jButton9 = new JButton();

JButton jButton10 = new JButton();

JTextField jText1=new JTextField();

JTextField jText2=new JTextField();

boolean kcu=true;

//用戶坐標(biāo)轉(zhuǎn)換對象

myGraphicsData mp=new myGraphicsData();

//曲線轉(zhuǎn)換對象

GraphicsCurve gracu=new GraphicsCurve();

//窗口范圍

double wx1,wx2,wy1,wy2;

//構(gòu)造函數(shù)

public DataDrawDemo() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//初始化代碼

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(null);

this.setSize(new Dimension(650, 500));

this.setTitle("Frame Title");

//contentPane.setSize(400,240);

//jPanel1.setLayout(null);

jPanel1.setBounds(0,90,650,420);

jButton1.setBounds(new Rectangle(30, 20, 80, 25));

jButton1.setText("開始");

jButton1.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton1_actionPerformed(e);

}

});

jButton2.setBounds(new Rectangle(120, 20, 80, 25));

jButton2.setText("左移");

jButton2.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton2_actionPerformed(e);

}

});

jButton3.setBounds(new Rectangle(210, 20, 80, 25));

jButton3.setText("右移");

jButton3.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton3_actionPerformed(e);

}

});

jButton4.setBounds(new Rectangle(300, 20, 80, 25));

jButton4.setText("上移");

jButton4.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton4_actionPerformed(e);

}

});

jButton5.setBounds(new Rectangle(390, 20, 80, 25));

jButton5.setText("下移");

jButton5.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton5_actionPerformed(e);

}

});

jButton6.setBounds(new Rectangle(120, 50, 80, 25));

jButton6.setText("X擴");

jButton6.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton6_actionPerformed(e);

}

});

jButton7.setBounds(new Rectangle(210, 50, 80, 25));

jButton7.setText("X縮");

jButton7.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton7_actionPerformed(e);

}

});

jButton8.setBounds(new Rectangle(300, 50, 80, 25));

jButton8.setText("Y擴");

jButton8.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton8_actionPerformed(e);

}

});

jButton9.setBounds(new Rectangle(390, 50, 80, 25));

jButton9.setText("Y縮");

jButton9.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton9_actionPerformed(e);

}

});

//樣條控制

jButton10.setBounds(new Rectangle(30, 50, 80, 25));

jButton10.setText("樣條");

jButton10.addActionListener(new java.awt.event.ActionListener() {

public void actionPerformed(ActionEvent e) {

jButton10_actionPerformed(e);

}

});

jText1.setBounds(new Rectangle(490, 20, 120, 20));

jText1.setText("");

jText2.setBounds(new Rectangle(490, 50, 120, 20));

jText2.setText("");

//鼠標(biāo)按下偵聽器

jPanel1.addMouseListener(new java.awt.event.MouseAdapter(){

public void mousePressed(MouseEvent e) {

JPanel_mousePressed(e);

}

});

//鼠標(biāo)拖動偵聽器

jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter(){

public void mouseDragged(MouseEvent e){

JPanel_mouseDragged(e);

}

});

//鼠標(biāo)釋放偵聽器

jPanel1.addMouseListener(new java.awt.event.MouseAdapter(){

public void mouseReleased(MouseEvent e) {

JPanel_mouseReleased(e);

}

});

contentPane.add(jPanel1, BorderLayout.CENTER);

contentPane.add(jButton1, null);

contentPane.add(jButton2, null);

contentPane.add(jButton3, null);

contentPane.add(jButton4, null);

contentPane.add(jButton5, null);

contentPane.add(jButton6, null);

contentPane.add(jButton7, null);

contentPane.add(jButton8, null);

contentPane.add(jButton9, null);

contentPane.add(jButton10, null);

contentPane.add(jText1, null);

contentPane.add(jText2, null);

}

public static void main(String[] args) {

DataDrawDemo frame=new DataDrawDemo();

frame.show();

frame.gracu.myGraphics=(Graphics2D)frame.jPanel1.getGraphics();

frame.mp.myGraphics=(Graphics2D)frame.jPanel1.getGraphics();

frame.mp.myGraphics.setBackground(Color.white);

frame.mp.myGraphics.clearRect(0,0,650,375);

}

//第一組數(shù)據(jù)

double[] Xs1=new double[]{-2,2,4,6,8,10,12,14};

double[] Ys1=new double[]{-4,10,3,14,4,10,6,7};

//第二組數(shù)據(jù)

double[] Xs2=new double[]{-1,2,4,6,8,10,12,14,16};

double[] Ys2=new double[]{1,5,7,1,13,11,4,10,8};

//這是一個畫曲線的程序

void DwData()

{

//剪裁,可以試試沒有剪裁是什么表現(xiàn)?

mp.myGraphics.clipRect(10,10,621,351);

//由于是用兩個對象繪圖,所以應(yīng)該分別剪切

gracu.myGraphics.clipRect(10,10,621,351);

//清除繪圖空間

mp.myGraphics.clearRect(0,0,650,375);

//用戶坐標(biāo)和屏幕坐標(biāo)轉(zhuǎn)換

mp.truemode(10,630,10,360,wx1,wx2,wy1,wy2);

//設(shè)置顏色

mp.myGraphics.setPaint(Color.darkGray);

//畫邊框

mp.myGraphics.drawRect(10,10,620,350);

mp.myGraphics.setFont(new Font("宋體", 0, 10)); //9為字大小

//畫坐標(biāo)

mp.axis(2,2,2,2);

//畫紅線

int[] x=new int[Xs1.length];

int[] y=new int[Ys1.length];

int[] myxy;

//統(tǒng)一實現(xiàn)坐標(biāo)轉(zhuǎn)換

for (int i=0;i
{

myxy=mp.moxy(Xs1[i],Ys1[i]);

x[i]=myxy[0];

y[i]=myxy[1];

}

if (kcu)

{

mp.myGraphics.setPaint(Color.red);

mp.myGraphics.drawPolyline(x,y,x.length);

}

else

{

gracu.myGraphics.setPaint(Color.red);

gracu.DrawCurves(x,y);

}

//畫藍線

x=new int[Xs2.length];

y=new int[Ys2.length];

for (int i=0;i
{

myxy=mp.moxy(Xs2[i],Ys2[i]);

x[i]=myxy[0];

y[i]=myxy[1];

}

if (kcu)

{

mp.myGraphics.setPaint(Color.blue);

mp.myGraphics.drawPolyline(x,y,x.length);

}

else

{

gracu.myGraphics.setPaint(Color.blue);

gracu.DrawCurves(x,y);

}

}

//退出窗口事件

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

System.exit(0);

}

}

//鼠標(biāo)按下事件

void JPanel_mousePressed(MouseEvent e)

{

double[] zs=mp.ScrtoCon(e.getX(),e.getY());

jText1.setText(String.valueOf((float)zs[0]));

jText2.setText(String.valueOf((float)zs[1]));

}

//鼠標(biāo)釋放事件

void JPanel_mouseReleased(MouseEvent e)

{

double[] zs=mp.ScrtoCon(e.getX(),e.getY());

jText1.setText("");

jText2.setText("");

//畫紅線

mp.myGraphics.setPaint(Color.darkGray);

mp.myGraphics.drawLine(e.getX()-3,e.getY(),e.getX()+3,e.getY());

mp.myGraphics.drawLine(e.getX(),e.getY()-3,e.getX(),e.getY()+3);

mp.myGraphics.drawString(String.valueOf((float)zs[0]),e.getX()+10,e.getY());

mp.myGraphics.drawString(String.valueOf((float)zs[1]),e.getX()+10,e.getY()+12);

}

//鼠標(biāo)拖動事件

void JPanel_mouseDragged(MouseEvent e)

{

double[] zs=mp.ScrtoCon(e.getX(),e.getY());

jText1.setText(String.valueOf((float)zs[0]));

jText2.setText(String.valueOf((float)zs[1]));

}

//開始

void jButton1_actionPerformed(ActionEvent e){

wx1=1000000;

wy1=1000000;

wx2=-1000000;

wy2=-1000000;

//試驗中數(shù)據(jù)來自一個數(shù)組,實際中可來自任何地方

//設(shè)置初始范圍

for (int i=0;i
{

if (Xs1[i]< wx1)

wx1=Xs1[i];

if (Xs1[i]> wx2)

wx2=Xs1[i];

if (Ys1[i]< wy1)

wy1=Ys1[i];

if (Ys1[i]> wy2)

wy2=Ys1[i];

}

for (int i=0;i
{

if (Xs2[i]< wx1)

wx1=Xs2[i];

if (Xs2[i]> wx2)

wx2=Xs2[i];

if (Ys2[i]< wy1)

wy1=Ys2[i];

if (Ys2[i]> wy2)

wy2=Ys2[i];

}

DwData();

}

//左移

void jButton2_actionPerformed(ActionEvent e) {

wx1-=1;

wx2-=1;

DwData();

}

//右移

void jButton3_actionPerformed(ActionEvent e) {

wx1+=1;

wx2+=1;

DwData();

}

//上移

void jButton4_actionPerformed(ActionEvent e) {

wy1-=1;

wy2-=1;

DwData();

}

//下移

void jButton5_actionPerformed(ActionEvent e) {

wy1+=1;

wy2+=1;

DwData();

}

//X擴

void jButton6_actionPerformed(ActionEvent e) {

wx1-=1;

wx2+=1;

DwData();

}

//X縮

void jButton7_actionPerformed(ActionEvent e) {

wx1+=1;

wx2-=1;

DwData();

}

//Y擴

void jButton8_actionPerformed(ActionEvent e) {

wy1-=1;

wy2+=1;

DwData();

}

//Y縮

void jButton9_actionPerformed(ActionEvent e) {

wy1+=1;

wy2-=1;

DwData();

}

//樣條控制

void jButton10_actionPerformed(ActionEvent e) {

if (kcu)

{

jButton10.setText("直線");

kcu=false;

}

else

{

jButton10.setText("樣條");

kcu=true;

}

DwData();

}

}

//圖形處理類

class myGraphicsData

{

//屏幕坐標(biāo)

private int X11, Y11, X12, Y12; //x1,y1,x2,y2

//用戶坐標(biāo)

private double W1, W2, W3, W4; //x1,x2,y1,y2

//繪圖對象

public Graphics2D myGraphics;

double Ax8, Ay8;

//用戶窗口與屏幕窗口的轉(zhuǎn)換

//x1,x2,,y1,y2為屏幕坐標(biāo)

//wx1,wx2,wy1,wy2為用戶坐標(biāo)

public void truemode(int x1, int x2, int y1,int y2, double wx1, double wx2, double wy1, double wy2)

{

X11 = x1 ; X12 = x2;

Y11 = y1 ; Y12 = y2;

W1 = wx1 ; W2 = wx2;

W3 = wy1 ; W4 = wy2;

Ax8 = (X12 - X11) / (wx2 - wx1);

Ay8 = (Y12 - Y11) / (wy2 - wy1);

}

//把用戶坐標(biāo)轉(zhuǎn)為屏幕坐標(biāo)

public int[] moxy(double Xa, double Ya)

{

int[] myout=new int[2];

myout[0] = (int)(Ax8 * (Xa - W1) + X11);

myout[1] = (int)(Y12 - Ay8 * (Ya - W3));

return myout;

}

//把屏幕坐標(biāo)轉(zhuǎn)為用戶坐標(biāo)

public double[] ScrtoCon(int X6, int Y6)

{

double[] myout=new double[2];

myout[0] = (X6 - X11) / Ax8 + W1;

myout[1] = (Y12 - Y6) / Ay8 + W3;

return myout;

}

//畫線

public void Dline(double xa, double ya, double xb, double yb)

{

try

{

int x6, y6, x7, y7;

x6 = (int)(Ax8 * (xa - W1) + X11);

y6 = (int)(Y12 - Ay8 * (ya - W3));

x7 = (int)(Ax8 * (xb - W1) + X11);

y7 = (int)(Y12 - Ay8 * (yb - W3));

myGraphics.drawLine(x6, y6, x7, y7);

}

catch(Exception e){}

}

//畫坐標(biāo)U,V為 X,Y軸單位,ns,nt為 x,y軸寫字間隔

public void axis(double u, double v, int ns, int nt)

{

double p9, q9, s;

int n2, swx,swy;

int xk=0;

int yk=0;

double ge;

int[] showxy=new int[2];

swx = 0;

swy=4;

ge = (double)0.008 * (W2 - W1);

p9 = W1;

q9 = (double)(W3 + (W4 - W3) * 0.05);

if ((W1 < 0) && (W2 > 0)) p9 = 0;

if ((W3 < 0) && (W4 > 0)) q9 = 0;

Dline(p9, W3, p9, W4);

n2 = 0;

s = 0;

while (s < W4)

{

Dline(p9, s, p9 + ge, s);

if (n2 >= nt)

{

Dline(p9, s, p9 + ge + ge, s);

n2 = 1;

showxy=moxy(p9 + ge + ge,s);

myGraphics.drawString(String.valueOf(s),showxy[0] - swx+4, showxy[1] - swy+4);

}

else

{

n2++;

}

s += v;

}

//End While

s = 0;

n2 = 0;

while (s > W3)

{

Dline(p9, s, p9 + ge, s);

if (n2 >= nt)

{

Dline(p9, s, p9 + ge + ge, s);

n2 = 1;

showxy=moxy(p9 + ge + ge, s);

myGraphics.drawString(String.valueOf(s),showxy[0] - swx+4, showxy[1] - swy+4);

}

else

{

n2 ++;

}

s -= v; 
網(wǎng)站名稱:Java2D高級繪圖-創(chuàng)新互聯(lián)
文章起源:http://weahome.cn/article/dihejd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部