Lập trình đồ họa trên Java 2D và 3D

Phần 1.............................................................................................................................9 Lập trình đồ họa với Java 2D..........................................................................................9 Chương 1..................................................................................................................10 Tổng quan về Java 2D API.......................................................................................10 1.1 Enhanced Graphics, Text, and imaging..........................................................10 1.2 Rendering Model............................................................................................11 1.2.1 Coordinate Systems.................................................................................12 1.2.1.1 User Space.......................................................................................12 1.2.1.2 Device Space....................................................................................13 1.2.2 Transforms...............................................................................................14 1.2.3 Fonts........................................................................................................15 1.2.4 Images......................................................................................................16 1.2.5 Fills and Strokes.......................................................................................17 1.2.6 Composites...............................................................................................18 Backward Compatibility and Platform independence..........................................19 1.3.1 Backward Compatibility..........................................................................19 1.3.2 Platform independence............................................................................21 1.4 The Java 2D™ API Packages.........................................................................21 Chương 2:.................................................................................................................25 Rendering with Graphics2D.....................................................................................25 2.1 Các lớp và giao diện.......................................................................................26 2.2 Rendering Concepts........................................................................................27 2.2.1 Rendering Process....................................................................................28 2.2.2 Controlling Rendering Quality................................................................29 2.2.3 Stroke Attributes......................................................................................31 2.2.4 Fill Attributes...........................................................................................32 Quá trình xử lý theo phiên............................................................................34 2.2.5 Clipping Paths..........................................................................................34 2.2.6 Transformations.......................................................................................35 2.2.6.1 Constructing an AffineTransform....................................................37 2.2.7 Composite Attributes...............................................................................38 2.2.7.1 Managing Transparency..................................................................39 2.2.7.2 Transparency and images.................................................................40 2.3 Thiết lập Graphics2Context............................................................................40 2.3.1 Setting Rendering Hints...........................................................................40 2.3.2 Specifying Stroke Attributes....................................................................41 2.3.2.1 Setting the Stroke Width..................................................................41 2.3.2.2 Specifying Join and Endcap Styles..................................................42 2.3.2.3 Setting the Dashing Pattern..............................................................42 2.3.3 Specifying Fill Attributes.........................................................................44 2.3.3.1 Filling a Shape with a Gradient.......................................................44 2.3.3.2 Filling a Shape with a Texture.........................................................45 2.3.4 Setting the Clipping Path.........................................................................46 2.3.5 Setting the Graphics2D Transform..........................................................48 2.3.6 Specifying a Composition Style..............................................................51 2.3.6.1 Using the Source Over Compositing Rule.......................................51 2.3.6.2 Increasing the Transparency of Composited Objects......................51 2.4 Rendering Graphics Primitives.......................................................................53 2.4.1 Drawing a Shape......................................................................................53 2.4.2 Filling a Shape.........................................................................................55 1

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D
2.4.3 Rendering Text........................................................................................56 2.4.4 Rendering images....................................................................................56 2.5 Defining Custom Composition Rules.............................................................56 2.6 Rendering in a Multi-Screen Environment.....................................................57 Chương 3..................................................................................................................75 Các đối tượng hình họa.............................................................................................75 3.1 Giao diện và lớp..............................................................................................75 3.2 Các khái niệm hình học:.................................................................................78 3.2.1 Constructive Area Geometry...................................................................79 3.2.2 Bounds and Hit Testing...........................................................................80 3.3 Combining Areas to Create New Shapes........................................................88 Chương 4:.................................................................................................................94 Hiển thị Font và văn bản...........................................................................................94 4.1.Giao diện và lớp..............................................................................................94 4.2.Các khái niệm về Font....................................................................................96 4.3 Các khái niệm về Text Layout........................................................................98 4.3.1 Vẽ chữ......................................................................................................99 4.3.2 Ordering Text.........................................................................................101 4.3.3 Đo và định vị văn bản............................................................................103 4.3.4 Hỗ trợ thao tác với văn bản....................................................................104 4.3.4.1 Hiển thị dấu nhắc............................................................................104 4.3.4.2 Di chuyển dấu nhắc........................................................................106 4.3.4.3 Hit Testing.....................................................................................107 4.3.4.4 Đánh dấu vùng lựa chọn................................................................108 4.3.5 Thực thi việc hiển thị văn bản trong ứng dụng Java™ .........................109 Quản lý việc hiển thị văn bản.............................................................................110 4.4.1 Trình bày văn bản..................................................................................111 Hiển thị dấu nhắc kép.....................................................................................112 4.4.3 Di chuyển dấu nhắc................................................................................113 4.4.4 Hit Testing.............................................................................................114 4.4.5 Đánh dấu vùng lựa chọn........................................................................115 4.4.6 Querying Layout Metrics.......................................................................115 4.4.7 Vẽ văn bản trên nhiều dòng...................................................................116 Chương 5................................................................................................................126 Tạo ảnh.......................................................................................................................126 5.1 Các giao diện và các lớp..........................................................................126 5.1.1 Các giao diện imaging (imaging interfaces).........................................127 5.1.2 Các lớp dữ liệu ảnh(image Data Classes)..............................................127 5.1.3 image Operation Classes........................................................................129 5.1.4 Sample Model Classes...........................................................................130 Color Model Classes.......................................................................................131 5.1.6 Exception Classes..................................................................................132 5.2 Immediate Mode imaging Concepts.............................................................133 5.2.1 Terminology...........................................................................................135 5.3 Using Bufferedimages..................................................................................136 5.3.1 Creating a Bufferedimage......................................................................136 5.3.2 Drawing in an Offscreen Buffer............................................................137 5.3.2.1 Creating an Offscreen Buffer.........................................................138 5.3.2.2 Drawing in an Offscreen Buffer....................................................140 5.3.3 Manipulating Bufferedimage Data Directly..........................................141 2

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D
5.3.4 Filtering a Bufferedimage......................................................................142 5.3.5 Rendering a Bufferedimage ..................................................................142 5.4 Managing and Manipulating Rasters............................................................150 5.4.1 Creating a Raster....................................................................................150 5.4.2 Parent and Child Rasters........................................................................151 5.4.4 The WritableRaster Subclass.................................................................151 5.5 Image Data and DataBuffers.........................................................................152 5.6 Extracting Pixel Data from a SampleModel.................................................153 5.7 ColorModels and Color Data........................................................................154 5.7.1 Lookup Table.........................................................................................155 5.8 image Processing and Enhancement.............................................................155 5.8.1 Using an image Processing Operation...................................................158 Chương 6................................................................................................................162 Mầu sắc...................................................................................................................162 6.1 Các lớp .........................................................................................................163 6.2 Những định nghĩa về mầu sắc.......................................................................163 6.2.1 Không gian mầu....................................................................................164 6.2.1 Biểu diễn màu.......................................................................................167 Chương 7 ...............................................................................................................171 In ấn........................................................................................................................171 7.1 Các giao diện và các lớp...............................................................................171 7.2.1 Supporting Printing................................................................................174 7.2.1.1 Điều khiển in (Job Control)...........................................................174 7.2.2 Page Painters..........................................................................................175 7.2.3 Printable Jobs and Pageable Jobs...........................................................177 7.2.4 Typical Life-Cycle of a PrinterJob................................................................178 7.3 Printing with Printables................................................................................181 7.3.2 Printing a File.........................................................................................185 7.4.1 Using a Pageable Job.............................................................................191 7.4.2 Using Multiple Page Painters................................................................193 Phần 2.........................................................................................................................206 Lập trình đồ họa với Java 3D......................................................................................206 CHƯƠNG 1............................................................................................................207 NHẬP MÔN LẬP TRÌNH TRÊN JAVA 3D.........................................................207 1.1 Tổng quan về Java 3D API ™......................................................................207 1.2 Các vấn đề cơ bản về Java 3D API™ ..........................................................208 1.3 Xây dựng đồ thị khung cảnh.........................................................................208 1.3.1 Thừa kế cấp cao từ Java 3D API ..........................................................214 1.4 Cách thức để viết một chương trình Java 3D....................................................216 1.4.1 Công thức đơn giản để viết một chương trình Java 3D ........................216 1.5 Một vài thuật ngữ trong Java 3D .................................................................221 1.6 Ví dụ đơn giản: HelloJava3Da .....................................................................223 1.6.1 Các lớp của Java 3D Classes được sử dụng trong HelloJava3Da..............229 Tạo nên hình lập phương có kích thước được định ra bởi các giá trị cho trước.....233 1.7 Quay hình lập phương.................................................................................233 1.7.1 Sự kết hợp của các phép biến hình: HelloJava3Db...............................235 1.8 Khả năng và hoạt động.................................................................................236 1.8.1 Dịch các nội dung..................................................................................236 1.8.2 Khả năng ...............................................................................................237 1.9 Thêm vào các hành vi animation..................................................................239 3

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D
1.9.1 Định nghĩa các hành vi animation.........................................................240 1.9.2 Các hàm biến đổi về thời gian: Ánh xạ một hành vi với thời gian........241 1.9.3 Lập danh mục các vùng.........................................................................242 1.9.4 Ví dụ về hành vi: HelloJava3Dc ...........................................................243 1.9.5 Phép biến hình và kết hợp các hành vi .Ví dụ: HelloJava3Dd .............246 CHƯƠNG 2............................................................................................................251 Tạo các hình............................................................................................................251 2.1 Hệ tọa độ thế giới ảo.....................................................................................251 2.2 Visual Object Definition Basics...................................................................252 2.2.1 An Instance of Shape3D Defines a Visual Object................................252 2.2.2 Node Components..................................................................................254 2.2.3 Defining Visual Object Classes.............................................................255 2.3 Các lớp tiện ích hình học .............................................................................256 2.3.1 Box.........................................................................................................257 2.3.2 Cone ......................................................................................................259 2.3.3 Cylinder.................................................................................................259 2.3.4 Sphere....................................................................................................260 2.3.5 More About Geometric Primitives........................................................261 2.3.6 ColorCube .............................................................................................261 2.3.7 Example: Creating a Simple Yo-Yo From Two Cones ........................261 2.4 Các lớp toán học...........................................................................................267 2.4.1 Point Classes .............................................................................................271 2.4.2 Color Classes.........................................................................................272 2.4.3 Vector Classes........................................................................................274 2.4.4 TexCoord Classes..................................................................................275 2.5 Các lớp hình học...........................................................................................276 2.5.1 GeometryArray Class ...........................................................................277 2.5.2 Subclasses of GeometryArray ..............................................................284 2.5.3 Subclasses of GeometryStripArray........................................................286 2.5.4 Subclasses of IndexedGeometryArray...................................................293 2.5.5 Axis.java is an Example of IndexedGeometryArray ............................296 2.6 Appearance and Attributes............................................................................296 2.6.1 Appearance NodeComponent................................................................298 2.6.2 Sharing NodeComponent Objects ........................................................298 2.6.3 Attribute Classes ...................................................................................299 2.6.4 Example: Back Face Culling ................................................................310 2.7 Bounds and Scope ........................................................................................320 2.7.1 Bounds Node Components ...................................................................321 2.7.2 BoundingLeafa Node ............................................................................325 2.7.3 Scope......................................................................................................327 2.8 Hình học nâng cao........................................................................................329 2.8.1 Multiple Geometries in a Single Shape3D ...........................................329 2.8.2 GeometryArray .....................................................................................332 2.8.4 AlternateAppearance <new in 1.2> ......................................................340 2.9 Clipping – Cắt xén........................................................................................343 2.9.1 View Defines a Frustum........................................................................343 2.9.2 Clip Node ..............................................................................................345 2.9.4 ModelClip Example ..............................................................................346 CHƯƠNG 3............................................................................................................350 TẠO NỘI DUNG....................................................................................................350 4

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D
3.1 Nội dung chính..............................................................................................350 3.1.1 GeometryInfo.........................................................................................351 3.2.1 Một ví dụ đơn giản về GeometryInfo........................................................351 3.2.2 Sử dụng GeometryInfo..........................................................................352 3.2.3 Một số lớp thông dụng có liên quan đến GeometryInfo........................353 Loaders................................................................................................................358 Một ví dụ đơn giản sử dụng leader.................................................................359 Các loader phổ biến...........................................................................................360 3.3.3 Giao diện của gói Loader và lớp cơ sở...............................................361 Viết một loader...................................................................................................365 Công việc của một loader...............................................................................365 Hàm tạo lớp Loader........................................................................................366 Viết một File Loader đơn giản........................................................................368 Text2D................................................................................................................379 3.5.1 Ví dụ Text2D đơn giản..........................................................................380 3.5.2 Lớp Text2D............................................................................................380 Text3D................................................................................................................382 Một ví dụ Text3D...........................................................................................382 Những lớp liên quan để tạo ra đối tượng Text3D...........................................384 Nền không gian đồ họa ......................................................................................391 Một ví dụ background.....................................................................................391 Lớp Background.............................................................................................392 CHƯƠNG 4............................................................................................................396 TƯƠNG TÁC.........................................................................................................396 4.1 Hành vi: Cơ sở của tương tác và hoạt hình...................................................397 4.1.1 Ứng dụng của hành vi............................................................................397 4.1.2 Tổng quan lớp Behaviour......................................................................399 4.2 Cơ bản về hành vi.........................................................................................399 4.2.1 Viết một lớp Behaviour.........................................................................400 4.2.2 Sử dụng một lớp Behaviour...................................................................405 4.2.3 Các hàm API trong lớp Behaviour.........................................................409 4.3 Điều kiện kích hoạt: Cách kích hoạt các hành vi..........................................412 4.3.1 Điều kiện kích hoạt................................................................................413 4.3.2 WakeupCriterion....................................................................................414 4.3.3 Quy định lớp WakeupCriterion.............................................................414 4.3.4 Thành phần của WakeupCondition .......................................................430 4.4 Lớp Behaviour tiện ích xử lý bàn phím........................................................432 4.4.1 Một ví dụ đơn giản.................................................................................433 4.4.2 Lớp KeyNavigatorBehaviour và KeyNavigator..................................435 4.5 Lớp tiện ích tương tác với chuột...................................................................437 4.5.1 Sử dụng lớp MouseBehaviour ..............................................................437 4.5.2 Mouse Behaviour Foundation................................................................442 4.5.3 Các lớp MouseBehaviour .....................................................................444 4.5.4 Mouse Navigation..................................................................................447 4.6 Picking Object...............................................................................................450 4.6.1 Using Picking Utility Classes................................................................454 4.6.2 Các hàm API cơ bản trong các lớp Picking ..........................................458 4.6.3 Các lớp picking......................................................................................467 4.6.4 Các lớp Picking Behavior .....................................................................471 CHƯƠNG 5............................................................................................................474 5

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D
Hoạt Hình................................................................................................................474 Animation - Hoạt hình:.......................................................................................476 Đối tượng Interpolator và Alpha với hoạt ảnh dựa thời gian.............................477 Alpha...................................................................................................................477 Sử dụng các đối tượng Interpolator và Alpha:...................................................480 Ví dụ sử dụng lớp Alpha và RotationInterpolator:.............................................480 Alpha API:..........................................................................................................486 Các lớp hành vi Interpolator :.............................................................................489 Core Interpolator API:.......................................................................................504 Các lớp đối tượng nội suy đường:......................................................................513 Lớp Billboard :........................................................................................................522 Sử dụng đối tượng Billboard .............................................................................523 Chương trình ví dụ sử dụng Billboard ...............................................................525 Giao diện lập trình ứng dụng của Billboard (Billboard API)...........................529 OrientedShape3D................................................................................................531 Giao diện lập trình ứng dụng của OrientedShape3D..........................................532 Ví dụ sử dụng OrientedShape3D........................................................................533 Hoạt ảnh mức chi tiết (Level Of Detail Animations).........................................535 Sử dụng đối tượng DistanceLOD.......................................................................536 Các lỗi thường gặp khi sử dụng LOD ............................................................537 Ví dụ sử dụng DistanceLOD..............................................................................537 Giao diện lập trình ứng dụng DistanceLOD API...............................................544 Morph .................................................................................................................545 Sử dụng đối tượng Morph ..................................................................................546 Ví dụ sử dụng Morph .........................................................................................547 Giao diện lập trình ứng dụng Morph API..........................................................553 Giao diện GeometryUpdater...................................................................................554 Sử dụng GeometryUpdater.................................................................................555 Chương trình ví dụ hệ thống phân tử đài phun nước sử dụng GeometryUpdater ............................................................................................................................556

Lời nói đầu Sự phát triển của khoa học, kĩ thuật, nghệ thuật, kinh doanh, và công nghệ luôn luôn phụ thuộc vào khả năng truyền đạt thông tin của chúng ta, hoặc thông qua các bit dữ liệu lưu trữ trong microchip hoặc thông qua giao tiếp bằng tiếng nói. Câu châm ngôn từ xa xưa “một hình ảnh có giá trị hơn cả vạn lời" hay "trăm nghe không bằng một thấy" cho thấy ý nghĩa rất lớn của hình ảnh trong việc chuyển tải thông tin. Hình ảnh bao giờ cũng được cảm nhận nhanh và dễ dàng hơn, đặc biệt là trong trường hợp bất đồng về ngôn ngữ. Do đó không có gì ngạc nhiên khi mà ngay từ khi xuất hiện máy tính, các nhà nghiên cứu đã cố gắng sử dụng nó để phát sinh các ảnh trên màn hình. Trong suốt gần 50 năm phát triển
http://tailieuhay.com 6

Lập trình đồ họa trên Java 2D và 3D của máy tính, khả năng phát sinh hình ảnh bằng máy tính của chúng ta đã đạt tới mức mà bây giờ hầu như tất cả các máy tính đều có khả năng đồ họa.Đồ họa máy tính là một trong những lĩnh vực lí thú nhất và phát triển nhanh nhất của tin học. Ngay từ khi xuất hiện, đồ họa máy tính đã có sức lôi cuốn mãnh liệt, cuốn hút rất nhiều người ở nhiều lĩnh vực khác nhau như khoa học, nghệ thuật, kinh doanh, quản lí, ... Tính hấp dẫn và đa dạng của đồ họa máy tính có thể được minh họa rất trực quan thông qua việc khảo sát các ứng dụng của nó. Ngày nay, đồ họa máy tính được sử dụng trong rất nhiều lĩnh vực khác nhau như công nghiệp, thương mại, quản lí, giáo dục, giải trí, … Số lượng các chương trình đồ họa ứng dụng thật khổng lồ và phát triển liên tục.Trong lĩnh vực công nghiệp,CAD(computer-aided design) đã được sử dụng hầu hết trong việc thiết kế các cao ốc, ô tô, máy bay, tàu thủy, tàu vũ trụ, máy tính,…Trong lĩnh vực giải trí,nghệ thuật, đồ họa máy tính giúp ta tạo ra các chương trình trò chơi,các kĩ xảo điện ảnh cho các nhà làm phim,hay ngay chính giao diện đồ họa đã làm nâng cao khả năng giao tiếp giữa người và máy tính. Để có thể làm được những ứng dụng đồ họa hữu ích cho cuộc sống,trước hết chúng ta cần phải có một nền tảng vững chắc về lập trình đồ họa.Có rất nhiều ngôn ngữ hỗ trợ lập trình đồ họa máy tính,mỗi ngôn ngữ được xây dưng trên những thư viện đồ họa riêng,có những thế mạnh riêng.Và khi nói về lập trình đồ họa,chúng ta không thể không nói đến ngôn ngữ Java,một ngôn ngữ rất mạnh trong lĩnh vực này.Với mục đích nghiên cứu,tìm hiểu và mang đến cho những ai muốn tìm hiều về lập trình đồ họa một tài liệu thiết thực,nhóm chúng em đã chọn đề tài làm tutorial về lập trình đồ họa trên nền tảng ngôn ngữ lâp trình Java,dựa trên các tài liệu training trên mạng của hãng Sun.Vì là lần đầu làm tài liệu tham khảo

http://tailieuhay.com

7

Lập trình đồ họa trên Java 2D và 3D nên chúng em không tránh khỏi sai sót.Chúng em mong thầy xem xét và góp ý cho tài liệu này.Chúng em chân thành cảm ơn.

http://tailieuhay.com

8

Lập trình đồ họa trên Java 2D và 3D

Phần 1 Lập trình đồ họa với Java 2D

http://tailieuhay.com

9

Lập trình đồ họa trên Java 2D và 3D

Chương 1 Tổng quan về Java 2D API

Java 2D™ API tăng cường về khả năng đồ hoạ, văn bản và ảnh của Abstract Windowing Toolkit (AWT), giúp phát triển về giao diện người sủ dụng và ứng dụng về JAVA trong một số lĩnh vực mới.Cùng với khả năng mạnh về đồ hoạ ,phông chữ và ảnh trong các API, thì Java 2D API còn hỗ trợ những thuộc tính và thành phần màu sắc đã được nâng cao, và thành công trong việc biểu diễn các bề mặt hình học tuỳ ý và một kiểu tô trát chuẩn cho máy in và thiết bị hiển thị. Java 2D API cũng cho phép tạo ra các thư viện đồ hoạ mở rộng,như các thư viện của CAD-CAM và các thư viện tạo hiệu ứng đặc biệt cho ảnh và đồ hoạ, cũng như việc tạo ra các bộ lọc đọc/viết file ảnh và đồ hoạ.Khi được sử dụng kết hợp với Java Media Framework Java Media APIs khác ,thì Java 2D APIs có thể được sử dụng để tạo ra và hiển thị hiện thực ảo và các dạng đa phương tiện khác. Java Animation và Java Media Framework APIs dưa trên Java 2D API để hỗ trợ việc tô trát(rendering). 1.1 Enhanced Graphics, Text, and imaging Nếu các phiên bản trước của AWT chỉ cung cấp các gói tô trát(rendering) đơn giản chỉ phù hợp cho việc rendering các trang HTML đơn giản,mà không đáp ứng đủ cho các dạng đồ hoạ,văn bản và ảnh phức

http://tailieuhay.com

10

Lập trình đồ họa trên Java 2D và 3D tạp. Thì Java 2D™ API cung cấp gói tô trát đẩy đủ các tính năng bằng cách mở rộng AWT để hỗ trợ cho đồ hoạ và các thao tác rendering. Ví dụ như thông qua các lớp đồ hoạ cho phép vẽ hình chữ nhật,hình ôval,và các đa giác. Đồ hoạ 2D tăng cường về khái niệm của phép tô trát hình học bằng cách cung cấp một cơ chế cho phép rendering ảo của bất kì bề mặt hình học nào.Tương tư như vậy với Java 2D API bạn có thể vẽ các dạng đường với bất kì độ rộng và dạng hình học nào. Dạng hình học được cung cấp thông qua các phần thực thi implementations của Shape interface trong Graphic class, như hình chữ nhật 2D và Elip 2D. Các đường cong và hình cung cũng thuộc phần implementations của Shape. Các kiểu vẽ và tô cũng được cung cấp thông qua phần thực thi implementations của giao tiếp Paint và Stroke interfaces, ví dụ BasicStroke, GradientPaint, TexturePaint,và Color. AffineTransform định nghĩa các phép biến đổi trong toạ độ 2 chiều, gồm có phép lấy tỉ lệ,phép chuyển đổi toạ độ ,phép quay và phép xén cắt. Khung nhìn được định nghĩa bởi các phương thức giống nhau của lớp Shape mà chúng được dùng để định nghĩa các khung nhìn chung,ví dụ như Rectangle2D và GeneralPath. Thành phần màu sắc được cung cấp bởi các phương thức của lớp Composite, ví dụ AlphaComposite. Một kiểu Font chữ thì được định nghĩa bởi các collection của Glyphs. 1.2 Rendering Model Kiểu tô trát đồ họa đơn giản không có gì thay đổi khi thêm vào Java 2D™ APIs. Để tô trát đồ họa thì phải thiết lập các thông số về đồ họa và gọi phương thức của đối tượng Graphics. Trong Java 2D API, lớp Graphics2D mở rộng lớp Graphics để hỗ trợ thêm nhiều thuộc tính đồ họa và cung cấp thêm các phương thức cho quá trình tô trát.

http://tailieuhay.com

11

2. Không gian người sủ dụng là hệ tọa độ logic và độc lập với thiết bị. Với Java 2 SDK.1 User Space Hệ tọa độ này được chỉ ra trong hình 1-1. version 1. x (0. 1.2.1 Coordinate Systems Java 2D API bao hàm hai hệ tọa độ: 1.tất cả các dạng hình học được tô trát bằng Java 2D đều được xác định trong hệ tọa độ này.com 12 . Bằng ứng dụng máy ảo một cửa sổ hiển thị có thể mở rộng thêm nhiều thiết bị hiển thị vậy lý tạo nên môi trường đa màn hiển thị.0) http://tailieuhay.3 .1.2. 1. hệ tọa độ của thiết bị này được sủ dụng làm hệ tọa độ của máy ảo sẽ được lấy làm hệ tọa độ cho tất cả các màn hiể thị còn lại. Mặc dù hệ tọa độ cho màn hình rất khác đối với hệ tọa độ cho máy in nhưng sự khác biệt này trong suốt đối với các ứng dụng. Java 2D API còn hỗ trợp cho các môi trường đa màn hình (multi-screen environments). Tại tầng ứng dụng. Hệ thống Java 2D sẽ tự động thực hiện những phép chuyển đổi cần thiết giữa không gian người sử dụng và không gian thiết bị .quá trình tô trát là giống nhau cho dù thiết bị cuối đó là màn hình hay máy in. Không gian thiết bị là hệ tọa độ phụ thuộc thiết bị.Lập trình đồ họa trên Java 2D và 3D The Java 2D API tự động cân chỉnh những sai khác trong các thiết bị tô trát và cung cấp một kiểu tô trát thống nhất cho các dạng thiết bị khác nhau.ứng với từng loại thiết bị cuối mà có hệ tạo độ khác nhau. Các ứng dụng thường sủ dụng hệ tọa độ này.

Còn không gian thiết bị cho một thiết bị cụ thể có thể có cùng gốc tọa độ và hướng của các trục hoặc là có thể không.1.2 Device Space Java 2D API định nghĩa 3 mức thông tin cấu hình để hỗ trợ cho việc chuyển đổi từ không gian người sử dụng sang không gian thiết bị.2.Lập trình đồ họa trên Java 2D và 3D y Figure 1-1 User Space Coordinate System Không gian người sử dụng biểu diễn một cách trừu tượng đồng nhất cho các hệ tạo độ của tất cả các thiết bị có liên quan. 1.Ngoài ra các tọa độ của không gian người sử dụng có thể chuyển đổi một cách tự động vào không gian thiết bị phù hợp mỗi khi một đối tượng đồ họa được tô trát.thường thì các chương trình driver của các thiết bị thực hiện điều này. Thông tin này được chứa trong 3 lớp : • GraphicsEnvironment • GraphicsDevice • GraphicsConfiguration Hai trong số chúng sẽ biểu diễn tất cả các thông tin cần thiết cho việc xác định thiết bi tô trát và cho việc chuyển đổi tọa độ từ không gian người http://tailieuhay.com 13 .

Lập trình đồ họa trên Java 2D và 3D sử dụng sang không gian thiết bị.Các thiết bị sử dụng cho quá trình tô trát gồm có màn hình . Ví dụ.2 Transforms Java 2D API có một chế độ chuyển tọa độ thống nhất.chuyển đổi hoặc cắt tọa độ cho một mặt hình học http://tailieuhay.Mỗi cấu hình phù hợp của thiết bị được biểu diễn bởi lớp GraphicsConfiguration.Lớp GraphicsEnvironment cũng bao gồm tập các font phù hợp trong môi trường đó.bao gồm các phép chuyển từ không gian người sử dụng đến không gian của thiết bị.lấy tỉ lệ .mỗi đối tượng GraphicsDevice có thể có 1 hay nhiều đối tượng kiểu GraphicsConfigurations. and 800x600x256 colors.com 14 . Tất cả các phép chuyển tọa độ. 640x480x256 colors. Lớp GraphicsDevice mô tả thiết bị tô trát như màn hình hoặc máy in.đều được biểu diễn bởi đối tượng kiểu AffineTransform . Ngược lại . Ứng dụng có thể truy cập thông tin này nhưng không nhất thiết phải thực hiện bất kì phép chuyển đổi nào giũa hai hệ tọa độchuyển . Cũng có thể thêm đối tượng AffineTransform cho các dạng đồ họa bằng các phép xoay .một thiết bị hiển thị SVGA có thể thực hiện trong một số chế độ màu như : 640x480x16 colors.2.Một đối tượng kiểu GraphicsEnvironment có thể bao gồm 1 hay nhiều đối tượng GraphicsDevices.AffineTransform định nghĩa các luật cho những thao tác trên các hệ tọa độ bằng các ma trận(các phép biến đổi ảnh bằng các bộ lọc). Màn hình SVGA được biểu diễn bởi một đối tượng GraphicsDevice và ứng với mỗi chế độ màu của màn hình SVGA sẽ được biểu diễn bởi một đối tượng GraphicsConfiguration. má in và các bộ đệm ảnh. Lớp GraphicsEnvironment mô tả tập các thiết bị mà đựợc chấp nhận bởi các ứng dụng Java trong một môi trường cụ thể. 1.

com 15 .các font được mô tả bằng các tên lôgíc mà ánh xạ trên các dạng font khác nhau fụ thuộc liệu các dạng font đó có sắn trong http://tailieuhay.họ các font tạo nên một tập font và tập này có sẵn trong một đối tượng GraphicsEnvironment cụ thể nào đó.1 .2. Một font có thể được xem như tập các glyph. Nhưng điều này lại khác với fần mềm JDK 1.một nhóm các glyphs với các kiểu riêng biệt tạo nên một dạng font.Các phép biến đổi được thêm vào này sẽ được ứng dụng cho các đối tượng đồ họa được tô trát trong trường hợp đó phép bién đổi này được thực hiện khi chuyển từ tọa độ không gian người sử dụng sang không gian của thiết bị. Hay nói cách khác . Trong Java 2D API.nhóm các dạng font tao nên môt họ font . Một font có thể biểu diễn một kí tự như chữ thường hoặc chữ hoa bằng cách sử dụng nhiều glyphs.Lập trình đồ họa trên Java 2D và 3D .gôtích…tất cả các kiểu chữ này trong một font có cùng thiết kế in và có thể ví như chúng là các thành viên trong cùng một gia đình.ví dụ Helvetica Bold. ví dụ sự kết hợp của 2 hay nhiều kí tự thường được thay thế bởi một hình dạng kí hiêu nào đó được gọi là ligature. Một font đơn có thể có rất nhiều kiểu khác nhau như kểi chữ đậm .Tuy nhiên.3 Fonts Một xâu thường được hiểu là tập các kí tự tao thành.văn bản hay ảnh khi chúng được tô trát. Các hình dạng mà một phông chữ sử dụng để biểu diễn các kí tự trong một xâu được gọi là glyphs.vừa. hình dạng mà font sử dụng để hiển thị lên màn hình xâu đó không phải lúc nào cũng giống với hình dáng của mỗi kí tự riêng biệt. các font được xác định bởi một tên mà mô tả một dạng font riêng biệt nào đó. một glyph chỉ đơn giản là một dạng (Shape) mà có thể đựoc thao tác và tô trát một cách giống nhau như bất kì với các dạng khác Shape. hoặc biểu diễn các liên kết kí tự như fi chỉ biểu diễn bởi 1 glyph. 1.Khi một xâu được vẽ.nghiêng . Trong Java 2D API. hình dạng của nó sẽ được xác định bởi font mà chúng ta chọn.

và thâm chí cả ngôn ngữ khác nhau. Trong ảnh màu đa màu (hơn 256 màu) các điểm ảnh thường trực tiếp biểu diễn luôn màu sắc và các đặc trưng khác cho mỗi vùng hiển thị của ảnh. the Java 2D API hỗ trợ việc xác định các font bằng tên lôgíc cũng như bằng tên dạng font. Trong ảnh màu hiển thị bằng chỉ số (indexed-color image). và thường số lượng màu trong bảng màu sẽ ít hơn sovới ảnh thật.com 16 . có thể soạn thảo và tô rát các xâu bao gồm nhiều font thuộc các họ font. những màu sắc của ảnh sẽ bị giới hạn bởi bảng màu . và thông tin sắp xếp được lưu trong đối tượng TextLayout và TextAttributeSet . Một mảng hai chiều của điểm ảnh được gọi là một raster.Các đối tượng Font được sử dụng để mô tả các hình dạng hiển thị của font.Định dạng này thường được dùng cho những ảnh có 256 màu. Các dạng của văn bản được lưu riêng biệt một cách lôgíc với sự sắp xếp các văn bản.Như để tương thích cho điều đó . Ảnh trong Java 2D API có hai thành phần chính • Dữ liệu ảnh thô(các điểm ảnh) http://tailieuhay.2. Một điểm ảnh hay một pixel sẽ định nghĩa thể hiện của một ảnh tại vùng quan sát của màn hình . 1. Tuy nhiên các ảnh khi được lưu như tập các chỉ số màu sẽ làm cho kích thước ảnh nhỏ đi. Sử dụng Java 2D API. nhưng chúng nhìn sẽ thật hơn .Lập trình đồ họa trên Java 2D và 3D môi trường đang xét không.hình dạng.kich thước. Thể hiện của một điểm ảnh có thể được định nghĩa một cách trực tiếp hoặc như là một chỉ số trong bảng màu dành cho ảnh.4 Images Ảnh được tạo nên từ tập các pixel . Việc lưu giứ các font và thông tin sắp xếp riêng biệt nhau làm dễ dàng hơn cho việc sử dụng cùng font chữ nhưng khác về cấu hình sắp xếp. Những ảnh như vậy sẽ có kích thước lớn hơn ảnh màu mà hiển thị bằng chỉ số(indexed-color images).

Một điểm ảnh trong ảnh dùng màu trực tiếp có thể được hiểu như một tập . gồm có không gian màu RGB và gray scale.image bao gồm một số phương thức ColorModel cho các biểu diễn thành phần điểm ảnh. Việc chia không gian màu sắc thành các chế độ màu sẽ tạo nên sự linh hoạt hơn trong việc biểu diễn và chuyển đổi từ phép biểu diễn màu này sang một phếp biểu diẽn màu khác.com 17 .Có thể xác định độ rộng cũng như các nét cho các đường thẳng và đường cong.awt. Lưu ý rằng một không gian màu không phải là một tập các màu sắc mà tập này định nghĩ các luật để có thể chuyển đổi các giá trị màu thành các màu tương ứng thông dịch.Lập trình đồ họa trên Java 2D và 3D • Những thông tin cần thiết cho quá trình chuyển đổi các điểm ảnh Các luật cho việc chuyển đổi các điểm ảnh được lưu bởi đối tượng ColorModel.2. Vì các chữ xét cho cùng cũng được biểu diễn bằng tập các glyph. Gói java. Các kiểu bút được định nghĩa băng các đối tượng kiểu Stroke. Đối với một điểm ảnh để hiển thị cần phải đi kèm với một kiểu màu sắc. nên các xâu kí tự cũng có thể được vẽ và tô. Một đối tượng ColorSpace chứa các luật để sao cho tập các giá trị màu tương ứng với một màu sắc nhất định . Các kiểu tô được định nghĩa bởi các phương thức thuộc đối tượng Paint.Ví dụ các thành phần màu đỏ là các daỉ màu trong ảnh RGB . 1. có thể tô các hình băng cách sử dụng các kiểu but khác nhau và các kiểu tô khác nhau.color sẽ biẻu diễn các không gian màu sắc thông dụng.awt. Một dải màu là một thành phần của không gian màu sắc dành cho ảnh.5 Fills and Strokes Với Java 2D API.Các phương thức của ColorSpace trong java. Lớp Color có sắn trong các phiên bản trước của AWT đây là một http://tailieuhay.

com 18 . • Sử dụng phương thức fill để tô các vùng trong của hình với kiểu tô đã dược xác định. GradientPaint định nghĩa một kiểu tô màu loang(gradient) giữa hai màu. Trong Java 2D. Tuy nhiên có một số vấn đề trong cách tiếp cận này: • Sẽ thật khó trong trường hợp nếu màu Red và màu Blue được thêm vào hây không được thêm vào. Khi một chuỗi kí tự được render. • Việc kết hợp lôgíc sẽ không được hỗ trợ trong trường hợp cácmàu thuộc các không gian màu khác nhau. rendering một đường nét của một hình và tô hình đó bằng một kiểu nào đó được thực hiên hai thao tác riêng biệt: • Sử dụng một trong các thuật toán draw để render các đường nét của hình sử dụng các kiểu bút được xác định bởi các thuộc tính của Stroke và kiểu tô được xác định bởi thuộc tính Paint.Lập trình đồ họa trên Java 2D và 3D dạng đơn giản của đối tượng Paint được sử dụng để định nghĩa tô màu trơn (solid color). http://tailieuhay.2. 1. Java 2D API có các luật cho việc kết hợp màu trong trường hợp này trong đối tượng Composite. Java 2D API cung cấp thêm hai phương thức mới cho Paint là TexturePaint và GradientPaint. Để vẽ các nét của các glyphs trong chuỗi kí tự cần phải chọn các đường nét và render chúng như đối với các hình sử dụng phương thức draw .các thuộc tính hiện tại của Paint đựơc áp dụng cho các glyphs tạo nên chuỗi đó.6 Composites Khi render một đối tượng mà chồng lên một đối tượng đã tồn tai trước đó cần phải xác định làm thế nào để kết hợp màu của các đối tuợng.Lưu ý thực chất đối tượng drawString sẽ tô các glyphs mà được render. TexturePaint định nghĩa kiểu tô dùng mẩu ảnh đơn giản(simple image fragment ) mà được lặp như nhau.

Java 2D API tăng cường thêm một số tính năng cho AWT bằng cách thêm các phương thức mới vào các lớp đã tồn tại.mở rộng thêm các lớp đã tồn tại và đồng thời thêm các lớp mới và các interface mới mà không ảnh hưởng tới các API hợp lệ.1.1 Backward Compatibility Để tương thích với các tính năng đã tồn tại trong đồ họa JDK . Graphics2D mở rộng các lớp Graphics trong JDK1.Lập trình đồ họa trên Java 2D và 3D • Sự kết hợp sẽ không có ý nghĩa trong trường hợp màu được biểu diễn bằng các gia trị màu thì khi đó sự kết hợp hai điểm ảnh là sự kết hợp của hai giá trị màu. Để cung cấp các thuộc tính mở rộng về đồ họa trong đó bao gồm cả yếu tố tương thích với các phần mềm đồ họa khác.3.com 19 . Và Java 2D™ API là một kiến trúc chính vì vậy mà các ứng dụng của nó có tính độc lập về môi trường 1. • paint • paintAll • update • print http://tailieuhay. Backward Compatibility and Platform independence Như đã nói.Java 2D™ API có sự tương thích đối với phần mềm JDK 1.Có rất nhiều tính năng củaJava 2D API được bắt nguồn từ việc mở rộng các thuộc tính về đồ họa trong Graphics2D. Một đối tượng AlphaComposite bao gồm các kiểu về màu sắc của các màu sắc của nguồn và đích.1 . Java 2D API tránh các loĩi này bằng cách thực hiện các luật pha trộn alpha mà sẽ đưa vào các thông tin về kiểu biểu diễn điểm ảnh mỗi khi thực hiện kết hợp màu. Ví dụ.

thì một applet tương thích với Java 2D API sẽ đưa ngữ cảnh đồ họa tới đối tượng Graphics2D: public void Paint (Graphics g) { Graphics2D g2 = (Graphics2D) g. Kĩ thuật này được sử dụng để thêm các phương thức và các dữ liệu thể hiện cho lớp kế thừa. Ví dụ. và các lớp thừa kế được cập nhật để mở rộng các lớp cha mới.. . hay đúng hơn là mở rộng một lớp thừa kế. .Lập trình đồ họa trên Java 2D và 3D • printAll • getGraphics JDK 1. Để có thể truy nhập những chức năng được thực thi trong đối tượng Graphics2D. Có hai kĩ thuật đã được sử dụng để khái quat hóa các lớp kế thừa: • Một hay nhiều lớp cha được chèn vào biểu đồ phân cấp của lớp . Java 2D API khái quat hóa nó..1 applet thông dịch ngữ cảnh đồ họa mà được đưa vào như là một thể hiện của lớp Graphics.. Kĩ thuật này được sử dụng để thêm các phương thức ảo tổng quát(general abstract methods) cho lớp kế thừa .com 20 ..setTransform (t). Java 2D API khái quát hóa lớp AWT Rectangle bằng cách sử dụng cả hai kĩ thuật Sự phân cấp cho hình chữ nhật giống như: http://tailieuhay. • Một hay nhiều triển khai các interface được thêm vào lớp kế thừa . } Trong môt vài trường hợp . g2.

Hai lớp cha được thêm vào phân cấp của lớp Rectangle là RectangularShape và Rectangle2D. 1. 1.4 The Java 2D™ API Packages Các lớp Java 2D API được tổ chức trong các package sau: http://tailieuhay. Và chỉ độc lập về font khi các font đó đã được xây dựng sẵn(được cung cấp như là một phần của phần mềm JDK ).1 .3. Các Applet được viết cho phần mềm JDK 1. Bây giờ mở rộng các lớp Rectangle2D mới và triển khai cả hai interface Shape và Serializable.nhưng điều này không ảnh hưởng bởi vì lớp Rectangle vẫn bao gồm các phương thức và các thành phần có trong các phiên bản trước. Mỗi glyph lại có thể được định nghĩa bởi Shape mà bao gồm các đoạn đường thẳng và các đường cong. Java 2D API không đảm đương về không gian màu sắc hay là chế độ màu của thiết bị rendering và Java 2D API có bất kì định dạng ảnh cụ thể nào.Lập trình đồ họa trên Java 2D và 3D Trong phần mềm JDK 1.hay là khi chúng được gởi tạo bằng lập trình. Java 2D API không hỗ trợ các font xây dựng sẵn và các font được tạo nên nhờ chương trình tạo font nhưng nó lại hỗ trợ việc định nghĩa các font thông qua tập các glyph của nó.2 Platform independence Có khả năng pháp triển các ứng dụng độc lập với môi trường. Có rất nhiều kiểu font với nhiều hình dang và kich thước được bắt nguồn từ tập các glyph đơn lẻ.com 21 .1 không truy cập được các lớp mới và các phần triển khai của các interface. Rectangle là một đối tuợng mở rộng đơn giản.

font • java.image.geom bao gồm các classe và interface có liên quan đến việc định nghĩa các dạng hình học nguyên thủy: http://tailieuhay.awt.awt bao gồm các lớp Java 2D API đã đề cập ở trên và các interface đã tồn tại trước đó và các interface fát triển thêm.awt.awt.com 22 .awt.renderable • java.geom • java.awt • java.Lập trình đồ họa trên Java 2D và 3D • java.awt.awt là các lớp của Java 2D ) Package java.awt.awt.image • java.color • java. (Rõ dàng là không phải tất cả các lớp trong java.print Package java.

Float và Double Điều này cho phép các implementation có thể ở hai mức chính xác là giá trị single và double.awt.awt.Lập trình đồ họa trên Java 2D và 3D Có nhiều dạng hình học nguyên thủy ứng với implementation.com 23 .color chứa các lớp và các giao diện cho việc định nghĩa các không gian màu và các mẫu màu: Các gói java.awt.renderable chứa các lớp và các giao diện cho việc định nghĩa và tạo bóng của ảnh. Gói java.image và java.image.font chứa các lớp và các giao diện được sử dụng cho việc bố trí văn bản và định nghĩa các kiểu font: các phần Gói java.awt. http://tailieuhay.

đồ họa và ảnh dựa trên công nghệ Java 2D.các lớp cho chế độ màu mới cũng có trong package java. Package java.com 24 .image tồn tại trong các version trước đó của AWT.awt.Để đảm bảo tính thống nhất.awt.image . http://tailieuhay.awt.print bao gồm các lớp và các interface cho phép in tất cả các dạng văn bản .Lập trình đồ họa trên Java 2D và 3D Package java.awt.image package cho sự tương thích . Java 2D API tăng cường thêm các lớp ảnh kế thừa từ AWT sau đây: • ColorModel • DirectColorModel • indexColorModel Các lớp chế độ màu sắc này vẫn tồn tại trong package java.

văn bản và ảnh . http://tailieuhay.Graphics để tạo ra điều khiển tinh vi hơn về biểu diễn các hình .Lập trình đồ họa trên Java 2D và 3D Chương 2: Rendering with Graphics2D Graphics2D mở rộng java.được áp dụng cho các đối tượng đồ họa khi chúng được tô trát. như là các kiểu đường thẳng và các phép biến đổi.cần thiết lập Graphics2D context và sau đó gọi một trong các phương thức tô trát Graphics2D như draw hay fill. Tập các thuộc tính trạng thái kết hợp với Graphics2D được tham chiếu tới như là Graphics2DContext. Để tô trát văn bản .com 25 . Các thuộc tính tạng thái Graphics2D .Quá trình tô trát Java 2D™ được điều khiển thông qua đối tượng Graphics2D và các thuộc tính trạng thái của nó.awt.hình và ảnh.

CompositeContex t Được thực thi bởi phương thức AlphaComposite.mà thực hiện việc ánh xạ tuyến tính từ tọa độ 2D này đến tọa độ 2D khác. Bảng cho sau đây sẽ liêt kê các giao diện và lớp trong việc kết hợp với ngữ cảnh Graphics2D context.com 26 .bao gồm các lớp biểu diễn các thuộc tính trạng thái.Gradient-Paint và TexturePaint. Được thực thi bởi đối tượng PaintContext Color.geom) Mô tả Miêu tả một phép biến đổi 2D affine .Các thao tác vẽ được tùy chọn bởi người lập Stroke trình. http://tailieuhay.Được thực thi bởi phương thức BasicStroke. Hầu hết các lớp này là một phần của package java.awt.awt.Việc thực hiện các luật kết hợp tùy chọn được thực hiện bơit người lập Paint trình. Định nghĩa một môi trương tối ưu và độc lập cho việc thực hiện các phép kết hợp . Các lớp và mô tả sơ lược về chúng: Lớp AffineTransform (java. Mở rộng: Transparency Định nghĩa các màu sắc cho việc tô hoặc vẽ.Lập trình đồ họa trên Java 2D và 3D 2. Các giao diện và mô tả chúng: Giao diện Composite Mô tả Định nghĩa các phương thức cho việc kết hợp một đối tượng vẽ gốc với cùng đồ họa được đánh dấu.1 Các lớp và giao diện. Định nghĩa một môi trương tối ưu và độc lập cho việc vẽ. Tạo ra một đối tượng Shape mà các đường viền của nó đựoc tạo bóng.

Có thể thay đổi các thuộc tính trạng thái mà tạo nên ngữ cảnh Graphics2D như : • Thay đổi độ rộng của nét bút • Thay đổi cho các nét bút kết hợp với nhau như thế nào. 2. cần thiết lập ngữ cảnh Graphics2DContext và sử dụng một trong các phương thức tô trát Graphics2D đối với đối tượng.Lập trình đồ họa trên Java 2D và 3D AlphaComposite Thực thi : Composite Thực hiện các luật kết hợp các giá trị alpha cơ bản cho BasicStroke các đối tượng Shape. http://tailieuhay.Mẫu này sẽ thay đổi từ màu C1 (tại điểm Graphics2D P1) tới màu C2(tai điểm P2). Thực thi :Stroke Định nghĩa kiểu bút vẽ( “pen style”) được áp dụng cho các đường bao của đối tượng Shape.Text và Image.Mẫu tô được tạo ra từu đối tượng BufferedImage.Graphics Thực thi: Paint Định nghĩa một kiểu tô theo mẫu cho đối tượng Shape.2 Rendering Concepts Để tô trát một đối tượng đồ họa sử dụng Java 2D™ API.awt.com 27 . Thực thi: Paint Định nghĩa một mẫu tô màu loang tuyến tính cho đối tượng Shape. Color Thực thi: Paint Định nghĩa một kiểu tô màu đồng nhất cho đối tượng GradientPaint Shape.Mở rộng lớp gốc java. Mở rộng: Graphics Lớp cơ sở cho quá trình tạo bóng trong không gian TexturePaint 2D.

Graphics2D định nghĩa một số phương thức để thêm và thay đổi các thuộc tính trong ngữ cảnh đồ họa . Hầu hết những phương thức này là những đối tượng biểu diễn các thuộc tính riêng biệt như đối tựơng Paint hay Stroke . • Chuyển đổi tọa độ .2. thông tin về hình học .Thay đổi một đối tượng trong quá trình thao tác render sẽ gây nên một số biểu hiện bất thương thường và không ổn định . Quá trình render cho một đối tượng Shape có thể được chia thành 4 bước : 1. 2. Ngữ cảnh Graphics2D cất giữ các tham chiếu tới các đối tương thuộc tính . Nếu biến đổi một đối tượng thuộc tính mà là một phần của ngữ cảnh Graphics2D . • Xác định các đối tượng đa đồ họa(multiple graphics objects) cần phải được tạo ra như thế nào. Nếu đối tượng Shape được taọ nét .xoay.thì cần phải gọi phương thức thiết lập phù hợp để khai báo ngữ cảnh.com 28 . Tọa độ của đường thuộc đối tượng Shape được biến đổi từ không gian người sử dụng sang không gian của thiết bị theo các thuộc tính biến đổi trong ngữ cảng đồ họa Graphics2D . • Định nghĩa các màu và các kiểu để tô các hình.Lập trình đồ họa trên Java 2D và 3D • Thiết lập một khung cắt để giới hạn vùng được tô trát. 2.ảnh và thuộc tính được kết hợp để tính toán những giá trị điểm ảnh cần phải thay đổi trên màn hiển thị.1 Rendering Process Khi một đối tượng đồ họa được render.lấy tỉ lệ hoặc cắt cá đối tượng khi chúng được render. http://tailieuhay.đối tượng Stroke quy vào ngữ cảnh Graphics2D được sử dụng để tạo nên một đối tượng Shape mới bao quanh những đường nét đó .

Đối với ảnh thì có sự khác biệt .2 Controlling Rendering Quality Java 2D API đưa ra các lựa chọn cho phép người sử dụng tạo bóng nhanh hay tạo bóng với chất lượng cao.2. Tạo bóng (Rendering) văn bản tương đương với việc tạo bóng các đối tượng thuộc kiểu Shape.có thể thiết lập tùy chọn default :on hoặc off. Thông tin về màu sắc lấy từ chính ảnh đó và nguồn alpha(alpha channel) được sử dụng kết hợp với thuộc tính hiện tại của Composite khi các điểm ảnh được hợp trên bề mặt tạo bóng. sự chuyển đổi và thực hiện các phép cắt bỏ với hộp xác định biên ảnh( image’s bounding box). speed. Phần còn lại của đối tượng Shape được tô băng cách sử dụng thuộc tính của đối tượng Paint và Composite thuộc tính trong ngữ cảnh của đối tượng Graphics2D. Chỉ có điều khác là Java 2D API phải xác định đối tượng Font nào sử dụng cho văn bản và lấy kiểu glyph tương ứng từ đối tượng Font trước khi tạo bóng. Lớp RenderingHints hỗ trợ cá kiểu chỉ dẫn sau đây: • Alpha interpolation . 2. khi đó văn bản được tạo bóng với từng glyph và mỗi glyph là một đối tượng thuộc kiểu Shape.có thể thiết lập tùy chọn default. Đường (path)của đối tượng Shape được cắt bỏ bằng cách sử dụng các thuộc tính cắt trong ngữ cảnh Graphics2D. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D 3. Không phải tất cả các môi trường đều hỗ trợ việc thay đổi chế độ tạo bóng vì vậy xác định các chỉ dẫn cho quá trình tạo bóng sẽ không được đảm bảo chúng sẽ được sử dụng hay không . 4. Những tham chiếu của người su dụng được xác định như là các chỉ dẫn thông qua thuộc tính của đối tượng RenderingHints trong ngữ cảnh của đối tượng Graphics2D . quality. • Antialiasing .com 29 .

http://tailieuhay. • Fractional Metrics . hoặc speed. Kĩ thuật làm trơn(Antialiasing) Khi các thực thể cơ sở được tạo bóng trên thiết bị hiển thị . • Dithering .có thể thiết lập tùy chọn default.có thể thiết lập tùy chọn nearest-neighbor. quality. Antialiasing là một kĩ thuật được sử dụng để tạo bóng các đối tượng với các cạnh trơn hơn. • Rendering . enable. hoặc speed.môi trường tạo bóng mặc định sẽ được sử dụng .Lập trình đồ họa trên Java 2D và 3D • Color Rendering .có thể thiết lập tùy chọn default:disable.có thể thiết lập tùy chọn default. hoặc off.các biên(cạnh) của chúng có thể không trơn hay nhám là do thuộc tính aliasing. Thay vì sử dụng các điểm ảnh gẩn giống với các đường chéo và đường cong . Đây là điều mà chúng ta có thể nhận thấy với các thiết bị trước đây với các cạnh nhám xuất hiện trái ngược hoàn toàn với các cạnh trơn của đườgn nằm ngang hay thẳng đứng.tăng mật độ các điểm ảnh bao quanh tới các vùng được tạo bóng. quality. Điều này làm cho cách cạnh trơn hơn và trải rộng sự chuyển tiếp bật/tắt với các pixel đa điểm(multi pixel) . • Text antialiasing .có thể thiết lập tùy chọn default: on hoặc off. • Interpolation. Để thiết lập hoặc thay đổi các thuộc tính RenderingHints trong ngữ cảnh của đối tượng Graphics2D thì gọi phương thức setRenderingHints.có thể thiết lập tùy chọn default. hoặc bicubic. on.com 30 . bilinear. Tuy nhiên kĩ thuật antialiasing đòi hỏi nhiều về tài nguyên máy tính và làm tăng thời gian tạo bóng. Các đường cung và đường chéo có dạng nhám bởi vì chúng được xấp xỉ bởi các điểm ảnh mà gần nhất về hìn dạng với chúng . Khi một chỉ dẫn được thiết lập măc định .

Như ví du. and a dashing pattern. BasicStroke đinh nghĩa các thuộc tính như độ rộng cuả nét vẽ . Thuộc tính của Graphics2DStroke định nghĩa các tính chất của nét bút vẽ.ảnh đầu tiên trong hình 2-3 sử dụng miter join-style.2. a round endcap style.và hình thứ hai sử dụng kiểu round join-style. http://tailieuhay.3 Stroke Attributes Tạo nét một đối tượng thuộc kiểu Shape như đối tượng GeneralPath tương đươnng với việc sử dụng một bút lôgíc theo các đoạn của đối tượng GeneralPath.mẫu tô… Để thiết lập hay thay đổi các thuộc tính Stroke trong ngữ cảnh của Graphics2D thì gọi phương thức setStroke. Đối tượng BasicStroke được sử dụng để định nghĩa các thuộc tính đường nét cho một ngữ cảnh của Graphics2D.Lập trình đồ họa trên Java 2D và 3D 2.com 31 .

drawPolygon. Graphics2D. Thuộc tính của Stroke sẽ quy định cho đường nét của hình chữ nhật . http://tailieuhay. Thuộc tính Stroke định nghĩa các tính chất của đường thẳng và các thuộc tính của Paint định nghĩa màu sắc hay mẫu của nét bút.drawString). 3. Quá trình xử lý này được minh hạo trong hình 2-4: 2.draw.2.Khi một trong các phương thức được gọi thì các đường nét của đối tượng Shape đã xác định sẽ được tậo bóng. drawRect. Đối tượng Paint is được áp dụngcác điểm ảnh thuộc miền giới hạn bởi đường bao của đối tựơng Shape. và drawRoundRect. drawOval. Có thể thêm một đối tượng vào ngữ cảnh của đối tượng Graphics2D (Graphics2D context) bằng cách gọi phương thức setPaint.com 32 .4 Fill Attributes Thuộc tính tô màu trong ngữ cảnh Graphics2D được biểu diễn bởi đối tượng Paint. drawPolyline.Lập trình đồ họa trên Java 2D và 3D Các phương thức tạo bóng Graphics2D có sử dụng thuộc tính của Stroke để vẽ như drawArc. 2. Các đường nét này sẽ được biến đổi thành một đối tượng kiểu Shape . drawLine. Ví dụ phương thức draw(myRectangle) được gọi: 1. Khi một đối tượng Shape hay là các glyph được vẽ (bởi các phương thức Graphics2D.

Xác định các điểm ảnh nào để thể hiện đối tượng đó.Color là phần triển khai (implementation) đơn giản nhất của giao tiếp Paint (Paint interface). Khi gọi phưong thức fill để tạo bóng một đối tượng Shape. Ghi các điểm ảnh ra thiết bị hiển thị đó. 3. 2. 4.com 33 .fill). Các lớp này sẽ loại bỏ các công việc tiêu tốn thời gian để tạo các kiểu tô phức tạp bằng cách sử dụng các kiểu tô mầu đồng nhất đơn giản . đối tượng Paint được áp dụng tới tất cả các điểm ảnh nằm trong đường bao của đối tượng Shape. Các kiểu tô màu đồng nhất đơn giản (solid color) được khởi tạo bởi phương thức setColor. Xác định màu cho mỗi điểm ảnh từ đối tựợng Paint. Để tô các hình với các kiểu tô phức tạp hơn như là tô loang(gradient) và tô dệt ( texture) bằng cách sử dụng các lớp trong Java 2D Paint là GradientPaint và TexturePaint.thì hệ thống sẽ: 1. http://tailieuhay. Khi một đối tượng Shape được tô màu (Graphics2D.Lập trình đồ họa trên Java 2D và 3D Đối tượng Paint này sẽ được áp dụng tới tất cả các pixel nằm trong đối tượng Shape mà biểu diễn các đường nét bao quanh đối tượng . Chuyển các màu này tới giá trị điểm ảnh tương ứng cho các thiết bị hiển thị.

http://tailieuhay. Đối tượng PaintContext này sẽ lưu thông tin ngữ cảnh về thao tác tạo bóng hiện thời và những thông tin cần thiết để tạo ra các màu.Lập trình đồ họa trên Java 2D và 3D Quá trình xử lý theo phiên Để tổ chức hợp lý quá trình xử lý các điểm ảnh . Đối tượng ColorModel xem như một chỉ dẫn không phải tất cả các đối tượng Paint có thể hỗ trợ một đối tượng ColorModel bất kỳ.và thực hiện quá trình chuyển đổi để ánh xạ từ không gian người sử dụng vào không gian của thiết bị.2. Quá trình xử lý theo phiên được thực hiện theo 2 bước: 1. Thông tin này passed to the next stage in the rendering pipeline.đối tượng ColorModel là nơi để tạo các màu sắc. Phương thức createContext của đối tượng paint được gọi để tạo một đối tượng PaintContext. thì chỉ những phần của đối tượng Shape hay image nằm trong khung nhìn đó mới được tạo bóng.5 Clipping Paths Một khung nhìn sẽ xác định phần của đối tượng Shape hay Image cần được tạo bóng . mà vẽ các màu đã được tạo bằng cách sử dụng đối tựợng Composite hiện thời . Mỗi phiên có thể là tập các điểm ảnh kề nhau trên một đường quét hay là một khối (block)các điểm ảnh. Phương thức getColorModel được gọi để nhận giá trị của đối tượng ColorModel cho màu vẽ từ đối tượng PaintContext. Phương thức createContext method is passed the bounding boxes of thegraphics object being filled in user space and in device space. 2. Java 2D API tổ chức chúng theo từng phiên. Khi một khung nhìn là một phần của ngữ cảnh của đối tượng Graphics2D. 2.com 34 . Phương thức getRaster sau đó được gọi lặp lại nhiều lần để nhận giá trị của đối tựợng Raster mà bao gồm dữ liệu màu thật cho mỗi phiên.

Graphics2D cung cấp một vài cách khác để thay đổi phép biến đổi trong ngữ cảnh của đối tượng Graphics2D . 2.Các phép biến đổi được thêm vào này sẽ trở thành một phần của ống biến đổi (pipeline of transformations) mà được ápdụng trong suôt qua trình tạo bóng.com 35 . Cách đơn giản nhất là gọi một trong các phương thức biến đổi trong đối tượng Graphics2D như : rotate. scale.2. shear. Khi một phép biến đổi được nối vào phép biến đổi đã tồn tại trước đó thì phép biến đổi sau cùng sẽ được xác định như là phép biến đổi được http://tailieuhay.6 Transformations Ngữ cảnh của đối tượng Graphics2D bao gồm một phép bién đổi mà được sử dụng để biến đổi những đối tượng từ không gian người sử dụng vào không gian thiết bị trong quá trình tạo bóng.tỉ lệ .quay và cắt bỏ với tập các hình cơ bản. Bất kì đối tượng Shape cũng có thể được sử dụng để định nghĩa một khung nhìn. Để thực hiện các phép biến đổi khác như phép quay hay lấy tỉ lệ thì cần phải thêm các phép biến đổi khác vào ngữ cảnh của đối tượng. Xác định các tính chất của phép biến đổi để áp dụng trong suốt qúa trình tạo bóng và Graphics2D tự động tạo ra các thay đổi phù hợp. Để thành đổi khung nhìn cần phải sử dụng phương thức setClip để xác định một khung nhìn mới hay là gọi phương thức clip để thay đổi khung nhìn cho phần giao nhau giữa khung nhìn cũ và một đối tượng Shape. Phép biến đổi AffineTransform thực hiện các phép biến đổi cho đường như phép dịch. hay translate.Lập trình đồ họa trên Java 2D và 3D Để thêm khung nhìn cho ngữ cảnh của Graphics2D thì goị phương thức setClip. Cũng có thể nối một phép biến đổi AffineTransform với phép biến đổi Graphics2D hiện tại.

Lập trình đồ họa trên Java 2D và 3D thực hiện đầu tiên.com 36 . Graphics2D cũng cung câp một phiên bản về drawimage mà trong đó đối tượng AffineTransform Được xem như một tham số . nhưng phương thức này cần cho môt số mục đích khác như: • Áp dụng phép biến đổi tỉ lệ điều chỉnh cho máy in.setTransform(aT). nhưng phương thức này không bao giờ được sử dụng để nối với các phép biến đổi tọa độ khác của phép biến đổi đang tồn tại. • Vẽ một đối tượng JComponent parent’s origin • Phóng to một thành phần để dễ dàng quan sát.draw(.. g2d. Để tiếp nối một phép biến đổi với phép biến đổi hiện tại . g2d. Phương thức setTransform sẽ ghi đè lên phép biến đổi hiện thời của đối tượng Graphics2D.). Ảnh này được được vẽ như khi kết nối http://tailieuhay. Lớp Graphics2D cũng bao gồm phương thức setTransform .. you pass an AffineTransform to Graphics2D. • Các tình huống khác mà người cung cấp đối tượng Graphics2D muốn chuyển đổi cho quá trình tạo bóng hiệu quả ..transform. Phương thức setTransform method được xem như để thiết lập đối tượng Graphics2D trở lai phép biến đổi ban đầu sau quá trình tạo bóng đồ họa .getTransform().). Điều này cho phép áp dụng một phép biến đổi cho đối tượng ảnh khi nó được vẽ mà không cần chỉnh sửa đường ống cuả phép biến đổi..văn bản và ảnh đã được chuyển đổi: non-zero translation from its AffineTransform aT = g2d. g2d.transform(.

2. AffineTransforms được sử dụng để biến đổi văn bản .com 37 . Sự kết hợp này xem như là sự móc nối.6. Cũng có thể ứng dụng các phép biến đổi cho đối tượng Font để tạo ra các dẫn xuất font mới(new font derivations).Lập trình đồ họa trên Java 2D và 3D phép biến đôit này với phép biến đôit hiện tại trong ngữ cảnh của Graphics2D Các phép biến đổi quan hệ(Affine Transforms) Java 2D API cung cấp một lớp biến đổi là AffineTransform.tuy nhiên khoảng cách giữa các điểm và các góc của các đường thẳng không song song có thể thay đổi. thì phép biến đổi cuối cùng được xác định là phép biến đổi đầu tiên được áp dụng . Phép móc nối trước được được áp dụng để thực hiện các phép biến đổi có liên quan với không gian thiết bị thay vì không gian người sử dụng.1 Constructing an AffineTransform http://tailieuhay.2. Trong trường hợp này thì phép biến đổi cuối cùng sẽ được thực hiện cuối cùng .. Các phép biến đổi có thể kết hợp để tạo ra đường ống các phép biến đổi một cách hiệu quả nhằm áp dụng cho một đối tượng nào đó. Ví dụ có thể sử dụng phương thức AffineTransform.preConcatenate để thực hiện phép chuyển đổi có liên quan tới không gian các điểm ảnh.hình và các ảnh khi chúng được tạo bóng. Một phép biến đổi đồng nhất (affine transformation) thực hiện một phép biến đổi tuyến tính trên tập đồ hạo cơ bản. Nó luôn biến các đường thẳng thành các đường thẳng và các đường thẳng song song thành các đường thẳng song song.concatenate. Khi một phép biến đổi được kết nối với một phép biến đổi đang tồn tại như với AffineTransform. Một phép biến đổi cũng có thể được móc nối trước với một phép biến đổi đang tồn tại .

Để xác định các kiểu kết hợp sẽ được sử dụng thì cần phải thêm vào một đối tượng AlphaComposite Graphics2D bằng cách gọi cho ngữ cảnh của đối tượng phương thức setComposite.Lập trình đồ họa trên Java 2D và 3D AffineTransform cung cấp một tập các phương thức cho việc xây dựng các đối tượng AffineTransform. có hỗ trợ một số kiểu kết hợp khác nhau . Có hai interface tạo các kiểu kết hợp cơ bản trong Java 2D là : Composite và CompositeContext.và một triển khai(implementation) của interface Composite . • getTranslateinstance • getRotateinstance • getScaleinstance • getShearinstance Để sử dụng các phương thức này cần phải xác định các tính chất của phép biến đổi mà cần tạo ra và lớp AffineTransform sẽ tạo ra các ma trận chuyển đổi phù hợp. Quá trình xử lý để xác định màu nào tạo bóng cho các điểm ảnh sẽ được chia sẽ cho các đối tượng chồng (overlaping objects)được gọi compositing. AlphaComposite. Cũng có thể xây dựng phép biến đổi đòng nhất một cách trực tiếp mà không cần thông qua lớp AffineTransform bằng cách xác định các thành phần của phép biến đổi đó.7 Composite Attributes Khi hai đối tượng đồ họa trồng lên nhau thì điều cần thiết là phải xác định những màu nào sẽ được tạo bóng cho các điểm ảnh chồng lên nhau.2. Ví dụ nếu một hình chữ nhật màu đỏ và một hình chữ nhật màu xanh chồng lên nhau thì các điểm ảnh đó sẽ có màu đỏ hoặc màu xanh hay là sự kết hợp của cả hai màu. Màu của những điểm ảnh trong vùng chồng nhau đó sẽ xác định hình chữ nhật nào nằm trên và bị che khuất như thế nào. Mỗi đối tượng của http://tailieuhay.com 38 . 2.

0) cho phép các màu tô đè lên nó được hiển thị.com 39 .. trong khi đó các màu trong suốt (có giá trị alpha=0. Các ảnh lưu thông tin về giá trị alpha của chính nó .7.Lập trình đồ họa trên Java 2D và 3D lớp này là một luật kết hợp để mô tả sự pha trộn một màu mới với màu đang tồn tại.0) thì các màu tô đè lên chúng sẽ không được hiển thị. Các màu tối (co giá tri alpha=1.2. Khi văn bản và hình được tạo bóng thì giá trị alpha sẽ bắt nguồn từ thuộc tính của đối tượng Paint trong ngữ cảnh của đối tượng Graphics2D .nó chỉ ra (theo phần trăm) bao nhiêu phần trăm màu trước khi tô được hiển thị ra khi các màu chồng lên nhau. 2. Khi tạo một đối tượng AlphaComposite . luật này chỉ ra màu mới (màu nguồn) sẽ được pha trộn với màu đang tồn tại (màu đích ) như thế nào. Khi các hình và văn bản được làm trơn thì giá trị alpha từ thuộc tính Paint (trong ngữ cảnh của Graphics2D) được kết hợp với thông tin về các điểm ảnh bị che từ “rasterized path”. có thể xác định được giá trị alpha được thêm vào . Khi thêm đối tượng AlphaComposite này tới ngữ http://tailieuhay. Một trong những luật kết hợp trong lớp AlphaComposite là SRC_OVER.1 Managing Transparency Giá trị alpha của một màu là giá trị đo đọ trong suôt của màu đó .

Stroke.giá trị alpha của mỗi đối tượng đồ họa được nhân lên bởi giá trị alpha của đối tượng AlphaComposite.1 Setting Rendering Hints Đối tượng RenderingHints đóng gói tất các tham chiếu để xác định một đối tượng sẽ được tạo bóng như thế nào .2. Thông tin này đựoc gọi là kênh alpha( alpha channel. Để tạo các chỉ dẫn cho quá http://tailieuhay.Clipping path.) .7.2 Transparency and images Các ảnh có thể lưu thông tin về độ trong suốt cho mỗi điểm ảnh của nó.com 40 .3.Lập trình đồ họa trên Java 2D và 3D cảnh của Graphics2D . Composite.3 Thiết lập Graphics2Context Để cấu hình ngữ cảnh Graphics2D cho quá trình tạo bóng phải sử dụng các phương thức khởi tạo cho đối tượng Graphics2D để xác định các thuộc tính như RenderingHints. 2.giá trị alpha thêm vào này sẽ làm tăng giá trị trong suốt của bất kì đối tượng đồ họa nào khi chúng được tạo bóng .nó được sử dụng kêts hợp với đối tượng Composite trong ngữ cảnh của Graphics2D để pha trộn màu của ảnh đó các đồ họa đang tồn tại. 2. 2. and Transform. Paint.

gồm có độ rộng và kiểu đường (dashing pattern).VALUE_ANTiALiAS_ON).3.để làm thế nào các đoạn thẳng được kết hợp với nhau.3.com 41 .setRendering Tạo chỉ dẫn cho quá trình tạo bóng sẽ không đảm bảo việc sẽ sử dụng một thuật toán tạo bóng cụ thể: không phải môi trường cũng hỗ trợ chế độ tạo bóng . qualityHints.thì cần tạo một đối tượng RenderingHints và chuyển nó vào lớp Graphics2D.Lập trình đồ họa trên Java 2D và 3D trình tạo bóng trong ngữ cảnh Graphics2D . Trong ví dụ cho sau đây thì cho phép sử dụng kĩ thuật làm trơn (antialiasing) và tạo ra các tham chiếu để xác định chất lượng cho quá trình tạo bóng: qualityHints = new RenderingHints(RenderingHints. Để khởi tạo các thuộc tính về đường nét trong ngữ cảnh Graphics2D .1 Setting the Stroke Width Để khởi tạo độ rộng đường nét thì khởi tạo đối tượng BasicStroke với độ rộng mong muốn và sau đó gọi phương thức setStroke http://tailieuhay.thì khởi tạo một đối tượng BasicStroke và chuyền nó vào phương thức setStroke 2.VALUE_RENDER_QUALiTY). g2.2.setRenderingHints(qualityHints).put(RenderingHints. 2.KEY_ANTiALiAS iNG.KEY_RENDERi NG. RenderingHints. RenderingHints.2 Specifying Stroke Attributes Một đối tượng BasicStroke sẽ định nghĩa các tính chất đuwoc áp dụng cho đường viền bao quanh một đối tượng Shape.

độ rộng đường nét được khởi tạo với 12 điểm và giá trị mặc định được sử dụng cho việc bố trí kiểu jont và kiểu endcap.0f).độ rộng đường nét được khởi tạo với 12 điểm và các kiểu join và endcap được sử dụng thay cho các gia tri mặc định: roundStroke = new BasicStroke(4. Trong ví dụ cho sau đây.2.CAP_ROUND. g2. Các phần tử xen kẽ của mảng biểu diễn kích thước nét gạch và khoảng cách giữa các nét gạch .3.3. Khi tạo một đối tượng BasicStroke .phải xác định 2 tham số để kiểm soát kiểu đường: • dash . 2.Lập trình đồ họa trên Java 2D và 3D Trong ví dụ cho sau đây . g2. phần tử thứ 1 biểu diễn khoảng trắng đầu tiên.JOiN_ROUND). BasicStroke. wideStroke = new BasicStroke(12.3 Setting the Dashing Pattern Các kiểu đường phức tạp có thể dễ dàng được định nghĩa với một đối tượng BasicStroke.setStroke(wideStroke). BasicStroke.setStroke(roundStroke). 2. http://tailieuhay.0f. Phần tử 0 biểu diễn nét gạch đầu tiên.2 Specifying Join and Endcap Styles Để khởi tạo cho các kiểu join và endcap .cần tạo một đối tượng BasicStroke với các thuộc tính mong muốn .com 42 .là một mảng biểu diễn kiểu đường.2.

4. BasicStroke BasicStroke. g2.Float(20.setStroke(bs). fot] la[ 4. . 0f = = {.f.0 40} . Trong mẫu thứ nhất . hai mẫu nét gạch được áp dụng cho một đường thẳng. BasicStroke.Lập trình đồ họa trên Java 2D và 3D • dash_phase . .JOiN_MiTER. Hai mẫu này được minh họa trong hình2-7 http://tailieuhay. . Line2D 10.f 60. Mẫu thứ hai thì phức tạp hơn . 00) . dash1. 2 f. g2.com 43 10. new BasicStroke(5. g2.draw(line).kích thước của các nét gạch và khoảng trống giữa chúng là không thay đổi. 10. new BasicStroke(5.0f. BasicStroke. g2.sử dụng mảng sáu phần tử để định nghĩa fot la dash1[] bs = = {00} 1. 10.0f.0f. .f. 00) .0f.CAP_BUTT.JOiN_MiTER. ln ie 100. Trong ví dụ sau đây.CAP_BUTT.là một offset định nghĩa nơi bắt đầu của mẫu nét gạch.0f.0f.0f). dash2.0f.f.setStroke(bs). = new Line2D.0 f.draw(line) Cả hai mẫu đều sử dụng offset(địa chỉ bắt đầu của hai mẫu) 0 khi đó các nét gạch đầu tiên sẽ ổ vị trí đầu của mẫu.f. BasicStroke. 0f bs dash2 2.

3. http://tailieuhay.3. 2.Tất cả các điểm dọc theo đường tô loang mở rộng qua điểm P1 sẽ nhận được màu ban đầu và các điểm dọc theo đường tô loang được mở rộng ngoài điểm P2 sẽ nhận màu kết thúc. Khởi tạo đối tượng GradientPaint . Các bước cần thực hiện để tô loang theo hai màu: 1.com 44 . Khởi tạo đối tượng Shape. cần xác định vị trí đầu tiên cùng với màu tô và vị trí cuối cùng một màu tô.cả hai điểm đều nằm trong cùng một hình.3.3. Khi khởi tạo đối tượng GradientPaint.1 Filling a Shape with a Gradient Lớp GradientPaint cung cấp một cách đơn giản để tô một hình bằng kiểu tô loang . 2. Gọi phương thức Graphics2D.3 Specifying Fill Attributes Thuộc tính cảu đối tượng Paint trong ngữ cảnh Graphics2D xác định các màu tô hay các mẫu (kiểu )tô khi một đối tượng văn bản và Shape được tạo bóng. Kiểu tô này sẽ thay đổi tỉ lệ từ màu này sang màu khác dọc theo đường nối của hai vị trí đã chọn.setPaint.Lập trình đồ họa trên Java 2D và 3D 2. minh họa trong hình 2-8. Trong ngôi sao thứ ba.

một hình chữ nhật được tô với mẫu dệt đơn giản từ một đối tượng buffered image.blue new Color.2 Filling a Shape with a Texture Lớp TexturePaint cung cấp một cách đơn giản để tô hình bằng mẫu lặp.createGraphics(). . Gọi phương thức Graphics2D. g2 ill ct( . 4. bi.setPaint(gp). 2. Khi tạo một đối tượng Bufferedimage để sử dụng như là một mẫu tô.com 45 . 200). một hình chữ nhật được tô với mẫu dệt đơn giản từ một đối tượng bufferedimage. g2. 250. http://tailieuhay. gp 50.được chi ra trong hình 2-9. Trong ví dụ sau đây.setColor(Color. = Color. 3. Tạo đối tượng TexturePaint 2.Lập trình đồ họa trên Java 2D và 3D Trong ví dụ sau đây.3. Tạo đối tượng Shape.0f.0f. 50.0f. Cần chuyển hàm khởi tạo một hình chữ nhật để định nghĩa tần số lặp cho mẫu . Gọi phương thức Graphics2D. 200. Để tô hình theo mẫu dệt: 1.green).setPaint.f Re 50 50. // of Create size a buffered bi = = new image texture patch 5.green).3. Bufferedimage Graphics2D big Bufferedimage. big. //5x5 Bufferedimage(5.fill(shape). GradientPaint GradientPaint(50.0f.TYPE_iNT_RGB).

new paint a to the graphics filled a texture paint from the buffered Rectangle TexturePaint // // with } Add the TexturePaint(bi.5).5).200.setColor(Color. Để thu hẹp khung nhìn: 1. Khởi tạo đối tượng Shape mà giao với khung hnìn hiện tại.com 46 . Trong ví dụ cho sau đây.setClip để sử dụng đối tuợng shape như là một khung nhìn cho ngữ cảnh Graphics2D .5.lightGray).fillOval(0. Khởi tạo một đối tượng Shape mà biểu diễn vùng muốn tạo bóng.NEAREST_NEiGHBOR).5).3.5.0.setPaint(tp).200).0.fillRect(0. một khung nhìn được tạo ra từ một elip và sau đó được thay đổi băng cách gọi phương thức clip.Lập trình đồ họa trên Java 2D và 3D big. texture and context.r. big.0. 2.4 Setting the Clipping Path Để định nghĩa một khung nhìn: 1. Create the render rectangle texture. 2. g2. Gọi phương thức clip để thay đổi khung nhìn cho phần giao nhau của khung nhìn hiện tại và đối tượng Shape mới.0. Gọi phương thức Graphics2D. big. 2. g2. public void paint(Graphics g) { http://tailieuhay.fillRect(0.5. // Create image r = tp new = Rectangle(0.TexturePaint.

Rectangle r = new Rectangle(w/4+10. // Fl il the the canvas.h/2-20).Float(w/4. g2.f Re 0. an elpe lis path e = new and use i t as Create clipping Ellipse2D Ellipse2D.height.lpr.h/4+10.0f.setColor(Color.0f.h/4.0f. . ci lp Only the area within // i s rendered http://tailieuhay. of and setting intersection current ci lp a new rectangle.w/2-20.cyan).0f). // it n it n // the The w h width = = and height of the canvas getSize(). g. 2ci() // Fl il the the new canvas. w/2.h // i t // Change to the the the clipping path.h/2.com 47 .w ). g2 ill ct( 0. ci lp Only i s the area within rendered g2.width.setClip(e). getSize(). .Lập trình đồ họa trên Java 2D và 3D Graphics2D g2 = (Graphics2D) g.

bởi vì setTransform sẽ ghi đè lên phép biến đổi hiện tại trong ngữ cảnh đồ họa 1.Float .xâu văn bản. Lấy một phép biến đổi Graphics2D trước khi thực hiện bất kì phép biến đổi nào . hay ảnh cần phải thêm vào một phép biến đổi mới AffineTransform cho đường ống phép biến đổi tronh ngữ cảnh của Graphics2D trước khi tạo bóng .com 48 .f Re 0.3. 2.magenta). Lấy phép quay bằng cách gọi AffineTransform. Gọi phương thức Graphics2D. Luôn gọi phương thức getTransform trong đối tượng Graphics2D trước khi thêm vào một phép biến đổi cho ngữ cảnh đồ họa bởi vì ngữ cảnh đồ họa có thể đã tồn tại một phép biến đổi cho một lí do khác . .draw để tạo bóng hình chữ nhật.setColor(Color. thì reset phép biến đổi của Graphics2D trở về phép biến đổi ban http://tailieuhay.Tạo đối tượng Rectangle2D. 5.transform để thêm vào các phép biến đổi mới cho đường ống biến đổi. 3. Ví dụ để vẽ một hình chữ nhật nghiêng 45 độ: 1. . Sau khi tạo bóng cho hình chữ nhật đã được biến đổi .Lập trình đồ họa trên Java 2D và 3D g2. 4.h 2. Gọi phươn thức Graphics2D.w ).5 Setting the Graphics2D Transform Để biến đổi đối tượng Shape. getRotateinstance. phép biến đổi được áp dụng khi đối tượng đồ họa được tạo bóng . 4. g2 ill ct( 0. Không được sử dụng phương thức setTransform để thêm một phép biến đổi tọa độ mới.định vị Swing và các thành phần trong một cửa sổ.

getRotateinstance(Math. Còn trong ví dụ này.một đối tượng AffineTransform được sử dụng để quay các câu text xung quang một điểm trung tâm.0.0).0.0.com 49 . Trong ví dụ sau đây. AffineTransform Rectangle2D aT = rect g2.0.Float(1. một thể hiện của AffineTransform được sử dụng để quay hình chữ nhật đi 45 độ khi nó được tạo bóng. g2.3.draw(rect).0. = new Rectangle2D.Lập trình đồ họa trên Java 2D và 3D đầu mà đã lưu trong bước 1 bằng cách gọi phương thức setTransform cho phép biến đổi ban đầu . // Define the rendering at transform = new AffineTransform AffineTransform().getTransform().Pi /4.transform(rotate45).0. AffineTransform rotate45 = AffineTransform.2. transform to rotated http://tailieuhay. g2.0.1.0) g2.setTransform(aT). // make // Apply room a for translation the t t ex .

setToRotation(Math.0.transform(at). i++) 00) . { 20. thì chuyển AffineTransform sang drawimage: AffineTransform rotate45 = AffineTransform.0. rotate45). .Lập trình đồ họa trên Java 2D và 3D at.Pi // Render at four 90 i copies degree = 0.0f . Có thể biến đổi ảnh trong cách tương tự -phép biến đổi trong ngữ cảnh Graphics2D được áp dụng trong quá trình tạo bóng mà không cần quan tâm đến kiểu đối tượng đồ hạo đang được tạo bóng Để áp dụng phép biến đổi cho ảnh mà không cần thay đổi phép biến đổi trong ngữ cảnh Graphics2D .transform(at).com 50 . g2.drawString(“Java”.0). } 0. rotate at.drawimage(myimage. Các phép biến đổi cũng được áp dụng cho đối tượng Font để tạo ra một kiểu.0) g2. g2. “ a a” Jv for (n it g2.0.0.setToTranslation(400.0.) the string rotation transform to 400.f. http://tailieuhay.Pi /4. // Create the a text / of angles i < 4.getRotateinstance(Math.

2. Gọi phương thức setComposite để thêm đối tuợng AlphaComposite cho ngữ cảnh của Graphics2D.3.1 Using the Source Over Compositing Rule Luật kết hợp SRC_OVER sẽ kết hợp các điểm ảnh nguồn (source pixel) với các điểm ảnh đích (destination pixel).6. Hay nói cách khác . AlphaComposite ER).6. cần tạo một đối tượng AlphaComposite và chuyền nó vào phương thức setComposite.thì vùng giao nhau đó sẽ có màu đỏ.nếu tạo bóng một hình chữ nhật màu xanh nước biển (blue) và sau đó tạo bóng một hình chữ nhật màu đỏ mà đè lên một phần của hình chữ nhật kia.đối tương mà được tạo bóng cuối cùng sẽ xuất hiện ở trên cùng .SRC_OV http://tailieuhay.setComposite(ac). Mỗi khi đối tượng kết hợp này được thiết lập . g2. Để xác định các kiểu kết hợp cho ngữ cảnh Graphics2D .Lập trình đồ họa trên Java 2D và 3D 2. Ví dụ .com 51 . 2.3.3.6 Specifying a Composition Style Một đối tượng AlphaComposite chứa các luật kết hợp để xác định các màu sẽ được tạo bóng như thế nào khi đối tượng nàu đè lên đối tượng khác . Kiểu thông dụng nhất là SRC_OVER.getinstance(AlphaComposite. Tạo một đối tượng AlphaComposite bằng cách gọi phương thức getinstance và xác định luật SRC_OVER .thì đối tượng đè lên được tạo bóng bằng cách sử dụng luật kết hợp đã xác định.2 Increasing the Transparency of Composited Objects ac =AlphaComposite. Để sử dụng luật kết hợp SRC_OVER : 1. 2.

g2.translate(100.getinstance(AlphaComposite. ac =AlphaComposite.5: AlphaComposite ER.5 and added to the graphics context.0.lang. g2. // radians=degree * pie / 180 g2.xác định một giá trị alpha là .100). causing subsequent shapes to be rendered 50% transparent. a source over alpha composite object is created with an alpha of .red).rotate((45*java.Pi)/180). { Graphics2D g2.setTransform(new set // to identity a new ac alpha = composite AffineTransform()).Lập trình đồ họa trên Java 2D và 3D AlphaComposite cho phép xác định một giá trị hằng số alpha thêm vào mà được nhân với giá trị alpha của các điểm ảnh nguồn để tăng độ trong suốt. public void g2 paint(Graphics = (Graphics2D) g) g.để khởi tạo một đối tượng AlphaComposite mà tạo bóng đối tượng nguồn có độ trong suốt là 50% . g2.setColor(Color.100. Ví dụ .fillRect(0. // Create AlphaComposite http://tailieuhay.5f).com 52 .Math.50). .SRC_OV Trong ví dụ cho sau đây.

và images: • draw—tạo nét cho đường viền của đối tựợng Shape bằng cách sử dụng các đối tượng Stroke và Paint trong ngữ cảnh Graphics2D . g2.75.125.100. g2.4 Rendering Graphics Primitives Graphics2D cung cấp các phương thưc tạo bóng cho các cơ sở đồ họa như Shapes.green). • drawimage—tạo bóng các ảnh đã được xác định 2.100). } 2.5f).100.setColor(Color.100). g2.100).blue).100.fillRect(-25. g2.yellow).setColor(Color.setColor(Color.75. http://tailieuhay.fillRect(50.setComposite(ac). Text. g2.fillRect(125. g2.0.setColor(Color.com 53 .fillRect(50.1 Drawing a Shape Đường biên của bất kì đối tượng Shape cũng được tạo bóng bằng phương thức Graphics2D.100.pink).getinstance(AlphaComposite.0.SR C_OVER. g2.Lập trình đồ họa trên Java 2D và 3D AlphaComposite. g2.draw. g2.100). • drawString—tạo bóng các xâu văn bản đã dược xác định bằng cách sư dụng đối tượng Paint trong ngữ cảnh Graphics2D .4. • fill—tô một đối tượng Shape bằng cách sử dụng đối tượng Paint trong ngữ cảnh Graphics2D .

setStroke 3. Gọi phương thức Graphics2D.thò có thể vẽ đường thẳng với độ rộng và mẫu nét gạch bất kì .setStroke(new // Create a BasicStroke(4. Trong ví dụ sau. Khởi tạo cho đối tượng Shape. drawPolygon.com 54 . drawRect. public void g2 paint(Graphics = (Graphics2D) g) g. { Graphics2D // create and set the stroke g2. thì đường biên của nó sẽ được tạo nét bằng đối tượng Stroke trong ngữ cảnh Graphics2D Bằng việc thiét lập đối tượng BasicStroke phù hợp trong ngữ cảnh Graphics2D . Đối tượng BasicStroke cũng định nghĩa các thuộc tính endcap và join của đường thẳng .drawPolyline.Lập trình đồ họa trên Java 2D và 3D Phương thức vẽ từ các phiên bản trước cũng được hỗ trợ : drawLine. Gọi phương thức Graphics2D.đối tượng GeneralPath được sử dụng để định nghĩa một ngôi sao và một đối tượng BasicStroke được thêm vào ngữ cảnh Graphics2D để định nghĩa cho các cạnh của ngôi sao với các thuộc tính join . drawOval.0f)).draw(shape). Để tạo bóng cho các đường biên của đối tượng shape: 1. Khởi tạo cho đối tượng BasicStroke 2. star using a general path object http://tailieuhay. Khi một đối tượng Shape được vẽ . 4. drawRoundRect. draw3DRect. drawArc.

50. fillOval.0f).moveTo(p. // render the sa' trs path g2.setPaint. Khi một đối tượng Shape được tô.Lập trình đồ họa trên Java 2D và 3D GeneralPath p = new GeneralPath(GeneralPath. TexturePaint. // translate origin towards center of canvas g2.closePath(). 100.translate(100.4.0f.clearRect. p. fillRoundRect.lineTo(+ 100. 100. Phương thức tô từ các phiên bản trước đó của phần mềm JDK cũng được hỗ trợ: fillRect.2 Filling a Shape Phương thức Graphics2D. } 2.lineTo(p.0f). 100. Để tô một đối tượng Shape: 1. 0f. http://tailieuhay. 100.0f. + + 25. 0.lineTo(+ p. 50.0f.draw(p).lineTo(+ p.fill có thể được sử dụng để tô bất kì đối tượng Shape. fillArc.0f). 25.0f). 100. Xác định màu tô và kiểu tô trong ngữ cảnh đồ họa bằng cách sử dụng Graphics2D. fill3DRect. p.com 55 . thì phần bị giới hạn bởi đương bao của đối tượng sẽ được tạo bóng với ngữ cảnh Graphics2D của thuộc tính Paint attribute—như Color.NON_ZERO).0f).0f. or GradientPaint.0f). fillPolygon.0f.setColor hay Graphics2D.

Lập trình đồ họa trên Java 2D và 3D 1. sau đó chuyển vào xâu mà bạn muốn tạo bóng . Khởi tạo đối tượng Shape.4.phương thức setColor được gọi để định nghĩa màu tô là green fill cho một đối tượng Rectangle2D.fill để tạo bóng đối tựơng Shape. public void g2 paint(Graphics = (Graphics2D) g) g.com 56 .3 Rendering Text Để tạo bóng văn bản .cần gọi Graphics2D. } 2.drawString. g. Rectangle2D r2 = new Rectangle2D.150).ilr) 2fl(2.Float(25.5 Defining Custom Composition Rules Có thể tạo một kiểu mới hoàn toàn của phép kết hợp băng cách thực thi các interface Composite và CompositeContext . Một đối tượng Composite cung cấp một đối tượng CompositeContext mà thực chất là lưu trạng thái và thưc hiện công việc kết hợp.4. Gọi phương thức Graphics2D. 2.4 Rendering images Để tạo bóng văn bản . Nhiều đối tượng http://tailieuhay.cần gọi Graphics2D. Trong ví dụ sau đây .150.green).25. sau đó chuyển vào xâu mà bạn muốn tạo bóng 2. 2. { Graphics2D g2.setPaint(Color.drawimage.

Một màn hiển thị trong môi trường này được xác định như là màn hiển thị chính và tạ vị trí (0.thiết bị ảo có thể có tọa độ âm .Một đối tượng GraphicsDevice có nhiều đối tượng GraphicsConfiguration kết hợp với nó .) 2. version 1. Khi hai hoặc nhiều màn hình được sử dụng để tạo một thiết bị ảo .hệ tọa độ ảo (mà tồn tại độc lập với thiết bị hiển thị vật lý )được sử dụng để biểu diễn thiết bị ảo đó . JFrame. hoặc Jwindow . Java 2D API cho phép tạo các đối tượng Frame.mỗi thiết bị hiển thị được biểu diễn bởi một đối tượng GraphicsDevice.com 57 . 0) của hệ tọa độ ảo .như trong hình 210: http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D CompositeContext có thể được tạo từ một đối tượng Composite để lưu các trạng thái riêng biệt trong môi trường đa luồng (multithreaded environment. Dựa trên vị trí của màn hiển thị chính .6 Rendering in a Multi-Screen Environment TrongJavaTM 2 SDK.3.Với một đối tượng GraphicsConfiguration để xác định các thiết bị hiển thị cho quá trình tạo bóng. Các biên cảu mỗi đối tượng GraphicsConfiguration trong cấu hình đa màn hiển thị có quan hệ với hệ tọa độ ảo . Java 2DTM API hỗ trợ những cấu hình đa màn hiển thi khác nhau mà có thể được cấu hình bởi một môi trường mà : • Có hai hoặc nhiều màn hình độc lập • Có hai hoặc nhiều màn hình nơi chỉ có một màn hình chính và các màn hiển thị khác sẽ copy những hình ảnh xuát hiện trên màn hình chính • Hai hoặc nhiều màn hình mà có dạng như một máy ảo và nó cho phép gọi các thiết bị ảo. Trong cả ba cấu hình. Window.

Đoạn mã này sẽ lấy đường bao của một đối tượng GraphicsConfiguration và sử dụng các đường bao để thiết lập vị trí của đối tượng Frame tại tọa độ (10. Vì vậy. Cho ví dụ. Frame g) c.com bounds = gc. thì môi trường đó chính là môi trường ảo.Vì vậy .thì gọi phương thức getBounds trên mỗi đối tượng GraphicsConfiguration trong hệ thống và kiểm tra nếu gốc tọa độ khác vị trí (0. phải sử dụng tọa độ ảo khi gọi phương thức setLocation của đối tượng Frame hay Window. 0). 10) trong hệ tọa độ của màn hiển thị vật lý . 58 . f = new Frame(GraphicsConfiguration Rectangle http://tailieuhay.các tọa độ của các đối tượng GraphicsConfiguration có quan hệ với hệ tọa độ ảo . 0).Lập trình đồ họa trên Java 2D và 3D Để xác định nếu là môi trường thiết bị ảo nơi mà một đối tượng Window hay Frame có thể xuất hiện trên hai hay nhiều màn hình vật lý . Phương thức getBounds của đối tượng GraphicsConfiguration trả về một đối tượng hình Rectangle trong hệ tọa độ ảo .nếu một gốc tọa độ không phải vị trí (0. Trong môi trường thiết bị ảo .getBounds().

j+ gs = GraphicsDevice GraphicsConfiguration[] gd.x. for +) (n it { gd = g[] sj.getScreenDevices().y).Lập trình đồ họa trên Java 2D và 3D f. Rectangle Rectangle(). Kĩ thuật này được sử dụng trong ví dụ sau. thì đối tượng Frame được hiển thị tại vị trí (10. http://tailieuhay. 10) trên mà hình vật lý chính .length. tính toán sự kết hợp của các đường bao.getLocalGraphicsEnviron ment(). + bounds. 10 + Nếu các đường bao của đối tượng GraphicsConfiguration không được tính đến . Gọi phương thức getBounds trên mỗi đối tượng GraphicsConfiguration trong hệ thống .getConfigurations(). Phương thức getBounds có thể được sử dụng để xác định các đường biên cảu thiết bị ảo. Để xác dịnh các đường bao cảu thiết bị ảo . gc = j = 0. GraphicsDevice[] ge. j < gs.com 59 . điều này có thể khác với mà hình vật lý của đối tượng GraphicsConfiguration đã được xác định .setLocation(10 bounds. virtualBounds = new GraphicsEnvironment ge = GraphicsEnvironment.

Đoạn mã sau phải được chạy với JavaTM 2 SDK. version 1. Mỗi đối tượng JFrame hiển thị một tập các vạch đỏ.0 * 27/03/06 * Day la doan chuong trinh mieu ta cac phep bien doi. /* * Transform. http://tailieuhay. } } Applet sau sẽ tạo một đối tượng JFrame với mỗi đối tượng GraphicsConfiguration của mỗi đối tượng GraphicsDevice trong đối tượng GraphicsEnvironment. xanh đậm .số lượng các màn hiển thị số lượng các đối tượng GraphicsConfiguration và các đường bao cuả đối tượng GraphicsConfiguration.*.union(gc[i]. import javax.Lập trình đồ họa trên Java 2D và 3D for +) (n it { = i = 0.swing. i+ virtualBounds virtualBounds.3 hoặc cao hơn.java * 1.length.com 60 .awt. i < gc. */ import java.getBounds()).xanh nhạt.*.

lineLabel. TransPanel display. JButton redraw. static JComboBox primitive. stroke.com 61 .Voi cac phuong * thuc paint. http://tailieuhay. paint. trans.Lập trình đồ họa trên Java 2D và 3D /* * Chuong trinh nay tao bong mot hinh duoc chon boi nguoi su dung. paintLabel. ActionListener { /** * */ private static final long serialVersionUiD = -2514519718222913151L. strokeLabel. va rendering cung duoc lua chon boi nguoi su dung. public static boolean no2D = false. line. transLabel.stroke. */ /** * @author Administrator * */ public class Transform extends JApplet implements itemListener. JLabel primLabel.

c. paintLabel. getContentPane(). lineLabel.add(primLabel).setConstraints(lineLabel. primLabel.setFont(newFont). Font newFont = getFont(). lineLabel = new JLabel().setHorizontalAlignment(JLabel.setConstraints(primLabel. primLabel = new JLabel().add(lineLabel).fill = GridBagConstraints. http://tailieuhay.setText("Các đường"). layOut. c). paintLabel = new JLabel().0. primLabel. GridBagConstraints GridBagConstraints().setHorizontalAlignment(JLabel. lineLabel. c).BOTH.setText("Hình gốc"). c.CENTER). getContentPane().setText("Kiểu vẽ").weightx = 1. lineLabel.setLayout(layOut).CENTER). getContentPane(). c = new layOut = new primLabel.setFont(newFont).Lập trình đồ họa trên Java 2D và 3D public void init() { GridBagLayout GridBagLayout().deriveFont(1).com 62 . layOut.

gridwidth GridBagConstraints. strokeLabel. = transLabel. getContentPane().setFont(newFont).CENTER) .Lập trình đồ họa trên Java 2D và 3D paintLabel.REMAiNDER. layOut.setFont(newFont). layOut.setConstraints(paintLabel. strokeLabel.setConstraints(transLabel. transLabel.setHorizontalAlignment(JLabel.CENTER). getContentPane().setHorizontalAlignment(JLabel.setHorizontalAlignment(JLabel. = strokeLabel. c. c). layOut.setFont(newFont). c.com 63 . transLabel. c).add(strokeLabel).RELATiVE.add(paintLabel). strokeLabel = new JLabel().setText("Các phép biến đổi").setConstraints(strokeLabel. http://tailieuhay. paintLabel. transLabel = new JLabel().gridwidth GridBagConstraints.CENTER). c).setText("Tô trát").add(transLabel). getContentPane().

layOut.add(paint). ls.0.setConstraints(line. paint. getContentPane().weightx = 1.setConstraints(primitive.Lập trình đồ họa trên Java 2D và 3D GridBagConstraints GridBagConstraints(). "Đậm". "Nét đứt" }). layOut. ls).setFont(newFont).setConstraints(paint. ls. "Tô loang". paint. line. line = new JComboBox(new Object[] ls = new { "Mảnh".add(line).setFont(newFont).RELATiVE. line. ls).deriveFont(0. "Hình elip".additemListener(this). "Văn bản" }).BOTH. primitive = new JComboBox(new Object[] { "Hình chữ nhật".add(primitive).additemListener(this). getContentPane(). 14.setFont(newFont).additemListener(this).fill = GridBagConstraints.com 64 . getContentPane(). paint = new JComboBox(new Object[] { "Đồng nhất".gridwidth GridBagConstraints. ls). newFont = newFont. primitive. ls. "polka" }).0f). layOut. = http://tailieuhay. primitive.

Lập trình đồ họa trên Java 2D và 3D trans = new JComboBox(new Object[] { "identity". getContentPane().additemListener(this).add(trans). layOut. layOut.add(redraw).addActionListener(this). redraw = new JButton("Vẽ lại"). button). "Tô đầy". getContentPane().gridwidth GridBagConstraints.setConstraints(trans. trans. stroke. layOut. stroke. redraw. ls). stroke = new JComboBox(new Object[] { "Đường nét".additemListener(this). getContentPane().setFont(newFont). "Quay". trans.setFont(newFont). "Tỉ lệ". "Đường nét va Tô đầy" }).setConstraints(redraw.REMAiNDER. ls). "shear" }). ls. tP = new = button = new = http://tailieuhay.com 65 . redraw.setFont(newFont).REMAiNDER.gridwidth GridBagConstraints. GridBagConstraints GridBagConstraints(). button. GridBagConstraints GridBagConstraints().setConstraints(stroke.add(stroke).

com 66 .length > 0 && argv[0]. } public void itemStateChanged(itemEvent e) { } public void actionPerformed(ActionEvent e) { display. } = http://tailieuhay. tP.white).weightx = 1. tP. } @SuppressWarnings("deprecation") public static void main(String[] argv) { if (argv.gridwidth GridBagConstraints.setBackground(Color.BOTH.renderShape(). display.0.equals("no2d")) { Transform. tP).REMAiNDER. display.Lập trình đồ họa trên Java 2D và 3D tP. validate(). layOut.0. display = new TransPanel().weighty = 1.setTrans(trans. getContentPane().setConstraints(display.getSelectedindex()).fill = GridBagConstraints. tP.no2D = true.add(display).

addWindowListener(new WindowAdapter() { public windowClosing(WindowEvent e) { System.CENTER. frame. int w.com 67 .setSize(550. http://tailieuhay. 400). applet.init().getContentPane().Lập trình đồ họa trên Java 2D và 3D JFrame chuyển đổi"). h.exit(0). frame. } }). frame.add(BorderLayout. } } @SuppressWarnings("serial") class TransPanel extends JPanel { AffineTransform at = new AffineTransform(). JApplet applet = new Transform(). applet).show(). void frame = new JFrame("Các phép frame.

getOutline(textAt). Bufferedimage bi. textTl. false)).translate(0.Lập trình đồ họa trên Java 2D và 3D Shape shapes[] = new Shape[3].0. FontRenderContext(null.white).Double(0. 0. break.setToidentity(). = new Ellipse2D. http://tailieuhay. shapes[0] 100).0. textAt = = new new new TextLayout("Brother Hood". shapes[2] = textTl. 100.0). AffineTransform AffineTransform().translate(w / 2. 100. 100. = new Rectangle(0.0.getBounds(). public TransPanel() { setBackground(Color. } public void setTrans(int transindex) { switch (transindex) { case 0: at. shapes[1] 0. boolean firstTime = true. h / 2). false. textAt.getHeight()).com 68 . at. TextLayout 1. (float) textTl 76). new Font("Tomaha".

case 3: at. w = d.width. String instruct = "Nhập một hình cơ sở ban đầu.". } public void paintComponent(Graphics g) { super. http://tailieuhay.kiểu vẽ.5. new Font("Helvetica".shear(0. Dimension d = getSize().paintComponent(g).no2D) { Graphics2D g2 = (Graphics2D) g. kiểu đường.height.0). break.scale(0.rotate(Math. phép biến đổi. case 2: at. 0.5.com 69 . if (!Transform. break.5). 0.toRadians(45)). h = d.Lập trình đồ họa trên Java 2D và 3D case 1: at. TextLayout thisTl = new TextLayout(instruct. break. } } public void renderShape() { repaint().

width = (float) thisTl. 0. float float width height = = (float) (float) thisTl. thisTl. 15).com 70 .getWidth().width / 2.Lập trình đồ họa trên Java 2D và 3D 0. if (firstTime) { at.setToidentity(). 10).getBounds(). thisTl.getHeight(). w / 2 . thisTl.getFontRenderContext()). firstTime = false. 10).width / 2.getStroke().getBounds().getBounds().". thisTl = new TextLayout(instruct.getWidth(). http://tailieuhay. h / 2).translate(w / 2. instruct = "và các phương thức tạo bóng sau đó nhấn nút VE LAi. new Font("Helvetica". Stroke oldStroke = g2.draw(g2. height + 17).getFontRenderContext()). } // Sets the Stroke. g2. at. // initialize the transform. w / 2 . g2 .draw(g2.

BasicStroke. 10.0f }.setStroke(new BasicStroke(3.0f)). break.setPaint(Color. break.setPaint(new GradientPaint(0. break. 0.com 71 .lightGray.getSelectedindex()) { case 0: g2.CAP_BUTT. g2.getSelectedindex()) { case 0: g2.0f. 0.getPaint(). } // Sets the Paint. Color. http://tailieuhay.0f. BasicStroke. break.0f)). case 1: g2.setStroke(new BasicStroke(8.JOiN_MiTER. dash.0f)).Lập trình đồ họa trên Java 2D và 3D switch (Transform. Paint oldPaint = g2.paint. switch (Transform. case 1: g2.250.blue).line. case 2: float dash[] = { 10.setStroke(new BasicStroke(3. w .

Color.Lập trình đồ họa trên Java 2D và 3D h. false)). // Sets the selected Shape to the center of the Canvas.fillOval(0. Rectangle r = shape. Graphics2D buffi. buffig. Rectangle r = new Rectangle(0.setPaint(new TexturePaint(buffi. buffig.com 72 .lightGray). 25). break. Bufferedimage.(5 / 2)). buffig. Shape shape = shapes[Transform. 15. buffig.blue. 0.createGraphics().getBounds().translate((15 / 2) .setColor(Color.getSelectedindex()]. r)).TYPE_iNT_RGB). case 2: Bufferedimage Bufferedimage(15. } // Sets the Shape. 7). 0.(5 / 2). break. g2.primitive. buffig = buffi = new http://tailieuhay. 25. 15). buffig. 15.setColor(Color. 0.fillRect(0.blue). 7. (15 / 2) .

toCenterAt. g2.stroke.transform(toCenterAt).setPaint(tempg2. toCenterAt = new saveXform = http://tailieuhay. // Sets the rendering method.getTransform().getSelectedindex()) { case 0: g2.concatenate(at).fill(shape). g2.draw(shape).fill(shape). break. } g2.getPaint()). g2. case 2: Graphics2D tempg2 = g2.width / 2).darkGray).com 73 .Lập trình đồ họa trên Java 2D và 3D AffineTransform g2.setColor(Color.translate(-(r. break.draw(shape). g2.setStroke(oldStroke). case 1: g2.height / 2)). g2. switch (Transform. AffineTransform AffineTransform(). toCenterAt. -(r.setPaint(oldPaint). break. g2.

} } } Kết quả sau khi chạy chương trình : http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D g2.com 74 .setTransform(saveXform).

hình chữ nhật.như rectangle.là thành phần của gói java.Những lớp hình học mới đó là một phần của gói java. Sử dụng các lớp hình học bạn có thể dễ dàng xác định và thao tác với nhiều đối tượng hai chiều.thành phần chính để có thể tương thích với các phiên bản trước đây của bộ JDK.Hình dáng cụ thể cung cấp cho ta một phương thức chung cho việc miêu tả và kiểm tra đường dẫn của các đối tượng hình học.Arc2D và Rectangle2D cho phép thực thi việc tạo giao diện bệ mặt được định nghĩa trong gói java.awt. Các lớp và giao diện của java.geom. Các đối tượng hình học trong Java 2D API như GenneralPath.awt.Một số.Lập trình đồ họa trên Java 2D và 3D Chương 3 Các đối tượng hình họa Java 2D™ API cung cấp một số lớp để định nghĩa các đối tượng geometric (hình học).com 75 .các lớp geometry có chứa trong các phiên bản trước đó của bộ JDK software.point và polygon. 3.đường cong.Một giao diện mới Pathlterator.awt. Bảng dưới đây liệt kê những giao diện và các lớp chính của các đối tượng hình học.geom http://tailieuhay.chẳng hạn như Shape.geom.Hầu hết trong sô các giao diện và các lớp là thành phần của gói java.awt.được chứa trong gói java.awt.chẳng hạn như điểm.cung cấp các phương thức định nghĩa việc khôi phục các phần tử từ một đối tượng hình học.Để có thể tương thích với các phiên bản cũ.1 Giao diện và lớp.awt.đường thẳng.

awt) Mô tả Định nghĩa các phương thức cho việc phục hồI các phần tử từ một đường dẫn.Việc thực thi chỉ rõ những đường cong trong kiểu số float và double. Cung cấp một tập các phương thức cho việc miêu tả và kiểm tra đường dẫn hình học. Các lớp Arc2D Arc2D.Được thực thi bởI GaneralPath và các lớp hình học khác. and http://tailieuhay. Dimension2D Đóng gói cả chiều rộng và chiều cao.Double. Miêu tả một diện tích hình học mà hỗ trợ các phép toán nhị phân. 76 CubicCurve2D.com .Một siêu lớp trìu tượng cho tất cả các đốI tượng lưu trữ dùng để lưu trữ các đốI tượng hai chiều.và một kiểu đóng kín.Cloneable.Float và Arc2D.Double Mở rộng:RectangularShape Arc2D.Float Miêu tả một đường cong được định nghĩa bằng một hình chữ nhật có giớI hạn.Việc thực thi để chỉ rõ các đường cong bậc ba vớI độ chính xác float và double do hai lớp: CubicCurve2D.Lập trình đồ họa trên Java 2D và 3D Giao diện PathIterator Shape (java.Doubl Lớp thực thi:Shape.Float CubicCurve2D. Area Chính xác:Arc2D.Area Lớp thực thi:Shape.Double. CubicCurve2D e CubicCurve2D.Float Implements: Shape Miêu tả các đoạn đường cong tham số bậc ba trong không gian tọa độ.góc ban đầu.

Được thực thi để xác đinh các điểm với độ chính xác float và double: Point2D. Mở rộng: RectangularShape 77 http://tailieuhay.Double.Float Mở rộng: RectangularShape Miêu tả việc định nghĩa đường e-lip bằng các hình chữ nhật giớI hạn.Double Point2D.Lập trình đồ họa trên Java 2D và 3D Ellipse2D Ellipse2D.Float và QuadCurve2D.Float và Point2D. Miêu tả một đoạn đường cong tham số bậc hai trong không gian tọa độ (x. Một điểm miêu tả một vị trí trong không gian tọa độ (x.Float đường thẳng và các đường bậc hai và bậc ba Thực thi đối tượng Shape.Double Ellipse2D.Được thưc thi để xác định các đường thẳng với độ chính xác float và double:: Line2D.Float và Ellipse2D.Công cụ để chỉ rõ các đường cong elip vớI độ chính xác float và double: Ellipse2D. Có thể sử dụng để cung cấp các flattening behavior cho các đối tượng Shape mà nó không GeneralPath thực hiện việc tính toán các thành phần thêm vào.Được thực thi để xác định các đường bậc hai với độ chính xác float Rectangle2D và double: QuadCurve2D. Thực thi đối tượng Shape Miêu tả một khung hinhg được xây dựng từ các Line2D Line2D.y) . Miêu tả một đoạn thẳng trong không gian tọa độ (x.y).Double Line2D. Thực thi đối tượng Shape.Double FlatteningPathIterator Trả về một flattened view của một đối tượng PathLterator.com .Double.Float và Line2D.y).Double.Doubl e QuadCurve2D.Float QuadCurve2D QuadCurve2D.Float Point2D Point2D.

Float Miêu tả một hình chữ nhật được định nghĩa bởi một vị trí (x. và và RoundRectangle2D. 78 http://tailieuhay.2 Các khái niệm hình học: Shape là một thể hiện của nhiều lớp mà nó thực thi Shape interface.Float RectangularShape Rectangle2D. y).Double Rectangle2D.Paint trong thư viện đồ họa 2D được áp dụng cho phần diện tích bên trong đường viền của nó.một kích góc cung. Đường viền (outline) còn được định nghĩa là path. Mở rộng: RectangularShape được định nghĩa bằng một vị trí (x. Cung cấp sự thao tác chung cho các tác động lên các đối tượng Shape mà nó có các hình chữ nhật RoundRectangle2D ouble oat biên. Được thực thi để xác đinh các hình chữ nhật có góc tròn với độ chính xác float và double: RoundRectangle2D.và chiều rộng và chiều cao của 3.D Miêu tả một hình chữ nhật các góc được làm tròn RoundRectangle2D.Float RoundRectangle2D.như GeneralPath or Rectangle2D .kiểu đường nét vẽ được địng nghĩa bởi đối tượng Stroke trong thư viện đồ họa 2D.x.Lập trình đồ họa trên Java 2D và 3D Rectangle2D.được áp dụng cho Shape’s path.Fl thước (w x h).Để biết thêm thông tin.com .bạn xem thêm phần “Rendering with Graphics2D”.Float .y) và kích thước(w.Khi một Shape được phủ đầy.Double. Thực thi đối tượng Shape.Double. Được thực thi để xác đinh các hình chũ nhật với độ chính xác float và double: Rectangle2D. Khi một Shape được vẽ.h).

3. Một GeneralPath là một shape mà nó có thể được sử dụng java.Để thuận lợi.2. Các Area hỗ trợ các phép toán nhị phân sau: • Union(hợp) • intersection(giao) • Subtraction(trừ) • Exclusive OR (XOR) (OR dành riêng) Các phép toán đó được miêu tả như hình 3-1 dưới đây: The Java2D™ API còn cung cấp một kiểu shape đặc biệt hỗ trợ cho việc xây dựng diện tích hình http://tailieuhay.bạn xem thêm phần “Setting the Clipping Path”. clipping path là một phần của Graphics 2D. cung cấp thêm các thành phần thực thi của giao tiếp Shape mà nó miêu tả các đối tượng đồ họa phổ biến như hình chữ nhật.Lập trình đồ họa trên Java 2D và 3D Đường viền của một hình cũng có thể được sử dụng để định nghĩa một clipping path.cung tròn và các đường cong.Bạn có thể tạo ra một đối tượng Area từ một số Shape. Để biết thêm thông tin.1 Constructive Area Geometry Constructive Area Geometry (CAG) là một quá trình tạo ra các đối tượng hình học mới bằng việc thực hiện các phép toán nhị phân trong các đối tượng đã tồn tại. học.awt.geom để miêu tả một số đối tượng 2 chiều có thể được vẽ từ các đường và các đường bậc hai hoặc bậc ba.hình elip.Một clipping path xác định những điểm ảnh nào được đưa ra(render).Trong Java 2D API một kiểu đặc biệt của Shape được gọi là Area hỗ trợ các phép toán nhị phân.com 79 .

com 80 .đó là getBounds và getBounds2D. bounding box được sử dụng để quết định một đối tượng có được chọn hay không hoặc được “hit” bởi người sử dụng.2 Bounds and Hit Testing Một bounding box là một hình chữ nhật bao bọc hoàn toàn một một thể thiện hình học.0 * 20/03/06 */ import java.Cung cấp một độ chính xác cao hơn trong việc miêu tả shape’s bounding box.2.*.awt. một thể hiện của Rectangle . http://tailieuhay.Phương thức getBounds2D trả về một đối tượng Rectangle2D .java * 1.Lập trình đồ họa trên Java 2D và 3D 3. Giao diện Shape xác định hai phương thức cho việc truy lại một shape’s bounding box. (contains ) • Một hình chữ nhật cụ thể phân cắt hình thể (intersects ) /* * Composite. Shape cũng cung cấp nhiều phương thức cho việc xác định : • Một điểm cụ thể bên trong bao đóng của hình thể(contains ) • Một hình chữ nhật cụ thể nằm hoàn toàn bên trong một bao đóng của hình thể.

l = new layOut = new http://tailieuhay.0".Lập trình đồ họa trên Java 2D và 3D import javax. int rule = 0.*. public void init() { GridBagLayout GridBagLayout(). GridBagConstraints GridBagConstraints(). JComboBox alphas. JLabel alphaLabel. */ @SuppressWarnings("serial") public class Composite extends JApplet implements itemListener { CompPanel comp. /* * Chuong trinh nay la mot vi du ve cac luat ket hop giua cac hinh.0.com 81 .swing. rules. getContentPane(). String alpha = "1. l. rulesLabel.setLayout(layOut).weightx = 1.

alphaLabel. layOut.setConstraints(alphaLabel.fill = GridBagConstraints. GridBagConstraints GridBagConstraints(). alphaLabel = new JLabel().gridwidth GridBagConstraints.gridwidth GridBagConstraints.setHorizontalAlignment(JLabel.setText("Các luật kết hợp. l. a. layOut.setConstraints(rulesLabel. a. = rulesLabel. l. rulesLabel. rulesLabel.add(alphaLabel). Font newFont = getFont(). newFont = getFont().weightx = 1.gridwidth GridBagConstraints. getContentPane().REMAiNDER.CENTER). l).setHorizontalAlignment(JLabel.BOTH. getContentPane().Lập trình đồ họa trên Java 2D và 3D l.setFont(newFont). = alphaLabel.0. l).deriveFont(1).setLayout(layOut)."). alphaLabel.RELATiVE.setText("Cường độ mầu").com 82 a = new = .setFont(newFont). rulesLabel = new JLabel().CENTER).add(rulesLabel).RELATiVE. getContentPane(). http://tailieuhay.deriveFont(1).

additem("CLEAR"). GridBagConstraints GridBagConstraints().additem("DST_iN").0"). alphas.50").setConstraints(rules. rules. rules. rules.additem("SRC_OVER"). layOut.fill = GridBagConstraints.additem("DST_OVER"). alphas.additemListener(this). rules. getContentPane(). rules. fC.additem("0.BOTH. fC.additem("SRC_OUT").BOTH.weightx = 1.setConstraints(alphas. a.Lập trình đồ họa trên Java 2D và 3D a.gridwidth GridBagConstraints. rules.add(alphas). alphas.75").additem("0. rules = new JComboBox(). alphas = new JComboBox().additem("SRC"). getContentPane(). layOut.25").add(rules).0.0").REMAiNDER. a).fill = GridBagConstraints. a). alphas.additem("SRC_iN"). alphas. rules.com 83 .additemListener(this). rules. alphas.additem("DST_OUT").additem("0. fC = new = http://tailieuhay.additem("1.additem("0. rules.

Lập trình đồ họa trên Java 2D và 3D fC. } comp. fC).0.addWindowListener(new WindowAdapter() { = (String) != itemEvent. getContentPane(). if (choice == alphas) { alpha alphas.setConstraints(comp. } public void itemStateChanged(itemEvent e) { if (e. } else { rule = rules.SELECTED) { = http://tailieuhay. comp = new CompPanel().com 84 .weighty = 1. } public static void main(String s[]) { JFrame f = new JFrame("Kết hợp").getSelecteditem(). layOut. validate().add(comp).getSelectedindex().gridwidth GridBagConstraints.getStateChange() return.getSource(). rule). fC. f.changeRule(alpha.REMAiNDER. } Object choice = e.

pack(). public CompPanel() { } public void changeRule(String a. JApplet applet = new Composite(). f.valueOf(a). ac repaint(). f. f.exit(0). } }). f.com 85 . } } class CompPanel extends JPanel { AlphaComposite ac = void AlphaComposite.getinstance(getRule(rule). float alpha = 1.SRC). applet). int rule) { alpha = Float. http://tailieuhay. alpha).Lập trình đồ họa trên Java 2D và 3D public windowClosing(WindowEvent e) { System. } = AlphaComposite.setSize(new Dimension(300.0f.floatValue().add("Center". applet.show().init(). 300)).getContentPane().getinstance(AlphaComposite.

http://tailieuhay.com 86 . break.CLEAR. case 1: alphaComp = AlphaComposite. case 2: alphaComp = AlphaComposite. case 7: alphaComp = AlphaComposite.DST_OVER. break.DST_iN.SRC. case 4: alphaComp = AlphaComposite.Lập trình đồ họa trên Java 2D và 3D public int getRule(int rule) { int alphaComp = 0. break. break. case 6: alphaComp = AlphaComposite.SRC_OVER. break. break. case 5: alphaComp = AlphaComposite. } return alphaComp.SRC_OUT. break.DST_OUT. case 3: alphaComp = AlphaComposite. switch (rule) { case 0: alphaComp = AlphaComposite. break.SRC_iN.

int rectx = w / 4.Double(rectx + rectx / 2. gbi.0f.0f)).createGraphics(). gbi. Dimension d = getSize(). int w = d. d.setColor(new Color(0. Bufferedimage.com 87 .fillRect(0. Bufferedimage Bufferedimage(w.width.0f.fill(new recty. gbi.setColor(Color. Graphics2D g2 = (Graphics2D) g.0f.white). g2.Lập trình đồ họa trên Java 2D và 3D } public void paintComponent(Graphics g) { super.height. g2. 150. 100)). h. 1.0f. int recty = h / 4.setColor(new Color(1. 0.0f. Graphics2D buffimg.fill(new Ellipse2D.setComposite(ac).TYPE_iNT_ARGB).height). 0. 0.Double(rectx. d.paintComponent(g). Rectangle2D. 0.0f)). 1. recty + recty / 2. 1. gbi = buffimg = new http://tailieuhay.0f.width. gbi. int h = d. gbi.

0.Gọi các toán tử nhị phân thích hợp: add. null. 0). exclusiveOr Ví dụ. } } Kết quả của chương trình : 3.Lập trình đồ họa trên Java 2D và 3D 150.Tạo một hình thể phức tạp mới bằng cách kết hợp các Area như sau: 1. 2.subtract .tạo ra các Area để kết hợp lại.Sử dụng các Shape.drawimage(buffimg.com 88 .intersect .CAG có thể được sử dụng để tạo ra quả lê giống như hình 3-2 dưới đây: http://tailieuhay.3 Combining Areas to Create New Shapes Các Area có thể được sử dụng để tạo ra một cách nhanh chóng các Shape phức tạp như các hình tròn và các hình vuông. g2. 100)).

Cái lá được tạo ra bằng cách thực hiện một phép giao trên hai vòng tròn chồng lên nhau và sau đó được đưa vào một Shape đơn thông qua phép hợp.event.awt.awt.awt. import java.awt. import java. import java.geom.swing.Ellipse2D.Graphics2D.swing. import javax.lapping Areas : circle và oval.Area. Chương trình: /* * @(#)Pear.WindowAdapter.event.Dimension.java */ import java.JFrame.awt.awt.Graphics. import java.Color.0 27/03/06 http://tailieuhay. import java.Việc nạp chồng các vòng tròn còn được sử dụng để tạo cuống lá thông qua hai phép trừ.JApplet. 1.WindowEvent.com 89 .Lập trình đồ họa trên Java 2D và 3D Cách thực hiện: Thân của quả lê được tạo ra bằng cách kết hợp các thao tác trong 2 over.awt.awt.geom. import java. import javax. import java.

white). leaf.com 90 . leaf2. circ = new Area(circle). stem = new Ellipse2D. oval = new Ellipse2D. leaf = new Ellipse2D.su dung phuong thuc ket hop giua cac */ @SuppressWarnings("serial") public class Pear extends JApplet { Ellipse2D. oval. setBackground(Color. st1 = new Area(stem). leaf1.Double circle. } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g. Area circ.Double().Lập trình đồ họa trên Java 2D và 3D /* * Chuong trinh nay ve mot qua le.Double(). ov. http://tailieuhay. Dimension d = getSize(). st1. public void init() { circle = new Ellipse2D. st2.Double().Double(). st2 = new Area(stem). stem. leaf2 = new Area(leaf). vung. ov = new Area(oval). leaf1 = new Area(leaf).

+ 1.0.0). eh . oval.com 91 .0. g2. 50. eh 29. eh 20.setFrame(ew 70. st2 = new Area(stem). leaf.0.0).setColor(Color. leaf.green). double eh = h / 2.0). 15.Lập trình đồ họa trên Java 2D và 3D int w = d.intersect(leaf1). http://tailieuhay.height. eh 47. eh. 16. + 3. g2.fill(leaf1).0). 40.25.setFrame(ew 30. g2.setColor(Color. g2.black). double ew = w / 2. 50. 50.0).0).setFrame(ew. eh 47.0. 14. int h = d.setFrame(ew 15. leaf2.0.setColor(Color.intersect(leaf2). 19. leaf1 = new Area(leaf). circle.setFrame(ew 50. 40. leaf2 = new Area(leaf).0. g2.yellow). leaf1.0.setFrame(ew . leaf1 = new Area(leaf).42. eh 29.fill(leaf2).subtract(st2). 15.fill(st1). 30. 40.setFrame(ew 15. g2.width. stem. st1 = new Area(stem).0). leaf. stem. st1.

circ. f. } public static void main(String s[]) { JFrame f = new JFrame("Quả lê").getContentPane(). g2. JApplet applet = new Pear().exit(0).add("Center". 400)).setSize(new Dimension(600. } } Kết quả của chương trình: void http://tailieuhay.com 92 .addWindowListener(new WindowAdapter() { public windowClosing(WindowEvent e) { System. f. applet.init().fill(circ). f.Lập trình đồ họa trên Java 2D và 3D circ = new Area(circle). f. f. ov = new Area(oval). applet).add(ov).show(). } }).pack().

com 93 .Lập trình đồ họa trên Java 2D và 3D http://tailieuhay.

awt.swing. Chương này tập chung vào khả năng hỗ trợ các kiểu font và các cách bố trí văn bản(text layout) bằng việc sử dụng các giao diện và các lớp trong java. Để có thêm thông tin về phân tích văn bản.bạn tham khảo thêm văn bản hướng dẫn về java.Được thực thi bởi các đối tượng Font mà chúng là các kiểu font nhiều đường để có thể truy cập đến các thiết kế điều khiển.bạn xem thêm phần java.awt được sử dụng để đảm bảo tính tương thích với các phiên bản trước đó của bộ JDK. Để có thêm thông tin về cách sử dụng công cụ bố trí văn bản bằng cách sử dụng Swing.Hầu hết trong số giao diện và lớp này là thành phần của gói ava.Một số.Giao diện và lớp.com . Bảng mô tả giao diện và lớp : Giao diện MultipleMaste r OpenType Miêu tả Miêu tả các font kiểu 1 với nhiều đường.font.Nó còn bao gồm cả lớp Font và lớp TextLayout.text và “Using the JFC/Swing Packages” trong Java Tutorial.là một phần của gói java. Miêu tả các font kiểu mở(Open Type)và kiểu thực(True 94 http://tailieuhay. Bảng dưới đây liệt kê các giao diện và các lớp chính sử dụng cho font và textlayout. Java 2D™ API còn cung cấp các lớp liên quan tới văn bản hỗ trợ các điều khiển font và các cách bố trí văn bản phức tạp. 4.text và theo dõi phần “Writing Global Programs” trong bộ Java Tutorial.như Font.Lập trình đồ họa trên Java 2D và 3D Chương 4: Hiển thị Font và văn bản Bạn có thể sử dụng các phép biến đổi và các công cụ drawing của Java 2D™ API với văn bản.font.awt.awt.awt và java.Hơn nữa.1.

sự GlyphMetrics GlyphVector GraphicAttribute thu hút và giới hạn.Hỗ trợ việc đặc tả chi tiết về thông tin font và cung cấp khả năng truy cập tới các thông tin về các FontRenderContext GlyphJustificationInfo kiểu font và các đường nét của nó.như trọng lượng (chữ).awt) Mô tả Miêu tả một thể hiện của bề mặt font(font face) từ tập hợp các font face đã có sẵn trong máy.Có thể phân lớp để thực thi kí tự tùy chọn để thay thế các graphic.Lập trình đồ họa trên Java 2D và 3D Type). Cung cấp các phép đo cho một đường nét đơn.Được thực thi bởi các đối tượng Font mà chúng là các font Open Type hoặc True Type có thể truy cập đến các bảng font’s sfnt. Chia một khối văn bản thành nhiều dòng trong các đối tượng TextLayout mà nó khit bên trong một dong. Một tập hợp các đường nét và các vị trí.mà nó có thể cho phép các đối tượng Shape và đối tượng Image nhúng vào một đối tượng TextLayout. ImageGraphicAttribute Mở rộng:GraphicAttribute Một đối tượng GraphicsAttribute được sử dụng LineBreakMeasurer để vẽ các ảnh bên trong một TextLayout. Đóng gói thông tin cần thiết cho các phép đo văn bản một cách chính xác.Được thực thi bởi và ShapẻGaphicAttribute ImageGraphicAttribute. http://tailieuhay.com 95 . Là lớp cơ sở cho thuộc tính TextLayout mà nó đặc tả một đối tượng Graphics để được nhungd vào văn bản. Lớp Font (java.độ ưu tiên. Miêu tả các thông tin về đặc tính căn lề của một đường nét.

Miêu tả thông tin hit test cho các kí tự trong một đối tượng TextLayout Thực thi:Cloneable Cung cấp một sự biểu diễn đồ họa cố định của các dữ liệu kí tự đã được định kiểu. leading.chiều cao và thông tin đường cơ bản(ascent.bao gồm cả các văn bản hai chiều. Có ba kiểu tên cho một đối tượng Font-đó là logical name.com 96 .Các font thương hay được sử dụng như font Helvet Bold và Courier Bold italic.phần mũ. 4. height.phần phía dưới. Một đối tượng Font miêu tả một thể hiện của kiểu font trong tập hợp các font của hệ thống. descent. family name.Lập trình đồ họa trên Java 2D và 3D LineMetrics Cung cấp khả năng truy cập đến các thước đo font cần thiết để hiển thị các kí tự trên một hàng và hiển thị tập các hàng đó.Các khái niệm về Font Lớp Font đã được cải tiến để hỗ trợ việc đặc tả chi tiết thông tin về kiểu font và có thể sử dụng các đặc tính phức tạp. and baseline information).2. ShapeGraphicAttribute Mở rộng:GraphicAttribute Một đối tượng GraphicsAttribute được sử dụng để vẽ các đối tượng Shape trong một đối TextAttribute tượng TextLayout Định nghĩa các thuộc tính quan trọng và các giá trị được sử dụng cho việc tạo bóng văn bản(text TextHitInfo TextLayout rendering). và font face name: http://tailieuhay.Các thước đo bao gồm phần nhô lên.

Một đối tượng LineMetrics đóng gói các thông tin về các số đo của Font.như ascent. logical name là tên font được sử dụng để chỉ rõ một đối tượng Font trong JDK 1.chẳng hạn như kiểu chữ Helvetica.Khoảng cách này miêu tả chiều cao của các chữ viết hoa.Bạn có thể lấy tên font bằng cách gọi phương thức geFontName.com 97 . Một family name của đối tượng Font là tên trong họ font mà nó định nghĩa cách thiết kế việc in thông qua một số bề mặt.Toolkit.Bạn có thể nhận logical name từ đối tượng font bằng cách goi j phương thức getName. • Descent là khoảng cách từ đường baseline đến đường descender.getFontList.nhưng một số kí tự có thể mở rộng về phía trên của đường ascender.Đó là tên mà bạn có thể sử dụng khi chỉ rõ một kiểu font trong Java 2 SDK.đặc tính font như hình dáng font. • Ascent là khoảng cách từ đường baseline đến đường ascender.Lập trình đồ họa trên Java 2D và 3D Một logical name của đối tượng Font là tên được ánh xạ đến một trong nhiều font cụ thể đã có sẵn trong platform. Các thuộc tính của Font bao gồm tên.Để nhận được danh sách các logical name.awt.Nó cũng thường được ám chỉ cho font name.hãy gọi java. Một font face name của đối tượng Font dùng để ám chỉ kích thước thật của font được cài đặt trong hệ thống.kích cỡ font.bạn có thể gọi phương thức GraphicsEnvironment.Khi chỉ định một đối tượng Font trong Java™ 2 SDK bạn nên sử dụng font face name thay cho logical name.Để xác định kiểu font nào được sử dụng trong hệ thống.Điểm thấp nhất của hầu hết các kí tự sẽ nằm bên trong http://tailieuhay.getAllFonts.descent và khoảng cách giữa các dòng chữ.transform. Bạn có thể truy xuất các thông tin về một đối tượng Font bằng việc gọi phương thức getAttributes.1 và các phiên bản trước đó.Bạn lấy họ tên font bằng cách sử dụng phương thức getFamily.

• Leading được nói tới như là khoảng cách từ đáy của đường Thông tin này được sử dụng để định vị một cách chính xác các kí tự dọc theo một dòng. và getLeading .Quá trình này được gọi là text layout.bao gồm các giai đoạn sau: • Sắp đặt các chữ sử dụng các nét chữ và các cách kết hợp thích hợp.com 98 . Trước khi một đoạn chữ có được hiển thị. baseline và underline của Font thông qua LineMetrics. http://tailieuhay. 4.Lập trình đồ họa trên Java 2D và 3D descent. descender đến đỉnh của dòng tiếp theo.nhưng có một số kí tự có thể mở rộng về phía dưới của đường descender.Bạn cũng có thể truy xuất thông tin vê weight. • Đánh giá và bố trí các đoạn text. • Ordering các đoạn text thích hợp. Bạn có thể truy xuất những phép đo các line bằng việc sử dụng các phương thức getAscent.3 Các khái niệm về Text Layout.nó cần phải được chỉ rõ về hình dáng cũng như vị trí hiển thị bằng việc sử dụng các nét chữ và các cách kết hợp một thích hợp. getDescent.và các đường có thể liên quan đến các đường khác.

và vị trí của glyph phụ thuộc vào văn cảnh của nó.các cursive form có thể khác nhau hoàn toàn về hình dáng. Để phát triển các phần mềm có thể triển khai trên toàn cầu. Gyph(nét chữ) là một cách hiển thị trực quan cho một hay nhiều kí tự.kích thước.đặc biệt là chữ Ả Rập. và highlighting.Hình dáng. Ví dụ như trong đoạn text viết bằng tay.com 99 .chữ heh trong tiếng Ả Rập có bốn cursive form http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D Các thông tin cho được sử dụng để hiển thị text cũng rất cần thiết cho việc biểu diễn text như caret positioning. the context of a glyph must always be taken into account .1 Vẽ chữ.Không giống tiếng Anh. Trong một số hệ thống văn bản. hit detection. 4.3.text phải được thể hiện trên nhiều ngôn ngữ khác nhau bằng nhiều để có thể thích hợp với quy tắc của các hệ thống văn bản thích hợp.các cursive form có tính bắt buộc trong chữ Ả Rập. Phụ thuộc vào từng context.các kí tự đặc biệt có thể thể hiện các hình dáng chữ khác nhau phụ thuộc vào cách nó kết hợp với các kí tự liền kề với nó.Ví dụ.Rất nhiều loại glyph có thể được sử dụng để miêu tả một kí tự đơn hoặc nhiêu kí tự kết hợp với nhau.phụ thuộc vào font và kiểu dáng(style).

Việc hòa hợp glyph đưa vào tính toán phần nhô ra trong kí tự f và kết hợp các kí tự theo một cách tự nhiên.Kiểu kết hợp này được gọi là ligature.thay vì các kí tự kề nhau http://tailieuhay. Trong một số ngữ cảnh.hầu hết các font tiếng anh chứa ligature như trong hình 43.com 100 .Ví dụ.nhưng những sự thay đổi về hình dáng không phải là sự khác biệt cơ bản về cursive trong tiêng Anh.Lập trình đồ họa trên Java 2D và 3D như trong hình 4-2 dưới đây: Mặc dù bốn kiểu form này chỉ khác nhau đôi chút so với cá form khác.hai glyph có thể thay đổi hình dáng một cách cơ bản và kết hợp vào form một glyph đơn.

Lập trình đồ họa trên Java 2D và 3D Các chữ ghép cũng được sử dụng trong tiếng Ả rập và cách sử dụng của một số chữ ghép is mandatory-nó không được chấp nhận để hiển thị các kí tự kết hợp chính xác mà không sử dụng chữ ghép thích hợp. script order cho văn bản kiểu Roman được bố trí từ trái qua phải và script order cho các văn bản Arabic và Hebrew được bố trí từ phải sang trái. Một số hệ thống ghi(writing systems) có các nguyên tắc trong việc thêm các script order cho việc sắp xếp các glyph và các từ trong nhiều dòng của văn bản. 4.là nơi mà trong đó các glyph tương ứng được hiển thị. logical order không nhất thiết phải giống như visual order.Ví dụ.văn bản được mã hóa bằng cách sử dụng các kí tự mã hóa Unicode.Văn bản sử dụng kí tự mã hóa Unicode được lưu trữ trong bộ nhớ trong logical order. logical order là nơi mà trong đó các kí tự và các từ được đọc và ghi.2 Ordering Text Trong ngôn ngữ lập trình Java.com 101 . các số Arabic và Hebrew chạy từ trái qua phải.hình dáng thay đổi một cách cơ bản hơn so với tiếng Anh.Khi các chữ ghép được tạo thành từ các kí tự Ả Rập.như trong hình 4-4 miêu tả cách hai chữ cái Ả rập kết hợp với nhau thành một chữ ghép khi chúng xuất hiện cùng nhau.Ví dụ.3.mặc dú các http://tailieuhay. Visual order cho các glyph trong hệ thống ghi cụ thể(script) được gọi là script order.Ví dụ.

Base direction là một script order của hệ thống ghi.các từ Arabic được hiển thị trong các Arabic script.từ phải qua trái.Mỗi phần miêu tả chia thành hai phần:việc hiển thị của các kí tự được lưu trữ trong bộ nhớ(các kí tự trong logical order) sau đó là cách hiển thị của những kí tự được hiển thị(các kí tự trong visual order).ngay cả khi không có các văn bản bằng tiếng Anh nhúng vào.com 102 .(Điều này có nghĩa Arabic và Hebrew. base direction sẽ được chỉ định.nếu văn http://tailieuhay.Các số bên dưới khung kí tự chỉ định insertion offsets. Hình 4-5 Bidirectional Text Cho dù chúng là một phần trong một câu tiếng Anh. Chú ý:Trong ví dụ này và trong các ví dụ sau.chúng vẫn thực sự là (kĩ thuật) hai chiều) Một hệ thống ghi visual order phải không được thay đổi ngay cả khi các ngôn ngữ hòa trộn với nhau. Khi một dòng văn bản với một sự pha trộn hai cách bố trí từ trái qua phải và từ phải qua trái được hiển thị.Điều này được mô tả trong hình 4-5.Ví dụ. các văn bản Arabic và Hebrew được hiển thị bằng các chữ cái in hoa và các khoảng cách giữa các chữ được hiển thị bằng dấu gạch dưới.Lập trình đồ họa trên Java 2D và 3D kí tự chạy từ phải qua trái.miêu tả một nhóm từ Arabic nhúng vào một câu văn bản tiếng Anh.

3 Đo và định vị văn bản Trừ khi bạn làm việc với font đơn cách.com 103 .nếu văn bản gốc là tiếng Arabic với một số chữ Anh nhúng vào hoặc các con số. Base direction xác định các bố trí trong mỗi đoạn của văn bản với một common direction được hiển thị.Để có vị trí .các kí tự giống nhau có thể có các hình dáng khác nhau về chiều rộng.Trong ví dụ 5-4.3.Bởi vì hình dáng và vị trí của các kí http://tailieuhay.bạn cần phải kiểm tra mỗi kí tự riêng lẻ và kiểu dáng được sử dụng cho kí tự đó. 4.văn bản tiếng Anh ở đoạn đầu của câu chạy từ trái qua phải. Các văn bản thường sử dụng cách hiển thị theo nhiều dòng và nhiều kiểu dáng.Thật may là lớp TextLayout đã làm điều này cho bạn.thì base direction sẽ là từ trái qua phải.các kí tự khác nhau trong kiểu font có chiều rộng khác nhau. base direction là từ trái qua phải.văn bản Arabic chạy từ phải qua trái.bạn cần phải biết chính xác chiều rộng của mỗi số mà bạn có thể điều chỉnh sao cho phù hợp.Có ba hướng bố trí văn bản trong ví dụ này.Đẻ căn lề các cột một cách đúng đắn. một cột các chữ số được căn lề phải được hiển thị trong kiêu font cân xứng.Ngược lại.Lập trình đồ họa trên Java 2D và 3D bản gốc là tiếng Anh với một số chữ Arabic được nhúng vào.và các văn bản khác chạy từ trái qua phải.như theo kiểu nét đậm và in nghiêng. Để hiển thị các văn bản đúng trong nhiều ngôn ngũ chẳng hạn như Hebrew và Arabic.Điều này có nghĩa tất cả các vị trí và kích thước của các văn bản phải được tính toán một cách chính xác với các kí tự được sử dụng.bạn không thể dễ dàng sử dụng các không gian mở rộng cho vị trí của các văn bản.kích thước và render text chính xác.mỗi kí tự cần phải được cân nhắc và đặt vào bên trong một ngữ cảnh với các kí tự bên cạnh.thì base direction sẽ là từ phải qua trái.Ví dụ.phụ thuộc vào cách nó thể hiện kiể u dáng.Trong trường hợp này.

bạn phải: • Hiển thị dấu caret mà nó chỉ địn nơi một kí tự mới sẽ được thêm vào khi người dùng thêm vào text. 4.4. Việc tính toán vị trí dấu caret có thể rất phức tạp. • Phát hiện sự lựa chọn của người dùng(hit detection).vị trí trong đoạn text nơi mà các kí tự mới sẽ được chèn vào.một dấu caret được thể hiện là một thanh thẳng đứng nhấp nháy giữa hai glyph. 4.đặc biệt là trong các text hai chiều.com 104 .Các đoạn chèn vào trong các đường biên định hướng có hai vị trí có thể chèn bởi vì hai glyph đó phù hợp với khoảng kí tự không được hiển thị sát ngay các kí tự khác.3.các dấu caret được thể hiện là các dấu ngoặc vuông. Để cho phép người dùng có thể sửa đổi text đã được hiển thị. • Làm nổi bật đoạn text được lựa chọn.dấu caret được sử dụng để hiển thị điểm chèn hiện tại. http://tailieuhay.1 Hiển thị dấu nhắc Trong các text có thể chỉnh sửa được.4 Hỗ trợ thao tác với văn bản.Kí tự mới được chèn vào và được hiển thị tại vị trí của dấu caret.Điều này được miêu tả trong hình 46.Thông thường.Lập trình đồ họa trên Java 2D và 3D tự có thể thay đổi được phụ thuộc vào từng ngữ cảnh.việc cân nhắc và sắp đặt các đoạn văn bản mà không cần xét đến văn cảnh là một điều không được tán thành.3. • Di chuyển dấu caret và điểm chèn trong câu trả lời khi người dùng đưa vào.Trong hình vẽ này.

glyph của nó được hiển thị bên trái(phía sau) của dấu _.bề rộng của các glyph ở phía bên trái của khoảng trống cần phải được thêm vào và ngữ cảnh http://tailieuhay. Để làm đươc điều này một số hệ thống hiển thị hai dấu caret.glyph của nó được hiển thị bên phải(phía trước) của kí tự A.Còn nếu người dùng muốn chèn một kí tự English.com 105 .bạn không thể đơn giản thêm vào bề rộng của các glyph trước một khoảng trống của kí tự để tính toán vị trí dấu caret.Nếu người dùng muốn thêm một kí tự Arabic vào chỗ đó.Lập trình đồ họa trên Java 2D và 3D Hình 4-6 Dual Carets Kí tự ở vị trí thứ 8 nằm sau dấu _ và nằm trước kí tự A. Khi làm việc với văn bản hai chiều.dấu caret có thể hiện ra tại vị trí sai như bạn thấy trong hình 4-7: Figure 4-7 Caret Drawn incorrectly Để dấu caret có thể hiển thị ở một vị trí hợp lý.một dấu là chính (primary) còn một dấu là phụ (secondary).Lớp TextLayOut tự động hỗ trợ cả hai dấu caret.Nếu bạn làm vậy.Còn dấu caret phụ cho biết một kí tự chèn vào sẽ được hiển thị khi hướng của kí tự đó ngược với hướng cơ sở của đoạn text.còn lớp JtextComponent thì không.Dấu caret chính chỉ định nơi mà một kí tự chèn vào được hiển thị khi hướng của kí tự đó cùng với hướng cơ sở của cả đoạn text.

Lập trình đồ họa trên Java 2D và 3D hiện tại đưa vào tính toán.Người sử dụng mong muốn dấu caret sẽ di chuyển theo hướng của các phím mũi tên đước ấn.4. Di chuyển dấu caret ngang qua hướng đường biên là một việc khá phức tạp như trong hình 4-8 dưới đây: http://tailieuhay.Nếu khoảng trống thêm vào hiện tại nằm bên trong một thi hành của các kí tự từ phải qua trái.các phép đo glyph sẽ không cần thiết khớp với việc hiển thị.2 Di chuyển dấu nhắc.việc di chuyển các khoảng trống thêm vào rất đơn giản:Phím mũi tên phải làm tăng khoảng trống được thêm vào bằng còn phím mũi tên trái làm giảm đi.Bạn ko thể đơn giản tăng khoảng trống thêm vào khi phím mũi tên phải được ấn và giảm nó khí phím mũi tên trái được ấn.3.cách làm này có thể khiến dấu caret nhẩy qua các glyph theo hướng của đường biên và di chuyển trong theo hướng ngược lại.. Tất cả các trình biên soạn văn bản đều cho phép người sử dụng di chuyển dấu caret với các phím mũi tên.bạn cần phải tính toán hướng của văn bản thi hành.Từ trái qua phải của đoạn text.Trong các văn bản hai chiều hoặc các văn bản có nhiều chữ ghép.thì phím mũi tên phải có thể làm giảm khoảng trống thêm vào và phím mũi tên trái sẽ làm tăng nó.com 106 . Để di chuyển dấu caret một cách mượt mà(smoothly) qua văn bản hai chiều.Trừ khi ngữ cảnh được đưa vào tính toán. 4.

com 107 .Theo một cách logic.Lập trình đồ họa trên Java 2D và 3D Figure 4-8 Caret Movement Chắc chắn các glyph sẽ không bao giờ có dấu caret giữa chúng.như trong hình 4-9 dưới đây: Hình 4-9 Hit Testing Bidirectional Text Bởi vì một vị trí trực quan có thể đáp ứng cho hai offset khác nhau.một vị trí trong không gian của công cụ phải được chuyển thành không gian trống của text.một vị trí trực quan trong phần hiển thị có thể đáp ứng cho hai offset khác nhau trong đoạn văn bản gốc. Khi bạn làm việc với văn bản hai chiều.Ví dụ.không bao giờ có một dấu caret bên trong chữ o và một sự biến âm(an umlaut) nếu chúng được hiển thị bằng hai kí tự phân cách.nó được chuyển ngược thành vị trí của dấu caret.vị trí của chuột được chuyển thành khoảng trống và được sử dụng như điểm cuối của vùng lựa chọn. hit testing các văn bản hai chiều không phải là quan trọng của các phép đo bề rộng của các đường nét (measuring glyph widths) trừ glyph tại các vị http://tailieuhay.Lớp TextLayOut cung cấp các phương thức getNextRightHit and getNextLeftHit để có thể dễ dàng di chuyển dấu caret một cách mượt mà qua các văn bản hai chiều.thay vào đó dấu caret di chuyển qua các hiển thị của glyph một kí tự đơn.4. 4.3 Hit Testing Thông thường.khi người sử dụng nhấn chuột vào văn bản được chọn.Ví dụ như.3.

Có hai cách để lựa chọn vùng sáng trong văn bản hai chiều: • Logical highlighting(vùng sáng logic) .và vùng sáng được lựa chọn một cách liên tiếp.xem hình 4-10. http://tailieuhay.4.một vùng sáng liên tục cho thấy một cách trực quan một dải liên tục các nét có thể không phù hợp với một kí tự đơn. Một vùng các kí tự được lực chọn được hiển thị đồ họa bằng một vùng được tô sáng.có nhiều phức tạp trong các văn bản hai chiều hơn là trong các văn bản một chiều(monodirectional text). Vùng được tô sáng.bạn có thể có nhiều dải các kí tự được lựa chọn.giống như dấu caret.4 Đánh dấu vùng lựa chọn.hitTestChar. Thông tin về hit được đóng gói trong đối TextHitinfo bao gồm các thông tin về cạnh mà việc hit được thấy trên đó.một dải liên tục các kí tự có thể không có một vùng được tô sáng liên tục khi hiển thị.xem hình 411. • Visual highlighting(vùng sáng trực quan) .dải liên tiếp của các kí tự.Ngược lại.com 108 .Xem ví dụ về logical highlighting.các kí tự được lựa chọn thường liên tiếp nhau trong mo hình văn bản(text model).đó là vùng mà mỗi đường nét được hiển thị với màu trái ngược với màu nền. Bạn có thể thực hiên hit testing bằng việc sử dụng lớp TextLayout.Ví dụ về visual highlighting.nhưng vùng sáng thông thường liên tiếp nhau.với visual highlighting.Trong văn bản hai chiều.Lập trình đồ họa trên Java 2D và 3D trí chính xác được tìm thấy và sau đó ánh xạ vị trí đó đến một character offset.3. 4.Với vùng sáng logic.

4. • Nếu bạn muốn hiển thị một đoạn chuỗi kí tự đơn giản.Để thêm thông tin về JtextComponent bạn xem thêm phần “Using the JFC/Swing Packages” của bộ Java Tutorial. • Nếu bạn muốn hiển thị cả một khối text hoặc cần các điều khiển chỉnh sửa text.các kí tự được lựa chọn thường liên tiếp nhau.com 109 .Lập trình đồ họa trên Java 2D và 3D Hình 4-10 Logical Highlighting (contiguous characters) Hình 4-11 Visual Highlighting (contiguous highlight region) Logical highlighting đơn giản hơn trong việc thực thi.bạn có thể gọi đối tượng Graphics2D.3.drawString và yêu cầu Java 2D hiển thị chuỗi kí tự cho bạn.nó sẽ thực hiện text layout cho bạn. Phụ thuộc vào Java™ APIs mà bạn sử dụng. JtextComponent được thiết kế để điều khiển việc cần thiết của hầu hết các ứng dụng và hỗ trợ cho các văn bản hai chiều.bạn có thể sử dụng JtextComponent. 2.Bạn cũng có thể sử dụng drawString để http://tailieuhay.bạn có thể có ít hoặc nhiều các điều khiển về text layout (hiển thị văn bản) như bạn cần: 1.5 Thực thi việc hiển thị văn bản trong ứng dụng Java™ .

bao gồm http://tailieuhay.bạn xem thêm phần Managing Text Layout.Để có thêm thông tin về cách thực thi công cụ text layput của bạn.com 110 .bạn không cần phải thực hiện text layout.và văn bản hai chiều.bạn có thể sử dụng TextLayout để điều khiển việc hiển thị văn bản(text layout).Các tiện lợi được cung cấp bởi lớp TextLayout cho hầu hết các trường hợp phổ biến.pha trộn các kiểu ngôn ngữ.bao gồm các xâu văn bản với việc pha trộn các kiểu Font. 3.Cho hầu hết các ứng dụng. •Nếu bạn muốn điều khiển toàn bộ việc làm thế nào để text được shape và được định vị trí.bạn có thể sử dụng Java 2D text layout APIs. Quản lý việc hiển thị văn bản.Tuy nhiên.hoặc bạn thích thực hiện việc chỉnh sửa văn bản của bạn.Nếu ứng dụng của bạn yêu cầu những đặc tính trên. JtextComponent không hỗ trợ việc hiển thị dấu caret kép hoặc các đoạn lựa chọn liên tiếp trong văn bản hai chiều.bạn xem thêm phần “implementing a Custom Text Layout Mechanism” .bạn có thể xây dựng lớp Glyphvector của bạn bằng cách sử dụng Font và sau đó render chúng dựa trên lớp Graphics2D.Để có thêm thông tin về cách sử dụng TextLayout. • Nếu bạn muốn thực thi việc chỉnh sửa văn bản của bạn.và hit detection.tô sáng( highlighting). 4. Lớp TextLayout hỗ trợ các text mà nó chứa đựng nhiều kiểu dáng(style) và nhiều kí tự từ các hệ thống writing khác nhau.Lập trình đồ họa trên Java 2D và 3D render(trả về) kiểu của xâu kí tự và các xâu kí tự đó chứa kiểu văn bản hai chiều.JtextComponent là giải pháp tốt nhất cho việc hiển thị các văn bản tĩnh và văn bản có thể chỉnh sửa.bạn xem thêm phần “Rendering Graphics Primitives”. Thông thường.Để có thêm thông tin về rendering text qua lớp Graphics2D.

Để shape và order một cách chính xác.các bảng co kéo(kerning tables). 4.4.tem’s layout mechanism).bạn có thể xây dựng giải thuật của bạn để tính toán cách bố trí văn bản.kể cả các văn bản một hướng(BiDi-bidirectional).Bằng việc sử dụng TextLayout bạn có thể đạt được việc tạo chữ với chất lượng cao mà không tốn nhiều công sức. Lớp TextLayout làm đơn giản việc sử lý cách hiển thị mà các phép đo văn bản nếu bạn làm việc với các văn bản chỉ có tiếng Anh.Bạn có thể dùng TextLayout để: • Hiển thị các văn bản một hướng và văn bản hai hướng. • Tô sáng vùng văn bản được lựa chọn. Lớp TextLayout sẽ đặt văn bản một cách tự động.bypassing công cụ bố trí của hệ thống(bypassing the sys. Text Layout Performance Lớp TextLayout giúp bạn trong việc xác định vị trí và thứ tự của các đường nét. • Thực hiện hit testing trên văn bản.com 111 . TextLayout phải biết toàn bộ ngữ cảnh của văn bản: http://tailieuhay.Việc sử dụng các thông tin như các kích cỡ đường nét(glyph sizes).Để có thêm thông tin bạn xem thêm phần “implementing a Custom Text Layout Mechanism”. • Hiển thị và di chuyển dấu caret.1 Trình bày văn bản.bạn có thể tính toán cách bố trí văn bản của bạn bằng cách điều khiển một cách chính xác các đường nét mà bạn sử dụng và nơi chúng sẽ được đặt(vào văn bản).các đường nét phải miêu tả các đường(line) của văn bản.và cách ghép chữ(ligature information).Lập trình đồ họa trên Java 2D và 3D Arabic và Hebrew(Arabic và Hebrew là các kiểu đặc biệt khó để hiển thị bởi vì bạn phải reshape và reorder văn bản để được chấp nhận hiển thị). ờng hợp.với việc tạo hình dáng(shaping) và ordering chính xác.

Lập trình đồ họa trên Java 2D và 3D • Nếu văn bản nằm trên một đường đơn(single line) .chẳng hạn như một từ đơn của nhãn(label) cho một nút lệnh hoặc một đường trong hộp thoại(dialog box). Hướng cơ bản của một văn bản thường được thiết lập bằng các thuộc tính(kiểu dáng) trên văn bản.vị trí và góc(angle). Hình 4-12 Angled Carets http://tailieuhay.và nhận được hướng cơ bản từ các kí tự bắt đầu trong đoạn. Lớp TextLayout chứa các thông tin về dấu caret như hình dáng của dấu(caret shape).lớp TextLayout sử dụng giải thuật của bảng mã hai chiều Unicode. Hiển thị dấu nhắc kép. • Nếu bạn có nhiều văn bản hơn là chỉ có một dòng hoặc bạn muốn chia văn bản từ các single line thành các đoạn.Bạn có thể sử dụng các thông tin này để dễ dàng hiển thị dấu caret trong cả văn bản một hướng và hai hướng.com 112 .Nếu thuộc tính đó bị thiếu.bạn không thể xây dựng đối tượng TextLayout một cách trực tiếp. TextLayout cung cấp cho ta nhiều hình dáng mặc định của dấu caret và hỗ trợ một cách tự động dấu caret kép.Khi bạn vẽ dấu caret cho văn bản một chiều.như bạn thấy trong hình 412.Các ví trí của dấu caret đó cũng được sử dụng như đường biên giữa các đường nét cho việc tô sáng và hit testing.Bạn phải sử dụng đối tượng LineBreakMeasure để đáp ứng đủ các ngữ cảnh.việc sử dụng lớp TextLayout sẽ đảm bảo dấu caret được đặt vị trí một cách chính xác.bạn có thể xây dựng một đối tượng TextLayout trực tiếp từ văn bản.

các dấu caret sẽ được render một cách tự động tại những vị trí chính xác. g2.setColor(SECONDARY_CARET_COLOR).phương thức getCaretShapes trả về một mảng hai phần tử của shape:phần tử thứ nhất chứa dấu caret chính và phần tử thứ hai chứa dấu caret phụ. if (caretShapes[1] != null){ g2.nó cho ta biết vị trí hiện tại của khoảng trống thêm vào. g2.bạn có thể tìm đến vị trí và góc của các dấu caret bằng đối tượng TextLayout và vẽ chúng theo cách của bạn.setColor(PRiMARY_CARET_COLOR). g2.Lập trình đồ họa trên Java 2D và 3D Căn cứ vào khoảng trống được thêm vào.nếu chúng cùng tồn tại.Dựa vào đối tượng TextHitinfo. Shape[] caretShapes = layout.Để hiển thị cả hai dấu caret(dấu caret kép).bạn đơn giản chỉ là vẽ cả hai shape của dấu caret. } 4.hình dáng của dấu caret chính và phụ mặc định được vẽ trên các màu khác nhau. Bạn cũng có thể sử dụng lớp TextLayout để xác định kết quả của việc thêm vào các khoảng trống khi người sử dụng ấn các phím mũi tên trái hoặc phải.Đây là cách phổ biến để tạo sự khác biệt của hai dấu caret . Nếu bạn muốn sử dụng shape của dấu caret một cách tùy thích.4. Trong ví dụ dưới đây.com 113 .draw(caretShapes[1]).3 Di chuyển dấu nhắc.getCaretShapes(hit).draw(caretShapes[0]).phương thức getNextRightHit trả về kiểu đối tượng TextHitinfo mà nó cho biết chính xác vị trí của khoảng trống thêm http://tailieuhay.

getinsertindex().getCaretShapes(newinsertionOffset).Đối tượng TextHitinfo chứa khoảng trống chèn vào cho vị trí và cạnh mà việc hit was on.Phương thức hitTestChar sẽ lấy tọa độ x và y từ chuột(takes x and y coordinates from the mouse) như các đối số và trả về kiểu đối tượng TextHitinfo. hit. TextHitinfo if { Shape[] // . insertionOffset } = newinsertionOffset.getNextRightHit(insertionOffset)..4.com 114 . newinsertionOffset != = layout.. TextHitinfo int hit = = layout. y).phương thức hitTestChar được gọi trong đối tượng TextLayout và sau đó phương thức getinsertindex được sử dụng để lấy lại khoảng chứa trống. insertindex http://tailieuhay.4 Hit Testing Lớp TextLayout cho ta một công cụ đơn giản để hit testing văn bản.vị trí hiện tại của khoảng trống chèn vào được di chuyển đến nơi tương ứng khi mà phím phải được ấn. (newinsertionOffset null) 4.Lập trình đồ họa trên Java 2D và 3D vào khi phím mũi tên phải được nhấn. draw caretShapes carets = layout.Còn phương thức getNextLeftHit cho ta thông tin như vậy khi phím mũi tên trái được nhấn. Trong ví dụ dưới đây.hitTestChar(x. Trong ví dụ dưới đây.

Các phép đo đã có sẵn trong lớp TextLayout bao gồm ascent.Đây là một cách đơn giản để hiển thị đoạn văn bản được tô sáng.Lập trình đồ họa trên Java 2D và 3D 4.Các giá trị ascent và descent của toàn bộ kiểu font được sử dụng trong đối tượng TextLayout.fill(highlightRegion). advance. Trong ví dụ dưới đây.drawString(layout. Có nhiều hơn một đối tượng Font có thể được liên kết với một đối tượng TextLayout:sự khác nhau về kiểu dáng khi thực thi có thể sử dụng các kiều font khác nhau. Shape hit2). Bạn có thể nhận một đối tượng Shape mà nó hiển thị vùng sáng từ đối tượng TextLayout. visible advance và bounding rectangle (giới hạn của khung hình chữ nhật). graphics.leading(khoảng cách giữa các dòng chữ so với dòng cơ sở).4. Đối tượng TextLayout sẽ tự động giữ ngữ cảnh trong một mảng khi tính toán số chiều của vùng được tô sáng. http://tailieuhay.6 Querying Layout Metrics Lớp TextLayout cung cấp cách truy cập đến các phép đo đồ họa cho toàn bộ dải văn bản hiển thị. 4.4.getLogicalHighlightShape(hit1.com 115 . 0).5 Đánh dấu vùng lựa chọn.Lớp TextLayout hỗ trợ cả vùng sáng logic và vùng sáng trực quan.setColor(HiGHLiGHT_COLOR).nó không có giá trị leading cực đại.Việc tính toán giá trị leading của đối tượng TextLayout thì phức tạp hơn nhiều.vùng sáng được điền với màu sáng và sau đó đối tượng TextLayout sẽ vẽ toàn bộ vùng được điền đó. 0.descent. graphics. highlightRegion = layout. graphics.

Lập trình đồ họa trên Java 2D và 3D Giá trị advance của đối tượng TextLayout chính là chiều dài của nó:đó là khoảng cách từ cạnh bên trái của nét bên trái nhất đến cạnh bên phải của nét bên phải nhất.Khung giới hạn có quan hệ với nguồn gốc của đối tượng TextLayout. 4.getWidth()+2. Rectangle2D bounds = 0. graphics.com 116 .getX()-1.getY()-1.4. Lớp TextLayout còn có thể được sử dụng để hiển thị đoạn text mà nó có nhiều dòng. Khung giới hạn của một đối tượng TextLayout bao quanh toàn bộ văn bản trong phần bố trí.(Một số trong đó có thể được lấy từ gốc hoặc gốc + advance).chồng các line của văn bản đó một bề rộng nào đó. layout.drawRect(bounds. Để làm được điều này.7 Vẽ văn bản trên nhiều dòng.bạn không phải làm trực tiếp bằng việc tạo ra nhiều đối tượng TextLayout mà bạn hiển thị mỗi dòng của văn bảnphương thức LineBreakMeasure sẽ làm điều đó cho bạn.getHeight()+2).Ví dụ như.Nó bao gồm toàn bộ các đườn nét trực quan(thấy được) và các dấu caret biên. Trong ví dụ dưới đây.Còn giá trị visible advance là chiều dài của đối tượng TextLayout mà không có các khoảng trắng. bounds.getBounds().Giá trị advance thường được chỉ định là total advance.không liên quan đến vị trí trên màn hình. graphics.và hiển thị các đoạn như nhiều dòng của văn bản. bounds. 0).. bounds.văn bản trong một đối tượng TextLayout được vẽ bên trong một khung giới hạn.Các kiểu văn bản hai chiều không thể thực hiện điều này một cách chính xác trừ khi tất cả http://tailieuhay.drawString(layout.bạn có thể lấy một đoạn của văn bản.

awt.awt. import java.event.awt. import java.Vector. import java.GraphicsEnvironment.event.awt. import java. http://tailieuhay.JApplet.Phương thức LineBreakMeasure đóng gói toàn bộ thông tin về ngữ cảnh để tạo ra các đối tượng TextLayout chính xác.awt.chiều dài của những dòng đó thường được xác định bằng chiều rộng của vùng hiển thị.Lập trình đồ họa trên Java 2D và 3D văn bản trong một đoạn đã có sẵn.Font. import java.awt. import java. import java.FontMetrics. /* * FontSelection. import java.awt.swing.BorderLayout.Color.itemListener.awt.Dimension.awt.event.awt.awt.util. import java.java * 1.Sự chia dòng(Line breaking hay line wrapping) là việc xác định nơi mà những dòng bắt đầu và kết thúc.itemEvent.Graphics. import java.0 * 12/03/06 */ import java.awt.WindowEvent. import java. import javax.event. import java. import java. Khi văn bản được hiển thị qua nhiều dòng.com 117 .Graphics2D.WindowAdapter.awt.GridLayout.

com 118 . String fontchoice = "Lựa chọn Font". int index = 0. JLabel fontLabel. */ public /** * */ private static final long serialVersionUiD = 5469031020823166920L. int stChoice = 0. import javax. JComboBox fonts. class FontSelection extends JApplet implements itemListener { http://tailieuhay.swing.JPanel.Lập trình đồ họa trên Java 2D và 3D import javax. sizeLabel. import javax. import javax. FontPanel fontC. sizes.JComboBox.swing. styles.swing.JLabel. /* * Applet nay hien thi mot xau voi lua chon cua nguoi su dung. styleLabel.swing.JFrame.

JPanel fontPanel = new JPanel(). topPanel. JPanel sizeAndStylePanel = new JPanel().WEST. GridLayout(2.add(BorderLayout. @SuppressWarnings("unchecked") public void init() { getContentPane(). JPanel topPanel = new JPanel().add(BorderLayout.setLayout(new BorderLayout()).com 119 . topPanel. sizePanel). http://tailieuhay.WEST. fontPanel).Lập trình đồ họa trên Java 2D và 3D String siChoice = "10". JPanel sizePanel = new JPanel().setLayout(new 1)). sizeAndStylePanel. JPanel stylePanel = new JPanel(). stylePanel. fontPanel.setLayout(new BorderLayout()). sizePanel.setLayout(new 1)). GridLayout(2. sizeAndStylePanel. GridLayout(2.setLayout(new 1)).setLayout(new BorderLayout()).

styleLabel. fontLabel.add(sizeLabel).deriveFont(1).add(fontLabel). http://tailieuhay.CENTER. sizePanel.setHorizontalAlignment(JLabel. fontLabel. styleLabel. topPanel). sizeLabel.setText("Kích Cỡ").add(BorderLayout. styleLabel = new JLabel().setHorizontalAlignment(JLabel. fontLabel.CENTER). fontPanel.CENTER). stylePanel).CENTER.setFont(newFont). sizeLabel = new JLabel().add(BorderLayout. styleLabel.CENTER). fontLabel = new JLabel(). sizeLabel. sizeAndStylePanel). topPanel.setText("Fonts").com 120 .setFont(newFont). Font newFont = getFont().setText("Kiểu chữ"). sizeLabel.NORTH.setHorizontalAlignment(JLabel. getContentPane().Lập trình đồ họa trên Java 2D và 3D sizeAndStylePanel.add(BorderLayout.setFont(newFont).

Lập trình đồ họa trên Java 2D và 3D stylePanel. sizePanel. Vector vector = new Vector().getAvailableFontFamilyNames(). sizes. "14". styles = new JComboBox(new Object[] { "PLAiN". styles.length. fontPanel. fonts.setMaximumRowCount(9). "16".setMaximumRowCount(9).addElement(envfonts[i]). "BOLD & iTALiC" }).add(sizes).getLocalGraphicsEnvironment(). "18" }). fontchoice = envfonts[0].setMaximumRowCount(9). http://tailieuhay. for (int i = 1.add(styleLabel). "iTALiC". "BOLD". styles. sizes. fonts.additemListener(this). String envfonts[] = gEnv.setMaximumRowCount(9). i++) { vector. sizes = new JComboBox(new Object[] gEnv = { "10". i < envfonts. } fonts = new JComboBox(vector).additemListener(this).add(fonts).com 121 . sizes. "12". GraphicsEnvironment GraphicsEnvironment .additemListener(this).

com 122 . siChoice).getStateChange() return.white). stChoice = index.SELECTED) { http://tailieuhay.getSelectedindex().setBackground(Color. } else { siChoice sizes. getContentPane(). if (list == fonts) { fontchoice fonts. } fontC.getSelecteditem(). fontC). } stChoice. fontC = new FontPanel().add(styles).changeFont(fontchoice.Lập trình đồ họa trên Java 2D và 3D stylePanel. = (String) = (String) != itemEvent. } Object list = e.getSource().getSelecteditem().add(BorderLayout.CENTER. fontC. } public void itemStateChanged(itemEvent e) { if (e. } else if (list == styles) { index = styles.

250)). fontSelection. } }). f. Font thisFont. JApplet FontSelection(). BorderLayout.getContentPane(). f.Lập trình đồ họa trên Java 2D và 3D public static void main(String s[]) { JFrame f = new JFrame("Chọn kiểu Font").com 123 .addWindowListener(new WindowAdapter() { public windowClosing(WindowEvent e) { System. public FontPanel() { fontSelection = new void http://tailieuhay. } } class FontPanel extends JPanel { /** * */ private static final long serialVersionUiD = 7850814263388447528L.exit(0).add(fontSelection.setVisible(true). f.CENTER).setSize(new Dimension(550. f.init().

int w = getWidth().drawString(change. } public String si) { integer newSize = new integer(si). } } metrics = void changeFont(String f.stringWidth(change).PLAiN. Font.paintComponent(g).darkGray).width / 2. thisFont = new Font(f. size). FontMetrics g2. } public void paintComponent(Graphics g) { super. g2.cỡ chữ và kiểu chữ. int st.Lập trình đồ họa trên Java 2D và 3D thisFont = new Font("Arial". g2. int size = newSize.setFont(thisFont). g2.setColor(Color. h / 2 . w / 2 .intValue().getHeight(). int h = getHeight().getFontMetrics(). repaint(). 10).height / 2). String change = "Chọn Font . st. Graphics2D g2 = (Graphics2D) g.". http://tailieuhay. int height = metrics. int width = metrics.com 124 .

com 125 .Lập trình đồ họa trên Java 2D và 3D Kết quả của chương trình: http://tailieuhay.

Trong chương này chúng ta tập trung vào các đối tượng và các công nghệ của model tạo ảnh mode trung gian(immediate mode). các lớp thao toán tử ảnh. các ngoại lệ (exceptions). 5.com 126 . Các lớp mode trung gian và các giao diện củan Java 2D API cuang cấp các công nghệ cho việc xử lý ánh xạ các điểm với dữ liệ của nó trong bộ nhớ. các lớp dữ liệu ảnh. các lớp model màu. các lớp model mẫu. •Model đường ống tương thích với model trung gian và sex được cài đặt đầy đủ trong bản Java Advanced imaging API sắp tới. •Model khách chủ (producer/consumer) đã hỗ trợ trong phiên bản trước củan bản JDK. •Model trung gian (immediate mode model) được giới thiệu tr ong Java™ 2 SDK release.1 Các giao diện và các lớp Các API tạo ảnh mode trung gian trong Java 2D™ API có thể được nhóm lại trong 6 Cataloge sau: Các giao diện.Lập trình đồ họa trên Java 2D và 3D Chương 5 Tạo ảnh Java 2D™ API hỗ trợ 3 model vẽ ảnh. Hàm API này hỗ trợ cho việc truy nhập dữ liệu ảnh tỏng các định dạng lưu trữ khác nhau và thao tác với dữ liệu ảnh qua vàiloại phép toán lọc. http://tailieuhay.

LookupOp và RescaleOp. LookupOp và 5. BandCombineOp.1. TileObserver Định nghĩa các đối tượng muốn được báo khi trang .1. http://tailieuhay. ColorConvertOp.Lập trình đồ họa trên Java 2D và 3D 5. ColorConvertOp. RescaleOp.com 127 .1 Các giao diện imaging (imaging interfaces) Interface BufferedImageOp Description Mô tả các thao tác vào đơn ra đơn thực hiện trên đối tượng Bufferedimage. Được cài đặt bởi RasterOp AffineTransformOp. ConvolveOp.2 Các lớp dữ liệu ảnh(image Data Classes) Clases Bufferedimage Description Mở rông image cài đặt WriteableRenderedimage Một ảnh với một bộ đệm dữ liệu có thể truy cập. ConvolveOp. RenderedImage Định nghĩa giao thức cho các đối tượng chứa hoặc có thể sản sinh dữ liệu ảnh trong kiểu WritableRenderedImag e Rasters Mở rộng Renderedimage Định nghĩa cac giao thức cho các đói tượng chứa hoặc sản sinh dữ liệu ảnh trong kiêu Raster có thể được thay đổi. thái chỉnh sủa của một WritableRenderedimage thay đổi. Định nghĩa các thao tác vào ra đơn thực hiện trên các đôi tượng Raster Được cài đặt bởi AffineTransformOp.

Một Raster chứa một DataBuffer và một SampleModel. Kernel Một ma trận mô tả cách nhập một dữ nó tác động đến giá trị liệu và các điểm biên của LookupTable của điểm trong bộ lọc ConvolveOP Mở rộng Object Một bảng ánh xạ các giá trị từ dữ liệu điểm đơn băng tới các giá trị màu. Mỗi mảng được gọi là “bank” Mở rộng DataBuffer.Lập trình đồ họa trên Java 2D và 3D Một Bufferedimage có một ColorModel và một ByteLookupTable DataBuffer DataBufferByte Raster dữ liệu ảnh. Một mảng các điểm góc từ đó bạn có thể nhận về các dữ liệu điểm. Một bộ đệm dữ liệu chứa các byte dữ liệu. Mở rộng LookupTable Một LookupTable chứa các bye dữ liệu. Bao bọc một hay nhiều các mảng dữ liệu chứa dữ liệu điểm. (đã dùng trong Java Advanced DataBufferint imaging API) Mở rộng DataBuffer (Final)) Một bộ đệm dữ liệu chứa dữ liệu số nguyên (đa DataBufferShort dùng trong Java Ađvance imaging API) Mở rộng DataBuffer (Final) Một bộ đệm dữ liệu chứa dữ liệu số nguyên short DataBufferUShort (đã dùng trong Java Advanced imanging API).com . 128 Raster ShortLookupTable WritableRaster http://tailieuhay. Mở rộng LookupTable Một bảng tham chiếu chứa các dữ liệu số nguyên short Mở rộng Raster Một Raster có thể chỉnh sửa. Mở rộng DataBuffer (Final) Một bộ đệm dữ liệu chứa dữ liệu số nguyên short không dấu.

Cài đặt BufferedimageOp. RasterOp Thực hiên sự chuyển đổi dữ liệu màu điểm theo ConvolveOp điểm trong ảnh nguồn. RasterOp Dùng một Kernel để thực hiện cải thiện ảnh nguồn. BufferedimageFilter Mở rộng imageFilter Một imageFilter cung cấp một cách đơn giản của việc sùng một BufferedimageOp(toán tử một nguồn ColorConvertOp đơn /một đích đơn) để lọc một Bufferedimage hoặc Raster.Lập trình đồ họa trên Java 2D và 3D 5.com 129 . Kernel định nghĩa một cách toán học quan hệ giữa các điểm trong quan hệ láng giềng trung gian của điểm vào và điểm ra. Cài đặt BufferedimageOp.1. Lớp này có thể thực hiện cả ánh xạ song ánh và các phép toán biến đổi BandCombineOp láng giềng gần nhất. Cài đặt RasterOp Dùng một ma trận xác định. RasterOp Một lớp định nghĩa một biến đổi affine để thực hiện một sự ánh xạ tuyến tính từ các toạ độ 2D trong một ảnh nguồn hoặc Raster sang các toạ độ 2D trong ảnh đích hoặc Raster.3 image Operation Classes Clases Description AffineTransformOp Cài đặt : BufferedimageOp. http://tailieuhay. thao tác này thực hiện một sự kết hợp tuyến tính tuỳ ý của các dải band trong một Raster. Một sự cải thiện là một sự tao tác không gian nơi các điểm cận biên vào được nhân bội bởi một giá trị Kernel để tạo giá trị của điểm ra.

các Bufferedimage.4 Sample Model Classes Clases BandedSampleModel Description Mở rộng (Final) ComponentSampleModel Cung cấp truy cập dữ liệu ảnh đã chứa giống như các mẫu đã chứa như những dải (bands) trong các bank riêng biệt của DataBuffer. thao tác tham chiếu RescaleOp trên thành phần màu và thành phần alpha. 5.1.com 130 . Cài đặt BufferedimageOp. Một điểm bao gồm ComponentSampleModel một mẫu từ mỗi dải (band) Mở rộng SampleModel Cung cấp truy cạp tới dữ liệu ảnh chứa với mỗt mẫu của môt điểm tâp trung trong mỗi phần tử riêng biệt của DataBuffer. RasterOp Thực hiện thao tác tham chiếu từ nguồn tới đích. RasterOp Thực hiện việc vẽ lại điểm bởi điểm (pixel by pixel rescaling) của dữ liệ trong ảnh nguồn bởi việc nhân mỗi giá trị điểm với hệ số và sau đó thêm vào một phần chênh (an offset). Với các Raster.Lập trình đồ họa trên Java 2D và 3D LookupOp Cài đặt BufferedimageOp. Các loại chèn điểm khác MultiPixelPackedSampleModel PixelinterleavedSampleModel nhau được hỗ trợ Mở rộng SampleModel Mở rộng ComponentSampleModel Cung cấp truy nhập tới dữ liệu ảnh đã chứa dữ liệu mẫu cho mỗi điểm trong http://tailieuhay. các thao tác tham chiếu trên các giá trị mẫu.

SinglePixelPackedSampleMode Mở rộng SampleModel l Cung cấp truy nhập tới dữ liệu ảnh đã được bảo quản với tất cả các mẫu phụ thuộc vào các điểm riêng lẻ đã gói vào trong một phần tử của một DataBuffer. Mở rộng ColorModel Một ColorModel có thể giữ một ColorSpace có thể thay đổi. Lớp này có thể được dùng để biểu diễn hầu hết các model màu trên hầu hết các loại thiết bị đồ hoạ (GraphicsDevices) ComponentColorModel http://tailieuhay. xanh lá cây. một mảng các thành phần màu ứng với ColorSpace. Color Model Classes Clases ColorModel Description Cài đặt lớp trong suốt định nghĩa các phương thức cho việc chuyển đổi từ các giá trị điểm ánh tới các thành phần màu như đỏ.com 131 . Một lớp trừu tượng định nghĩa một cơ chế cho viễc xuất ra dữ liệu mẫu từ một ảnh mà không biết cách dữ liệu được chứa trong một DataBuffer. xanh da trời (red. và tất cả các phần tử trong bank SampleModel đơn của một DataBuffer. blue). green.Lập trình đồ họa trên Java 2D và 3D các phần tử hiệu chỉnh của mảng dữ liệu.

Lập trình đồ họa trên Java 2D và 3D DirectColorModel Mở rộng lớp PackedColorModel JDK1. 132 RasterFormatException http://tailieuhay.getRGBdefault DirectColorModel.1 . 5. Một ColorModel trừu tượng biểu diễn các giá trị điểm có các thành phần nhúng trực tiếp trong các bit của mở một điểm. Model màu này tương tự với một X11 TrueColor. PackedColorModel Extends: ColorModel Mở rộng ColorModel. Một ColorModel biểu diễn các giá trị có các thành phần màu RGB đã nhúng trực tiếp trong các bit của điểm. Mở rộng RuntimException. rộng DirectColorModel indexColorModel PackedColorModel để hỗ trợ các điểm chứa SampleModel các thành phần màu RGB. RGB như một ColorModel mặc định được trả về bởi ColorModel.com .1. Một lớp trừu tượng định nghĩa một cơ chế cho viễc xuất ra dữ liệu mẫu từ một ảnh mà không biết cách dữ liệu được chứa trong một DataBuffer. Đưa ra nếu một trong các phương thức BufferedimageOp hoặc RasterOp không thể xử lý ảnh.6 Exception Classes Clases imagingOpException Description Mở rộng RuntimException.

và cung cáp một cơ chế cho http://tailieuhay. Lớp Raster cung cấp quản lý dữ liệu ảnh.2 Immediate Mode imaging Concepts Model tạo ảnh mode trung gian hỗ trợ các phân giải cố định đã chứa trong bộ nhớ. 5. Một đối tượng Bufferedimage chứa 2 đối tượng khác: một Raster và một ColorModel. Như hình 5-1.Lập trình đồ họa trên Java 2D và 3D Tạo ra nếu có một thông tin bố trí không hợp lệ trong Raster. Một Bufferimage có thể được tạo trực tiếp trong bộ nhớ và được dùng để giữ và thao tác dữ liệu ảnh đã nhận từ một file hoặc URL. Một số các lớp và các giao diện được dùng trong model này Hình 5-1 Bufferedimage và các lơp hỗ trợ. Nó biểu diễn toạ độ de-cac của ảnh và duy trì dữ liệu ảnh trong bộ nhớ. hoặc đẩy tới bất cứ đích nào khác dùng ngữ cảnh tương thích Graphics2D. Model cũng hỗ trợ các thao tác lọc trên dữ liệu ảnh. Một Bufferedimage có thể được hiển thì dùng bất cứ đối tượng Graphics2D nào cho một thiết bị màn hình.com 133 . Bufferedimage cung cấp việc quản lý ảnh chung.

một DataBuffer và một SampleModel. Các thao tác đã hỗ trợ bao gồm: • Biến đổi Affine • Amplitude scaling • Lookup-table modification • Linear combination of bands • Color conversion http://tailieuhay. Nó cũng cung cấp các phương thức cho việc truy cập các điểm xác định với một ảnh(image).Lập trình đồ họa trên Java 2D và 3D tao ảnh vớ nhiều ảnh nhỏ từ một bộ đệm dữ liệu ảnh đơn. hoặc cả hai giao diện.com 134 . Lớp SampleModel thể hiện dữ liệu trong bộ đệm và cung cấp no như các điểm riêng rẽ hoặc dải điểm chữ nhật. Một đới tượng Raster chứa hai đối tượng khác. giao diện RasterOp. Lớp DataBuffer giữ dữ liệu điểm trong bộ nhớ. lớp thao tác định nghĩa các phương thức lọc (filter) thực hiện thao tác ảnh thực sự. MỖi thao tác xử lý ảnh được nhúng trong lớp cài đặt giao diện BufferedimageOp. image Package cung cấp thêm các lớp định nghĩa các thao tác lọc trên các đối tượng Bufferedimage và Raster. Hình 5-2 minh hoạ model cơ bản cho Java 2D™ API image xử lý ảnh.

Sự phân biệt giữa thành phần(component) và mẫu(sample) là hữu ích với indexColorModel. hỗ trợ hai trong Java 2D API đang được tụ họp và thêm vào. 5.Samples: Các thành viên riêng biệt của các điểm của một ảnh. Một SampleModel cung cấp một cơ chế cho việc chuyển đổi các phần tử trong DataBuffer sang các điểm và các mẫu của nó. Ví dụ. Các mẫu .Components: Các giá trị của các điểm độc lập với sự biểu diễn màu.com 135 . Các thành phần .Lập trình đồ họa trên Java 2D và 3D • Convolution Chú ý rằng nếu bạn thích hiển thị và thao tác các ảnh. bạn chỉ cần hiểu lớp Bufferedimage và các lớp thao tác lọc. giống như tất cả các mẫu màu đỏ hoặc tất cả các mẫu màu xanh lá cây. Bố trí (layout)của các phần tử trong bộ đệm dữ liệu là độc lập với cách biểu điễn của dữ liệu như là các điểm bởi một SampleModel của ảnh. Các Data element là các thành viên riêng lẻ của một mảng DataBuffer. Dải . một điểm trong model màu RGB bao gồm 3 mẫu : red. nơi mà các thành phần điểm được đánh chỉ số sang LookupTable.2. Dữ liệu điểm có thể được chứa trong một số cách.Band: Tập tất cả các mẫu của một loại trong một ảnh. và một điểm được trang bị mọt dữ liệu mẫu từ vị trí mẫu với http://tailieuhay. nếu bạn có ý định viết các bộ lọc hoặc trực tiếp truy nhập dữ liệu ảnh. green và blue. bạn cần phải hiểu các lớp liên quan với Bufferedimage. Lưu trữ tập hợp tổ chức dữ liệu ảnh bởi các dải (bands). Mặt khác. Các mẫu của một điểm có thể biểu diễn các giá trị nguyên thuỷ trong model màu cụ thể.1 Terminology Ở đây có vài khái niệm được dùng qua các thảo luận dưới đây: Các phần tử dữ liệu-Data Elements: các loại nguyên tố dùng như là các đơn vị lưu trữ dữ liệu ảnh.

cung cấp các cách để lưu các dữ liệu điểm. và blue.1 Creating a Bufferedimage Để tạo một Bufferedimage.createimaget.width. green. Ảnh được tạo là không rõ .getWidth() { 136 != width offimg.3. và các dải bao gồm tập các mẫu cùng chỉ số vị trí trong mỗi điểm. gọi Component. Nó cũng quản lý mọt ảnh trong bộ nhớ.com height) . 5.3 Using Bufferedimages Lớp Bufferedimage là lớp chính hỗ trợ mode tạo ảnh trung gian. getSize(). biểu diễn dữ liệu điểm. 5.getHeight() http://tailieuhay. null != || offimg.Primaries: Các thành viên phân biệt của một giá trị màu trong một model màu xác định. ví dụ model RGB dạng các giá trị màu từ các nguyên tố red.Lập trình đồ họa trên Java 2D và 3D mảng đơn chứa tất cả các điểm.height. Các nguyên tố . Graphics2D width height (offimg || getSize(). public g) int int if { Graphics2D g2 = = == = createDemoGraphics2D(Graphics null. hàm này trả về mọt Bufferedimage các đặc tính vẽ của nó tương ứng các thành phần đã dùng tạo nó. và đẩy dữ liệu điểm tới một Graphics hoặc ngữ cảnh Graphics2D. phần nổi và phần nền có các màu của các thành phần bạn không thể hiệu chỉnh độ trong của một ảnh.Bạn có thể dùng kỹ thuật này khi bạn muốn làm gấp đôi bộ đêm vẽ ảnh cho sự động trong một thành phần.

g2. 0.Lập trình đồ họa trên Java 2D và 3D offimg height). width.com 137 . Java.createGraphics(). Bằng việc vẽ các hình một lần và việc sao chép nó bạn có thể hiển thị đồ hoạ nhanh hơn. Tất cả các http://tailieuhay. offimg. return } Bạn cũng có thể tạo một Bufferedimage trống trong bộ nhớ dùng một vài hàm tạo đã được cung cấp. Ví dụ. (offimg = != null) { = (Bufferedimage) createimage(width. canvas . } if g2 } // . 5..3. g2.setBackground(getBackground()). bạn có thể vẽ nó một lần trong bộ đệm offscreen và sau đó copy nó tới các vị trí khác nhau trên cửa sổ.clearRect(0..awt package có khả năng dùng các bộ đệm offsceam bởi điều này bạn vẽ một đối tượng ảnh cùng cách mà bạn vẽ ra cửa sổ.2 Drawing in an Offscreen Buffer Lớp Bufferedimage có thể đuợc đùng để chuẩn bị các phần tử đồ hoạ không hiêển thị (offscreen )sau đó copy chúng ra màn hình. nếu bạn muốn hiển thị`hình ảnh tinh vi trong vài lần. Kỹ thuật này hữu ích đặc biệt khi một graphic phức tạp hoặc dùng lặp lại. clear height).

Tương tự. Thay vào việc vẽ lại hình tại mỗi vị trí.com 138 . 5.Lập trình đồ họa trên Java 2D và 3D tính năng đẩy (rendering) ở Java 2D™ API có thể được dùng khi vẽ các ảnh offscreen. Ví dụ. Lần cuối cùng ảnh được sao chép. nó đã được biến đổi. bạn có thể dùng một bộ đệm offscreen để cung cấp sự hồi tiếp như khi người dùng di chuyển một hình dùng chuột. bạn có thể dùng một bộ đệm offscreen để vẽ một đối tượng một lần và sau đó cho nó chuyển động trong một cửa sổ. Hình 5-3Using an Offscreen Buffer Hình 5-3 mô tả cách một chương trình có thể vẽ ra một offscreen image sau đó sao chép nó ra một cửa sổ nhiều lần.3.2. Các bộ đệm offscreen thường được dùng cho hoạt hoạ.1 Creating an Offscreen Buffer http://tailieuhay. bạn có thể vẽ hình một lần ra bộ đệm offscreen và sau đó copy nó tới vị trí chuột như khi người dùng thả chuột(drag the mouse). Chú ý rằng sự biến đổi ảnh thay cho việc vẽ lại nó với sự biến đổi có thể kết quả không được thoả mãn.

sâu. image có thể được đưa tới (blitted) thiết bị đồ hoạ một cách hiệu quả.createimage. Trong http://tailieuhay. Điều này cho phép hàm drawimage làm việc nhanh chóng. và bố trí các điểm chính xác với cửa sổ trong đó bạn đang vẽ. một kênh alpha được dùng để phân biệt các vùng được vẽ và không được vẽ. Trong hình 5-3. Bạn cũng có thể tạo một đối tượng Bufferedimage trực tiếp để dùng như là một offscreen buffer. cho phép một hình dạng bất quy tắc xuất hiện qua các hình mà bạn đã vẽ (trong trường hợp này.com 139 . Điều này rất hữu ích khi bạn cần điều khiển qua kiểu của offscreen hoặc trong suốt. một hình chữ nhật bóng). Bufferedimage hỗ trợ vài kiểu định nghĩa trước: • TYPE_3BYTE_BGR • TYPE_4BYTE_ABGR • TYPE_4BYTE_ABGR_PRE • TYPE_BYTE_BiNARY • TYPE_BYTE_GRAY • TYPE_BYTE_iNDEXED • TYPE_CUSTOM • TYPE_iNT_ARGB_PRE • TYPE_iNT_ARGB • TYPE_iNT_BGR • TYPE_iNT_RGB • TYPE_USHORT_555_RGB • TYPE_USHORT_565_RGB • TYPE_iNT_GRAY Một đối tượng Bufferedimage có thể chứa một kênh alpha.Lập trình đồ họa trên Java 2D và 3D Cách đơn giản nhất để tạo ra một image mà bạn có thể dùng như một offscreen buffer là dùng phương thức Component. Bằng việc tạo một image mà không gian màu của nó.

Chú ý : trừ khi bạn cần một dữ liệu ảnh alpha cho rõ ràng. có thể gọi tát cả các phương thức Graphics2D để vẽ các hình ảnh nguyên tố. new Rectangle(dim).createGraphics().width.com 140 .Lập trình đồ họa trên Java 2D và 3D vài trường hợp khác. Bạn cũng có thể lấy về cấu hình đồ hoạ liên kết với thiết bị đồ hoạ trên đó cửa sổ tập trung để lấy thông tin. text. Dùng alpha ở nơi nó không cần làm chậm hiệu năng render. getSize(). (Bufferedimage)createimage(w. if(firstTime){ dim. và render các hình ảnh khác trong image.2. bạn có thể dùng một kênh alpha để trộn các màu của một ảnh mới vào nó trong một ảnh đã tồn tại. h). Gọi Bufferimage. bạn cần khởi tạo một đối tượng Bufferedimage thích hợp 5. như với một hình ảnh dạng bất thường biểu diễn trong hình 5-2. Đoạn code dưới đây minh hoạ sử dụng offscreen buffering : public void g2 dim update(Graphics = = g){ Graphics2D Dimension int int area bi big = = w h = = = (Graphics2D)g. GraphicsConfiguration cung cấp các phương thức thuận tiện tự động tạo các bộ đệm ảnh trong định dạng tương thích với cấu hình của bạn.2 Drawing in an Offscreen Buffer Để vẽ trong một bộ đệm ảnh. dim.height. Với đối tượng này. Kỹ thuật vẽ này hỗ trợ việc rung động và các cải thiện khác được cung cấp bởi 2D imaging package.3. tra về một đối tượng Graphics2D.createGraphics() . bi. http://tailieuhay. bạn nên tránh tạo một bộ đệm offscreem alpha.

setPaint(strokePolka).3 Manipulating Bufferedimage Data Directly Cùng với việc vẽ ảnh trực tiếp trong Bufferedimage.height). không có sự lay động khi bạn modify các http://tailieuhay.setLocation(w/2-50. image this). 0.setColor(Color.clearRect(0.setRGB để đặt trực tiếp giá trị của một điểm hoặc một mảng các điểm tới một giá trị RGB xác định. drawn. big.setStroke(new firstTime } // Clears the rectangle 0. buffered 0. BasicStroke(8.drawimage(bi.white). Bạn cũng có thể dùng phương thức Bufferedimage.Lập trình đồ họa trên Java 2D và 3D rect.0f)).draw(rect). big. the area. big. that was previously = false. h/2-25). // Draws and area. g2. } 5.setPaint(fillPolka). positioned buffer.com 141 . to the screen.fill(rect). big. // Draws the big. bạn có thể truy cập trực tiếp và xử lý dữ liệu điểm ảnh trong 2 cách. big.3. fills to newly the rectangle big. Những cách này hữu ích nếu vạn đang cài đặt giao diện bộ lọc BufferedimageOp như đã được mô tả trong chương xử lý và cải thiện ảnh. Chú ý rằng.width.

.paint. g.width 0) return. g2.5 Rendering a Bufferedimage Để render một bộ đệm ảnh vào trong một ngữ cảnh cụ thể.drawimage(offimg. Việc lọc và các lớp cung cấp giao diện lọc đã thảo luân trong phần Xử lý và cải thiện ảnh (image Processing and Enhancement). { (offimg isShowing()) 0.height (getSize().3.com 142 g2 != = (Graphics2D) null && 0. Ví dụ khi rendering trong phương thức Component. bạn gọi drawimage() trên đối tượng đồ hoạ đã truyền cho phương thức.Lập trình đồ họa trên Java 2D và 3D điểm một cách trực tiếp.3. Graphics2D if } } Chương trình ví dụ: http://tailieuhay. 5. public if <= void paint(Graphics <= 0 g) || { getSize(). this).4 Filtering a Bufferedimage Bạn có thể ứng dụng một bộ lọc cho một Bufferedimage dùng một đối tượng cài đặt BufferedimageOp. Bạn cũng có thể xử lý dữ liệu điểm ảnh bởi việc xử lý một đối tượng WritableRaster liên kết với một Bufferedimage 5. gọi hàm drawiamge của ngữ cảnh của đối tượng Graphics.

import java.com 143 . } }). add(new BSMCanvas()).awt."). Applet applet = new BufferedShapeMover().add("Center".awt. applet).*. public class BufferedShapeMover extends Applet { static protected Label label.*. f. f.exit(0).applet. import java. } public static void main(String s[]) { Frame f = new Frame("BufferedShapeMover").event. void http://tailieuhay.addWindowListener(new WindowAdapter() { public windowClosing(WindowEvent e) { System.Lập trình đồ họa trên Java 2D và 3D import java.awt.Applet. add("South". label = new Label("Đặt hình chữ nhật này xung quanh vùng frame. import java.*. public void init() { setLayout(new BorderLayout()). label).image.

init(). 250)).com 144 . f. 100. f. last_y. int last_x. } } class BSMCanvas extends Canvas implements MouseListener. Graphics2D big. 0. f.show().setSize(new Dimension(550.Lập trình đồ họa trên Java 2D và 3D applet. strokePolka. Bufferedimage bi. http://tailieuhay. boolean pressOut = false. boolean firstTime = true. TexturePaint fillPolka. public BSMCanvas() { rect = new Rectangle(0. Rectangle area. MouseMotionListener { Rectangle 50).pack().

Rectangle r = new Rectangle(0. 3.Lập trình đồ họa trên Java 2D và 3D setBackground(Color. strokePolka = new TexturePaint(bi. big. 5. 3).dispose(). big.setColor(Color. 0. addMouseListener(this).dispose(). 7.pink).com 145 .fillOval(0. 5). fillPolka = new TexturePaint(bi.x . bi = new Bufferedimage(5. http://tailieuhay.pink). r). 5). 5. 3). big. } public void mousePressed(MouseEvent e) { last_x = rect. big. 0. bi = new Bufferedimage(5. 7.e. big = bi. 7).createGraphics(). 0. Bufferedimage.setColor(Color. 0.cyan). r = new Rectangle(0. big. 3.fillOval(0. 0. addMouseMotionListener(this). big. big.fillRect(0.setColor(Color.TYPE_iNT_RGB).white). big = bi.createGraphics(). big.getX().TYPE_iNT_RGB).setColor(Color. r). big. 0. 5.fillRect(0. 7). big.cyan). 5. Bufferedimage.

y .setText("Đầu trỏ lên hình chữ nhật và kéo. } else { BufferedShapeMover.getY(). } else { BufferedShapeMover.label . e. e. pressOut = true. if (rect.com 146 . } } public void mouseDragged(MouseEvent e) { if (!pressOut) { updateLocation(e).").label tiên đặt con tiên đặt con http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D last_y = rect.setText("Đầu trỏ lên hình chữ nhật và kéo. } else { BufferedShapeMover. } } public void mouseReleased(MouseEvent e) { if (rect.").getY())) { updateLocation(e).getX().label .contains(e.e.getX().getY())) { updateLocation(e).contains(e.

Lập trình đồ họa trên Java 2D và 3D .setText("Hình nhật ở vị trí : " + rect.getY()).getX() + "" + chữ + e.com 147 .").setText("Đầu trỏ lên hình chữ nhật và kéo.getX(). if (checkRect()) { BufferedShapeMover. } else { rect.getY()). tiên đặt con http://tailieuhay. } } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void updateLocation(MouseEvent e) { rect.setLocation(last_x last_y + e. pressOut = false.label.

rect. int w = dim.createGraphics(). area = new Rectangle(dim). } repaint().label . big.Lập trình đồ họa trên Java 2D và 3D BufferedShapeMover.setLocation(w / 2 . h). } cố gắng đưa http://tailieuhay. bi = (Bufferedimage) createimage(w.setText("Đừng hình ra ngoài frame. int h = dim.width. } public void update(Graphics g) { Graphics2D g2 = (Graphics2D) g.setStroke(new BasicStroke(8.com 148 . if (firstTime) { Dimension dim = getSize(). big = bi. h / 2 25).height.50. firstTime = false.").0f)). } public void paint(Graphics g) { update(g).

height). } boolean checkRect() { if (area == null) { return false.x < 0) { new_x = -1.height) { (area. } int new_x = rect.Lập trình đồ họa trên Java 2D và 3D big. g2.drawimage(bi.99. big.y.draw(rect).setPaint(strokePolka).y. 0.x.y + 50) > area.x + 100) > area. big. area. if ((rect. big. } if ((rect. area.width.x.white).setColor(Color. } if 50)) { return true.fill(rect). 100. big.com 149 . int new_y = rect.contains(rect. big. rect.width . 0.setPaint(fillPolka).clearRect(0. http://tailieuhay. this). 0. } if (rect.width) { new_x = area.

và gốc toạ độ.độ rộng .Lập trình đồ họa trên Java 2D và 3D new_y = area. 5. Bạn cũng có thể dùng các bộ sản sinh này khi cài đặt các lớp bộ lọc RasterOp. Lớp Raster định nghĩa các trường cho toạ độ hệ thống của ảnh. http://tailieuhay. } } 5. Một đối tượng Raster tự nó dùng 2 đối tượng để quản lý dữ liệu điểm.49. return false.1 Creating a Raster Trong hầu hết các trường hợp.4 Managing and Manipulating Rasters Một đối tượng Bufferedimage dùng một Raster để quản lý mảng dữ liệu điểm 2 chiều. bởi vì một Raster được cung cấp với bất cứ Bufferedimage bạn tạo trong bộ nhớ.setLocation(new_x. độ cao. Lớp Raster cung cấp một số sản sinh (factory) hàm tĩnh cho tạo ra các Raster với DataBuffers và SampleModels bạn xác định.y < 0) { new_y = -1. } if (rect. không cần phải tạo một Raster trực tiếp. } rect. DataBuffer là đối tượng lưu giữ dữ liệu điểm cho raster cung cấp sự biểu diễn bên trong của dữ liệu điểm từ DataBuffer.com 150 . Tuy nhiên. một trong những hàm khởi tạo của Bufferedimage cho phép tạo một Raster bởi truyền vào trong một WritableRaster. new_y). một DataBuffer và một SampleModel.height .4.

dùng phương thức Raster. Phương thức Raster. xác định vùng của cha của nó mà nó chiếm và xác định offset của nó từ góc toạ độ của cha. Các đối tượng này cung cấp thêm các cách truy cập và biểu diễn dữ liệu điểm của Raster. Các phương thức Raster. Raster liên kết với một Bufferedimage thực ra là một http://tailieuhay. Một con xác định cha của nó qua bằng hàm getParent().4. Cha và các con của nó tham chiếu tới cùng một bộ đệm dữ liệu. Phương thức getSamples trả về một dải (band) cho một vùng cụ thể của một image. Operations on a Raster Lớp Raster định nghĩa một số cách để truy cập trực tiếp các điểm và dữ liệu điểm. Điều này có thể cải tiến hiệu quả lưu trữ bằng việc cho phép tạo bất kỳ số bộ đệm ảnh từ cùng một cha. Các phương thức Raster. Cũng có thể truy cập dữ bộ đệm và model mẫu qua các biến thể nghiệm (instance variables) của lớp Raster . Để tạo ra một Raster con (subraster). nó cung cấp bộ lọc cấp và xử lý dữ liệu của ảnh. và mỗi con có một (độ lệch) offset xách định và danh giới chỉ định tới vị trí ảnh của nó trong bộ đệm.getSample() trả về mẫu của một điểm cụ thể.getPixel cho phép lấy về một điểm riêng biệt.2 Parent and Child Rasters Lớp Raster kết hợp ý tưởng các raster cha và con.Lập trình đồ họa trên Java 2D và 3D 5.4.createSubRaster. nó trả về như là một mẫu riêng biệt trong một mảng. Điều đó rất hữu ích khi khi bạn cài đặt giao diện RasterOp.4 The WritableRaster Subclass Lớp con WritableRaster cung cáp các phương thức để đặt dữ liệu điểm và các mẫu. 5. Cùng với các phương thức đó.com 151 . hoặc khi cài đặt bất cứ một phương thức nào mà cần thực hiện xử lý điểm ở mức thấp. Khi tạo một subraster.getDataElements trả về một phần tử thực thi cụ thể của diễn dữ liệu ảnh không thể hiện từ DataBuffer.

Khi bạn tạo một Raster trực tiếp hoặc qua các hàm tạo Bufferedimage. cùng với một SampleModel cho dữ liệu ảnh. Các thông tin đó cũng được dùng để tạo một DataBuffer với dữ liệu và kiểu và kích thước phù hợp.Lập trình đồ họa trên Java 2D và 3D WritableRaster vì cung cấp truy cập đầy đủ để xử lý dữ liệu điểm của nó. 5.com 152 . Các lớp con SampleModel cũng có khả năng cài đặt ánh xạ và cung cấp cách để lấy các điểm xác định từ một DataBuffer cụ thể. http://tailieuhay. Có 3 lớp con của DataBuffer. mỗi lớp biểu diễn một loại khác nhau của một phần tử dữ liệu: • DataBufferByte (represents 8-bit values) • DataBufferint (represents 32-bit values) • DataBufferShort (represents 16-bit values) • DataBufferUShort (represents unsigned short values) Như đã định nghĩa từ trước. bạn xác định độ rộng và chiều cao trong các pixel.5 Image Data and DataBuffers DataBuffer phụ thuộc vào một Raster biểu diễn một mảng các dữ liệu ảnh. Các hàm tạo DataBuffer cung cấp các cách để tạo các bộ đệm với một cỡ xác định và một số các bank xác định. Bạn có thể truy cập dữ liệu của một ảnh trong DataBuffer một cách trực tiếp. và các thành phần hoặc các mẫu là các giá trị rời rạc kết hợp với nhau tạo nên một điểm. bạn cũng dễ dàng và thuận tiện làm điều đó hơn qua các phương thức của các lớp Raster và WritableRaster. Có nhiều cách ánh xạ giữa kiểu của phần tử trong một DataBuffer và kiểu của điểm được biểu diễn bởi một SampleModel. các phần tử là các thành phần rời rạc của mảng dữ liệu bộ đệm.

image package cung cấp năm loại model mẫu: • ComponentSampleModel— Được dùng để extract các điểm từ các image chứa các mẫu dữ liệu trong các phần tử mảng dữ liệu riêng trong một bank của một DataBuffer • BandedSampleModel— Được dùng để extract các điểm từ các image chứa mỗi mẫu trong một phần tử dữ liệu riêng với các band chứa trong một dãy các phần tử dữ liệu. Dữ liệu điểm được biểu diễn bởi SampleModel có hoặc không thể liên quan trực tiếp tới một dữ liệu màu biểu diễn một model màu cụ thể.awt.6 Extracting Pixel Data from a SampleModel Lớp trừu tượng SampleModel định nghĩa các phương thức cho extracting các mẫu của một ảnh mà không cần biết cách dữ liệu được lưu trữ ở bên dưới. Các phương thức SampleModel cung cấp dữ liệu ảnh như tập(collection) các điểm.Lập trình đồ họa trên Java 2D và 3D 5. với mỗi điểm bao gồm có một số các mẫu hoặc các thành phần. và cho việc mô tả số lượng các band và kiểu dữ liệu đệm.com 153 . • PixelinterleavedSampleModel— Được dùng để extract các điểm từ các image chứa mỗi sample trong một phần tử riêng vói các điểm được lưu trong một dãy tuân tự (sequence) của các phần tử dữ liệu. • MultiPixelPackedSampleModel— Được dùng để extract các điểm từ các iamge đơn band chứa nhiều mẫu một các điểm trong một phần tử dữ liệu( used to extract pixels from single banded images that store multiple one-sample pixels in one data element ). Lớp cung cấp các trường cho việc ghi lại chiều cao và chiều rộng cả dữ liệu ảnh trong DataBuffer liên kêt nó . • SinglePixelPackedSampleModel—used to extract samples from images that store sample data for a single pixel in one data array element in the first bank of a DataBuffer. java. http://tailieuhay.

Trong dữ liệu ảnh từ một thiết bị ảnh y tế. lớp Bufferedimage bao gồm một ColorModel cho biểu diễn dữ liệu như các giá trị điểm màu. • ComponentColorModel—một ColorModel có thể handle một ColorSpace thay đổi và một mảng các thành phần màu tương ứng với ColorSpace. các mẫu có thể biểu diễn dữ liệu RGB. DirectColorModel model tương tự với một X11 TrueColor visual. • indexColorModel— Một ColorModel biểu diễn các giá trị màu vào trong bản đồ màu trong không gian màu sRGB. DirectColorModel là một lớp con (subclass) của PackedColorModel. với mỗi đầu vào cho mỗi mẫu.Lập trình đồ họa trên Java 2D và 3D phụ thuộc vào dữ liệu nguồn.awt. Ví dụ. Các phương thức getDataElement cung cấp truy cập tới dữ liệu thô. Lớp trừu tượng ColorModel định nghĩa các phương thức cho việc đặt các điểm của image một giá trị màu trong ColorSpace liên kết với nó. trong dữ liệu ảnh đồ hoạ photo. 5. các mẫu có thể biểu diễn các loại dữ liệu khác nhau giông như nhiệt độ hoặc mật độ xương.com 154 . • DirectColorModel—một ColorModel biểu diễn các giá trị điểm có các thành phần màu RGB được nhúng trực tiếp trong các bit của điêm.image cung cấp bốn loại model màu: • PackedColorModel— Một ColorModel trừu tượng biểu diễn các giá trị điểm có các thành phần màu được nhúng trực tiếp trong các bit của một điểm nguyên. không thể hiện được chứa trong DataBuffer. http://tailieuhay.7 ColorModels and Color Data Cùng với Raster cho quản lý dữ liệu ảnh. Các phương thức getPixel trả về cả một điểm trong một mảng. Các phương thức getSample cung cấp truy nhập tới các thành phần điểm cho một band xác định. Gói java. Có ba category của các phương thức cho truy cập dữ liệu ảnh.

một thao tác làm bóng . ví dụ. and color correct images). SampleModel cung cấp ColorModel cho điểm.1 Lookup Table Một bảng tham chiếu (lookup table) chứa dữ liệu cho một hoặc nhiều kênh hoặc các thành phần. 5. G và B.( blur. http://tailieuhay. Các lớp này có thể được dùng để biến đổi hình học. ColorModel sau đó biểu diễn như một màu. BandCombineOp. thiện độ tương phản. ngưỡng. Các lớp cài đặt những giao diện này bao gồm AffineTransformOp.com 155 .8 image Processing and Enhancement Image package cung cấp một cặp giao diện định nghĩa các thao tác trên Bufferedimage và Raster : BufferedimageOP và RasterOp.thay đổi tăng cường độ trong một ảnh.image định nghĩa 2 kiểu bảng tham chiếu mở rộng lớp LookupTable trừu tượng.Lập trình đồ họa trên Java 2D và 3D Dựa trên dữ liệu trong DataBuffer. các mảng riêng R. cho phép viewer để phân biệt chi tiết hơn. làm sắc. sharpen. ConvolveOp. Phát hiện biên được dùng tăng độ tương phản giữa cấu trúc kề trong một ảnh. RescaleOp. làm mờ. một chứa byte dữ liệu và một chứa short data (ByteLookupTable and ShortLookupData). 5. enhance contrast. LookupOp. threshold.7. ColorConvertOp. và làm đúng màu. Phát hiện biên thường được dùng trong xử lý ảnh y tế và các ứng dụng bản đồ.awt. Goi java. Hình 5-4 minh hoạ phát hiện biên và cải thiện .

TYPE_iNT_RGB).0f. Hình 5 -5 demo xử lý bảng tham chiếu. 0. Xử lý bảng tham chiếu có thể được dùng để thay cho các thành phần riêng lẻ của một điểm.0f.. Bufferedimage Kernel kernel = new = bimg Kernel(3.0f. ConvolveOp cop ConvolveOp(kernel. -1. . 0. = { 0.bimg).Lập trình đồ họa trên Java 2D và 3D Figure 5-4 Phát hiện biên và cải thiện ảnh Đoạn code sau đây minh hoạ phát hiện biên: float[] -1.com 156 . ConvolveOp. 0..0f. new elements).EDGE_NO_OP.bh. elements 4.f.0f. new = 3.0f}.0f. cop. -1. null). -1. Hình 5-5 Xử lý Lookup-Table Đoạn code sau demo thao tác Lookup-table: http://tailieuhay.0f.Bufferedimage. Bufferedimage(bw.filter(bi.

đưa ra chi tiết trong các vùng tự nhiên hoặc phẳng. null). blut=new ByteLookupTable(0. Rescaling có thể được dùng để tăng dải động của các ảnh tự nhiên khác. Hình 5-6 Rescaling Đoạn Code dưới đây minh hoạ rescaling: http://tailieuhay.com 157 . = new byte[256].filter(bi. Rescaling có thể tăng hoặc giảm cường độ của tất cả các điểm. reverse[j]=(byte)(256-j). lop. Hình 5-6 minh hoạ rescaling. j++){ j<200.Lập trình đồ họa trên Java 2D và 3D byte for } reverse[] (int j=0. LookupOp lop = new LookupOp(blut. ByteLookupTable reverse).bimg).

0f. = array i < with 9.0f. nine { equal elements weight = 1. http://tailieuhay.5f.bimg).8. mỗi điểm tỏng ảnh nguồn được làm cân bằng với 8 điểm xung quanh nó.Lập trình đồ họa trên Java 2D và 3D RescaleOp null). float float[] 2D // for } array fill (i = the 0. Đoạn mã sau minh hoạ cách dùng một trong các lớp xử lý hình ảnh. rop. // create elements i++) elements[i] weight.1 Using an image Processing Operation Convolution là quá trình bên dưới hầu hết các thoật toán lọc không gian. Trong ví dụ này. 1. lớp ConvolveOp.com 158 . Convolution la quá trình đánh giá (weighting) hoặc làm đều (averaging) giá trị của mỗi điểm trong một ảnh với các gía trị điểm lân cận. = new float[9].filter(bi. Điều này cho phép mỗi điểm ra được đạt bởi lân cận trung gian trong cách màd có thể được xác định với một nhân (kernel) Hình 5 -7 minh hoạ Convolution rop = new RescaleOp(1.0f/9. 5.

= 3. các phương thức chính của lớp ConvolveOp đặt giá trị của mỗi điểm trong ảnh đích bởi việc bằng giá trị trung bình của 8 điểm xung quanh điểm tương ứng với nó trong ảnh nguồn. http://tailieuhay.com 159 .filter(sourceimage. Khi bạn gọi filter. // of blur sourceimage Bufferedimage destimage) // the image and destimage are instances simpleBlur. Nhân convolution trong ví dụ này có thể được biểu diễn bởi ma trận dưới đây. Giả định rằng sourceimage và destimage là 2 thể nghiệm của Bufferedimage. new of elements as argument create private public Kernel elements). ConvolveOp simpleBlur ConvolveOp(myKernel). giá trị của mỗi điểm trong ảnh đích được tính toán bới việc dùng một nhân như là một tập với trung bình của các giá trị xung quanh mỗi điểm tương ứng trong ảnh nguồn. Việc xử lý này được thực hiện dựa trên mỗi kênh của ảnh.Lập trình đồ họa trên Java 2D và 3D // to use the a array Kernel myKernel = new Kernel(3. với các phần tử đã xác định tới 4 phần: Khi một ảnh được vonvolved. Biến simpleBlur chứa một thể nghiệm mới của ConvolveOP cài đặt toán tử blur trên một Bufferedimage hoặc một Raster.

radial blur. Với nhiều bộ lọc đơn giản. 160 http://tailieuhay. Giá trị của điểm đích tỏng tổng các kết quả của trọng số trong nhân được nhân với giá trị của các điểm nguồn tương ứng. và motion blur). và smoothing Hình 5-8 minh hoạ sharpening dùng Convolution.0f. Đối tượng Kernel.0f. xác định kiểu bộ lọc nó thực thi. sharpening. -1. kernel là một ma trận vuông Convolution kernel trong ví dụ này liên quan đơn giản. Bởi việc đặt các gía trị khác. bạn có thể thực hiện các kiểu convolution khác nhau bao gồm blurring (như Gaussian blur. Nó đo (weights) mỗi điểm từ hình ảnh nguồn bởi chọn một nhân đo (weights) ảnh nguồn ở mức cao hơn hoặc thấp hơn. Mỗi giá trị tỏng nhân được tied tới các vị trí trong hình ảnh.Lập trình đồ họa trên Java 2D và 3D Công thức sau biểu diễn cách các trọng số trong nhân được liên hệ với các điểm trong ảnh nguồn khi thực hiện convolution.com . một chương trình có thể tăng hoặc giảm cường độ của ảnh đích. được đặt trong khởi tạo của ConvolveOP . Hình 5-8 Sharpening with Convolution Đoạn code dưới đây minh hoạ sharpening với float[] elements = { 0. 0.0f.

new ConvolveOp(kernel. Kernel kernel = new = Kernel(3.bimg).0f }. -1. 0.EDGE_NO_OP.0f. cop ConvolveOp. cop. . -1.Lập trình đồ họa trên Java 2D và 3D -1. ConvolveOp null).0f.f. 5.0f.elements).com 161 .filter(bi. http://tailieuhay.0f..3.. 0.

Một Color là một màu cố định đa được xác định trong định nghĩa của các thành phần của nó trong một ColorSpace cụ thể.Lập trình đồ họa trên Java 2D và 3D Chương 6 Mầu sắc Vẽ ảnh màu là một trong những thành phần nền tảng của các hệ thống đồ họa và nó luôn là nguồn gốc của sự phức tạp trong những ô hình tạo ảnh. Lớp ColorSoace chứa các phương thức cho chuyển đổi các không gian màu và hai không gian màu chuẩn là CiEYZ và GRB.. Một ColorSpace biểu diễn cho một hệ thông cho việc định lượng màu. chẳng hạn màu đỏ. Để vẽ một Shape với một màu.image http://tailieuhay. Color được đinh nghĩa trong java.awt. ColorModel được định nghĩa trong java. Tiêu biểu như biểu diễn bằng 3 giá trị số(RGB) họăc các thành phần. ColorModel đựoc hệ tiêu biểu với một image hoặc một Bộ đệm hình ảnh(Bufferimage) và cung cấp thông tin cần thiêt thíc hợp để biểu diễn các gía trị đỉêm.com 162 .Thư viện Java 2D™ API cung cấp Sự hỗ trợ cho sự tạo ảnh màu chất lượng cao nhưng lại dễ dàng sử dụng Các lớp quản lý màu trong Java 2D API gôm CorlorSpace. Color. bạn phải truyền mọt đối tượngc Color bỉêu diễn màu với ngữ cảnh đồ hoạ 2D.ColorModel miêu tả một cách cụ thể những điểm được ánh xạ tới các màu.awt.

http://tailieuhay.1 Các lớp Clases ColorSpace Description Identifies the color space of a Color object. Extends: ICC_Profile A representation of color space type gray. Một ColorModel được sử dụng để biểu diễn một dữ liệu diểm trong ảnh. or GraphicsDevice.Lập trình đồ họa trên Java 2D và 3D 6. Điều này bao gồm cả ánh xạ các thành phần trong những dải(bands) của một ảnh tới các thành phần của một không gian màu cụ thể.com 163 .2 Những định nghĩa về mầu sắc. A representation of color profile data for device independent and device dependent color spaces based on the ICC Profile ICC_ProfileGray ICC_ProfileRGB Format Specification. Extends: ColorSpace Represents device-independent and devicedependent color spaces based on the ICC ICC_Profile Profile Format Specification. Image. BufferedImage. Has methods to transform between RGB and ICC_ColorSpace CIEXYZ color spaces. ColorModel liên hệ với một ảnh sẽ đóng gói dữ liệu và các phương thức cần thiết cho việc chuyển đổi giá trị điểm tới và từ các đơn vị thành phần màu. Extends: ICC_Profile A representation of color space type RGB. 6. và chuyển dữ liệu điểm qua một bảng tham chiếu(lookup table) Để xác định được giá trị màu của một điểm cụ thể trong ảnh bạn phải biết các mã hoá thông tin cho mỗi điểm. Nó có thể cũng bao hàm cả xuất các thành phần điểm từ một dữ liệu diểm dóng gói hay nhận về nhiều thành phần từ một dải đơn bằng sử dụng các mặt nạ.

1 Không gian mầu Đối tượng ColorSpace biểu diễn một hệ thống cho việc định lượng các màu. Tất cả đối tượng ColorSpace phải có thể ánh xạ một màu từ không gian biểu diễn sang sRGB và chuyển đổi một màu sRGB sang không gian biểu diễn màu đó. Vì mỗi Color chứa một đối tượng ColorSpace đặt tường minh hoặc mặc định. PackedColorModel là lớp cơ sở cho các model biểu diễn giá trị điểm bao gồm các thành phần màu nhúng trực tiếp trong các bit của một điểm nguyên.Lập trình đồ họa trên Java 2D và 3D Java 2D™ API cung cấp 2 color model va thêm vào DirectColor – Model và indexColorModel được định nghĩa trong JDK 1. mỗi Color cũng có thể chuyển từ sRGB. ĐirectColorModel trong JDK 1.1 release la một PackedColorModel. ColorSpace cung cấp các phương thức chuyển đổi các màu trong không gian xác định tới và từ RGB và tới và từ không gian CiEXYZ.1 release. Model này có thể sử dụng để biểu diễn hầu hết các model màu trến hầu hết các loại Thiết bị đồ hoạ(GrphicsDevices ).Ví dụ RGB. CMYK là các không gian màu. hoặc một GraphicsConfiguration. Một đối tượng ColorSpace dùng như là thẻ một colorspace xác định không gian màu cụ thể của đối tưọng màu hoặc qua một đối tượng ColorModel .(ColorSpace). Mỗi GraphicsConfiguration dược liên hệ với một đối tượng ColorSpace khi có được liên hệ với ColorSpace. PackedColorModel chứa cac thông tin gói mô tả cách các thành phần màu và alpha được xuất ra từ một kênh. Một màu được xác định trong bất cứ http://tailieuhay.2.: ComponentColorModel co thể giữ một ColorSpace không hạn chế và một mảng thành phần màu ứng với ColorSpace.com 164 . 6. một Bufferedimage. tiêu biểu như việc sử dụng 3 giá trị số riêng biệt. của một imae .

toRGB chuyển một Color trong không gian màu tới một màu trong sRGB fromRGB nhận một màu trong sRGB và chuyển nó sang không gian mầu Mặc dù việc ánh xạ qua sRGB luôn thực hiện nhưng nó không luôn luôn la pháp tốt nhất.( Xem ColorConvertOp trong imaging trang 67) Hình 6-1 và 6-2 minh hoạ quá trình translating một màu được xác định trong không gian màu CMYK để hiển thị trên màn hình RGB. Tất nhiên. Hình 6-1 biểu diễn mapping qua sRGB. Những điêm màu sẽ không được http://tailieuhay.com 165 . thao tác trên toàn ảnh. sRGB không thể biểu diễn mọi màu trong cả giải màu CiEXYZ. như CiEXYZX Các phương thức toCiEXYZ và fromCiEXYZ ánh xạ giá trị màu từ không gian màu tới không gian khác (CiEXYZ).Tuy nhiên cũng hi vọng rằng cài đặt Java 2D API se bổ trợ cho chuyển đổi với hiệu năng cao dựa trên hệ thông quản lý màu. Các phương thức được dùng cho quá trình này là toRGB() và fromRGB(). để giải quyết vấn đề này. sự chuyển đổi của màu CMYK sang màu RGB không chính xác bởi sự không tương ứng hoàn toàn. Như hình minh hoạ. Nếu một màu đựơc xác định trong một vài không gian có giải phổ màu khác nhau hơn sRGB Thì việc sử dụng sRGB như là một không gian trung gian và ở đó bị mất thông tin. những màu được sử dụng trong các này mang tính chất biểu đồ minh hoạ và không chính xác. lớp ColorSpace có thể ánh xạ các màu tới và từ không gian màu khác . với một Color một lúc.Lập trình đồ họa trên Java 2D và 3D không gian màu nào cung có thể hiển thị được bởi bất cứ thiết bị nào bởi việc ánh xạ nó tới sRGB như một không gian màu trung gian. Các phương thức này bổ trợ chuyển đổi giữa hai không gian màu bất kỳ với mật độ và cấp độ cao. Ví dụ.

Tiêu http://tailieuhay. ColorSpace la thực ra là một lớp trừu tượng.Lập trình đồ họa trên Java 2D và 3D ánh xạ đúng giữa các không gian màu trừ khi có một sự chuyển đổi không gian phù hợp được sử dụng. màu được chuyển qua một cách đứng đắn. Bạn có thể định nghĩa lớp con của bạn để biểu diễn các không gian màu chuyển đổi miễn là các phương thức được thảo luận trên được cài đặt. Hình 6-2 biểu diễn cùng quá trình sử dụng CiEXYZ như là không gian màu chuyển đổi. Tuy nhiên hầu hết các developers có thể sử dụng một cách đơn giản lớp ColorSpace mặc định hoặc các không gian màu được biểu diễn bởi các iCC Profiles thông thường. ColorSpace trong trang 90 miêu tả cách đối tượng ColorSpace biểu diễn một không gian màu và biểu diễn các màu trong không gian màu có thể ánh xạ tới và từ một không gian chuyển đổi. hoặc thông tin được nhứng trong dữ liệu ảnh. Java 2D API cung cấp sự cài đặt iCC_Profile lớp dựa trên dữ liệu iCC Profile như được biểu diễn bởi lớp iCC_Profile. Các hệ thống quản lý màu thường được sử dụng để giữ ánh xạ giữa các không gian màu. giống như các thông tin cho màn hình và máy in. Khi CiEXYZ được sử dụng.com 166 .

một thể nghiệm của Color chứa giá trị các thành phần màu và một đối tượng ColorSpace. Lớp Color có một số phương thức bổ trợ cho không gian màu chuẩn RGB được gọi là sRGB(tham khảo http:// www.1 Biểu diễn màu Lớp Color cung cấp sự mô tả màu trong không gian màu cụ thể. và định nghĩa cách ánh xạ giữ chúng.html). Các đối tượng iCC_ColorSpace có thể được khởi tạo từ các iCC_Profile. iCC profiles mô tả một không gian vào và không gian kết nối. org/pub/www/Graphics/color/sRGB. W3.(Có một số giới hạn – không phải tất cả các iCC Profile là thích hợp cho việc định nghĩa một iCC_ColorSpace)iCC_Profile có vài lớp con tương ứng với các loại không gian màu như iCC_ProfileRGB và iCC_ProfileGray. Hệ thống quản lý màu rất tốt ở việc chỉ ra cách ánh xạ một màu được gắn với một profile vào trong không gian màu của một profile khác.Lập trình đồ họa trên Java 2D và 3D biểu như hệ thông quản lý màu (CMS) quản lý các thông tin iCC (iCC profiles) nó giông như đối tượng ColorSpace. màn hình. Bởi một đối tượng ColorSpace có thể được xác định thêm vào các thành phần màu khi một thể nghiệm mới của mà được tạo ra nên lớp Color có thể giữ các màu trong bất cứ không gian màu nào. Vai hàm khởi tạo được định nghĩa bởi lớp Color http://tailieuhay.máy in. Mỗi lớp con của nó có một không gian vào được định nghĩa thích hợp(giông như không gian RGB) và không gian kết nối thích hợp (không gian CiEXYZ). Java 2D API định nghĩa một lớp gọi là iCC_Profile giữ dữ liệu cho một bộ chuyển đổi iCC profile. iCC_ColorSpace là một sự cài đặt của lớp trừu tượng ColorSpace. Cũng có thể sử dụng CMS để tìm sự ánh xạ tốt nhất giữa các profiles 6.com 167 . sRGB la không gian màu mặc định cho Java 2D API. Java 2D API có thể sử dụng hệ thông nền CMS (platform’s CMS ) để truy nhập các thông tin màu co nhiều loại thiết bị đa dạng giông như scanner .2.

Lóp ColorSpace định nghĩa các phương thức toRGB và frỏmGB làm cho các developers có thể nhận các màu một cách đễ dàng trong không gian chuẩn này. Để hiển thị một hình chữ nhật đúng màu giống như màu cyan. magenta. yellow. ví dụ một màu có thể được mô tả bằng một tập hợp các thành phần (RGB) đỏ(red). xanh lá cây(green). bạn cần một cách để mô tả màu này cho hệ thống. và sử dụng thể nghiệm mặc định của ColorSpace để biểu diễn cho không gian đó. black để tạo ra màu trên trang giây in . (xem ColorSpace trang 90 ) Để tạo ra một màu (color) trong một không gian màu không phải là sRGB. Các kỹ thuật khác nhau này cho việc xác định màu được gọi là các không gian màu (color spaces). Magenta. xanh lá cây (Green). quá trình in 4 màu dùng cyan. Tương tự. Các phương thức này không mong đợi sử dụng cho màu với độ chính xác cao hay việc chuyển đổi. Như bạn biết. các màu trên một màn hình máy tình được tạo bởi sự pha trộn lượng khác nhau của ba thành phần đỏ (Red). Nhiều ứng dụng chủ yếu tập trung vào anh RGB và màn hình và việc định nghĩa không gian màu RGB lam cho việc viết chúng dễ dàng hơn.com 168 . xanh da trời(blue) hay tập hợp các thành phần(CMYK) Cyan. Có một số cách khác nhau để mô tả một màu. Các khởi tạo này mặc định rằng giá trị màu RGB được định nghĩa trong sRGB. Yellow. http://tailieuhay. Vì thế nên dùng không gian màu RGB làm chuẩn cho vẽ ảnh trên man hình máy tính. ban dùng hàm tạo Color với đối tượng ColorSpace và một mảng so thực biểu diễn các thành phần màu tương ứng với không gian đó.các màu in được xác định bằng tỉ lệ phần trăm trong không gian màu CMYK.Lập trình đồ họa trên Java 2D và 3D cho phép bỏ qua tham số ColorSpace. Đối tượng ColorSpace xác định không gian màu. không phải là tham chiếu không gian màu cho sự chuyển đổi màu. xanh da trời (Blue). Java 2D API dùng sRGB tạo thuận lơi cho các lập trình viên lập trình ứng dụng. Black .

Lập trình đồ họa trên Java 2D và 3D Để thích hợp vơi sự phổ biến của cả màn hình và máy in màu. cả 2 loại không gian màu có một hạn chế là phụ thuộc thiết bị. một màu biểu diễn bằng một màu RGB có thể trông giông màu xanh da trời (blue) trên một màn hình và màu đỏ tía (purplish) trên một màn hình khác . Tương tự. Một cách để ánh xạ giữa các không gian màu là thêm thông tin vào cách không gian phụ thuộc thiết bị liên hệ với không gian độc lập thiết bị. Không gian RGB hoặc không gian CMYK có thể liên hệ với nhau qua không màu gian độc lập thiết bị Các chuẩn cho việc xác đinh màu độc lập thiết bị đã được định nghĩa bởi international Commission on illumination (CiE). không phải lúc nào cũng dùng không gian màu CiEXYZ. Tương tự. cần biểu diễn chác không gian RGB liên hệ vớ không gian độc lập thiết bị giống như CiEXYZ. Color profile thường sử dụng là iCC Color Profile. có một số lý do cho việc biểu diễn màu trong các không gian màu khác. được định nghĩa bởi international Color http://tailieuhay. bạn được cách ly với độc lập thiết bị. Không gian màu độc lập thiết bị thường đựơc dùng nhất là không gian 3 thành phần màu (three-component XYZ ) được phát triển bởi CiE.com 169 . Tuy nhiên. Khi bạn xác định một màu dùng CiEXYZ. Mapping Colors qua sRGB và CiEXYZ Java 2D API dùng RGB và CMYK la 2 loại không gian màu. Những thông tin thêm này được gọi là profile. Một model màn hình phôt pho cụ thể xác định một không gian màu RGB của nó. môt model máy in cũng có không gian CMYK của nó. mực cẩm thạch(cyan) được sử dụng bởi một máy in có thể không tương ứng với mực cyan của một máy in khác. Thật không may mắn. Không gian khác nhau . Để đạt được kết quả ổn định khi một màu đựơc biểu diễn dung không gian phụ thuộc thiết bị như không gian RGB. cả hai không gian màu RGB và CMYK được dùng để biểu diễn màu.

Lập trình đồ họa trên Java 2D và 3D Consortium. sự chuyển đổi được dùng để xác định toạ độ trong không gian http://tailieuhay. Việc đạt được màu ổn định và chính xác yêu cầu cả màu vào và thiết bị ra đưa thêm thông tin trở lại cho không gian màu chuẩn. như màn hình và máy in. một màu vào có thể ánh xạ từ không gian màu gốc của nó sang không gian màu độc lập thiết bị chuẩn. Trong nhiều khía cạnh. Ví dụ.color. Một profile được liên kết với mỗi thiết bị ra để mô tả cách các màu cần được chuyển đổi để tạo ra kết quả chính xác.com 170 . Như bạn thấy trong 6-3 cả màu vào và ảnh có các profile được gắn vào. Các thiết bị này có các đặc tính tạo ảnh của nó đảm bảo rằng kết quả tạo ra là chính xác. Cả 2 trường hợp. Chi tiết xem iCC Color Format Specification. và sau đó từ không gian đó sang không gian màu thiết bị ra. sự chuyển đổi màu bắt chước sự chuyển đổi của đối tượng đồ hoạ trong không gian toạ độ x. Khi API có một màu xác định một cách chính xác. Org. y. Hình 6-3 minh hoạ một màu đơn (Solid color) và một ảnh quét được truyền cho Java 2D API và cách chúng hiển thị bởi các thiết bị ra đa dạng. nó phải tạo lại màu trên thiết bị ra.4 trên trang http:// www. phiên bản 3.

thứ tự in. cả Windows và Solaris. Các hàm điều khiển các hàm tài liệu đa hợp như so sánh mềm. 7. bao gồm đồ hoạ đa hợp (composited graphics) và hình ảnh. Điều này bao gồm máy in đã được gắn trực tiếp với máy tính cũng như với platform software cho phép truy cập sử dụng các giao thức in qua mạng. Các hàm in xác định trợ giúp như in duplex (duplex printing) và stapling. 2.com 171 .1 Các giao diện và các lớp http://tailieuhay. In với AWT và đồ hoạ Java 2D™ . 4. In với tất cả các platform. Nhưng API sẽ được mở rộng để bộ trợ cho tất cả các thuộc tính này ở các bản release trong tương lai. Không phải tất cả các tính năng đó được bổ trợ và được cài đặt trong in ấn với Java™ 2 SDK API. 3. và booklet printing. Chương 7 In ấn Java Printing API cho phép ứng dụng cho: 1.Lập trình đồ họa trên Java 2D và 3D chuẩn và sau đó ánh xạ toạ độ đó sang không gian thiết bị xác định cho đầu ra.

the application class(es) called by the printing system to render a page. The system calls the page painter’s print method to request that a page be rendered. and the page painter to PrinterGraphics use to render each page. Class Book Description Implements: Pageable Represents a document in which pages can have different page formats and page painters. The Graphics2D objects that a page painter uses to render a page implement the PrinterGraphics interface. The Printable interface is implemented by each page painter. This class uses the Pageable interface to interact with a PrinterJob. This enables an application to get the Printable PrinterJob object that is controlling the printing. the application class(es) called by the printing system to render a page.Lập trình đồ họa trên Java 2D và 3D Interface Printable Description The Printable interface is implemented by each page painter. Through the Pageable methods. The system calls the page painter’s print method to request that a page be Pageable rendered. Describes the size and orientation of a page to be 172 PageFormat http://tailieuhay. the format to use for each page. The Pageable interface is implemented by a document that is to be printed by the printing system. the system can determine the number of pages in the document.com .

không phải úng dụng sẽ điều khiển khi các trang được in. Describes the physical characteristics of a piece of paper. The principal class that controls printing. For example. Trong khía cạnh đó.Lập trình đồ họa trên Java 2D và 3D printed. hệ thống in giông như window toolkit. display a print dialog to the user (optional). Ứng dụng cung cấp thông tin về tài liệu được in và hệ thống in sẽ yêu cầu ứng dụng đẩy tới các trang in khi nó cần chúng. Mô hình in callback mềm dẻo hơn các mô hình ứng dụng điều khiển in truyền thống và bổ trợ cho việc in trên dải rộng hơn các hệ thống và các máy in.com 173 . and to print the pages in the job. The application calls PrinterJob methods to set up a job. Hệ thống in có thể yêu cầu rằng một trang in riêng biệt được đưa ra hơn một lần hoặc yêu cầu các trang được đưa ra ngoài theo thứ tự. Ứng dụng phải cho phép tạo ra hình ảnh đúng của trang. http://tailieuhay. không phụ thuộc trang nào hệ thống in yêu cầu. as well as the Paper used to print it. portrait and landscape paper orientations are rep. Các định nghĩa về in Java Printing API dựa trên mô hình in callback trong đó hệ thông in.resented by Paper PrinterJob PageFormat. có thể yêu cầu các thành phần để vẽ lại bât cư lúc nào trong thứ tự nào.

nó chỉ đơn giản khả đẩy mỗi trang khi được yêu cầu. mỗi lần điền vào mỗi dải. và bắt đầu quá trình in. ứng dụng phải đẩy dữ liệu mỗi trang khi hệ thống in yêu cầu nó.Khởi tạo và quản lý việc in. Ứng dụng không cần biết số lượng hay cỡ của các dải. ứng dụng cung cấp một http://tailieuhay. Điều khiển in(Job control). Trong tình huống này.1 Supporting Printing Một ứng dụng phải thực hiện 2 tác vu để bổ trợ cho việc in là: 1. 7.com 174 . Ứng dụng có khả năng đáp ứng cho việc cài đặt điều khiển in. thi trang sẽ được chỉ thành 10 dải. Mô hình này cũng cho phép ứng dụng để in ra các máy in ảnh nhị phân từ máy tính mà không có đủ bộ nhớ hày không gian đĩa để đệm cho toàn trang bitmap.Lập trình đồ họa trên Java 2D và 3D Ví dụ.1 Điều khiển in (Job Control) Người sử dụng thường khởi tạo việc in bởi việc kích một nút hoặc chọn mục in trên menu trong một ứng dụng. In (imaging) – Đẩy (rendering) dữ liệu ra mỗi trang khi hệ thống in yêu cầu nó 7.1.2.2. một trang được in như là một dãy cá bitmap nhỏ hay các dải (bands). hệ thống in có thể yêu cầu ứng dụng tạo các trang trong thứ tự đảo ngược sao cho tác vụ cuối cùng là đúng thứ tự đọc . ứng dụng tạo ra một đối tượng PrinterJob và dùng nó để quản lý quá trình in. imaging Khi một tài liệu được in. nều bộ nhớ chỉ đủ đệm cho 1/10 trang in. Ví dụ. Khi một thao tác in được kích hoạt bởi người sử dụng. hiển thị các hộp thoại cho người sử dụng. 2. Để bổ trợ cho kỹ thuật này. nếu một máy in thực hiện đưa ra các trang trong thứ tự đảo ngược. Hệ thống in đòi hỏi ứng dụng đẩy mỗi trang 10 lần.

print: public int print(Graphics g.able có thể được dùng miễn là tất cả các trang chia sẻ cùn một định dạng và một máy in 7. bạn đưa một đối tượng Graphics cho phương thức in cho raphics2D Để in các tài liệu trong đó các trang dùng các page painter khác nhau và có các định dạng khác nhau. Một page painter cài đặt phưong thức Printable. Print. Khi hệ thống in cần một trang được đây ra. int pageindex) Ngữ cảnh đồ hoạ được truyền cho phương thức in là một thể nghiệm của Graphics hoặc Graphics2D. Để cài đặt các thao tác in đơn giản. Khi một phương thức của page painter được gọi.com . Hệ thống in hỗ trợ cả việc đẩy Graphics và Graphics2D. bạn có thể dùng lớp Book hoặc cài đặt giao diện Pageable của bạn. PageFormat pf. để in Java 2D™ Shapes .2 Page Painters Việc chủ yếu của một page painter là đẩy ra một trang dùng ngữ cảnh đồ hoạ được cung cấp bởi hệ thống in.Lập trình đồ họa trên Java 2D và 3D page painter cài đặt giao diện Printable. nó gọi phương thức in của page painter. 175 http://tailieuhay. nó được truyền cho một ngữ cảnh đồ hoạ (Graphics context) dùng để đẩy hình anh trang. Nó cũng được truyền cho một đối tượng PageFormat xác định (specifies) hình hiện ra của trang. bạn không cần dùng một pageable print job.2. phụ thuộc vào các package được load trong Java Vỉtual Machine của bạn. và chỉ số xác định thứ tự vị trí của trang trong việc in. Để tạo một pageable job. bạn dùng một pageablejob. Để dùng các tính năng Graphics2D .Text và images.

chiều cao của trang dài hơn với chiều rộng của nó).getClip. (Thông thường. PageFormat được truyền cho một Printable mô tả hình ảnh của một trang được in. gọi hàm PrinterJob. gọi hàm Graphics. Hệ tọa độ của ngữ cảnh đồ hoạ được truyền để in được fixed với trang : gốc toạ độ của hệ thống là góc trái trên của trang. Y theo chiều từ trên xưống dưới. nhưng không phải luôn luôn. Bởi nhiều máy in không thể trên cả bề mặt trang. X tăng theo chiều phải sang trái. Đôi khi mong muốn cả thao tác in thực hiện ngầm để cho người dùng có thể tiếp tục tao tác vói úng dụng trong khi các trang đang được đẩy ra (đang in). Để làm điều này. và trục y theo chiều cao của trang. thì ngược lại: trục x căn theo chiều cao của trang còn trục y căn theo chiều rộng của nó. Ngữ cảnh đồ hoạ được truyền để in có một miền xén mô tả phần miền có thể in mà cần được in. Để lấy vùng cắt xén từ ngữ cảnh đồ hoạ. để loại overhead của các phần vẽ của trang không được in. bạn có thể dùng miền cắt xén để giới hạn vùng đẩy ra. Thể nghiệm Graphics được truyền để in cũng cài đặt giao diện PrinterGraphics. nó được cung cấp sao cho nội dung của trang có thể được đẩy ra sao cho chúng không thể mở rông vào trong vung mà máy in không thể in. Sự xác định của vùng in không thay đổi theo toạ độ hệ thống. Nó cũng luôn an toàn để in toàn bộ trang vào trong ngữ cảnh đó. trục x căn theo chiều rộng của trang giấy. hệ thống in sẽ nắm dữ vùng xén cần thiết. PageFormat xác định (specifies) vùng in (imageable area) của trang: phần của trang mà nó đẩy ra an toàn. Nếu trang trong hướng portrait. Tuy nhiên.print trong một tuyến riêng.com 176 . Nếu trang theo hướng landscape. với đơn vì là 1/72 inch. Vùng cắt xén rất mạnh mẽ để giảm bớt rendering overhead.Lập trình đồ họa trên Java 2D và 3D bạn có thể thay đối tượng Graphics bằng Graphics2D. http://tailieuhay.

ứng dụng cung cấp một lớp đơn cài đặt giao diện Printable. nó cũng sẽ không hiển thị số trang trong tài liệu vì thông tin đó không có với hệ thống in. giống như copyArea. bắt đầu với trang có chỉ số là 0. Các trang được yêu cầu theo thứ tự. Tuy nhiên. Trong một Printable job: 1. Chỉ một page painter được dùng . 4. 3.com 177 . hệ thống goi phương thức in của page painter để đẩy ra mỗi trang. Tất cả các page painter được gọi trong cùng một tuyến. 2.3 Printable Jobs and Pageable Jobs Một Printable job cung cấp cách đơn giản nhất để in. Ví dụ. Đôi khi hệ thống in có thể không có khả năng biết được mục đích đưa ra. và sự liên hợp (compositing). tác vụ của các trang hiện ra từ máy in có thể là thứ tự http://tailieuhay. Tất cả các trang dùng cung một page painter và PageFormat. Ví dụ. Không trang nào bị quên. 7. nếu người dùng yêu cầu in trang 2 và trang 3 của một tài liệu.Lập trình đồ họa trên Java 2D và 3D Nếu có thể. Page painter báo cho hệ thống in khi nó đã đến cuối tài liệu. Khi in.2. Khi trang cuối cùng được in. bắt đầu với trang có chỉ số là 0. thì page painter sẽ được gọi với các chỉ số 0. page painter có thể được yêu cầu để đẩy mỗi trang vài lần trước khi nó sang trang tiếp. Hệ thống in có thể yêu cầu một trang được đẩy ra nhiều lần trước khi chuyển sang trang kế. Hệ thống in luôn đòi hỏi page painter để in mỗi trang đúng thứ tự. 5. phương thức in của page painter trả về NO_SUCH_PAGE. 1. bạn nên tránh các thao tác đồ hoạ mà yêu cầu thông tin về nội dung của image trước đó. Các thao tác này có thể đẩy ra chậm và các kết quả có thể không ổn định. setXOR. Nếu một hộp thoại in được hiển thị. 2.

Ví dụ. hoặc các trang có thể không được kiểm tra thứ tự nếu nhiều bản sao được yêu cầu.2. không giống với Printable job. Các ứng dụng cần in các tài liệu có một cấu trúc đã định và định dạng nên dùng các Pageable job. Tuy nhiên. Qua Pageable. thì page painter se được gọi với chỉ số 1 và 2 còn trang chỉ số 0 sẽ được bỏ qua. 2. Pageable job không cần biết có bao nhiêu trang tiếp theo trong tài liệu. Thứ tự đơn giản nhất được dùng bởi ứng dụng là: http://tailieuhay. chúng phải có khả năng đẩy ra các trang trong bất kỳ thứ tự. Không giống như các trang trong Printable job.Lập trình đồ họa trên Java 2D và 3D sai. Có thể có các chỗ trống trong thứ tự và hệ thống in có thể yêu cầu một trang được đẩy ra nhiều lần trước khi chuyển sang trang tiếp theo.com 178 . 1. các trang trong Pageable job có thể khác về cách bố trí và cài đặt. Để quản lý một Pageable job. 1 và 1. Ví dụ. hệ thống in có thể xác định số lượng trang để in. và PageFormat cho mỗi trang. bạn có thể dùng lớp Book hay cài đặt lớp Pageable của bạn. 7. Hệ thống in có thể đòi hỏi các page painter để in các trang trong một thứ tự tuỳ ý và một trang có thể được bỏ qua. Nếu người dùng yêu cầu in các trang 2 và 3 của một tài liệu. Trong một Pageable job: Các trang khác nhau có thể dùng các page painter và các PageFormat khác nhau. Một Pageable job linh hoạt hơn một Printable job.4 Typical Life-Cycle of a PrinterJob Một ứng dụng hướng theo đối tượng PrinterJob qua một dãy các bước để hoàn thành công việc in. 6. yêu cầu để in trang 2 và 3 của một tài liệu có thể kết quả trong dãy lời gọi là các trang yêu cầu với chỉ số 2. và page painter dùng cho mỗi trang.

Trên hầu hết các platform.print để in. hoặc bạn có thể gọi một hộp thoại cho phép người dùng xác định định dạng . Gọi hàm printDialog để hiển thị hộp thoại cho người dùng. Phương thức cancel có thể được gọi từ một tuyến riêng biệt cái hiển thị một hộp thoại và cho phép người dùng hủy bỏ việc in bởi bấm vào một nút trên hộp thoại đó. Điều này là tuỳ chọn. giống như số bản sao để in hay tên của công việc trên đầu đề trang.  Xác định các thuộc tính thêm cho việc in. phương thức printDialog trả về FALSE. Cho một Printable job.getPrintJob  Xác định PageFormat để dùng cho việc in.  Gọi Printerjob. Một công việc có thể bị ngắt quá trình in nếu:  Một PrinterException được đưa vào ngoại lệ được bắt boẻi phương thức in và công việc sẽ bị dừng.com 179 .  Xác định các đặc điểm của công việc để in cho PrinterJob.cancel được gọi. PrinterJob. Những nội dung và hình dạng của hộp thoại có thể đa dạng với các platform và các máy in khác nhau. gọi setPrintable. vòng lặp in sẽ bị chấm dứt và công việc bị huỷ bỏ. gọi setPageable. người dùng có thể dùng hộp thoại này để thay đổi các lựa chọn của máy in. Chú ý một đối tượng Book là một mẫu truyền cho setPageable. với Pageable job. Phương thức này khi trả về gọi print trên các page painter tương ứng. Một page painter đưa ra một PrinterException nếu nó phát hiện một trầm trọng lỗi (fatal error). Một PageFormat mặc định có thể lấy về bởi gọi hàm defaultPage.Lập trình đồ họa trên Java 2D và 3D  Lấy một đối tượng PrinterJob mới bởi việc gọi PrinterJob. Nếu người dùng huỷ việc in.  http://tailieuhay.

Để hiển thị một hộp thoại page setup bạn gọi hàm PrinterJob. và thay đổi http://tailieuhay. Do trạng thái của một PrinterJob thay đổi trong quá trình vòng đời của nó. nên dùng hộp thoại. Không hợp lý yêu cầu các phương thức vào nhiều lúc.illegalStatException. thị một thể nghiệm của PageFormat được tạo(cloned). việc gọi setPageable sau khi bạn đã gọi hàm print là không hợp lý. các hộp thoại không cần thiết. Với các ứng dụng tương tác. Nếu người dùng click vào nút OK trong hộp thoại. Ví dụ. Tuy nhiên. Một việc in không yêu cầu tương tác với người dùng đôi khi được gọi là “silent print job”. Page setup dialog Bạn có thể cho phép người dung thay đổi thông tin cài đặt trang(page setup information) chứa trong PageFormat bởi hiển thị hộp thoại page setup. Khi có các lời gọi không hợp lý được phát hiện PrinterJob sẽ đưa vào một ngoại lệ java.pageDialog. Các hộp thoại này có thể được cung cấp bởi hệ điều hành (platform software) hoặc bởi sự cài đặt phần mềm Java™ 2 SDK . bạn không cần hiển thị hộp thoại khi tự động tạo và in một báo cáo cơ sở dữ liệu.Lập trình đồ họa trên Java 2D và 3D Các trang phân ra trước khi một công việc in bị dừng có thể là không được in hoặc được in. Dialogs Java Printing API yêu cầu các ứng dụng cần đến hộp thoại giao tiếp với người dùng một cách tường minh. ví dụ như. Việc in thường không kêt thúc (finished) khi phương thức in tra về. Trạng thái của đối tượng PrinterJob có thể không phản ánh trạng thái thực tế của công việc đang được in.lang.com 180 . Việc này thường vẫn đang được thực hiện bởi trình điều khiến máy in. các ứng dụng in kết qủa(production printing application). Hộp thoại page setup được khởi tạo dùng tham số truyền cho pageDialog.

Nếu người dùng click OK trong hộp thoại in. Nều người dùng ấn cancel.awt.*. Tạo một PrinterJob.3 Printing with Printables Cung cấp bổ hỗ trợ in cơ bản: 1. 7.awt.com . class import java. thì pageDialog trả về PageFormat chưa bị thay đổi. một ứng dụng hiển thị một hộp thoại in cho người dung khi được kích hoạt ở thực đơn hay bởi nút bấm. 3. bạn gọi hàm printDialog của PrinterJob. implements Printable SimplePrint http://tailieuhay. Còn click vào Cancel nó trả về FALSE và việc in coi như bỏ qua.print.Lập trình đồ họa trên Java 2D và 3D theo tới các chọn lựa của người dùng rồi trả về. mỗi cái hiển thị một số trang màu xanh. Các lựa chọn của người dùng trong hộp thoại được ràng buộc dựa trên số và định dạng của các trang trong Printable hoặc Pageable đã được cung cấp cho PrinterJob. Gọi setPrintable để thông báo cho PrinterJob cách thức in tài liệu. Để hiển thị hộp thoại in này. Gọi hàm print của đối tượng PrinterJob để bắt đầu công việc. phương thức lấy về và điều khiển PrinterJob. Việc đẩy ra (Rendering) được thực hiện trong phương thức print của page painter. Print dialog Thông thường. một Printabble job được dùng để in 5 trang.*. printDialog trả về TRUE. Cài đặt giao diện Printable để cung cấp một page painter có thể đẩy mỗi trang ra để in. Điều khiển công việc được quản lý trong phương thức chính. import public { 181 java. Trong ví dụ dưới đây. 2.

setPrintable(new (job. public { // Get a PrinterJob job the up = PrinterJob.PLAiN. } public int { // pageindex 1 to 0 5.exit(0).Lập trình đồ họa trên Java 2D và 3D private static Font fnt = new Font("Helvetica".com 182 .printDialog()) SimplePrint()). dialog exception pageindex) PrinterException http://tailieuhay. Printable the is an instance box of if PrinterJob // // { // try catch { } System. /* Print { the job } */ } if the user didn't cancel printing job. (Exception handle e) Specify Put static void main(String[] args) SimplePrint job. to 4 corresponds to page numbers throws int print(Graphics g.Font.24). PageFormat pf.getPrinterJob().print().

print. Using Graphics2D for Rendering Bạn có thể cần các hàm Graphics2D trong phương thức print của page painter bởi trước tiên chuyển ngữ cảnh Graphics tới một Graphics2D Trong ví dụ dưới đây. class import java. implements SimplePrint2D Color. java.com . import public Printable { private static Font fnt = new Font("Helvetica".Lập trình đồ họa trên Java 2D và 3D if (pageindex >= 5) return Printable.PAGE_EXiSTS.*.*. g.red. g.PLAiN. các số trang được đẩy ra dùng một hướng redgreen(red-green gradient).awt.setColor(Color.drawString("Page 100). 100. 183 http://tailieuhay. Để làm điều này.awt.setFont(fnt).green).24). một GradientPaint được đặt trong ngữ cảnh Graphics2D. private 100f.Font. return } } Printable. g. " + (pageindex+1). Paint pnt = new GradientPaint(100f.NO_SUCH_PAGE.

Lập trình đồ họa trên Java 2D và 3D 136f.com 184 . http://tailieuhay. Printable is an instance of PrinterJob Specify 100f. box dialog (job. static Color. (Exception e) Put up the SimplePrint2D()).exit(0).getPrinterJob(). public { // // Get a PrinterJob job the = PrinterJob. } Print { the job } { /* handle exception if the user didn't cancel printing job.green. } public int { // if pageindex 1 to 0 5. args) main(String[] SimplePrint2D job. >= 5) return to 4 corresponds to page numbers throws int print(Graphics g.print(). void true).printDialog()) pageindex) PrinterException (pageindex Printable.NO_SUCH_PAGE. PageFormat pf.setPrintable(new // if { // try catch */ } System.

Có nhiều cách để chắc chắn rằng các yêu cầu lặp lại để đẩy ra một trang thuận tiện ra cùng đầu ra. http://tailieuhay.3.PAGE_EXiSTS.awt. Tên của file được truyền như là đối số cho hàm main.print. 7. import import import java.*.2 Printing a File Khi môt phương thức in của page painter được yêu cầu vài lần cho cùng trang.Lập trình đồ họa trên Java 2D và 3D Graphics2D // // Use Use the the g2 = font (Graphics2D) defined color + g. Ví dụ.drawString("Page 100f).*. java. g2. Khi cùng trang được đây ra lần nữa.*. g2.awt. Lớp PrintListingPainter chứa con trỏ file thực tế ở lúc bắt đầu của mỗi trang mới nó được yêu cầu để đẩy ra(to render). Trong ví dụ dưới đây. page painter có thể lưu trữ và sử dụng lại các con trỏ file cho mỗi trang hoặc chứa dữ trang thực tế.io. return } } Printable. (pageindex+1). con trỏ file được reset tới vị trí đã nhớ. above defined above 100f.setPaint(pnt). để chắc chắn rằng cùng đầu ra được sinh ra mỗi lần hệ thống in yêu cầu các trang cụ thể của một file văn bản.com 185 .setFont(fnt). gradient " g2. nó phải được sinh ra cùng đầu ra mỗi lần. một danh sách các file văn bản được in. java.

com 186 .defaultPage()). (Exception e) Print Put up 1 copy the dialog box job.Lập trình đồ họa trên Java 2D và 3D public { public { // // Get class static a PrintListing void main(String[] args) PrinterJob job user = PrinterJob.getPrinterJob().printDialog()) pf).print().exit(0). PrintListingPainter. http://tailieuhay. = of PrinterJob Ask portrait/landscape) PageFormat // // Specify job.pageDialog(job.setCopies(1).. // // if { // try catch */ } System.setPrintable(new PrintListingPainter(args[0]). (job. for page pf the Printable is also an instance format (e.g. } } Print { the job } { /* handle exception if the user didn't cancel printing job. provide given PageFormat job.

rememberedPageindex rememberedEOF = = -1. false. file) rememberedFilePointer fileName. (Exception e) { rememberedEOF = true. = file. raf.Lập trình đồ họa trên Java 2D và 3D } class { private private private private private private public { fileName try{ // raf } catch } } public int { try { throws int print(Graphics g.com 187 . = -1. Open = file new RandomAccessFile(file. PrintListingPainter implements Printable Font. fnt = new Font("Helvetica". boolean PrintListingPainter(String pageindex) PrinterException http://tailieuhay. PageFormat pf.PLAiN. RandomAccessFile String Font int long 10). "r").

rememberedPageindex encountered pageindex. g. First if time we've = visited EOF on this page page.setColor(Color.Lập trình đồ họa trên Java 2D và 3D // if { // // done if // } else raf. Save (rememberedEOF) current position = in input return file Printable.seek(rememberedFilePointer).com 188 . (y + 12 < pf. g.black).getFilePointer().getimageableY() + + 10.readLine().drawString("File: (pageindex+1). rememberedFilePointer raf. previous For catching != iOException rememberedPageindex) (pageindex Title g. null) (line http://tailieuhay. imageable while { String if line == = area +pf. as y).getimageableY() many x y = = (int) (int) line " + fileName + ".setFont(fnt).NO_SUCH_PAGE.getimageableX() pf. lines as will fit in Generate += 36. page: pf.getimageableHeight()) raf. 12. int int // " // y + x.

Lập trình đồ họa trên Java 2D và 3D { rememberedEOF break. http://tailieuhay.} Printable. = true.com 189 . += 12. y). y } return } catch } } Giao diện của chương trình: (Exception e) { return Printable.drawString(line. } g.NO_SUCH_PAGE. x.PAGE_EXiSTS.

bạn có thể chuyển cho giá trị UNKNOW_NUMBER_OF_PAGES cho phương thức append. Điều này trợ giúp cho người dùng để chắc chắn rằng công việc (job) được thực hiện (specified) chính xác hoặc chọn một dải các trang để in. Các trang trong một book không phải cũng cỡ. trang bởi trang. Lớp Book là một cách thuận lợi để dùng các Pageable. Phần này chỉ cho bạn cách dùng Book. Một Book biểu diễn một tập các trang. Phương thức này nhận 2 đối tượng PageFormat xác định (defines) cỡ trang. Các Pageable job được đề cập qua các Printable job bởi vì hệ thống in có khả năng linh hoạt hơn. Nhiều trang trong một Book có thể dùng chung cùng định dang và painter.Lập trình đồ họa trên Java 2D và 3D Printing with Pageables and Books Các Pageable được làm phù hợp với các ứng dụng dựa trên biểu diễn lại tương minh dữ liệu.com 190 . số lượng các trang. http://tailieuhay. cùng hướng. Ví dụ. Phương thức append được nạp chồng để cho phép bạn thêm vào một dãy các trang mf có cùng thược tính bởi việc xác định tham số thứ 3. bạn dùng phương thức append. hướng và một page painter cài đặt giao diện Printable. Khi một Book khởi tạo đàu tiên. một Book có thể chứa các trang với 2 cỡ chữ trong hướng portrait và một trang cỡ chữ trong hướng landscape. nhưng bạn cũng có thể xây dựng cầu trúc Pageable của chính bạn nếu Book không phù hợp với cái của bạn cần. Nếu bạn không biết tổng số trang trong một Book. nó trống rỗng. hoặc page painter. vùng có thể in. Hệ thống in sau đó sẽ gọi các page painter của bạn theo thứ tụ tăng dần chỉ số trang đế khi một trong chúng trả về NO_SUCH_PAGE. Để thêm các trang vào một Book. Một cải tiến chính của Pageable là số trang trong tài liệu thường được biết và có thể hiện thị cho người dùng trong hộp thoại in.

một Book được dùng để tạo lại ví duj in đơn giản đầu tiên( Do trường hợp này qúa đơn giản.getPrinterJob(). main(String[] java.*.1 Using a Pageable Job Ví dụ sau. PrinterJob static static void Font fnt = args) new Font("Helvetica".*. Hàm setPageablbe và hàm setPrintable là loại trừ nhau. import import public Printable { private public { // // Book Get Set bk a up = PrinterJob job a new = book Book(). nhưng nó minh hoạ cơ bản cách cùng một Book) Chú ý rằng bạn vẫn phải cài đặt giao diện Printable và thực hiện page rendering trong phương thức print của page painter.PLAiN. class SimplePrintBook implements http://tailieuhay.4. có rất it lợi ích trong việc dùng một Pageable job thay cho một Printable job.Font.awt.print. Do đó bạn gọi một hoặc cái này hoặc cái kia chứ không thể cả hai khi đang chuẩn bị in PrinterJob. 7. java. Trang để thay đổi được xác định (identified) bởi chỉ số trang cái chỉ ra vị trí của trang trong Book.Lập trình đồ họa trên Java 2D và 3D Phương thức setPage có thể được dùng để thay đổi định dạng trang hoặc painter. Ban gọi setPageable và truyền trong Book để chuẩn bị cho việc in.awt.24). PrinterJob.com 191 .

// // if { // try catch */ } System.setFont(fnt).com .setPageable(bk).green).drawString("Page 100). g.PAGE_EXiSTS.setColor(Color.print(). to the box PrinterJob book the Pass Put the up job.append(new job. (Exception e) int print(Graphics g. PageFormat pf.defaultPage().exit(0).printDialog()) Print { } the job } { /* handle exception if the user didn't cancel printing job. 5). pageindex) PrinterException throws " + (pageindex+1). g. return } } Giao diện của chương trình: 192 SimplePrintBook(). dialog (job. Printable. } public int { g. 100.Lập trình đồ họa trên Java 2D và 3D bk. http://tailieuhay.

setOrientation(PageFormat. page format job. http://tailieuhay. class static PrintBook void main(String[] args) PrinterJob Create PageFormat // Book Set bk up = PrinterJob.awt.Lập trình đồ họa trên Java 2D và 3D 7. java. landscape pfl.2 Using Multiple Page Painters Ví dụ dưới đây.awt. 193 java. import import public { public { // // Get a PrinterJob job a pfl a new = = book Book(). có hai page painter khác nhau được sử dụng: một cho bìa và một cho các trang bên trong.*.defaultPage(). Trang bìa được in trong landscape mode và nội dung in portrait mode.4.com .getPrinterJob().LANDSCAPE).print.*.

g.append(new job.append(new bk. pageindex) PrinterException http://tailieuhay. dialog box (job. new Font("Helvetica-Bold". } } class { Font fnt = 72).PLAiN.setFont(fnt). (Exception e) Pass Put the up book the job. Font.setPageable(bk).printDialog()) 2). throws int PaintCover implements Printable } Print { the job } { /* handle exception if the user didn't cancel printing job.print().com 194 .defaultPage(). to the PrinterJob PaintCover(). print(Graphics g. pfl).black). PaintContent().setColor(Color.Lập trình đồ họa trên Java 2D và 3D bk. // // if { // try catch */ } System. public int { g. PageFormat pf.exit(0).

pf.getimageableY(). (int) (int) page red Fill alternating (int (int pf. g. + pf.red).getimageableY() inc. useRed xo yo = = g2 = = 0.com 195 .Lập trình đồ họa trên Java 2D và 3D int yc = (int) (pf. Printable. 36) 0. g. return } } class { public int { Graphics2D int int int // for for { if else useRed (useRed = 1 == 0) g.getimageableHeight().getimageableWidth().". pf. useRed. pf. PageFormat pf. http://tailieuhay. with & x y green = x = y += += 0. pageindex) PrinterException PaintContent implements Printable yc+36). 36) y+28 < x+28 < circles or squares.green).PAGE_EXiSTS. throws int print(Graphics g. 72.getimageableX().drawString("Widgets.setColor(Color.setColor(Color.getimageableHeight()/2). (Graphics2D) g.

28). % 2 == 0) g.ActionListener.awt.com 196 . 28).*.awt. g. import java. import java.PAGE_EXiSTS. import java.awt.*.swing. yo+y+4.*.drawRect(xo+x+4.event.drawOval(xo+x+4.ActionEvent.PrinterJob. yo+y+4. http://tailieuhay.event. import java. import java. import javax.awt.awt. 28.Lập trình đồ họa trên Java 2D và 3D if else } return } Giao diện cua chương trình: Printable.event. Ví dụ in một một chương trình.*.awt. (pageindex 28. import java.geom.print.

final static Color fg = Color. BasicStroke.0f.*. http://tailieuhay. 10.Lập trình đồ họa trên Java 2D và 3D import java. ActionListener { final static Color bg = Color.JOiN_MiTER. dash1. final static Color white = Color.white.0f). BasicStroke.black. 0. final static float dash1[] = { 10.0f }. final static JButton button = new JButton("in"). final static BasicStroke dashed = new BasicStroke(1.0f). final static BasicStroke stroke = new BasicStroke(2.awt.0f. final static Color red = Color.com 197 . final static BasicStroke wideStroke = new BasicStroke(8. public class ShapesPrint extends JPanel implements Printable.white.red.0f).print.CAP_BUTT.

printJob = http://tailieuhay. } public void actionPerformed(ActionEvent e) { if (e.Lập trình đồ họa trên Java 2D và 3D public ShapesPrint() { setBackground(bg).getPrinterJob().printStackTrace().getSource() instanceof JButton) { PrinterJob PrinterJob. } catch (Exception ex) { ex.print(). Graphics2D g2 = (Graphics2D) g.paintComponent(g).com 198 .printDialog()) { try { printJob. } public void drawShapes(Graphics2D g2) { Dimension d = getSize().addActionListener(this). button.setPrintable(this). printJob. if (printJob. drawShapes(g2). } } } } public void paintComponent(Graphics g) { super. int gridWidth = 400 / 6.

y. int x = 85.Double(x. g2. g2 . 135. g2.Double(x. rectHeight. 10)). 310). y. g2.draw(new x += gridWidth.Double(x. rectWidth = gridWidth - http://tailieuhay. rectHeight)). Color fg3D = Color. int columnspacing. 400 .drawRect(80. rectWidth. y)). rectWidth.setStroke(wideStroke).setPaint(fg). Line2D. int rectHeight = gridHeight .draw(new RoundRectangle2D. 80. y + rectHeight .1.setStroke(dashed). y.1. g2. g2. g2. x + rectWidth.draw(new Arc2D. int rowspacing = 5. 10.com 199 .draw(new Rectangle2D.Double(x. rectHeight. x += gridWidth.Lập trình đồ họa trên Java 2D và 3D int gridHeight = 300 / 2.rowspacing.setStroke(stroke). g2. int y = 87.lightGray.setPaint(fg3D). g2. x += gridWidth. rectWidth. 90. g2. int columnspacing = 7.

} . int y1Points[] = { y.Lập trình đồ họa trên Java 2D và 3D Arc2D. y }. int x1Points[] = { x. index < x1Points. rectHeight)). g2. x += gridWidth. x + rectWidth }. index++) { polygon. int x2Points[] = { x. g2. Ellipse2D. int y2Points[] = { y.draw(polygon). x + rectWidth. g2. y1Points[index]). y + rectHeight. y + rectHeight. x += gridWidth. http://tailieuhay. y + rectHeight.Double(x. y + rectHeight. y += gridHeight. x.com 200 . y }.lineTo(x1Points[index]. y1Points[0]).closePath(). GeneralPath polygon = new GeneralPath(GeneralPath.WiND_EVEN_ODD. polygon. for (int index = 1.moveTo(x1Points[0].length.setStroke(stroke). polygon. y. x. x + rectWidth }.draw(new rectWidth. x + rectWidth. x1Points. x = 85.OPEN)).length).

http://tailieuhay. x + rectWidth.Double(x. for (int index = 1.Lập trình đồ họa trên Java 2D và 3D GeneralPath polyline = new GeneralPath(GeneralPath. x += gridWidth. g2. index++) { polyline.setPaint(fg). index < x2Points. g2.fill(new Rectangle2D.Double(x.length. rectHeight)). x += gridWidth. g2. y. y2Points[index]). g2. x2Points.setPaint(redtowhite). rectWidth. white). y2Points[0]). GradientPaint redtowhite = new GradientPaint(x. g2. g2 .draw(polyline).lineTo(x2Points[index]. rectHeight. y. rectWidth.fill(new RoundRectangle2D.com 201 . g2. 10. } . y. x += gridWidth.length). red.setPaint(red). y.setPaint(fg). polyline.WiND_EVEN_ODD.moveTo(x2Points[0]. 10)).

fill(new rectWidth. x + rectWidth.moveTo(x3Points[0]. x += gridWidth. rectHeight. int x3Points[] = { x. y3Points[index]).length). x + rectWidth }.Double(x.OPEN)). g2. Ellipse2D. white). x3Points. x += gridWidth.fill(new Arc2D.setPaint(fg). y + rectHeight. g2. 90. redtowhite = new GradientPaint(x. GeneralPath filledPolygon = new GeneralPath(GeneralPath.setPaint(red).length. rectWidth. y. } . index++) { filledPolygon. for (int index = 1.lineTo(x3Points[index].Lập trình đồ họa trên Java 2D và 3D g2. y. g2.com 202 . Arc2D.WiND_EVEN_ODD. y. rectHeight)).setPaint(redtowhite). filledPolygon. y. g2. y3Points[0]). http://tailieuhay. 135. x + rectWidth. y + rectHeight. int y3Points[] = { y. index < x3Points.setPaint(fg). g2. y }.Double(x. x. red.

NO_SUCH_PAGE.fill(filledPolygon).exit(0). g2. g2.setPaint(red). void http://tailieuhay. } drawShapes((Graphics2D) g). g2. } public int print(Graphics g.setPaint(fg). } public static void main(String s[]) { WindowListener l = new WindowAdapter() { public windowClosing(WindowEvent e) { System. g2. } }.Lập trình đồ họa trên Java 2D và 3D filledPolygon. return Printable.PAGE_EXiSTS. JFrame f = new JFrame().exit(0). PageFormat pf.com 203 . int pi) throws PrinterException { if (pi >= 1) { return Printable.closePath(). } public void windowClosed(WindowEvent e) { System.draw(filledPolygon).

f. panel.show().CENTER. f. panel). new ShapesPrint()).setSize(580.SOUTH.addWindowListener(l). f. f.add(BorderLayout. JPanel panel = new JPanel().add(BorderLayout.getContentPane().getContentPane(). } } Giao diện của chương trình: http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D f. 500).com 204 .add(button).

Lập trình đồ họa trên Java 2D và 3D http://tailieuhay.com 205 .

Lập trình đồ họa trên Java 2D và 3D Phần 2 Lập trình đồ họa với Java 3D http://tailieuhay.com 206 .

việc dựng hình trong Java 3D cho phép làm song song. Dù có nhiều chức năng như vậy nhưng các hàm API vẫn có thể sử dụng rõ ràng. Đồ thị khung cảnh là một sắp xếp các đối tượng Java 3D trên một cấu trúc cây cho phép chỉ ra nội dụng của một thế giới ảo và chúng có thể được dựng hình như thế nào. Chương trình Java 3D tạo các instances của các đối tượng và đưa chúng vào cơ sở dữ liệu đồ thị khung cảnh. Các hàm API được thiết kế rất linh động cho phép tạo một trường ảo đó chính xác với rất nhiều dạng kích cỡ từ lớn đến bé. đồng thời cũng cho phép tối hưu hóa việc dựng hình.1 Tổng quan về Java 3D API ™ Java 3D API được thừa kế từ các lớp của java cho phép tạo các giao diện phức tạp như hệ thống âm thanh và hình ảnh 3 chiều. Các chi tiết được dưng hình tự động. http://tailieuhay. Sử dụng lợi thế của các luồng trong java. Những đối tượng này cư trú trên một môi trường ảo sau đó mới được dựng hình lại.Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 1 NHẬP MÔN LẬP TRÌNH TRÊN JAVA 3D 1.com 207 . Người lập trình có thể sử dụng nó để xây dựng điều khiển các đối tượng hình học 3 chiều. Chương trình Java 3D có thể được viết để chạy độc lập hay như là một applet trên các trình duyệt hỗ trợ Java 3D hoặc cả 2.

vecmath định nghĩa các lớp cho điểm. Chương này còn bao gồm ví dụ HelloJava3D hiển thi một khối lập phương quay.j3d những lớp này được coi như là những lớp cơ bản nhất của Java 3D. chúng bổ sung thêm những tính năng hiệu quả và rất mạnh cho nhân. một đồ thị khung cảnh được tạo nên bởi các instance của các lớp Java 3D. Đồ http://tailieuhay. Chương này mô tả tập nhỏ nhất các đối tượng và tương tác giữa chúng để dựng nên một môi trường ảo.(chẳng hạn: một hình lập phương hay hình cầu).utils thường gọi là các lớp tiện dụng.awt và javax. Gói javax. Ngoài gói nhân Java 3D chúng ta còn sử dụng thêm một gói nữa là com. Ví dụ này được phát triển theo từng bước lần lượt thể hiện các phần xử lí trong lập trình Java 3D. Content tương ứng với những đối tượng quan sát trong một đồ thị khung cảnh. vector ma trận và những đối tượng toán học khác.sun. các lớp hình học. 1.2 Các vấn đề cơ bản về Java 3D API™ Java 3D API định nghĩa hơn 100 lớp trong gói javax. Từ object được sử dụng cho một instance của một lớp.3 Xây dựng đồ thị khung cảnh Môi trường ảo trong Java 3D được tạo từ một đồ thị khung cảnh.media.awt định nghĩa các lớp AWT cho phép tạo cửa sổ cho việc dựng hình.com 208 .Lập trình đồ họa trên Java 2D và 3D 1. Tất nhiên là ngoài gói nhân và gói tiện ích thì mọi chương trình java đều sử dụng các lớp từ gói java. hỗ trợ xây dựng đồ thị khung cảnh. Có đến hàng trăm trường và phương thức trong các lớp của Java 3D API tuy nhiên một môi trường ảo đơn giản chỉ cần dùng một vài lớp. Gói java. Lớp utility gồm 4 mục: content loader(nạp nội dung). và các công cụ tiện ích. Trong phần còn lại của giáo trình này từ visual object(đối tượng quan sát) được sử dụng thay cho “một đối tượng trong đồ thị khung cảnh”.vecmath.j3d.

Từ đó chỉ có một đường đi đồ thị khung cảnh đến mỗi lá trong một đồ thị khung cảnh. Thông tin trạng thái đó bao gồm địa điểm. Một quan hệ khác là quan hệ tham chiếu. Đồ thị khung cảnh trong Java 3D được cấu thành từ các nút đối tượng trong các mối liên hệ cha con định ra một cấu trúc cây. Một tham chiếu liên kết một đối tượng NodeComponent với một nút của đồ thị khung cảnh. hướng và bề ngoài về trực quan cũng như âm thanh của đối tượng. Với một đồ thị bình thường thì cấu trúc dữ liệu hay dùng là các nút và các cung. Một nút của đồ thị khung cảnh là một instance của một lớp Java 3D.com 209 . Các nút còn lại được truy cập tới thông qua các cung đi từ nút gốc. Quan hệ hay gặp nhất là quan hệ cha con – một nút cha có rất nhiều nút con. Bộ dựng hình Java 3D dựa trên điểm này để dựng nên các lá theo thứ tự hiệu quả nhất. Một đồ thị khung cảnh được định dạng từ các cây mà gốc tại các đối tượng xảy ra.Lập trình đồ họa trên Java 2D và 3D thị khung cảnh đó được ghép nối bởi các đối tượng được định nghĩa về mặt hình học. NodeComponent định nghĩa về mặt hình học và các thuộc tính bề mặt được sử dụng để dựng nên đối tượng quan sát. âm thanh và ánh sáng. Những người lập trình Java 3D thường không phải điều khiển quá trình này. từ đó chỉ có một đường đi duy nhất từ gốc của một đồ thị khung cảnh đến mỗi nút lá. Đường đi đó gọi là đường đi của đồ thị khung cảnh. Chỉ tồn tại một đường duy nhất từ gốc của cây đến một lá. hướng. và kích thước của đối tượng quan sát. Kết quả là các thuộc tính trực quan của mỗi đối tượng quan sát phụ thuộc vào mỗi đường đi trên đồ thị khung cảnh của nó. http://tailieuhay. Trong cây này chỉ có một nút gốc. Mỗi dường đi đồ thị khung cảnh trong đồ thị khung cảnh của Java 3D chỉ ra thông tin về trạng thái của lá. NodeComponent và các cung tham chiếu không phải là một phần của đồ thị khung cảnh. các cung trên cây không tạo thành chu trình. Các cung đại diện cho 2 dạng quan hệ giữa các instances của Java 3D. vị trí.

3 biểu tượng tiếp theo đại diện cho các đối tượng của các lớp Group. Sau khi việc thiết kế hoàn thành.com 210 . Chương trình Java 3D có thể có nhiều đối tượng hơn so với những đối tượng ở trong đồ thị này.Lập trình đồ họa trên Java 2D và 3D Về mặt đồ họa thì một đồ thị khung cảnh được dùng như là một công cụ thiết kế hoặc tài liệu hóa cho các trương trình Java 3D. Đồ thị khung cảnh được vẽ trên các biểu tượng như hình 1.1 đại điện cho một đối tượng đơn lẻ khi sử dụng trong đồ thị khung cảnh. một đồ thị khung cảnh tương tự đại diện cho chương trình (giả sử là những đặc điểm đó được tuân theo). Đối tượng được tham chiếu có http://tailieuhay. Đồ thị được vẽ từ chương trình minh chứng cho đồ thị mà chương trình tạo ra. Leaf và NodeComponent. Sau khi chương trình hoàn thành. Như vậy để thiết kế môi trường ảo. Biểu tượng cuối cùng bên trái đại diện cho bất cứ lớp của đối tượng nào. đồ thị khung cảnh được vẽ dựa trên những biểu tượng chuẩn. Nét đứt chỉ tham chiếu đến một đối tượng khác. sơ đồ đồ thị khung cảnh sẽ là tiêu chí của chương trình. Mũi tên liền đại diện cho một liên kết cha con giữa 2 đối tượng. 2 biểu tượng đầu tiên đại diện cho các đối tượng của 2 lớp đặc biệt VirtualUniverse và Locale. 3 biểu tượng sau đó thường được dùng để chỉ các lớp con của những đối tượng trên.1. Mỗi một biểu tượng ở phía bên trái của hình 1.

com 211 . mỗi đối tượng TransformGroup cha chung của đối tượng Shape3D phải đặt một hình ảnh của đối tượng quan sát trên các vị trí khác nhau.2) Rất dễ xây dựng một đồ thị khung cảnh sai. Đồ thị này sai bởi vì nó vi phạm những đặc tính của DAG. Bạn có thể nghĩ cấu trúc xây dựng trong hình 1-3 định nghĩa 3 đối tượng quan sát trong một môi trường ảo. Vấn đề nằm ở chỗ chỉ với 2 đối tượng TransformGroup có chung một đối tượng lá Shape3D là con.Lập trình đồ họa trên Java 2D và 3D thể chia sẻ giữa các nhánh khác nhau của một đồ thị khung cảnh. Nó xuất hiện trên biểu đồ khung cảnh dựa trên định nghĩa 2 đối tượng quan sát thông qua sử dụng đối tượng quan sát Shape3D phía bên phải của đồ thị. Mà dựa trên các khái niệm. Tuy nhiên đây là một đồ thị không hợp lệ vì cung cha con http://tailieuhay. Dưới đây là một ví dụ (Hình 1. Nhớ rằng một đối tượng lá chỉ có thể có 1 cha duy nhất. Nói cách khác chỉ có một đường đi từ đối tượng Locale đến 1 lá (hay là đường từ một lá đến một Locale). Một ví dụ sai đơn giản có thể xem ở hình 1-3.

Và khi vấn đề được phát hiện thì hệ thống Java 3D sẽ thông báo lỗi. Một đối tượng Locale cung cấp một điểm tham chiếu trong môi trường ảo đó. Mỗi đồ thị khung cảnh chỉ có một môi trường ảo. Chương trình Java 3D mà có đồ thị khung cảnh không hợp lệ có thể dịch được nhưng không thể dịch được. hệ thông Java 3D sẽ phát hiện ra vấn đề. Vì kết quả của sự giới hạn cấu trúc cây mà mỗi đối tượng Shape3D bị hạn chế chỉ có một cha. kết quả là đối tượng Shape3D có hơn 1 cha. Trên hình 1-4 đưa ra giải pháp cho vấn đề này.Lập trình đồ họa trên Java 2D và 3D không định ra một cây. Sự tranh cãi về cấu trúc của cây và DAG là chính xác.com 212 . Đối tượng môi trường ảo có một danh sách các đối tượng Locale. Chương trình có thể vẫn chạy nhưng vẫn cần phải dừng lại vì chẳng có hình ảnh nào dựng nên cả. Với ví dụ trong hình 1-3. Khi một chương trình Java 3D có đồ thị khung cảnh không hợp lệ được chạy. Tuy nhiên hệ thống runtime của Java 3D đưa ra thông báo có lỗi trong mối quan hệ cha con. Trong ví dụ này. Có thể coi như đối http://tailieuhay. lỗi thông báo là chính là việc có nhiều cha.

Do đó chỉ nên sử dụng một và chỉ một instance của môi trường ảo trong mỗi chương trình Java 3D. http://tailieuhay. Xa hơn. hành vi. một đối tượng đồ thị khung cảnh không thể tồn tại trong đa môi trường ảo cùng một lúc. Tuy nhiên. Nhánh hình thức chỉ ra các tham số cho phép xem như địa điểm xem và hướng xem. địa điểm. Trong khi một đối tượng môi trường ảo có thể tham chiếu đến nhiều đối tượng Locale thì hầu hết các chương trình Java 3D chỉ có một đối tượng Locale. Mỗi đối tượng Locale có thể phục vụ như là gốc của nhiều đồ thị con của đồ thị khung cảnh. Nhánh nội dung chỉ ra nội dung của môi trường ảo – hình học. thể có nhiều môi trường ảo trong một chương trình Java 3D. và ánh sáng. Theo ví dụ ở hình 1-2 có thể thấy đối tượng Locale có 2 nhánh đồ thị con từ nó. không có cách cố định nào cho việc liên lạc giữa các môi trường ảo này. bề mặt.com 213 .Lập trình đồ họa trên Java 2D và 3D tượng Locale là cột mốc sử dụng để xác định vị trí của các đối tượng quan sát trong môi trường ảo. âm thanh. Các đồ thị con thì phân ra làm 2 loại nhánh hình thức và nhánh nội dung. vì thế có thể định nghĩa nhiều hơn một môi trường ảo.

định nghĩa những phương thức chung và rất quan trọng cho các lớp con của nó. Thông qua cấu trúc này chúng ta sẽ hình dung được chương trình Java 3D như thế nào. Lớp node Lớp node là lớp cha của 2 lớp Group và Leaf. Trong đồ thị khung cảnh hình ảnh đại diện của 2 lớp này có biểu tượng là hình tròn và thường được viết tắt thành BG và TG. 2 lớp con của là BranchGroup và TransformGroup. Thông tin về các phương thức này sẽ được mô tả ở phần sau của tài liệu Lớp Group Lớp group là lớp gốc sử dụng để chỉ ra vị trí và hướng của đối tượng quan sát trong một môi trường ảo.Lập trình đồ họa trên Java 2D và 3D 1.1 Thừa kế cấp cao từ Java 3D API Có 3 cấp thừa kế từ Java 3D API thể hiện trong hình 5-1.3.com 214 . Lớp Leaf http://tailieuhay.

Lập trình đồ họa trên Java 2D và 3D Lớp Leaf là lớp gốc để định nghĩa hình dạng. âm thanh. Một NodeComponent có thể được tham chiếu bới nhiều đối tượng Shape3D. Những đối tượng này có thể không có lớp con nhưng phải tham chiếu đến NodeComponent. http://tailieuhay. Behavior và Sound. Một vài lớp con của lớp này là Shape3D. texture và những thuộc tính của node Shape3D. NodeComponent không phải là một phần của đồ thị khung cảnh nhưng lại được tham chiếu đến. và hành vi của đối tượng quan sát trong mội trường ảo.com 215 . bề mặt. Light. Lớp NodeComponent Lớp NodeComponent là lớp gốc sử dụng để mô tả về hình học.

Đây là công thức hữu ích để xây dựng các ứng dụng Java 3D.3.com 216 .1 Công thức đơn giản để viết một chương trình Java 3D Các chương trình của Java 3D được viết sử dụng công thức trên có nhánh đồ thị hình thức có cấu trúc đúng đắn. Create a PhysicalBody object d. PhysicalBody. and Canvas3D objects to View object http://tailieuhay. 1.4 Cách thức để viết một chương trình Java 3D Việc xây dựng một chương trình Java 3D gồm có 7 bước được giới thiệu trong hình 1-6. Mỗi instance của lớp này thực hiện các bước 2. và cấu trúc này đã sẵn có trong lớp SimpleUniverse. Công việc thực sự khi viết một chương trình Java 3D là như vậy. Công thức này cũng bỏ qua môt vài chi tiết nhưng diễn tả phần lớn những công việc cần làm trong đó việc tạo các nhánh đồ thị của đồ thị khung cảnh là công việc quan trọng nhất của việc lập trình. Create a View object b. PhysicalEnvironment. Construct a view branch graph a. attaching it to the VirtualUniverse object 4. Attach ViewPlatform. Trong phần tới chúng ta sẽ được biết làm thể nào để tạo một đồ thị khung cảnh mà không phải lập trình nhiều. Create a Canvas3D object 2. Create a VirtualUniverse object 3. Create a ViewPlatform object c.Lập trình đồ họa trên Java 2D và 3D 1. Create a PhysicalEnvironment object e.4 trên công thức cơ bản trên điều đó giúp cho người lập trình giảm thiểu thời gian và công sức để tạo nhánh hình thức qua đó tập trung vào công việc chính là nội dung hơn.4. Create a Locale object. 1.

Construct content branch graph(s) 6.universe chứa các lớp SimpleUniverse.utils. Compile branch graph(s) 7. http://tailieuhay. SimpleUniverse Class Hàm khởi tạo của đối tượng SimpleUniverse tạo nên đồ thị khung cảnh bao gồm các đối tượng VirtualUniverse và Locale và một nhánh đồ thị hình thức hoàn thiện.com 217 .sun. Insert subgraphs into the Locale Việc sử dụng lớp này cho phép người lập trình tạm quên đi nhánh đồ thị hình thức. ViewingPlatform và Viewer.j3d. Nhánh này sử dụng instances của các lớp ViewingPlatform và Viewer trong nhân của lớp để tạo thành nhánh đồ thị hình thức. Gói com. Tuy nhiên nó không cho phép có nhiều view trong môi trường ảo của nó.Lập trình đồ họa trên Java 2D và 3D 5. Đối tượng SimpleUniverse cung cấp tất cả các chức năng được chỉ ra trong hình 17.

1.4 đã được thay bằng bước 2 của công thức mới. Hình 1-8 đưa ra công thức đơn giản hơn trong đó các bước 2. Compile content branch graph 5. Một bảng hình ảnh là một dạng hình chữ nhật là nơi mà nội dung của được chiếu đến để định dạng hình ảnh cần dựng.universe Lớp tiện ích này cho phép dễ dàng cài đặt môi trường người dùng. Create a Canvas3D Object 2.sun. ViewingPlatform và Viewer (với tất cả các giá trị mặc định của chúng). có thể coi như là một bảng hình ảnh vậy. Phương thức khởi tạo quan trọng SimpleUniverse () Khởi tạo một môi trường ảo SimpleUniverse (Canvas3D canvas3D) Khởi tạo một môi trường ảo với tham chiếu đến đối tượng được đặt tên là Canvas3D Đối tượng SimpleUniverse tạo thành một đồ thị nhánh hình thức hoàn thiện cho một môi trường ảo. Insert content branch graph into the Locale of the SimpleUniverse SimpleUniverse Constructor gói com. Create a SimpleUniverse object which references the earlier Canvas3D object a. Lớp này tạo nên các đối tượng Locale. VirtualUniverse. tạo các đối tượng cần thiết cho đồ thị nhánh hình thức. Các đối tượng này liên hệ với nhau để tạo nên đồ thị nhánh hình thức. Customize the SimpleUniverse object 3.Lập trình đồ họa trên Java 2D và 3D Việc sử dụng lớp SimpleUniverse là cho công việc đơn giản hơn rất nhiều. Construct content branc h 4.j3d. Để rõ hơn chúng ta quan sát hình http://tailieuhay. Đồ thị này bao gồm một bảng hình ảnh.com 218 .utils. Đối tượng Canvas3D cung cấp hình ảnh trên một cửa sổ trên màn hình hiển thị của máy tính.3.

utils. Vị trí của mắt là đằng sau bảng hình ảnh.0. Lớp ViewingPlatform. hướng mặc định là nhìn theo trục z.0. Chương trình Java 3D thông thường sẽ chuyển điểm nhìn ra phía sau (hướng dương của trục z) để làm cho đối tượng ở vị trí hoặc gần so với vị trí ban đầu giữa hướng nhìn. Việc dựng hình cũng ví như chiếu một đối tượng quan sát lên bảng hình ảnh.com 219 . lớp này có phương thức setNominalViewingTransform cho phép chuyển vị trí của mắt nhìn tới trung tâm là (0. 2.universe http://tailieuhay. Lớp SimpleUniverse có một lớp thành viên là ViewingPlatform. môi trường ảo. phương thức setNominalViewingTransform () Package: com. hình 1-9 chỉ ra mối quan hệ giữa bảng hình ảnh (image plate) và vị trí của mắt. Trục y là cạnh ngang của bảng hình ảnh với giá trị dương hướng lên trên.0) là tâm của bảng hình ảnh.j3d. Từ vị trí này trục x là đường biên ngang của bảng hình ảnh với hướng dương là bên phải. Đối tượng quan sát đứng trước bảng hình ảnh được dựng trên bảng hình ảnh.Lập trình đồ họa trên Java 2D và 3D ảnh dưới đây.41) nhìn từ phía âm của trục z so với vị trí ban đầu. Thông thường thì vị trí (0.sun. Mặc định bảng hình ảnh đặt trung tâm của SimpleUniverse ban đầu..

Phương thức này thường được sử dụng để kết nối với phương thức getViewingPlatform của lớp SimpleUniverse.41 mét từ trong biến đổi tầm nhìn của một SimpleUniverse. Phương thức này lấy một instance của BranchGroup như là tham số duy nhất. Sau khi tạo xong đồ thị nhánh nội dung.Lập trình đồ họa trên Java 2D và 3D Lớp ViewingPlatform được sử dụng để thiết lập đồ thị nhánh hình thức của đồ thị khung cảnh Java 3D với đối tượng SimpleUniverse. ViewingPlatform getViewingPlatform() http://tailieuhay.sun. void setNominalViewingTransform() Set tầm nhìn khoảng cách khoảng 2.j3d. nó được chèn vào môi trường sử dụng phương thức addBranchGraph của SimpleUniverse. Tại khoảng cách này và thì đối tượng với chiều cao khoảng 2 mét so thể vừa vặn với bảng hình ảnh.utils. Sau khi tạo xong các đối tượng Canvas3D và SimpleUniverse. Đồ thị nhánh nội dung biến đổi khác nhau từ chương trình này đến chương trình khác do đó có thể xây dựng chi tiết trong công thức. Điều đó có nghĩa là không có những lớp nội dung đơn giản cho bất cứ môi trường nào mà bạn muốn thiết lập.universe void addBranchGraph(BranchGroup bg) Sử dụng để thêm nút vào đối tượng Locale của đồ thị khung cảnh được tạo bởi SimpleUniverse. BranchGroup này chỉ được thêm vào như là một con của đối tượng Locale được tạo bởi SimpleUniverse. Điều này sử dụng để thêm vào một đồ thị nhánh nội dung tới môi trường ảo. Các phương thức SimpleUniverse Package: com.com 220 . bước tiếp theo là tạo đồ thị nhánh nội dung. Quy tắc của cấu trúc được tìm thấy trong đồ thị nhánh hình thức (do việc sử dụng lớp SimpleUniverse).

2). Khi chèn một đồ thị nhánh vào Locale làm cho nó có thể sống (“live”) và kết quả là mỗi đối tượng của đồ thị nhánh trở thành sống. và NodeComponent. Những đối tượng sống là những đối tượng mà chuẩn bị được dựng hình. Mục đích của công việc này là chuẩn bị bước cuối cùng trước khi làm cho đối tượng đó sống. http://tailieuhay. Phương thức BranceGroup compile () Void compile () Dịch nguồn BranchGroup tương ứng với đối tượng bằng cách tạo và đệm một đồ thị khung cảnh đã được dịch. 1. Leaf. 2 phương thức của SceneGraphObject được mô tả dưới đây. Phương thức này sử dụng với phương thức setNominalViewingTransform () của lớp ViewingPlatform để điều chỉnh vị trí quan sát. Việc dịch BrandGroup chuyển đối tượng BranchGroup và tất cả những hình thức sơ khai của nó thành dạng phù hợp để dựng hình. Danh sách các phương thức cơ bản của SceneGraphObject SceneGraphObject là lớp cơ bản của tất cả các lớp lân cận dùng để tạo đồ thị khung cảnh bao gồm Group. Khi các đối tượng BranchGroup được dịch (compiled).5 Một vài thuật ngữ trong Java 3D Hai thuật ngữ được nói trong phần này là “live” và “compiled”. Cơ sở của việc dịch và sống được bổ sung trong lớp SceneGraphObject.com 221 . cho nên những tham số của một đối tượng sống không thể thay đổi trừ khi khả năng tương ứng của nó được thiết lập trước khi đối tượng sống (capability được mô tả trong phần 1.8.Lập trình đồ họa trên Java 2D và 3D Sử dụng để lấy thông tin từ đối tượng ViewingPlatform mà SimpleUniverse chỉ ra.

com 222 . http://tailieuhay. Những thảo luận xung quanh đồ thị nhánh nội dung được xoay quanh các ví dụ của chương trình. Việc tạo đồ thị nhánh nội dung là chủ đề của một số phần tiếp theo. 2 phương thức được trình bày dưới đây. bộ dựng hình Java 3D thực hiện hoạt động như hình 1-10 while(true) { Process input If (request to exit) break Perform Behaviors Traverse the scene graph and render visual objects } Cleanup and exit Phần trước đó đã giải thích cấu trúc của một môi trường ảo đơn giản mà không có đồ thị nhánh nội dung. Khi đã bắt đầu.Lập trình đồ họa trên Java 2D và 3D SceneGraphObject cung cấp khá nhiều phương thức và thuộc tính cho các lớp con của nó. Bộ dựng hình của Java 3D bắt đầu chạy trong một vòng lặp vô hạn khi một đồ thị nhánh chứa một instance của View băt đầu sống trong một môi trường ảo. boolean isCompiled() Trả về một giá trị cờ chỉ ra khi nào thì node (là một phần của đồ thị khung cảnh được dịch) boolean isLive () Trả về giá trị cờ chỉ ra khi nào node là một phần của đồ thị khung cảnh sống Chú ý rằng không có bước “bắt đầu dựng hình”cả trong công thức cơ bản lẫn công thức đơn giản đã nói ở trên.

add("Center". Lớp chính của chương trình Java 3D thường định nghĩa phương thức thiết lập đồ thị nhánh nộ dung. Bước 4 dịch đồ thị nhánh nội dung được thực hiện trong dòng 10. và việc sử dụng nó giúp đơn giản đi rất nhiều so với chương trình Java 3D được viết như ứng dụng độc lập.java dưới đây ta cũng có lớp HelloJava3Da được mở rộng từ lớp Applet. Trong ví dụ HelloJava3Da. Bước 2 tạo đối tượng SimpleUniverse hoàn thành ở dòng 17.Lập trình đồ họa trên Java 2D và 3D 1. Bước 1. Trong ví dụ này phương thức như thế được đặt tên là creatSceneGraph(). // Utility class SimpleUniverse is a Convenience http://tailieuhay. canvas3D). Canvas3D canvas3D = new Canvas3D(null).com 223 . Cuối cùng bước thứ 5 chèn đồ thị nhánh nội dung vào Locale của SimpleUniverse thực xong ở dòng 19. BranchGroup scene = createSceneGraph().6 Ví dụ đơn giản: HelloJava3Da Chương trình Java 3D bắt đầu bằng việc định nghĩa lớp mới mở rộng từ lớp Applet. được hoàn thành bằng lời gọi ở đến phương thức creatSceneGraph(). Bước 3 tạo nhánh nội dung.tạo đối tượng Canvas3D (dòng 4 đến dòng 6). Mọi bước theo công thức phía trên đều được thể hiện trong lớp HelloJava3Da. public class HelloJava3Da extends Applet { public HelloJava3Da() { setLayout(new BorderLayout()).

// This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. Đó là đồ thị nhánh nội dung đơn giản nhất có thể.setNominalViewingTra nsform(). objRoot.getViewingPlatform(). simpleU = new simpleU. public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). simpleU.4)).addChild(new ColorCube(0. return objRoot. Một đồ thị nhánh nội dung được tạo trong đoạn mã 1-2. Hình này được đặt ở vị trí ban đầu trong hệ thống thế giới ảo.Lập trình đồ họa trên Java 2D và 3D SimpleUniverse SimpleUniverse(canvas3D). hình lập phương này xuất hiện như hình chữ nhật khi được dựng lên.addBranchGraph(scene).com 224 . http://tailieuhay. Nó chứa một đối tượng đồ họa tĩnh đó là hình lập phương màu. } // end of HelloJava3Da (constructor) Ta thấy bước 3 của công thức này là tạo đồ thị nhánh nội dung. Với vị trí và hướng nhìn này.

Đoạn mã 1-3 bên dưới sẽ chỉ ra cách sử dụng trong HelloJava3Da.Applet applet.sun.j3d.Runnable. java.com 225 .Frame và bổ sung thêm Hàm MainFrame(java. Tham số: Applet – Hàm tạo của một lớp thừa kế từ applet.utils. 256. từ java. 256).applet. http://tailieuhay. Một lớp thừa kế từ applet có thể có phương thức main() dùng để gọi hàm khởi tạo của MainFrame. int height) Tạo tạo đối tượng Mainframe cho phép applet chạy như ứng dụng độc lập.lang.applet. int width. Lớp Applet được sử dụng là lớp cơ sở để dễ dàng cho việc viêt một chương trình Java 3D chạy trên một cửa sổ.Lập trình đồ họa trên Java 2D và 3D } // end of CreateSceneGraph method of HelloJava3Da Lớp HelloJava3Da được thừa kế từ Applet nhưng chương trình có thể chạy như là một ứng dụng với việc sử dụng lớp MainFrame.AppletStub. MainFrame cung cấp AWT frame public static void main(String[] args) { Frame frame = new MainFrame(new HelloJava3Da().AppletContext. Kích thước của cửa sổ được chỉ ra trong phần thiết lập của lớp MainFrame.applet MainFrame giúp cho một applet có thể chạy như một ứng dụng. và java.java. MainFrame cung cấp một AWT frame (cửa sổ) cho một apple điều đó cho phép apple chạy như một ứng dụng.awt. MainFrame ConStructor package: com.applet. MainFrame mở rộng từ java.

ColorCube.j3d.MainFrame. hoặc javax.geometry.sun.media. import com. import java.sun. 1-3 trên định nên một chương trình Java 3D hoàn thiện khi các câu lệnh import được sử dụng.utils. import java.utils.j3d.Frame. import com.com 226 .Canvas3D.awt. import javax. ngoại trừ lớp tiện ích ColorCube.Applet.geometry kết quả là hầu hết chương trình Java 3D đều có những câu lệnh để import các thư viện như hình 1-4.applet.utils.j3d.awt. Trong ví dụ phía trên một đối tượng đồ họa đơn được đặt trong một vị trí đơn.j3d. 1-2.media.media. Trong ví dụ này lớp tiện ích ColorCube được tìm thấy trong gói com.applet.sun.BorderLayout.Lập trình đồ họa trên Java 2D và 3D } // end of main (method of HelloJava3Da) Ba đoạn mã 1-1.vecmath.j3d.SimpleUniverse. Hầu hết các lớp sử dụng trong chương trình Java 3D ở trong các gói javax. Ta có đồ thị khung cảnh như bên dưới: http://tailieuhay.j3d.utils.BranchGroup. import javax. import java.universe. import com.j3d.sun.

Lập trình đồ họa trên Java 2D và 3D Mã nguồn của chương trình là: package HelloJava3D. import javax.sun. import com.applet.setNominalViewingTransform(). public class HelloJava3Da extends Applet { public HelloJava3Da() { setLayout(new BorderLayout()).Applet. import com. // SimpleUniverse is a Convenience Utility class SimpleUniverse simpleU = new SimpleUniverse(canvas3D). // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed.j3d. add("Center". import javax.MainFrame. http://tailieuhay. canvas3D).com 227 . rotating cube.Canvas3D. BranchGroup scene = createSceneGraph(). simpleU.j3d.BorderLayout.awt. // HelloJava3Da renders a single. import com.media. import java.j3d.utils.geometry. Canvas3D canvas3D = new Canvas3D(null).utils.sun.universe.sun.applet.utils.ColorCube. import java. import java.getViewingPlatform().SimpleUniverse.media.j3d.j3d.awt.BranchGroup.Frame.

objRoot. 256. 256). return objRoot. } // end of CreateSceneGraph method of HelloJava3Da // The following allows this to be run as an application // as well as an applet public static void main(String[] args) { Frame frame = new MainFrame(new HelloJava3Da().addChild(new ColorCube(0.com 228 . } // end of main (method of HelloJava3Da) } // end of class HelloJava3Da Kết quả của chương trình chạy là: http://tailieuhay.addBranchGraph(scene).4)).Lập trình đồ họa trên Java 2D và 3D simpleU. } // end of HelloJava3Da (constructor) public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().

BranchGroup có thể có nhiều con.com 229 . BranchGroup constructor BranchGroup () Instance của BranchGroup được coi là gốc của một nhánh đồ thị. Mỗi instance của BranchGroup là gốc của một đồ thị con. con của nó có thể là Group hoặc Leaf.6.Lập trình đồ họa trên Java 2D và 3D 1.1 Các lớp của Java 3D Classes được sử dụng trong HelloJava3Da Để hiểu chi tiết hơn về các lớp Java 3D và ví dụ trên chúng ta quan tâm đến những lớp sau: Lớp BranchGroup Đối tượng kiểu này thường được dùng để định dạng đồ thị khung cảnh. http://tailieuhay. mỗi đối tượng BranchGroup chỉ là đối tượng có thể chèn vào tập các đối tượng của Locales. Đối tượng BranchGroup chỉ được phép là con của đối tượng Locale.

có khả năng liên kết với các đối tượng Transform3D khác. Lớp Transform3D Đối tượng Transform3D đại điện cho việc biến hình của hình học 3D như dịch và quay. quay. biến hình theo quy mô. Đối tượng Transform3D không được sử dụng trong đồ thị khung cảnh. Nó là phần mở rộng của lớp AWT Canvas.hoặc là kết hợp các phương pháp trên lại. Đầu tiên đối Transform3D được khởi tạo. Những đối tượng này thường chỉ sử dụng để tạo một đối tượng TransformGroup.Lập trình đồ họa trên Java 2D và 3D Lớp Canvas3D Lớp Canvas3D được thừa kế từ Canvas của AWT. Transform3D Default Constructor Mội đối tượng tổng quan khi thay đổi hình dáng thông qua một ma trận 4x4 với các điểm thực. Canvas3D constructor Canvas3D(GraphicsConfiguration graphicsconfiguration) Khởi tạo và thiết lập một đối tượng Canvas3D mới cho phép Java 3D có thể dựng nên cấu hình đúng đắn của đối tượng (GraphicsConfiguration). Một vòng quay đầy đủ http://tailieuhay. Transform3D() Tạo đối tượng Transform3D mà đại diện cho ma trận ban đầu (không có biến đổi) Một đối tượng Transform3D có thể đại diện cho tịnh tiến. Sau đó TransformGroup được khởi tạo sử dụng Transform3D vừa tạo. góc được thể hiện dưới dạng radians.com 230 . Khi có hiện tượng quay. Nó chỉ được dùng để chỉ ra sự biến hình của một đối tượng TransformGroup. Tối thiểu một đối tượng Canvas3D phải được tham chiếu đến trong một đồ thị nhánh hình thức của đồ thị khung cảnh.

mỗi instance của TransformGroup được sử dụng để tạo đồ thị khung cảnh và có một tập các đối tượng nút con.dịch phóng lớn thu nhỏ. nếu không thì có thể chỉ ra góc quay chính xác. Việc biến hình do Transform3D điều khiển đều được tác động lên đối tượng TransformGroup mà được sử dụng trên đồ thị khung cảnh. void rotX(double angle) Phép quay với trục X ngược chiều kim đồng hồ. Lớp TransformGroup Đây là lớp con của lớp Group. Các phương thức của Transform3D Đối tượng Transform3D đại diện cho các phép biến đổi hình học như quay. Transform3D là một trong số it các lớp không trực tiếp sử dụng trong đồ thị khung cảnh. void rotZ(double angle) Phép quay với trục Z ngược chiều kim đồng hồ.com 231 . void set(Vector3f translate) Tạo giá trị biến đổi của ma trận cho giá trị của tham số Vertor3f.Lập trình đồ họa trên Java 2D và 3D là 2 PI radians. với góc (angle) là giá trị radian. Đối tượng TransformGroup giữ giá trị biến hình.PI. TransformGroup Constructors http://tailieuhay. với góc (angle) là giá trị radian. với góc (angle) là giá trị radian. Việc biến hình thường được tạo trên đối tượng Transform3D vốn không phải là một đối tượng của đồ thị khung cảnh. và tạo các thành phần khác của ma trận nếu việc biến hình dựa trên ma trận. Một cách để chỉ ra góc quay là sử dụng hằng Math. void rotY(double angle) Phép quay với trục Y ngược chiều kim đồng hồ.

Lập trình đồ họa trên Java 2D và 3D TransformGroup() Khởi tạo và thiết lập một đối tượng TransformGroup sử dụng phép biến đổi đồng nhất TransformGroup(Transform3D t1) Khởi tạo và thiết lập một đối tượng TransformGroup từ một đối tượng Transform3D Tham số: t1 – đối tượng Transform3D Phép biến hình lưu trong đối tượng Transform3D được copy vào một đối tượng TransformGroup khi đối tượng TransformGroup được tạo hoặc bằng cách sử dụng phương thức Transform ().com 232 . Vector3f Constructors Vector3f() Tạo và thiết lập các giá trị Vertor3f cho (0. float z) Tạo và thiết lập các giá trị Vertor3f cho (x. Chúng thường được sử dụng để chỉ ra các đặc đính biến đổi.y.vecmath để định ra một vertor sử dụng 3 điểm số thực. Đối tượng Vertor3f không được sử dụng trực tiếp trong cấu trúc của đồ thị khung cảnh. TransformGroup setTransform() void setTransform(Transform3D t1) Lập thành phần biến hình của TransformGroup cho giá trị của phép biến hình trước đó Tham số: T1 – phép biến hình cần sao chép Lớp Vertor3f Là lớp toán học trong gói javax.0) Vector3f(float x. float y.z) ColorCube http://tailieuhay.0. Các đối tượng vertor thường được sử dụng để chỉ ra phép biến hình trong hình học.

Đối tượng Transform3D được tạo ra ở dòng 6.com 233 . Đoạn mã 1-5 đưa ra một đối tượng Transform3D trong đồ thị khung cảnh để quay hình lập phương quanh trục x. ColorCube () Tạo một hình lập phương với kích thước mặc định. Trong đó góc quay được xác định thông qua tham số đầu vào. public BranchGroup createSceneGraph() { http://tailieuhay. vị trí ở 1 mét cách mỗi trục tọa xyz ColorCube(double scale) Tạo nên hình lập phương có kích thước được định ra bởi các giá trị cho trước. Đối tượng Transform3D được sử dụng trong đồ thị khung cảnh đối tượng objRotate sau đó lấy đối tượng ColorCube làm con của nó. ColorCube rất dễ sử dụng khi đưa vào trông một môi trường ảo. Đến lượt objRoot lại lấy objRotate làm con.j3d. Do đó phép biến hình đầu tiên là quay. 1.sun. sử dụng phương thức rotX() ở dòng 8. Đối tượng Transform3D được tạo xong thì được sử dụng để tạo đối tượng TransformGroup là objRotate. được mở rộng từ lớp Shape3D.Lập trình đồ họa trên Java 2D và 3D ColorCube Constructors Package: com.utils. từ đó là một nút lá. Đối tương TransformGroup sau đó được tạo giữ thông tin quay ở dòng thứ 10.geometry Là một hình lập phương các mặt có các màu khác nhau. tham số chỉ ra phép quay này:là trục và góc quay.7 Quay hình lập phương Để quay hình lập phương chúng ta vừa tạo thì bước đầu tiên là tạo phép biến hình mong muốn sử dụng đối tượng Transform3D.

0d). rotate. rotate.Lập trình đồ họa trên Java 2D và 3D // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). objRoot.com 234 .compile(). objRotate.0d).addChild(new ColorCube(0.mul(tempRotate). objRoot. return objRoot.addChild(objRotate).PI/4. tempRotate. objRotate = new http://tailieuhay. // Let Java 3D perform optimizations on this scene graph. Transform3D tempRotate = new Transform3D().4)).rotX(Math.PI/5. chú ý là đối tượng BranchGroup bao giờ cũng là con của một Locale. } Như vậy bên đồ thị nhánh nội dung có các đối tượng như hình dưới. TransformGroup TransformGroup(rotate).rotY(Math. // rotate object has composited transformation matrix Transform3D rotate = new Transform3D().

Trong ví dụ hình 1-6 chúng ta quan sát dưới đây thực hiện 2 phép quay trên 2 trục x và y. ở ví dụ của chúng ta là sẽ có 2 phép biến hình đồng thời. 2 phép biến đổi có thể thông qua một ma trận biến đổi và được giữ bởi một đối tượng TransformGroup. Sau đó 2 phép quay riêng rẽ này được chỉ ra trên 2 đối tượng TransformGroup (dòng 9 và 10). Sau đó các phép quay được nối lại với nhau bằng các nhân đối tượng Dưới đây là đồ thị khung cảnh và kết quả chạy chương trình Kết quả: http://tailieuhay. sẽ được chỉ trên một đối tượng quan sát duy nhất.7. 2 đối tượng Transform3D với mỗi phép quay được tạo ra ở dòng 6 và 7.1 Sự kết hợp của các phép biến hình: HelloJava3Db Trong trường hợp có nhiều phép biến hình đồng thời xảy ra.com 235 .Lập trình đồ họa trên Java 2D và 3D 1.

com 236 . Thêm vào đó. Với một miêu tả tốt hơn của môi trường ảo sẽ tăng cường khả năng dựng hình rất nhiều. Một trong những cách đó là. tuy nhiên mô tả của nó lại không hiệu quả. http://tailieuhay.1 Dịch các nội dung Đối tượng BranchGroup có một phương thức dịch. 1.8.Lập trình đồ họa trên Java 2D và 3D 1. những mô tả bên trong này có thể tối ưu hóa theo cách này hay cách khác.8 Khả năng và hoạt động Đồ thị khung cảnh được tạo bởi chương trình Java 3D có thể sử dụng trực tiếp trong việc dựng hình. Hình 1-16 dưới đây đưa ra một mô tả mới hiệu quả hơn. Phương thức này chuyển toàn bộ đồ thị nhánh dưới thành các mô tả Java 3D trong của đồ thị nhánh. kết hợp TransformGroups với đường đi đồ thị khung cảnh . Một cách khác là liên kết đối tượng Shape3D vốn có mối liên hệ vật lí tĩnh. Ví dụ nếu một đồ thị khung cảnh có 2 đối tượng TransformGroup trong một mối liên hệ cha con chũng có thể đại diện bằng một đối tượng TransformGroup.

Một danh sách các tham số có thể truy cập được và khi đó người ta gọi là năng lực (capability) của một đối tượng. Ví dụ như việc thay đổi giá trị của một đối tượng TransformGroup tạo hoạt họa.8. Việc biến đổi qua mô tả bên trong có những tác động khác nhau. Một trong số đó là cố định giá trị biến hình và các đối tượng trong đồ thị khung cảnh. Trừ phi có chỉ ra chi tiết của chương trình. Có những trường hợp một chương trình vẫn cần khả năng thayđỏi giá trị của chúng trong một đối tượng đồ thị khung cảnh sau khi nó “sống”. Giá trị của các bit này xác định khả năng có thể tồn tại cho đối tượng sau khi http://tailieuhay.2 Khả năng Một khi đồ thị nhánh được làm cho sống và dịch. thì sẽ không có khả năng thay đổi giá trị của các đối tượng đồ thị khung cảnh sau khi chúng “sống”.com 237 . Mỗi đối tượng SceneGraphObject có một tập các bit năng lực. qua đó cũng tăng cao hiệu năng dựng hình.Lập trình đồ họa trên Java 2D và 3D 1. hệ thống dựng hình của Java 3D chuyển đồ thị nhánh sang một mô tả bên trong hiệu quả hơn.

Trong phần tới. TransformGroup Capabilities khả năng dưới đây là một trong những khả năng được định nghĩa bởi TransformGroup. http://tailieuhay. Như trong một ví dụ đã nói. Leaf và NodeComponent. để có thể đọc được giá trị biến hình đại diện cho một đối tương TransformGroup. Tập các năng lực này biến đổi khác nhau trên các lớp. void clearCapability(int bit) Xóa các bit khả năng boolean getCapability(int bit) Phục hồi. TransformGroup thừa kế rất nhiều bit khẳ năng của lớp tiền bối của nó là Group và Node. ALLOW_TRANSFORM_WRITE Cho phép ghi tới thông tin biến hình của đối tượng của nó.com 238 . các hoạt họa có thể được tạo ra tùy theo các thời gian khác nhau của phép biến hình. Đối tượng TransformGroup. SceneGraphObject Methods SceneGraphObject là lớp gốc thường được sử dụng để tạo một đồ thị khung cảnh bao gồm cả Group. thì các khả năng của nó phải được thiết lập trước khi hoặc nó được dịch hoặc trở nên sống. Muốn có điều này TransformGroup phải có tập khả năng ALLOW_TRANSFORM_WRITE trước khi nó được dịch hoặc sốngViệc điều khiển khẳ năng truy cập đến các lĩnh vực khác của đối tượng TransformGroup cũng như vậy.Lập trình đồ họa trên Java 2D và 3D nó được dịch hay sống. Các khả năng như set.reset hay retrieve được địng nghĩa ở SceneGraphObject. ALLOW_TRANSFORM_READ Chỉ ra các nút cho phép truy cập tới thông tin biến hình của đối tượng của nó.

Sự khác nhau giữa animation và interaction là khi nào thuộc tính được kích hoạt khi phàn hồi qua thời gian hay phản hồi qua các hành động của người sử dụng. ALLOW_CHILDREN_WRITE Thiết lập khả năng cho phép them chiếu đến các con của nút Group để ghi hay thay đổi sau khi nó được dịch hoặc sống.Lập trình đồ họa trên Java 2D và 3D Group Capabilities TransformGroup thừa kế các khả năng từ các lớp cha của nó.com 239 .9 Thêm vào các hành vi animation Trong Java 3D. Trong một môi trường ảo với rất nhiều hành vi. Khi cả việc dựng hình và các hành vi sử dụng cùng chung nhiều process. Người lập trình có thể thay đổi bất cứ thuộc tính nào của một đối tượng quan sát. http://tailieuhay. Behavior là một lớp quan trọng về animation với các tương tác của các đối tượng. thêm vào các đối tượng quan sát tới đồ thị khung cảnh và xây dựng những tham chiếu giữa các đối tượng đồ thị và các đối tượng hành vi. thì thật khó có thể nâng cao hiệu năng hoạt động được. ALLOW_CHILDREN_READ Thiết lập khả năng cho phép các tham chiếu đến con của nút Group có thể được đọc sau khi nó được dịch hoặc sống. Thực tế thì thường có nhiều hành vi . 1. ALLOW_CHILDREN_EXTEND Thiết lập khả năng cho phép con có thể thêm vào nut Group sau khi nó được dịch hoặc sống. Với mỗi đối tượng quan sát trong một môi trường ảo có thể có những hành vi sẵn có của nó. Để chỉ ra một hành vi cho một đối tượng quan sát. người lập trình tạo một đối tượng mà chỉ ra hành vi đó. thì cần một lượng tính toán rất lớn.

Create a target TransformGroup Set the ALLOW_TRANSFORM_WRITE capability 2. Hình 1-7 chỉ ra các bước bao gồm cả việc định ra một animation với một đối tượng thêm vào. Create an Alpha5 object Specify the time parameters for the alpha 3. Create the interpolator object Have it reference the Alpha and TransformGroup objects Customize the behavior parameters 4. Tính năng vùng danh mục làm cho Java 3D hiệu qua hơn trong việc nắm bắt một môi trường ảo với rất nhiều hành vi.9.1 Định nghĩa các hành vi animation Một hành vi có thể thay đổi trên địa điểm (PositionInterpolator).không có chỗ trong rừng để lá rơi thì sẽ không có lá rơi. kích cỡ(ScaleInterpolator). Tất cả các hành vi nói trên đều có thể sử dụng mà không cần định trước tuy nhiên việc định trước cho phép việc http://tailieuhay. Make the behavior a child of the TransformGroup 1. Nói cách khác. Specify a scheduling region Set the scheduling region for the behavior 5. hướng (RotationInterpolator). 1. Một hành vi không hoạt động trì phi activation volume của ViewPlatform phân cắt một vùng danh mục đó. Như đã nói ở phía trên Interpolator là các lớp hành vi được định nghĩa trước.com 240 . Khu vực này được gọi là scheduling region. màu sắc(ColorInterpolator) hoặc độ trong suốt(TransparencyInterpolator) của một đối tượng quan sát.Lập trình đồ họa trên Java 2D và 3D Java 3D cho phép lập trình viên có thểm quản lí vấn đề này bằng cách chỉ ra vị trí của một hành vi.

Lớp RotationInterpolator Lớp này sử dụng để chỉ ra một hành vi quay của một đối tượng quan sát hoặc một nhóm các đối tượng như vậy. Giá trị này phụ thuộc vào thời điểm và thông số của đối tượng Alpha. Lớp này cung cấp các giá trị giữa 0 và 1. Lớp Alpha Lớp này được sử dụng để tạo hàm biến đổi theo thời gian.. Một đối tượng RotationInterpolator thay đổi một đối tượng TransformGroup qua một phép quay khi phản hồi giá trị của một đối tượng Alpha. bằng đối tượng TransformGroup được chỉ ra bằng hành vi mặc định.2 Các hàm biến đổi về thời gian: Ánh xạ một hành vi với thời gian Việc ánh xạ một đối tượng với thời gian thông qua một đối tượng Alpha. Một đối tượng RotationInterpolator rất linh động trong việc chỉ ra trục quay. Tham số: alpha – thời gian hàm thay đổi để tham chiếu target – đối tượng TransformGroup cần thay đổi 5 Alpha là một lớp trong Java 3D để tạo ra các hàm biến đổi thời gian. Đối tượng Alpha thường được sử dụng với các đối tượng hành vi sẵn có để thực hiện các thay đổi hoạt họa của các đối tượng quan sát.9. RotationInterpolator Constructor RotationInterpolator(Alpha alpha. TransformGroup target) Hàm khởi tạo này sử dụng các giá trị mặc định cho một vài tham số của hành vi mặc định để khởi tạo một phép quay đầy đủ trên trục y. http://tailieuhay. Các lớp định trước này cung cấp các hành động khác nhau thậm chí kết nối các hành động đó. góc quay ban đầu góc quay kết thúc.Lập trình đồ họa trên Java 2D và 3D tạo các hành vi trở nên dễ dàng hơn rất nhiều. Khi giá trị của đối tượng Alpha thay đổi qua thời gian việc thay đổi phép quay cũng dễ dàng.com 241 . 1.

cánh bay. Điều này lặp đi lặp lại nhiều lần thông qua loopCount. cửa mở.hay bắn rocket.9. Các tùy chọn khác như bounding box.3 Lập danh mục các vùng Như đã nói ở phần 1-9 mỗi hành vi có một vùng danh mục. Đối tượng Alpha tạo ra cung cấp giá trị khởi đầu từ 0 lên 1. Có rất nhiều cách để định nghĩa vùng danh mục này nhưng cách đơn giản nhất là tạo đối tượng BoundSphere . hoặc bouding polytope. do đó giúp cho người lập trình sử dụng linh động. Alpha Constructor Alpha() Liên tục lặp với thời gian định kì là 1 giây Alpha(int loopCount. Nếu loopCount = -1 đối tượng alpha lặp đi lặp lại vô hạn. Vùng này quanh các hành vi được thiết lập dựa trên phương thức setSchedulingBounds của lớp Behavior.Lập trình đồ họa trên Java 2D và 3D Có 10 tham số cho Alpha. Behavior setSchedulingBounds method void setSchedulingBounds(Bounds region) http://tailieuhay. Tham số: loopCount – số lần chạy đối tượng alpha này. long increasingAlphaDuration) Hàm khởi tạo này lấy loopCount và increasingAlphaDuration như là tham số và đăng kí giá trị mặc định cho tất cả các tham số còn lại.com 242 . giá trị bằng -1 lặp vô hạn increasingAlphaDuration – thời gian tính bằng giây giữa bước nhẩy từ 0 lên 1 1. Mỗi instance của đối tượng Alpha có thể dễ dàng kết hợp với một hành vi để đưa ra các phép quay đơn giản.

Đối tượng TransformGroup của môt hành vi sẵn có phải có khả năng ghi.Lập trình đồ họa trên Java 2D và 3D Xác định ranh giới cho vùng danh mục của hành vi Parameters: region – ranh giới chứa Behavior's scheduling region. Bán kính sau đó được lựa chọn đủ sao cho hình cầu chứa đối tượng quan sát. bao gồm tất cả các vị trí mà đối tượng có thể ở đó. Animation được tạo trong đoạn mã này là hình lập phương quay liên tục trong thời gian 4 giây. double radius) 2 tham số lần lượt là center – tọa độ của tâm trong không gian radius – bán kính của hình cầu 1. Lớp BoundingSphere Việc định nghĩa một vùng cầu phải đi đôi với việc chỉ ra điểm trung tâm và bán kính của nó.9.0) với bán kính bằng 1 BoundingSphere(Point3d center.com 243 . Bước đầu tiên của công thức là tạo đối tượng TransformGroup để sửa đổi tại thời điểm chạy.4 Ví dụ về hành vi: HelloJava3Dc Đoạn mã hình 1-7 đưa ra một ví dụ hoàn thiện về việc sử dụng lớp thêm vào để tạo animation.0). http://tailieuhay. Khả năng của nó được thiết lập ở dòng thứ 8.0.0. Cách thường làm là để tâm của hình cầu ở vị trí trung tâm là (0. Bounding Sphere Constructors BoundingSphere() Tạo một hình cầu bao mà tâm ở vị trí (0. Đối tượng TransformGroup tên là objSpin được tạo ở dòng 7.

public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). Điều này được mô tả trong hàm khởi tạo. Cuối cùng là bước 5 trong công thức. Bước 4 chỉ ra vùng danh mục. Add it to the root of the subgraph. Vùng cầu này là vùng bao quanh của hành vi trong dòng 26. Thời gian được tính theo mili giây giá trị 4000 được sử dụng trong chương trình tương đương với 4 giây. Bước 3 là tạo đối tượng thêm vào. Trong đoạn mã. // Create the transform group node and initialize it to the // identity.setCapability(TransformGroup. một đối tượng BoundingSphere được sử dụng với giá trị mặc định.com 244 objSpin = new . Đối tượng thêm vào phải tham chiếu đến đối tượng biến hình và alpha.ALL OW_TRANSFORM_WRITE). objSpin. 2 tham số chỉ ra trong dòng 16 của đoạn mã là số vòng lặp và thời gian cho mỗi vòng . http://tailieuhay. biến hành vi thành một con của TransformGroup trên dòng 27. Giá trị “-1” của số vòng lặp thể hiện việc lặp liên tục. để thực hiện phép quay hoàn toàn quanh trục y. Từ đó hành vi là quay một lần trên 4 giâys. rotationAlpha. được sử dụng để xác định thời gian quay liên tục. Trong ví dụ này hành vi mặc định RotationInterpolator là được sử dụng. Đối tượng quay RotationInterpolator được tạo ra ở dong 21 và 22. được tạo ra ở dòng 25. TransformGroup TransformGroup().Lập trình đồ họa trên Java 2D và 3D Bước 2 là tạo đối tượng Alpha.

Lập trình đồ họa trên Java 2D và 3D objRoot. Alpha rotationAlpha = new Alpha(-1. 4000). add it to the scene graph.addChild(rotator). // a bounding sphere specifies a region a behavior is active // create a sphere centered at the origin with radius of 100 BoundingSphere BoundingSphere(). RotationInterpolator rotator = new RotationInterpolator(rotationAlpha. // Create a simple shape leaf node. bounds = new http://tailieuhay. objSpin. // Create a new Behavior object that will perform the desired // operation on the specified transform object and add it into // the scene graph.4)).setSchedulingBounds(bounds).addChild(objSpin). objSpin). // ColorCube is a Convenience Utility class objSpin.addChild(new ColorCube(0. rotator.com 245 .

} // end of CreateSceneGraph method Code Fragment 1-7 createSceneGraph method with RotationInterpolator Behavior Đồ thị khung cảnh của chương trình và kết quả chạy trên màn hình.5 Phép biến hình và kết hợp các hành vi .com 246 .Lập trình đồ họa trên Java 2D và 3D return objRoot.9. Kết quả 1.Ví dụ: HelloJava3Dd Tất nhiên chúng ta có thể kết hợp các hành vi với các phép biến hình quay với ví dụ dưới đây. Trong đồ thị nhánh nội dung có những đối tượng http://tailieuhay.

mul(tempRotate).Lập trình đồ họa trên Java 2D và 3D objRotate và objSpin.com 247 . // rotate object has composited transformation matrix Transform3D rotate = new Transform3D().PI/4. Đồ thị khung cảnh public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). tempRotate. TransformGroup TransformGroup(). rotate. our TRANSFORM_WRITE modify it at capability so that behavior Add it to the objSpin = new // root of the subgraph. rotate.0d).rotY(Math.rotX(Math. http://tailieuhay. TransformGroup TransformGroup(rotate). Create the transform Enable code the can group node and objRotate = new initialize it to the identity. phân biệt với những phép quay tĩnh và hành vi của đối tượng hình lập phương.0d). // // // runtime.PI/5. Transform3D tempRotate = new Transform3D().

// a bounding sphere specifies a region a behavior is active // create a sphere centered at the origin with radius of 1 (float) http://tailieuhay.0f). objRoot.PI*2. objSpin. objRotate.ALLOW_TRANSF ORM_WRITE).setCapability(TransformGroup. // Create a simple shape leaf node.Lập trình đồ họa trên Java 2D và 3D objSpin. yAxis.0f. Transform3D yAxis = new Transform3D(). 0. add it to the scene graph. Alpha rotationAlpha = new Alpha(-1. // Create a new Behavior object that will perform the desired // operation on the specified transform object and add it into // the scene graph.com 248 .addChild(new ColorCube(0.addChild(objSpin). RotationInterpolator rotator = new RotationInterpolator(rotationAlpha.4)). 4000).addChild(objRotate). // ColorCube is a Convenience Utility class objSpin. Math.

com 249 .Lập trình đồ họa trên Java 2D và 3D BoundingSphere bounds = new BoundingSphere(). return objRoot. rotator.addChild(rotator). } // end of CreateSceneGraph method of HelloJava3Dd Kết quả http://tailieuhay. objSpin.setSchedulingBounds(bounds).

Lập trình đồ họa trên Java 2D và 3D http://tailieuhay.com 250 .

1 Hệ tọa độ thế giới ảo Trong chương 1 ta đã biết với mỗi instance của một lớp VirtualUniverse có chức năng như một gốc của đồ thị khung cảnh trong tất cả chương trình Java 3D. Từ khóa virtual universe là chỉ một không gian ảo 3 chiều trong đó có các đối tượng 3D. trục Z hướng dương chỉ vào người nhìn với đơn vị là mét. Hình 2-1 dưới đây chỉ ra hướng nhìn trong SimpleUniverse. Mỗi đối tượng Locale trong một môi trường ảo thiết lập một thế giới ảo Cartesian. Với một đối tượng Locale trong SimpleUniverse có một hệ tọa độ duy nhất. http://tailieuhay. Đối tượng này tương đương với một con trỏ tham chiếu cho một đối tượng quan sát trong một môi trường ảo.com 251 . Hệ tọa độ của môi trường ảo Java 3D là thuận phải tức là trục X hướng dương bên tay phải.Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 2 Tạo các hình 2. trục Y hướng dương chỉ lên trên.

biểu tượng hình tứ giác dùng để đại diện cho đối tượng ColorCube.com 252 . Đối tượng Shape3D không chứa thông tin về hình dạng hay màu sắc của một đối tượng quan sát.Lập trình đồ họa trên Java 2D và 3D 2. Shape3D là một trong các lớp con của lớp Leaf từ đó đối tượng Shape3D chỉ có thể là lá trong đồ thị khung cảnh.2. sau khi đi vào những định nghĩa cơ bản về hình học trong gói tiện ích. Thông tin này được lưu trong đối tượng NodeComponent được chuyển đến bới đối tượng Shape3D. phần còn lại của chương này sẽ thảo luận về góc độ hình học và hình dáng của các nút thành phần. Đồ thị khung cảnh trong hình 2-2 chỉ ra đối tượng quan sát được đại diện bởi một lá Shape3D (hình tam giác) và 2 NodeComponent (ô van) thay cho hình dạng tứ giác. 2.2 Visual Object Definition Basics Phần 2. còn lớp Chen code lai cho ro rang ..2.2.được giới thiệu ở phần 2. Một đối tương Shape3D có thể quy vào một nút thành phần hình học và một nút thành phần giao diện. Trong đồ thị khung cảnh Hellojava3D ở chương 1.1 giới thiệu lớp Chen code lai cho ro rang . http://tailieuhay.1 An Instance of Shape3D Defines a Visual Object Nút đồ thị khung cảnh Shape3D định nghĩa một đối tượng quan sát.2.

đối tượng Shape3D quy cho một nút Appearance. hoặc chỉ với tham chiếu thành phần hình học. hoặc cả 2 dạng. Shape3D Methods 253 http://tailieuhay. Shape3D Constructors Shape3D() Khởi tạo và thiết lập đối tượng Shape3D mà không có nút thành phần hình học và giao diện Shape3D(Geometry Geometry) Khởi tạo và thiết lập chỉ với thành phần hình học Shape3D(Geometry Geometry. Cho đến khi đối tượng Shape3D không sống hoặc không được dịch nữa thì tham chiếu nút thành phần có thể thay đổi với các phương thức dưới đây. Với tùy chọn này. Appearance Appearance) Khởi tạo và thiết lập chỉ với cả 2 thành phần.com .Lập trình đồ họa trên Java 2D và 3D Một đối tượng quan sát có thể định nghĩa bằng cách sử dụng chỉ dối tượng Shape3D và một nút thành phần hình học. Hàm tạo cho đối tượng Shape3D cho phép đối tượng Shape3D được tạo mà không cần tham chiếu của nút thành phần.

Phần 2-6 giới thiệu về Appearance NodeComponent.com 254 . Phần 2-5 sẽ giới thiệu về NodeComponent Germetry.Lập trình đồ họa trên Java 2D và 3D Đối tượng Shape3D tham chiếu đến đối tượng nút thành phần hình học và giao diện. void setGeometry(Geometry Geometry) void setAppearance(Appearance Appearance) Shape3D Capabilities Đối tượng Shape3D thừa kế các khả năng từ SceneGraphObject. Node và Leaf.2. ALLOW_GEOMETRY_READ | WRITE ALLOW_APPEARANCE_READ | WRITE ALLOW_COLLISION_BOUNDS_READ | WRITE 2. Hình 2-3 chỉ ra các phần thừa kế của Java 3D API chứa lớp NodeComponent và lớp trước nó.2 Node Components Đối tượng NodeComponent chứa các định nghĩa chính xác về các thuộc tính của một đối tượng quan sát. Với mỗi lớp con của NodeComponent định nghĩa đích xác các thuộc tính quan sát. http://tailieuhay.

Tổ chức của lớp VisualObject cũng giống như lớp ColorCube mà trong đó nó được thừa kế từ đối tượng VisualObject.Lập trình đồ họa trên Java 2D và 3D 2. Chúng ta có thêm xem một ví dụ đầy đủ về lớp ColorCube trong gói com.Geometry . Điều đó gợi ý cho việc định nghĩa một lớp để tạo đối tượng quan sát thay vì thiết lập mỗi đối tượng quan sát riêng lẻ. Mỗi người lập trình Java 3D sẽ tùy biến lớp VisualObject theo ý của họ.3 Defining Visual Object Classes Cùng một đối tượng quan sát sẽ thường xuất hiện nhiều lần trong một môi trường ảo. Sử dụng Shape3D như là lớp cơ bản cho việc tạo một đối tượng quan sát cho phép dễ dàng sử dụng trong chương trình Java 3D. Lớp VisualObject là một điểm đề nghị đầu tiên cho việc định nghĩa các lớp nội dung để sử dụng trong xây dựng đồ thị khung cảnh.sun. Lớp đối tượng quan sát có thể được sử dụng dễ dàng như lớp ColorCube trong ví dụ HelloJava3D từ chương. Hàm tạo có thể được gọi và những đối tượng http://tailieuhay.j3d.com 255 . Có nhiều cách để thiết kế một lớp để định nghĩa một đối tượng quan sát.utils.2.

Còn cách dễ nhất đương nhiên là dùng hình lập phương.com 256 . 2. hình nón. Trong đoạn mã dưới đây objRoot là một instance của Group. Các lớp cơ bản này cung cấp cho người lập trình tính linh động hơn rất nhiều so với lớp hình lập phương màu đưa ra. Phương thức createAppearance()có trách nhiệm cho việc tạo NodeComponent để định nghĩa bề ngoài cho đối tượng quan sát. Cone.3 Các lớp tiện ích hình học Phần này bao gồm tất cả các lớp tiện ích dùng để tạo hình hộp. Các hình cơ bản này là cách dễ thứ hai để tạo một môi trường ảo. Ngoài ra còn có các lớp khác trong gói về hình học như Box. Trong thiết kế này lớp đối tượng quan sát sẽ chứa một Group Node hoặc Shape3D như là gốc của một nhánh đồ thị nó định nghĩa. và hình cầu cơ bản. Lớp này phải định nghĩa phương thức để trả về một tham chiếu đến gốc. Đoạn mã này tạo một VisualObject và thêm nó vào như là cong của objRoot trong đồ thị khung cảnh. Công nghệ này có thể có nhiều việc hơn nhưng lại dễ dàng để hiểu.Lập trình đồ họa trên Java 2D và 3D mới nhất được thêm vào như là con của một vài Group trên một dòng của đoạn mã. Hàm tạo của VisualObject tạo đối tượng quan sát bằng cách định nghĩa một lớp container không không thừa kế tù Java 3D API.addChild(new VisualObject()). hình trụ. Phương thức createGeometry()tạo một nút thành phần hình học được sử dụng trong đối tượng quan sát. Hàm tạo của VisualObject tạo đối tượng quan sát bằng cách tạp một đối tượng Shape3D tham chiếu đến NodeComponent được tạo bởi phương thức createGeometry()và createAppearance(). vốn mở rộng từ Group. Lớp ColorCube định http://tailieuhay. Mỗi lớp mở rộng từ Primitive. Cylinder và Sphere. objRoot.

Kích thước hình lập phương chỉ được xác định khi đối tượng được tạo.1 Box Lớp gốc Box (hình hộp) tạo đối tượng quan sát hình hộp 3D.com 257 . người lập trình không thể thay đổi hình học nhưng có thể thay đổi bề ngoài. Một lớp cơ bản được gọi là linh động nếu nó xác định hình dạng mà không phải xác định màu sắc đi kèm. Các lớp này cung cấp cho người lập trình tính linh động khi có nhiều instance trên một hình cơ bản ở đó mỗi phần có một diện mạo khác nhau bằng cách tham chiếu đến các NodeComponent Appearance khác nhau.sun.utils.j3d. Lớp cơ bản nhất của các lớp này là lớp Primitive. Chiều dài chiều rộng chiều cao mặc định là 2 met. Chiều dài http://tailieuhay. Trong các lớp tiện ích cơ bản hình học. Các lớp này được định nghĩa trong gói com. Kết quả là mọi thứ xung quanh nó trở nên cố định trừ kích thước của nó.Lập trình đồ họa trên Java 2D và 3D nghĩa về mặt hình học và màu trên các nút thành phần hình học.3.Geometry. dưới đây là hình2-4 thể hiện cây thừa kế các lớp này. với tâm ở gốc. 2.

and Cylinder Methods Package: com.j3d. void setAppearance(Appearance Appearance) http://tailieuhay. Cone.j3d. Cone. dọc theo đường đồ thị khung cảnh tới Box.j3d. float zdim.utils. một lớp khác trong gói com. với nút thành phần hình học của nó.utils. Shape3D getShape(int id) Lấy một trong những mặt Shape3D từ lớp cơ bản chứa hình học và bề mặt. Các lớp cơ bản này được kết hợp từ các đối tượng Shape3D trong một nhóm. mở rộng từ Primitive.Geometry Box. Box Constructors Package: com. có thể được sử dụng để thay đổi vị trí và hướng của các instance của Box và các đối tượng quan sát khác. Giá trị đưa ra để xác định nút thành phần nào được lấy. và tâm ở gốc.com 258 . tâm ổ gốc. Cone.Geometry Các phương thức này được định nghĩa trong mối lớp cơ bản: Box. và Cylinder được tập hợp từ nhiều đối tượng Shape3D. Tất nhiên TransformGroup.sun. float ydim. Appearance Appearance) Thiết lập hình hộp với hướng.sun.sun.Geometry Box Box() Thiết lập một hình hộp với mặc định chiều cao chiều dài chiều rộng là 2 met.Đối tượng Box. bề ngoài. Box(float xdim.utils.Lập trình đồ họa trên Java 2D và 3D chiều rộng chiều cao được xác định trong thời gian đối tượng được tạo. và Cylinder.

Cylinder(float radius. Giá trị mặc định là bán kính là 1.j3d. Appearance Appearance) Khởi tạo với bán kính. chiều cao và bề mặt. đường kính là 2.sun.Geometry Cylinder() Hàm khởi tạo mặc định với bán kính là 1. chiều cao là 2. Cylinder Constructors Package: com.2 Cone Hình nón định nghĩa đối tượng hình nón. bịt nắp tâm tại gốc tọa độ với trục song song với trục Y. http://tailieuhay.j3d. chiều cao là 2.utils.3. Tâm của hình nón được coi như là tâm của hình bao củanó hơn là tâm thực.utils.Geometry Cone() Hàm khởi tạo mặc định với bán kính là 1.3 Cylinder Lớp Cylinder (hình trụ) tạo một đối tượng hình trụ bị bịt tâm ở gốc với trục dọc theo trục Y. float height) Khởi tạo với tham số bán kính và chiều cao. Cone Constructors Package: com. Cone(float radius. Bán kính là 1 và chiều cao là 2. float height. Cylinder(float radius.3.sun.com 259 .Lập trình đồ họa trên Java 2D và 3D 2. float height) Hàm khởi tạo với 2 tham số bán kính và chiều cao 2.

utils. bán kính mặc định là 1.sun. Sphere Methods Package: com. bề mặt cho trước.Geometry Sphere() Hàm khởi tạo mặc định.3.sun.j3d.j3d.Lập trình đồ họa trên Java 2D và 3D 2.com 260 .4 Sphere Lớp này tạo đối tượng hình cầu tâm ở gốc. Tuy nhiên 1 Sphere chỉ có một đối tượng Shape3D nên id =1. void setAppearance(Appearance Appearance) Lập bề mặt cho hình cầu.Geometry Shape3D getShape() Lấy đối tượng Shape3D chứa dạng hình học và bề mặt. Shape3D getShape(int id) Phương thức này cũng được sử dụng với các lớp cơ bản phía trên. http://tailieuhay. Sphere Constructors Package: com.utils. Appearance Appearance) Hàm khởi tạo với bán kính. Sphere(float radius) Hàm khởi tạo với bán kính xác định Sphere(float radius. bán kính là 1.

Nếu không có tham chiếu đến nút thành phần bề mặt. Cone.5 More About Geometric Primitives Các cơ bản chưa được định nghĩa về màu sắc. 2.3. Lớp này mở rộng theo hướng thừa kế khác. Cylinder và Sphere. mục tiêu của chương trình là dựng nên một con yo-yo. Các hình không định nghĩa màu mà thừa kế màu từ nút thành phần bề mặt của nó.6 ColorCube Lớp ColorCube được trình bày ở đây thể hiện sự tương phản với các lớp hình cơ bản như Box. Cây thừa kế được chỉ ra trong hình 2-5.3. Chúng ta phải dùng 2 http://tailieuhay. 2. đối tượng quan sát sẽ có màu mặc định là trắng. Lớp này cũng là lớp duy nhất cung cấp với Java 3D API cho phép người lập trình bỏ qua các phần như màu sắc và ánh sáng. Vì lí do này nên nó thường được dùng để nhanh chóng tạo ra một đồ thị khung cảnh để kiểm thử hình nguyên mẫu.7 Example: Creating a Simple Yo-Yo From Two Cones Phần này giới thiệu ví dụ đơn giản qua việc sử dụng lớp Cone.com 261 . nó là lớp con của Shape3D.3.Lập trình đồ họa trên Java 2D và 3D 2.

Các hành của Java 3D API cho phép yo-yo có thể di chuyển lên xuống nhưng trong phần này sẽ không trình bày đến. Yo-yo định ra 2 hình nón mà được quay quanh Z và dịch theo trụ X để đỉnh của chúng trùng nhau ở gốc. đỉnh nằm trên trục Y. Những kết hợp của phép quay và dịch cho phép ghép các đối tượng hình nón với nhau. đường của đồ thị khung cảnh tới mỗi đối tượng Cone bắt đầu bằng đối tượng TransformGroup chỉ ra phép dịch.Lập trình đồ họa trên Java 2D và 3D hình nón để tạo nên được Yo-Yo.com 262 . Hướng của hình nón là hướng dương. theo đó là TransformGroup xác định phép quay và hủy đối tượng Cone. Hình 2-5 dưới đây hiển thị đồ thị khung cảnh của chương trình thiết kế lớp ConeYoyo và ConeYoyoApp. Nhánh đồ tị này bắt đầu bằng đối tượng BranchGroup được tạo bơi ConeYoyo. Ví trị mặc định của một đối tượng Cone thông qua hình bao của nó tâm ở gốc. http://tailieuhay.

thay đổi đầu tiên là đối tượng BranchGroup có con là ConeYoyo và được chèn vào đối tượng ConeYoyo trực tiếp trên Locale.đưa ra một ví dụ về thông báo lỗi khi cố gắng sử dụng cùng một đối tượng Cone trong đồ thị khung cảnh.com 263 . Lỗi này không tồn tại trong ví dụ chương trình đưa ra. Một thay đổi khác là kết nối 2 đối tượng TransformGroup trong đối tượng ConeYoyo. Hình 2. Hình 2-8 chỉ ra một hình ảnh được dịch với ví dụ vừa qua. Nút Shape3D của đối tượng Cone tham chiếu đến nút thành phần hình học. Đối tượng Shape3D của Cone là con của Group trong Cone. thì Cone còn lại không thể sử dụng thêm lần nào nữa trong đồ thị khung cảnh. Phép biến đổi được mô tả đơn giản như dưới đây. http://tailieuhay. Khi đối tượng Cone thừa kế từ Group. Lớp ConeYoyo được sửa lại như trong đoạn mã 2-2. Trong ví dụ hình 2-6 có một vài thay đổi. BranchGroup này sau đó là để thêm vào các đối tượng quan sát trong tương lai tới thế giới quan sát.Lập trình đồ họa trên Java 2D và 3D Một vài đồ thị khung cảnh có thể đại diện cho cùng một môi trường ảo.

Appearance app = new Appearance(). Transform3D Transform3D(). 264 rotate translate http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D Dòng 14 đến 21 tạo các đối tượngcủa ½ đồ thị yo-yo . // ////////////////////////////////////// //// // // appearance // yoyoGeometry // the appearance is created in method yoyoAppearance // public ConeYoyo() { yoyoBG = new BranchGroup(). một nút thành phần bề mặt với giá trị mặc định được sử dụng bởi đối tượng Cone. // rotate object has composited = = new new the geometry is created in method create Shape3D with geometry and transformation matrix Transform3D Transform3D().com . Dòng 12 tạo yoyoApear. Dòng 23 đến 25 tạo mối quan hệ giữa các đối tượng. Tiến trình này được lặp lại trên một nửa đồ thị còn lại từ dòng 27 đến dòng 38. Dòng 21 đến 34 thiết lập bề mặt cho 2 hình nón.

TransformGroup TransformGroup(rotate).set(new 0.addChild(yoyoTGR2). Vector3f(0.0d). rotate.2f).addChild(yoyoTGT2). translate.0d).1f. TransformGroup TransformGroup(translate).0f. yoyoTGR2 = new yoyoTGT2 = new Vector3f(-0. TransformGroup TransformGroup(rotate). 0.PI / 2.rotZ(-Math.set(new 0.0f. Cone cone1 = new Cone(0.6f.rotZ(Math. yoyoTGT1 = new yoyoBG.addChild(cone2). Cone cone2 = new Cone(0. cone1.com 265 .6f.Lập trình đồ họa trên Java 2D và 3D translate. yoyoTGT1. 0.addChild(yoyoTGT1).2f).1f. yoyoTGR1.0f)).0f)).addChild(yoyoTGR1). yoyoTGR1 = new http://tailieuhay.addChild(cone1).setAppearance(app). 0. yoyoBG.setAppearance(app).PI / 2. 0. cone2. yoyoTGT2. yoyoTGR2. TransformGroup TransformGroup(translate). rotate.

Mặc định tất các các primitives là cùng một kích thước. Ví dụ như lớp Sphere có hàm khởi tạo Sphere (int). và Spheres.Lập trình đồ họa trên Java 2D và 3D yoyoBG. Lớp này cũng cho phép chia sẻ nút thành phần hình học giữa các instance của một primitive với cùng một kích cỡ. Nó định nghĩa một lượng lớn các trường và phương thức cũng như giá trị mặc định của các trường. } // end of ConeYoyo constructor Code Fragment 2-2 Class ConeYoyo From ConeYoyoApp. Danh sách các cờ ở dưới đây: GEOMETRY_NOT_SHARED Normals are generated along with the positions. GENERATE_TEXTURE_COORDS Texture coordinates are generated. chia sẻ một nút thành phần hình học. Trường này chỉ ra dạng hình học được sẽ không được chia sẻ với những instance khác. GENERATE_NORMALS_INWARD Normals are flipped along the surface. Mỗi lớp con của Primitive có một hàm khởi tạo cho phép thiết lập các cờ khi đối tượng được xây dựng.java Example Program Advanced Topic: Geometric Primitive – Các dạng hình học cơ bản Cây thừa kế trong hình 2-4 chỉ ra Primitive là lớp cha của tất cả các lớp Cone. Thiết lập cờ này để tránh http://tailieuhay. Cylinder.com 266 . Một ví dụ của một trường được định nghĩa trong lớp Primitive là giá trị integer GEOMETRY_NOT_SHARED.compile(). Box. GEOMETRY_NOT_SHARED The Geometry created will not be shared by another node.

Cylinder và Sphere. Cylinder được gom lại với hơn một đối tượng Shape3D. mỗi thứ có tiềm năng sử dụng nút thành phần bề mặt của nó. 2.utils. cần cả lớp hình học và các lớp con của nó. Cone. Giá trị cho mỗi phần này được xác định khi mỗi nút thành phần bề mặt được thiết lập.j3d.com 267 .GEOMETRY_NOT_SHARED). void setAppearance(int partid. như điểm đường thẳng và đa giác. Cone. Primitive Methods Package: com.4 Các lớp toán học Để tạo đối tượng quan sát.sun. Appearance Appearance) Thiết lập bề mặt của các phần con.Lập trình đồ họa trên Java 2D và 3D việc chia sẻ giữa các primitive của cùng một tham số (chẳng hạn với hình cầu bán kính 1). Các đối tượng Box. void setAppearance() Thiết lập bề mặt chính của primitive (tất cả các phần con) tới bề mặt trắng mặc định.Geometry Primitive mở rộng từ Group và là lớp cha của của các lớp Box. Rất nhiều lớp con của lớp hình họcmo tả dựa trên các hình cơ bản véc tơ. public void setNumVertices(int num) Thiết lập tổng số đỉnh trong primitive này. Cone myCone = new Cone(Primitive. Các lớp con của lớp hình học sẽ được mô tả trong phần 2-5 nhưng trước đó chúng ta quan tâm đến các lớp toán http://tailieuhay.

* Gói này định nghĩa một số lớp Tuple như là các lớp trừu tượng. màu.Lập trình đồ họa trên Java 2D và 3D học như điểm. Chú ý rằng với mỗi kí hiệu có “*” đằng sau đại diện cho một lớp tên.com 268 . còn các chữ cái nhỏ cuối cùng đại diện cho kiểu. ‘i’ là integer. http://tailieuhay. ‘b’ đại diện cho byte. Ví dụ Tuple* tương đương với Tuple2f. Rất nhìều các lớp hữu ích thừa kế từ các lớp này. Dưới đây là hình 2-9 cây thừa kế. ‘f’ chỉ float. Trong đó các chữ số đằng sau chỉ ra số thành phần trong tuple. Vì thế lớp Tuple3f là một lớp mà quản lí 3 giá trị điểm thực. vertor và textcord dùng để định nghĩa các dữ liệu liên đỉnh. Tuple2d Tuple3i…. ‘d’ chỉ double. Tất cả các lớp toán học này đều nằm trong gói javax.vecmath.

Ví dụ như Tuple2f cung cấp cơ sở cho Point2f. Nếu bề mặt ánh xạ được thiết lập thì tọa độ bề mặt cũng cần thiết vậy.Lập trình đồ họa trên Java 2D và 3D Mỗi đỉnh của một đối tượng quan sát có thể chỉ ra tới 4 đối tượng trong javax.vecmath Các lớp Tuple* thường không được sử dụng trực tiếp trong chương trình Java 3D nhưng cung cấp nền tảng cho Point*. Color2f. Tuple2f Constructors Package: javax. Ví dụ như một màu có thể được định nghĩa tại mỗi đỉnh và các màu của các hình cơ bản là được thêm vào giữu các màu tại các đỉnh.tùy thuộc vào các hình cơ bản được dựng hình như thế nào. Các dữ liệu khác là tùy chọn . màu bề mặt bình thường và bề mặt tọa độ. float y) http://tailieuhay. TexCoord*.com 269 . Tât cả các lớp cần thiết được trình bày bên dưới đây. Color*. Nếu ánh ánh sáng được thiết lập. Tuple2f() Khởi tạo và thiết lập đối tượng Tuple với tọa độ (0.vecmath đại diện cho tọa độ. Các hàm khởi tạo dưới đây đều đúng với các lớp con tương tụ như Tuple3f và Tuple4f. bề mặt bình thường (Vertor* object) là cần thiết.0). và TexCoord2f. Các lớp thường được sử dụng:  Point* (for coordinates)  Color* (for colors)  Vector* (for surface normals)  TexCoord* (for texture coordinates. Tuple2f(float x. see Chapter 7) Tuple2f Constructors Chú ý rằng tọa độ (Point* object) là cần thiết để địa chỉ mỗi đỉnh. Vector*.

void sub(Tuple2f t1. final void add(Tuple2f t1) Lập giá trị của tuple này tới vertor tổng của nó và Tuple t1. Tuple2f(Tuple2f t) Khởi tạo và thiết lập đối tượng Tuple từ dữ liệu của một Tuple khác Tuple2f(Tuple2d t) Khởi tạo và thiết lập đối tượng Tuple từ dữ liệu của một Tuple khác Tuple2f Methods (partial list) Package: javax. Vector*. Tuple2f(float t[]) Khởi tạo và thiết lập đối tượng Tuple từ một mảng đặc biệt. boolean equals(Tuple2f t1) Trả về giá trị true nêu trong Tuple t1 bằng với giá trị sẵn có của tuple. Color2f.vecmath Các lớp Tuple* thường không được sử dụng trực tiếp trong chương trình Java 3D nhưng cung cấp nền tảng cho Point*. float y) void set(float t[]) Lập giá trị của tuple này từ một giá trị định trước. TexCoord*. Color*.y). void set(float x. Các phương thức của chúng cũng tương tự như vậy. Tuple2f t2) http://tailieuhay. và TexCoord2f.com 270 .Lập trình đồ họa trên Java 2D và 3D Khởi tạo và thiết lập đối tượng Tuple với tọa độ (x. Các hàm khởi tạo dưới đây đều đúng với các lớp con tương tụ như Tuple3f và Tuple4f. Ví dụ như Tuple2f cung cấp cơ sở cho Point2f. Tuple2f t2) Lập giá trị của tuple này tới vertor tổng của nó và Tuple t1 và t2. void add(Tuple2f t1.

http://tailieuhay. lớp Point* có thêm các phương thức riêng của nó. Point3f Methods (partial list) Package: javax. void negate() Loại bỏ giá trị của một vertor.1 Point Classes Đối tượng Point* thường được đại diện cho tọa độ của một đỉnh. void negate(Tuple2f t1) Lập giá trị cho tuple sau khi loại bỏ giá trị của nó void absolute() Đổi tất cả thành phần của tuple này thành giá trị tuyệt đối. nguồn âm thanh và các dữ liệu điểm khác.vecmath Lớp Point* được thừa kế từ lớp Tuple*. float distance(Point3f p1) Trả về khoảng cách giữa điểm này và điểm p1. Hàm tạo cho lớp Point* giống như hàm tạo của Tuple* ngoại trừ chúng trả về đối tượng Point*. Thêm vào các phương thức của Tuple*. 2.Lập trình đồ họa trên Java 2D và 3D Lập giá trị của tuple này tới vertor khác của t1 và t2 (this = t1 . được chỉ ra dưới đây.t1). chẳng hạn như một vạch quét ảnh.4. void sub(Tuple2f t1) Lập giá trị của tuple này tới vertor khác của nó và t1 (this = this . 3 hoặc 4 không gian. void absolute(Tuple2f t) Lập giá trị của các thành phần thành giá trị tuyệt đối và ghi vào tuple.com 271 . Mỗi instance của lớp Tuple* đại diện cho một điểm đơn trong 2.t2). một điểm nguồn sáng.

0. đối với giá trị alpha là từ 0.2 Color Classes Đối tượng lớp màu đại diện cho một màu. Đối với đối tượng Color4* có thêm giá trị về độ sâu. public static final Color3f blue Color3f(0.4. Khoảng cách L1 là: abs(x1 .0f.0f).255].x2) + abs(y1 .0.0f.0.vecmath.0f).0f.0f).com . sương mù hoặc các đối tượng quan sát khác.1. float distanceL1(Point3f p1) Trả về khoảng cách L1 (Manhattan) giữa điểm này và điểm p1.0f. Giá trị của màu là kiểu byte có giá trị [-128. Color3* xác định màu thông qua 3 màu đỏ.*.0f. 272 = new = new = new http://tailieuhay.0 đến 1.0.0f.z2) 2.Giá trị của màu là từ 0 đến 255. class ColorConstants{ public static final Color3f red Color3f(1. có thể là một đỉnh. Ví dụ về một lớp màu: import javax.y2) + abs(z1 . public static final Color3f green Color3f(0. Khi giá trị alpha bằng 1 thì màu hiện nguyên vẹn.0. Các màu được chỉ ra hoặc là Color3* hoặc Color4* kiểu dữ liệu thường là kiểu thực. thuộc tính của chất liệu.127] tuy nhiên Java vẫn xử lí giá trị màu [0.Lập trình đồ họa trên Java 2D và 3D float distanceSquared(Point3f p1) Trả về khoảng cách bình phương giữu 2 điểm p và p1. xanh da trời và xanh nước biển.1.

0. http://tailieuhay.com 273 .0f.0f.0f.0f). Khi khởi tạo đối tượng Color4* sử dụng đối tượng AWT Color giá trị alpha được thiết lập bằng 1.0f. Color3f. } = new = new = new = new Ta có thể thấy hàm tạo của lớp Color* giống như lớp Tuple*.1. Color* Constructors (partial list) Package: javax.0f. public static final Color3f white Color3f(1.1. public static final Color3f black Color3f(0.0f).0f).0f).0. public static final Color3f magenta = new Color3f(1.1.0f.0. ngoại trừ là nó trả về đối tượng Color*.1. xanh lá cây và xanh nước biển (RGB).0f. public static final Color3f cyan Color3f(0.vecmath Mỗi instance trong lớp Color* đại diện cho một màu đơn trong 3 thành phần đỏ.Lập trình đồ họa trên Java 2D và 3D public static final Color3f yellow Color3f(1.0.0f.0f. Color4b.0f. Color*(Color color) <new in 1.1. Lớp này chỉ có một hàm khởi tạo và 2 phương thức thêm vào so với lớp cha của nó Tuple*. Color4f) sử dụng một đối tượng AWT Color.0f). Giá trị alpha bằng 0 là trong suốt còn bằng 1 là hiện nguyên bản.1.2> Tạo đối tượng Java 3D Color*() (Color3b. hoặc một trong bốn thành phần 3 màu và thêm độ alpha (RGBA).

vecmath http://tailieuhay. void set(Color color) <new in 1. Color4f) thừa kế từ lớp Tuple*. Một lần nữa ta có thể thấy các hàm tạo của Vertor* cũng tương tự như Tuple*. the constructors for Vector* classes are similar to the Tuple* constructors. 2.Lập trình đồ họa trên Java 2D và 3D Color* Methods Package: javax.vecmath Lớp Color* (Color3b.2> Lập màu sử dụng mầu từ đối tượng AWT Color Color get() <new in 1.3 Vector Classes Vector* objects often represent surface normals at vertices although they can also represent the direction of a light source or sound source. Again. Đối tượng Vertor* đại diện cho bề mặt bình thường tại các định dù chúng cũng có thể đại diện cho hướng của một nguồn sáng hoặc nguồn âm thanh. However. Vector3f Methods (partial list) Package: javax.com 274 . Dưới đây là một vài phương thức trong Color3* và Color4*.4.2> Lấy một màu coi là một màu của đối tượng AWT Color. Mỗi instance của lớp này đại điện cho một màu trong 3 (RGB) hoặc 4 (RGBA) thành phần. Color4b. Color3f. Vector* objects add many methods that are not found in the Tuple* classes.

Vector3f v2) Lập một vertor trở thành vertor pháp tuyến của 2 vertor v1 và v2. giá trị này được rằng buộc trong khoảng [0.4 chiều. float angle(Vector3f v1) Trả về góc radians giữa vertor hiện tại với vertor tham số. Hàm tạo của lớp này cũng tương tự như lớp Tuple* và không có thêm phương thức nào so với lớp cha của nó.3. với TexCoord3f thì có 3 tọa độ là (s.2. Mỗi instances của lớp Vector* đại diện cho một đỉnh vertor trong không gian 1. t). r).4 TexCoord Classes Chỉ có 2 lớp TexCoord* được sử dụng như là một tập các kết cấu bề mặt tọa độ tại một đỉnh. Với TexCoord2f có một cặp tọa độ là (s. 2.4.com 275 . http://tailieuhay. float length() Trả về độ dài của một vertor float lengthSquared() Trả về giá trị bình phương độ dài của một vertor. void cross(Vector3f v1. float dot(Vector3f v1) Tính toán và trả về tích số điểm của product hiện tại và vertor v1.Lập trình đồ họa trên Java 2D và 3D Lớp Vector* thừa kế từ Tuple*. là TexCoord2f và TexCoord3f. t. void normalize() Bình thường hóa vertor hiện tại void normalize(Vector3f v1) Lập giá trị của vertor này với giá trị của vertor v1 được bình thường hóa.PI]. Ngoài ra nó còn có thêm những phương thức như dưới đây.

Lập trình đồ họa trên Java 2D và 3D 2. Trong Java 3D mỗi đối tượng Shape3D có thể gọi phương thức setGeometry() của nó để tham chiếu đến một hoặc chỉ một đối tượng Geometry. cho nên một đối tượng tham chiếu là một instance của lớp con của Geometry. Các lớp con của Geometry có những dạng sau: 1. Non-indexed vertex-based Geometry (mỗi khi đối tượng quan sát được dựng các đỉnh của nó chỉ được sử dụng một lần) 2. Cây thừa kế được hiển thị dưới hình 2-10 http://tailieuhay. và CompressedGeometry) Phần này chỉ nói về 2 dạng trên. Chính xác hơn Geometry là lớp trừu tượng.5 Các lớp hình học Trong đồ họa 3D. mọi thứ từ hình tam giác đơn giản đến hình phức tạp như một chiếc máy bay đều được mô hình hóa và dựng dưới dạng dữ liệu theo đỉnh. Text3D.com 276 . Indexed vertex-based Geometry (mỗi khi đối tượng quan sát được dựng các đỉnh của nó được sử dụng nhiều lần) Các đối tượng quan sát khác (Các lớp Geometry.

Vì vậy những mảng nầy chứa tọa độ. Điền đầy đối tượng với dữ liệu 3. 3 thành phần được định nghĩa. màu.1 GeometryArray Class Như cái tên của lớp này cho bạn hình dung lớp con này của Geometry được sử dụng để định nghĩa điểm đường và hình đa giác điền đầy. int vertexFormat) Hàm tạo này tạo đối tượng GeometryArray rỗng với những số đỉnh và định dạng đỉnh cho trước. Còn được gọi là “vertex format” (định dạng đỉnh). bề mặt thường. Ngoài định ra tọa độ thì các giá trị này có thể định nghĩa màu.5. và texture) được lưu tại mỗi đỉnh. bề mặt bình thường hoặc texture. và texture. GeometryArray Constructor GeometryArray(int vertexCount. Với mỗi thành phần của mảng này duy trì một vị trí tọa độ cho đỉnh của nó (có thể định nghĩa bằng Point* với dữ liệu tương tự) . màu.com 277 . bề mặt thường. Đồng hóa (tham chiếu) đối tượng từ (1 hoặc nhiều) đối tượng Shape3D. hay số thành phần cần thiết Định dạng của dữ liệu (tọa độ. Một trong những cờ riêng là các bitwise “OR” http://tailieuhay. Những thành phần nguyên tố dựa trên điểm này là lớp con của của lớp trừu tượng GeometryArray. Có 3 bước trong vòng đời của một đối tượng GeometryArray 1. chỉ ra một mảng chứa các dữ liệu về đỉnh. Bước 1: Tạo một đối tượng GeometryArray rỗng Khi một đối tượng GeometryArray vừa được khởi tạo thì cần thiết phải định nghĩa 2 thứ Số đỉnh. dưới dạng dữ liệu mảng.Lập trình đồ họa trên Java 2D và 3D 2. Ví dụ như một đối tượng dùng để chỉ một tam giác. mỗi thành phần cho mỗi đỉnh. Tạo một đối tượng rỗng 2.

com 278 . Mỗi mảng này là số đỉnh (vertexCount) về kích cỡ. Chú ý lớp Axis trong AxisApp. đăng kí dữ liệu cho mảng tương ứng với tạo định dạng của các đỉnh. Với mỗi cờ định dạng được thiết lâp sẽ có một mảng tương ứng tạo trong đối tượng GeometryArray. COLOR_3: Chỉ ra mảng đỉnh chứa màu (không có thành phần trong suốt) COLOR_4: Chỉ ra mảng đỉnh chứa màu (có thành phần trong suốt) TEXTURE_COORDINATE_2: Chỉ ra mảng đỉnh chứa 2D texture coordinates. TEXTURE_COORDINATE_3: Chỉ ra mảng đỉnh chứa 3D texture coordinates. Các phương thức sẵn có sau: GeometryArray Methods (partial list) http://tailieuhay. Vì lớp GeometryArray là lớp trừu tượng nên ta chỉ gọi phương thức thiết lập cho lớp con của nó như LineArray. Bit này buộc phải lập. Những giá trị cờ để định dạng các đỉnh là: COORDINATES: Chỉ ra mảng các đỉnh chứa tọa độ. Có thể làm việc này trên mỗi đỉnh hoặc sử dụng mảng để đăng kí dữ liệu cho nhiều đỉnh chỉ với một lời gọi phương thức . NORMALS: Chỉ ra mảng đỉnh chứa bề mặt thường.java là khác với lớp Axis chúng ta tự định nghĩa trong ví dụ này Bước 2: Điền đầy dữ liệu vào đối tượng GeometryArray rỗng Sau khi khởi tạo đối tượng GeometryArray.Lập trình đồ họa trên Java 2D và 3D hợp với nhau để mô tả dữ liệu mỗi đỉnh.

void setNormals(int index. float colors[]) void setColors(int index. GeometryStripArray. float color[]) void setColor(int index. byte color[]) void setColor(int index.Lập trình đồ họa trên Java 2D và 3D GeometryArray là lớp trừu tượng cho PointArray. LineArray. QuadArray. float coordinate[]) void setCoordinate(int index. byte colors[]) void setColors(int index.với mỗi đỉnh được định nghĩa là một chỉ mục cho đối tượng này. TriangleArray. float normal[]) void setNormal(int index. float normals[]) void setNormals(int index. void setCoordinate(int index. Point* coordinates[]) Lập các tọa độ tương ứng với đỉnh với các đỉnh được định nghĩa là chỉ mục cho đối tượng này. Point* coordinate) Lập tọa độ tương ứng với đỉnh với mỗi đỉnh được định nghĩa là một chỉ mục cho đối tượng này. void setColor(int index. Color* color) Lập màu tương ứng với đỉnh với mỗi đỉnh được định nghĩa là một chỉ mục cho đối tượng này. void setCoordinates(int index. double coordinates[]) void setCoordinates(int index.com 279 . Vector* normals[]) http://tailieuhay. float coordinates[]) void setCoordinates(int index. Vector* normal) Lập trực giao tương ứng với mỗi đỉnh tại vị trí chỉ mục được chỉ ra cho đối tượng này. Color* colors[]) Lập các màu tương ứng với các đỉnh . void setColors(int index. và IndexedGeometryArray. void setNormal(int index. double coordinate[]) void setCoordinate(int index.

Đoạn mã 2-5 chỉ ra trường hợp sử dụng phương thức của GeometryArray để lưu giữ tạo độ và giá trị màu trong mảng LineArray. int index. void setInitialVertexIndex(int initialVertexIndex) <new in 1. void setTextureCoordinate(int texCoordSet. Đối tượng trục Y gọi cả 2 phương thức setColor() và setCoordinate() để nạp giá trị màu RGB và giá trị tọa độ. int index.Lập trình đồ họa trên Java 2D và 3D Lập các trực giao tương ứng với các đỉnh tại vị trí chỉ mục được chỉ ra cho đối tượng này. GeometryArray Methods (partial list. TexCoord* coordinate) Lập texture coordinate ứng với mỗi đỉnh tại vị trí chỉ mục cho trước cho một tập texture coordinate của đối tượng. và các hoạt động khác. <new in 1. Đối tượng trục Z thì gọi 10 lần phương thức setCoordinate() cho mỗi đỉnh và gọi setColors() một lần để nạp cho cả 10 đỉnh với 1 phương thức. http://tailieuhay. int index. chọn lọc và các hoạt động khác. Đối tượng trục X chỉ gọi phương thức setCoordinate() để lưu trữ dữ liệu tọa độ. void setValidVertexCount(int validVertexCount) <new in 1. <new in 1.2> Lập chỉ mục cho đỉnh ban đầu với đối tượng GeometryArray.com 280 . continued) void setTextureCoordinates(int texCoordSet. int index. Cho phép một vài dữ liệu đỉnh có thể bỏ qua khi dựng hình. float texCoord[]) void setTextureCoordinate(int texCoordSet.2> float texCoords[]) void setTextureCoordinates(int texCoordSet. Cho phép một vài đỉnh có thể bỏ qua trong việc dựng hình.2> Lạp các giá trị tính toán đỉnh đúng cho đối tượng GeometryArray.2> TexCoord* texCoords[]) Lập các texture coordinate ứng với các đỉnh tại vị trí chỉ mục cho trước cho một tập texture coordinate của đối tượng.

axisXLines. green = new Color3f(0.setCoordinate(0. Point3f(-1.0f). 0.0f.0f)). Color3f 0. Color3f 0.com 281 .COORDINATES).addChild(new Shape3D(axisXLines)).0f.0f. // create line for X axis LineArray axisXLines = new LineArray(2. // create line for Y axis blue = new Color3f(0. 0.Lập trình đồ họa trên Java 2D và 3D // ////////////////////////////////////// //// // // create axis subgraph // public Axis() { axisBG = new BranchGroup(). 1.0f.0f. 0. LineArray. new new http://tailieuhay. Color3f 1.0f.setCoordinate(1.0f.0f).0f.0f. axisXLines. 0.0f. 0.0f)). Point3f(1. axisBG. red = new Color3f(1.0f). 0.

0. axisBG. axisYLines.0f.0f. -1.setColor(1. axisZLines.setCoordinate(0.addChild(new Shape3D(axisYLines)).0f. axisYLines. 1. axisYLines. LineArray. green). http://tailieuhay. axisZLines. 0.0f)).COLOR_3).COORDINATES | LineArray.0f. 0. // create line for Z axis Point3f z1 = new Point3f(0. Point3f(0.com 282 . 1. Point3f(0. z1).0f.Lập trình đồ họa trên Java 2D và 3D LineArray axisYLines = new LineArray(2.0f).COLOR_3).setCoordinate(1. LineArray.addChild(new Shape3D(axisZLines)). axisBG.setCoordinate(0.0f.0f)). z2).0f). blue).0f. Point3f z2 = new Point3f(0. axisZLines.0f. -1.COORDINATES | LineArray.setColor(0. axisYLines. 0.setCoordinate(1. z2). LineArray axisZLines = new new new LineArray(10.setCoordinate(2.

axisZLines. 1.setCoordinate(3.9f)). colors[0] = new Color3f(0. 0. 0. z2). Point3f(-0. Color3f colors[] = new Color3f[9]. -0. 0.1f.1f. } // end of axis constructor Màu mặc định cho các đỉnh của một đối tượng mảng GeometryArray là trắng.setCoordinate(8.1f.1f. z2). axisZLines. 0. 0.Lập trình đồ họa trên Java 2D và 3D axisZLines. colors). Khi các đường hoặc đa giác đầy được dựng với các màu khác nhau tại mỗi đỉnh thì các màu sẽ mịn dần giữa các đỉnh sử dụng phép đánh bóng Gouraud.1f. axisZLines. axisZLines. 1. -0.0f.setCoordinate(4.0f.setColors(1.com 283 new new new new .1f.1f. v < 9.1f. axisZLines. 0. } axisZLines.setCoordinate(5. v++) { colors[v] = red.9f)).setCoordinate(9. z2).setCoordinate(7.9f)). http://tailieuhay. nếu cả COLOR_3 và COLOR_4 không được định nghĩa. Point3f(0.0f). Point3f(-0.setCoordinate(6. axisZLines. for (int v = 0.9f)). Point3f(0.

Lập trình đồ họa trên Java 2D và 3D Bước 3: Tạo đối tượng Shape3D tham chiếu đến đối tượng GeometryArray Đoạn mã dưới đây chỉ ra cách làm thế nào để đối tượng Shape3D tham chiếu đến đối tượng GeometryArray. chẳng hạn như LineArray.com 284 .5.2 Subclasses of GeometryArray Như đã nói ở phần trên do GeometryArray là lớp trừu tượng là lớp cha của rất nhiều lớp con hữu dụng. Lí do tồn tại của các lớp con này là làm sao để trình dựng hình của Java 3D có thể quyết định dựng đối với các đỉnh của các lớp đó. vì thế Shape3D có thể thêm vào thành con của một đồ thị khung cảnh ) Đồ thị khung cảnh được chỉ ra ở dưới đây: 2. Đối tượng Shape3D được thêm vào một BranchGroup sẽ được thêm vào ở nơi nào đó trên đồ thị khung cảnh. http://tailieuhay. (Shape3D là lớp con của Node. Hình 1-2 cho thấy cây thừa kế đối với lớp GeometryArray và các lớp con của nó.

Hình thứ 4 chỉ ra 4 đỉnh định nghĩa một tứ giác. TriangleArray. Trong hình này. các tập bên trái nhất của các đỉnh chỉ ra 3 điểm đỉnh dựng thành 6 điểm. Chú ý rằng các định này không dùng chung: mỗi đường hoặc một đa giác đầy được dựng độc lập với nhau. và QuadArray (các lớp này không phải là lớp con của GeometryStripArray). PointArray(int vertexCount. int vertexFormat) QuadArray(int vertexCount.Lập trình đồ họa trên Java 2D và 3D Hình 2-13 chỉ ra một ví du về các lớp con của GeometryArray gồm: PointArray. hoặc 2 tam giác. int vertexFormat) LineArray(int vertexCount. LineArray.com 285 . int vertexFormat) http://tailieuhay. int vertexFormat) TriangleArray(int vertexCount. GeometryArray Subclass Constructors Tạo một đối tượng rỗng với số đỉnh và định dạng đỉnh cho trước. 3 đường.

để cho kết quả dựng hình tốt hơn. Ta có hình 2-14 chỉ ra một instance của một dạng các đỉnh được sử dụng lại. GeometryStripArray lớp LineStripArray. 2.5. TriangleStripArray và TriangleFanArray. GeometryStripArray có 2 phương thức thường sử dụng đến là getNumStrips() và getStripVertexCounts(). Nếu bạn đang dựng một hình tứ giác cẩn thận với các đỉnh có thể tạo thành hình lõm. GeometryStripArray Subclass Constructors http://tailieuhay. Lớp GeometryStripArray là lớp trừu tượng từ đó mỗi thực thể hình học cơ bản (để ghép là tạo đường cha và bề của mặt ) thừa kế.com 286 . Lớp GeometryStripArray có hàm tạo khác với lớp GeometryArray. Nếu xảy ra. Hàm tạo của nó có 3 tham số. một mảng cách đỉnh tính trên mỗi mảnh cho phép một đối tượng có thể duy trì nhiều mảnh. tuy nhiên có một vài trường hợp ta cần sử dụng lại các đỉnh. chúng không thể dựng đúng được.2-6 sử dụng đối tượng LineArray.3 Subclasses of GeometryStripArray Phần trước mô tả 4 lớp con của GeometryArray. tự cắt nhau hoặc không phẳng.Lập trình đồ họa trên Java 2D và 3D Để tìm hiểu cách sử dụng hàm tạo và phương thức xem lại đoạn mã 24 và 2-5. không cho phép sử dụng lại các đỉnh.

Nhiều mảnh cùng một lúc cũng được hỗ trợ.sun. Định dạng là một hay nhiều các bit cờ “OR” để mô tả cho mỗi dữ liệu đỉnh. vtxCount.utils. int vtxCount. Tổng các tính toán đỉnh cho tất cả các mảnh phải bằng với tổng số các đỉnh LineStripArray(int vtxCount. cùng nằm trên một mặt phẳng các cạnh không giao nhau. Triangulator Method Summary void triangulate(GeometryInfo ginfo) http://tailieuhay. Triangulator Constructor Summary Triangulator() Tạo một đối tượng tam giác.com 287 . Các đa giác phải là lồi.Geometry Sử dụng để chuyển các đa giác hình học không có dạng tam giác về các tam giác để có thể dựng hình bằng Java 3D.j3d. Người lập trình phải có trách nhiệm trong việc sử dụng kĩ thuật tách để tách hình phức tạp ra thành nhiều các đối tượng của Java 3D như mảng tam giác hoặc hình quạt.Lập trình đồ họa trên Java 2D và 3D Tạo một đối tượng rỗng với giá trị các đỉnh và định dạng các đỉnh và một mảng tính toán các đỉnh qua các mảnh. int vertexFormat. int Triangulator Class Package: com. int vertexFormat. Định dạng các cờ là giống nhau như đã định nghĩa trong lớp GeometryArray. int stripVertexCounts[]) TriangleStripArray(int stripVertexCounts[]) TriangleFanArray(int stripVertexCounts[]) Chú ý rằng Java 3D không hỗ trợ các hình cơ bản đầy với nhiều hơn 4 mặt. int vertexFormat.

tr. Ví dụ về cách sử dụng: TRIANGLE_ARRAY Triangulator tr = new Triangulator(). phương thức yoyoGeometry()tạo và trả về đối tượng TriangleFanArray mong muốn. // ginfo contains the Geometry shape. Trong đoạn mã 2-7.com.getGeometryArray()).setGeometry(ginfo.GeometryInfo to be triangulated.com 288 .Geometry. http://tailieuhay. // shape is a Shape3D Yo-yo Code Demonstrates TriangleFanArray Đối tượng Yoyo trong chương trình YoyoApp.Lập trình đồ họa trên Java 2D và 3D Chương trình con này chuyển đối tượng GeometryInfo từ dạng cơ bản POLYGON_ARRAY thành dạng TRIANGLE_ARRAY sử dụng kĩ thuật tách đa giác Tham số: ginfo .utils.j3d.triangulate(ginfo).sun.java schỉ ra cách sử dụng đối tượng TriangleFanArray để mô hình hóa con yo-yo Hình 2-15 chỉ 3 hình dựng của TriangleFanArray.

23.sin(a)). private Geometry yoyoGeometry() { 2. Point3f coords[] = new Point3f[totalN].n = 0. 4. N+1. coords[1*(N+1)+n+1] = new Point3f(x. 20. -w). 19. 12. int N = 17. y = (float) (r * Math. y. 7. y. 16. Mỗi hình nón có 18 đỉnh được tính toán ở dòng 20-28.0f. 0. N+1}.6f. w). float r = 0.0f. int totalN = 4*(N+1). w). float w = 0. 3. 10. w). TriangleFanArray tfa. double a. 0. 0. Dòng 30-32 tạo một đối tượng TriangleFanArray và dòng 34 là nơi để tính toán dữ liệu tọa độ (từ dòng 15-28) để lưu đối tượng 1. 18. 0.cos(a)). 6. 25. 5. coords[3*(N+1)] = new Point3f(0. a = 2. for (a = 0. 24. coords[1*(N+1)] = new Point3f(0. 11. coords[0*(N+1)+N-n] = new Point3f(x. http://tailieuhay. // set the central points for four triangle fan strips 15.4f.0f. 8. n < N. 0.0*Math. 9. int n. 0.Lập trình đồ họa trên Java 2D và 3D Dòng 15-18 tính toán tâm điểm cho 4 hình nón. int stripCounts[] = {N+1.0f. y. 17. x = (float) (r * Math.com 289 . coords[2*(N+1)] = new Point3f(0. 22. 14.PI/(N-1) * ++n){ 21. coords[0*(N+1)] = new Point3f(0.0f. N+1. 13.0f).0f. float x.0f.0f).0f.

return tfa. TriangleFanArray. coords).Lập trình đồ họa trên Java 2D và 3D 26. TriangleFanArray tfa. Color3f red = new Color3f(1. 37.setCoordinates(0. 34. y. 33.com 290 . 5. 0. tfa = new TriangleFanArray (totalN. Color3f colors[] = new Color3f[totalN].COORDINATES. Dòng 23 qua 26. http://tailieuhay. coords[2*(N+1)+N-n] = new Point3f(x. 31. Phương thức được yoyoGeometry()thay đổi. 8. 35. Hình 2-16 chỉ ra một đối tượng tương tự nhưng màu đã được thay đổi ở mỗi đỉnh. 1. 28. int totalN = 4*(N+1).0f. 32. 7. private Geometry yoyoGeometry() { 2. 36 tới 39. y. Point3f coords[] = new Point3f[totalN]. tfa. -w). 3. 27. 6. stripCounts).0f). 0.0f. coords[3*(N+1)+n+1] = new Point3f(x. và dòng 46 chỉ định màu cho mỗi đỉnh. 30. int N = 17.} // end of method yoyoGeometry in class Yoyo Code Fragment 2-7 yoyoGeometry() Method Creates TriangleFanArray Object Hình yo-yo trắng mới chỉ là điểm khởi đầu. } 29. -w). 4. 36.

26. int n.4f.0f. 0.0f). 0. for(a = 0.cos(a)). 0.0f. w). coords[2*(N+1)+n+1] = new Point3f(x.7f. 16. coords[0*(N+1)+n+1] = new Point3f(x.sin(a)). 15.0f. colors[2*(N+1)] = yellow. 32. y. 13. 25. 14. N+1. 11. http://tailieuhay. float w = 0. 12. n < N. 27. y. 19.5f.0f). y = (float) (r * Math. int stripCounts[] = {N+1.0f.0f. 20. N+1}. coords[3*(N+1)] = new Point3f(0. 0. 0.0f. 24. colors[3*(N+1)] = red.n = 0. // set the central points for four triangle fan strips 18. colors[0*(N+1)] = red. 31. float r = 0. 35. a = 2. 37.Lập trình đồ họa trên Java 2D và 3D 9. 30. float x. 22.com 291 . N+1. w). 0. -w).PI/(N-1) * ++n){ 29. 0.0*Math. 0. 10.6f. 23.0f. 28. 36. y.0f. coords[3*(N+1)+N-n] = new Point3f(x. -w). y. y. coords[1*(N+1)] = new Point3f(0.0f). coords[1*(N+1)+N-n] = new Point3f(x. 17. w). coords[2*(N+1)] = new Point3f(0. double a. x = (float) (r * Math. 34. 33. coords[0*(N+1)] = new Point3f(0. colors[1*(N+1)+n+1] = yellow. -w). colors[0*(N+1)+N-n] = red. Color3f yellow = new Color3f(0. colors[1*(N+1)] = yellow. 21.

colors). return tfa. 46. 39.Lập trình đồ họa trên Java 2D và 3D 38. 43. coords).com 292 . stripCounts). tfa. 42. } // end of method yoyoGeometry in class Yoyo Code Fragment 2-8 Modified yoyoGeometry() Method with Added Colors http://tailieuhay. tfa.COLOR_3. tfa = new TriangleFanArray (totalN. TriangleFanArray. 47. 49. 48. } 41. colors[2*(N+1)+N-n] = yellow. 40.setColors(0.COORDINATES|TriangleFanArray. 44. 45.setCoordinates(0. colors[3*(N+1)+n+1] = red.

com 293 . Với những mảng này cũng chứa tạo độ. Các lớp con của IndexedGeometryArray song song với các lớp con của lớp GeometryArray.4 Subclasses of IndexedGeometryArray Các phần trước mô tả các lớp con của GeometryArray. Trong trường hợp xấu nhất chúng ta phải định nghĩa 24 đỉnh mặc dù chỉ 8 đỉnh là đủ. bề mặt thường và tạo độ bề mặt. Cây thừa kế được vẽ dưới hình 2-18 http://tailieuhay. Đối tượng IndexedGeometryArray cung cấp một cấp bậc khác sao cho có thể tránh việc sử dụng thừa. cho thấy chỉ lớp GeometryStripArray có thêm quyền hạn sử dụng lại các đỉnh.5. từ đó cho phép sử dụng lại hiệu quả rõ ràng. Tuy nhiên đối tượng IndexedGeometryArray cũng cần thêm các mảng phụ gọi là mảng chỉ số chứa các chỉ mục đến mảng dữ liệu. màu sắc. Chúng ta có thể xen ví dụ dưới đây. Ví dụ để định nghĩa một hình lập phương mỗi đỉnh trong 8 đình của nó phải được sử dụng bởi 3 hình vuông.Lập trình đồ họa trên Java 2D và 3D 2. Mảng chỉ mục này có nhiều tham chiếu đến các đỉnh tương tự trong cùng một mảng dữ liệu.

int ic. int vf.com 294 . IndexedGeometryStripArray cùng các lớp con của chúng dưới đây. int stripVertexCounts[]) vc. IndexedGeometryStripArray(int stripVertexCounts[]) IndexedLineStripArray(int vc. IndexedGeometryArray(int indexCount) IndexedPointArray(int vertexCount. int vertexFormat. int IndexedGeometryStripArray and Subclasses Constructors Tạo một đối tượng rỗng với số đỉnh và định dạng đỉnh cho trước và số các chỉ mục trong mảng này và một mảng các tổng số các đỉnh mỗi mảnh. int ic. int vertexFormat.Lập trình đồ họa trên Java 2D và 3D Hàm tạo cho IndexedGeometryArray. int vertexFormat. int vertexFormat. int indexCount) IndexedQuadArray(int vertexCount. int http://tailieuhay. IndexedGeometryArray and Subclasses Constructors Tạo một đối tượng rỗng với số đỉnh và định dạng đỉnh cho trước và số các chỉ mục trong mảng này. int indexCount) vertexCount. int vf. int vertexFormat. int indexCount) IndexedTriangleArray(int vertexCount. int indexCount) IndexedLineArray(int vertexCount.

int ic. int colorIndices[]) Lập các chỉ mục màu tương ứng với các đỉnh tại vị trí chỉ mục đã cho với đối tượng.Lập trình đồ họa trên Java 2D và 3D IndexedTriangleStripArray(int vc. int index. int coordinateIndex) Tạo các chỉ mục tọa độ tương ứng với các đỉnh tại vị trí chỉ mục cho đối tượng void setCoordinateIndices(int index. void setNormalIndex(int index. void setTextureCoordinateIndex(int texCoordSet. int stripVertexCounts[]) IndexedTriangleFanArray(int vc.com 295 . int colorIndex) Lập chỉ mục màu tương ứng với đỉnh tại vị trí chỉ mục đã cho với đối tượng. int vf. http://tailieuhay. <new in 1. int vf.2> int texCoordIndex) Lập chỉ mục toạ độ tương ứng với đỉnh tại chỉ mục định trước cho đối tượng. int normalIndices[]) Lập các chỉ mục bình thường tương ứng với các đỉnh tại chỉ mục định trước cho đối tượng. int normalIndex) Lập chỉ mục bình thường tương ứng với đỉnh tại chỉ mục định trước cho đối tượng. int coordinateIndices[]) Tạo các chỉ mục các tọa độ tương ứng với các đỉnh tại vị trí chỉ mục cho đối tượng void setColorIndex(int index. void setNormalIndices(int index. int stripVertexCounts[]) Các phương thức của chúng cho đưới dây: IndexedGeometryArray Methods (partial list) void setCoordinateIndex(int index. int ic. void setColorIndices(int index.

Trong trường hợp đó rất cần thiết đối tượng Apperance. 2. int texCoordIndices[]) Lập các chỉ mục toạ độ tương ứng với các đỉnh tại chỉ mục định trước cho đối tượng.5 Axis. Dữ liệu trong đối tượng Geometry thường không đủ để mô tả bề ngoài của một bối tượng.Lập trình đồ họa trên Java 2D và 3D void setTextureCoordinateIndices(int texCoordSet. int index. Một đối tượng Appearance không chứa dữ liệu mô tả đối tượng quan sát mà nó biết nơi nào có dữ liệu đó.java is an Example of IndexedGeometryArray Ví dụ Axis về IndexedGeometryArray ta có định nghĩa 18 đỉnh và 30 chỉ mục cho 15 đường. đối tượng Geometry chỉ ra thông tin của mối đỉnh với một đốt tượng quan sát. http://tailieuhay.com 296 . do đó cách làm của nó là tham chiếu đến một vài đối tượng khác như lớp con của NodeComponent .5.6 Appearance and Attributes Đối tượng Shape3D có thể tham chiếu đến cả đối tượng Geometry và Apperance.5. Như vậy có 5 đường cho mỗi trục. Thông tin mỗi đỉnh này có thể chỉ định ra màu của đối tượng. Như đã thảo nói ở phía trên trong phần 2. 2.

setColoringAttributes(). Ví dụ như tham chiếu đến đối tượng ColoringAttributes nó sử dụng phương thức Appearance. Để tham chiếu đến nó dựa trên phương thức với một cái tên chính xác. Một đối tượng Appearance với các thuộc tính của đối tượng khác mà nó tham chiếu đến gọi là một gói giao diện.Lập trình đồ họa trên Java 2D và 3D Một đối tượng Appearance có thể tham chiếu đến thuộc tính một vài đối tượng lớp khác như:  PointAttributes  LineAttributes  PolygonAttributes  ColoringAttributes  TransparencyAttributes  RenderingAttributes  Material  TextureAttributes  Texture  TexCoordGeneration Sáu thuộc tính được đề cập đến trong tài liệu này còn lại dành cho chương 6 và chương 7. Trên đồ thị khung cảnh http://tailieuhay.com 297 .

màu mặc định là màu trắng. hiệu quả càng cao.2 Sharing NodeComponent Objects Việc tham chiếu đến một vài đối tượng là hợp lệ và cũng cần thiết vì thế nên chia sẻ cùng các đối tượng NodeComponent.com . Appearance() 2. khả năng xuyên qua vô hiệu hóa.6. 298 http://tailieuhay.6.Lập trình đồ họa trên Java 2D và 3D 2. Việc chia sẽ này giúp cho việc dựng hình nhanh hơn.1 Appearance NodeComponent Appearance Constructor Hàm tạo này tạo đối tượng Appearance với mọi thành phần chiếu nhận giá trị null. Các giá trị mặc định có thể đoán được: điểm và đoạn thẳng được vẽ với kích thước và độ dài 1 pixel và không có có khử răng cưa. Ví dụ trong hình 221 2 đối tượng Shape3D chia sẻ cùng thành phần LineAttributes.

boolean state) Tạo một đối tượng thành phần và mô tả kích thước 1 pixel dùng khử răng cưa PointAttributes Methods void setPointSize(float pointSize) Mô tả kích thước pixel của các điểm void setPointAntialiasingEnable(boolean state) Thiết lập hoặc bỏ thiết lập chống răng cưa. Lúc đó điểm vuông được làm tròn đi. http://tailieuhay.3 Attribute Classes PointAttributes Đối tượng PointAttributes quản lí việc mỗi điểm cơ bản được dựng hình như thế nào. Thường làm nếu pointSize >= 1 pixel. Mặc định một đỉnh được dựng như một điểm. PointAttributes Constructors PointAttributes() Tạo một đối tượng thành phần và mô tả kích thước 1 pixel không dùng khử răng cưa PointAttributes(float pointSize. bạn có thể dùng setPointSize() để làm cho điểm đó to ra tuy nhiên mặc định một điểm to sẽ trông như một hình vuông.com 299 .6.Lập trình đồ họa trên Java 2D và 3D Tuy nhiên cần chú ý rằng một node không được có nhiều hơn một cha từ đó NodeComponent có thể chia sẻ hay tham chiếu đến bởi nhiều đối tượng khác. trừ phi bạn dùng setPointAntialiasingEnable(). 2.

Sau khi cả 16 mẫu đều được sử dụng. thì mẫu được lặp lại. Mẫu đường thẳng do người dùng tự định nghĩa Một mẫu thường dược định nghĩa bằng một mặt nạ mẫu và một thành phần quy mô. int linePattern.giá trị bên ngoài khoảng này là không chấp nhận được. Mặt nạ mẫu giá trị 0x0101 định nghĩa một mẫu lặp của một pixel mở và 7pixel tắt. Bit 0 tương ứng với pixel đầu tiên trong mẫu. LineAttributes(float pointSize. Mẫu này được lặp lại nhiều lần tùy theo yêu cầu. nên mẫu bit được đọc từ phải sang trái. và setLineAntialiasingEnable(). với độ rộng 1pixle không chống răng cửa. Mặc định đường được vẽ là nét liền. Nhớ rằng.bit phóng đại bé nhất được sử dụng đầu tiên khi vẽ. Ví dụ như quy mô của 3 x với một mặt nạ mẫu 0x001f tương đương với sản sinh ra mẫu với 15 pixel mở theo bởi 33 pixel đóng. Các mẫu có thể mở rộng đến 240 pixel sử dụng nhân tố quy mô.Lập trình đồ họa trên Java 2D và 3D LineAttributes Đối tượng này thay đổi cách dựng các đường cơ bản theo 3 cách.15]. boolean state) http://tailieuhay. Một giá trị 16 bit định nghĩa một mặt nạ mẫu. setLineWidth(). LineAttributes Constructors LineAttributes() Tạo một đối tượng thành phần mô tả độ rộng 1 pixel.com 300 . Ví dụ một mặt nạ của 0x00ff (0b0000000011111111) định nghĩa 8 pixel mở sau đó là 8 pixel đóng. mẫu khởi động lại trước mỗi đường mới của một mảnh. Bạn có thể thay đổi điều này bằng cách sử dụng các phương thức setLinePattern(). một đường thẳng liền nét không khử răng cưa. Mỗi bit trong 16 bit giá trị định nghĩa khi nào 1 pixel trong mẫu được bật hay tắt (1/0). Khoảng cách đúng là [1.

Lập trình đồ họa trên Java 2D và 3D Tạo một đối tượng thành phần mô tả độ rộng 1 pixel cho một đường thẳng, mẫu dùng để vẽ, có khử răng cưa.

LineAttributes Methods void setLineWidth(float lineWidth) Mô tả độ rộng pixel cho đường thẳng void setLinePattern(int linePattern) linePattern là một trong số các hằng sau: PATTERN_SOLID (the default), PATTERN_DASH, PATTERN_DOT, PATTERN_DASH_DOT, or PATTERN_USER_DEFINED. Mô tả làm sao một pixel của một đường được điền vào. void setLineAntialiasingEnable(boolean state) Bỏ hay có chống răng cưa với đường thẳng void setPatternMask(int mask) <new in 1.2> Lập một mặt nạ mẫu với một giá trị đặc biệt void setPatternScaleFactor(int scaleFactor) <new in 1.2> Sets the line pattern scale factor to the specified value.

Line Attributes Line Patterns PATTERN_SOLID solid lines (no pattern). This is the default. PATTERN_DASH dashed lines; ideally, a repeating pattern of 8 pixels on and 8 pixels off. PATTERN_DOT dotted lines; ideally, a repeating pattern of 1 pixel on and 7 pixels off.

http://tailieuhay.com

301

Lập trình đồ họa trên Java 2D và 3D PATTERN_DASH_DOT dashed-dotted lines; ideally, a repeating pattern of 7 pixels on, 4 pixels off, 1 pixel on, and 4 pixels off. PATTERN_USER_DEFINED lines with a user-defined line pattern. See "User-defined Line Patterns,"above. PolygonAttributes PolygonAttributes chi phối việc dựng hình của các thành phần cơ bản đa giác theo 3 cách: đa giác bị phân tách như thế nào, nếu nó được chọn lọc và khi nào thì độ sâu bù được chấp nhận. Mặc định các đa giác đều là đa giác lồi tuy nhiên khi đa giác bị tách thì đa giác được vẽ lại thành các khung (đường) hoặc chỉ các điểm tại các đỉnh. Phương thức setCullFace() dùng để loại bỏ các đa giác đã được dựng. Nếu phương thức này thiết lập hoặc CULL_FRONT hoặc CULL_BACK thì một nửa số đa giác không được dựng. Tùy theo sự hiệu quả của hệ thống dựng hình mà các đỉnh được dựng cả là các dây khung và các đa giác lồi luôn được phân tách với giá trị độ sâu chính xác. Kết quả là các đa giác và các dây khung có thể được dựng ở độ sâu khác nhau, gây ra hiện tượng đường khâu. Hiện tương stitching này là do độ sâu khác nhau nên các dây khung xuất hiện lúc ẩn lúc hiện trên đa giác. Với 2 thuộc tính PolygonOffset và PolygonOffsetFactor về giá trị độ sâu cho phép đa giác lồi có thể hướng khửu tay về phía khung hình ảnh. setBackFaceNormalFlip()được sử dụng để dựng một đa giác lồi sáng với cả 2 mặt của đa giác đều mờ đi. PolygonAttributes Constructors PolygonAttributes()

http://tailieuhay.com

302

Lập trình đồ họa trên Java 2D và 3D Tạo đối tượng thành phần với giá trị mặc định của đa giác lồi không có cắt bề mặt không có rìa đa giác. PolygonAttributes(int polygonOffset) Tạo đối tượng thành phần với giá trị cho trước của giác lồi PolygonAttributes(int polygonOffset, boolean backFaceNormalFlip) Tạo đối tượng thành phần giống như các hàm tạo phía trước nhưng cũng cho phép chỉ ra mặt phía trước và phía sau của đa giác như thế nào PolygonAttributes(int polygonOffset, polygonMode, int cullFace, float float boolean backFaceNormalFlip, polygonMode, int cullFace, float polygonMode, int cullFace, float

polygonOffsetFactor) <new in 1.2> Tạo đối tượng PolygonAttributes với giá trị cho trước.

PolygonAttributes Methods void setCullFace(int cullFace) cullFace là CULL_FRONT, CULL_BACK, or CULL_NONE. Cull (không dựng) trước mặt và mặt sau của các đa giác hoặc không tách đa giác nào. void setPolygonMode(int polygonMode) polygonMode là: POLYGON_POINT, POLYGON_LINE, or POLYGON_FILL. Dựng polygons trên points, lines, or filled polygons (mặc định). void setPolygonOffset(float polygonOffset) polygonOffset là screen-space offset thêm vào để hiệu chỉnh giá trị độ sâu của polygon primitives.

http://tailieuhay.com

303

Lập trình đồ họa trên Java 2D và 3D void setPolygonOffsetFactor(float polygonOffsetFactor) <new in 1.2> Lập polygon offset factor với giá trị cho trước. void setBackFaceNormalFlip(boolean backFaceNormalFlip) trong đó backFaceNormalFlip xác định khi nào đỉnh bình thường hoặc mặt sau của đa giác cần khuất sáng. Khi cờ này được lập giá trị true mặt sau bỏ lựa chọn mặt sau. ColoringAttributes Thuộc tính ColoringAttributes điều khiển chuyện tô màu. Phương thức setColor() lập một màu bên trong trong đó tùy trường hợp mà để màu đó vào. Thêm vao đó setShadeModel() xác định khi nào có khi cần thêm ngang một màu vào. ColoringAttributes Constructors ColoringAttributes() Tạo đối tượng thành phần sử sụng màu trắng cho màu bên trong và SHADE_GOURAUD là mô hình đánh bóng. ColoringAttributes(Color3f color, int shadeModel) ColoringAttributes(float red, float green, float blue, int shadeModel) shadeModel là một trong SHADE_GOURAUD, SHADE_FLAT, FASTEST, or NICEST. (trong hầu hết trường hợp, FASTEST là SHADE_FLAT, và NICEST là SHADE_GOURAUD.) ColoringAttributes Methods void setColor(Color3f color) void setColor(float red, float green, float blue) cả 2 phương thức đều định nghĩa màu bên trong void setShadeModel(int shadeModel)

http://tailieuhay.com

304

Lập trình đồ họa trên Java 2D và 3D shadeModel or NICEST. là một trong các hằng: SHADE_GOURAUD,

SHADE_FLAT, FASTEST,

TransparencyAttributes Thuộc tính này quản lí độ trong suốt của bất cứ hình cơ bản nào. setTransparency() định nghĩa giá trị trong suốt (bằng 1 là trong suốt hoàn toàn, bằng 0.0 là không trong suốt) TransparencyAttributes Constructors TransparencyAttributes() Tạo đối tượng thành phần với độ trong suốt lập ở chế độ NONE. TransparencyAttributes(int tMode, float tVal) Trong đó tMode là một trong những BLENDED, SCREEN_DOOR, FASTEST, NICEST, hoặc NONE, và tVal định nghĩa tính mờ của đối tượng (0.0 không trong suốt và 1.0, trong suốt hoàn toàn). TransparencyAttributes(int tMode, float tVal, int srcBlendFunction, int dstBlendFunction) <new in 1.2> Tạo một đối tượng TransparencyAttributes với giá trị định trước

TransparencyAttributes Methods void setTransparency(float tVal) tVal định nghĩa tính mờ của đối tượng (0.0 không trong suốt và 1.0, trong suốt hoàn toàn). void setTransparencyMode(int tMode)

http://tailieuhay.com

305

Lập trình đồ họa trên Java 2D và 3D tMode (one of BLENDED, SCREEN_DOOR, FASTEST, NICEST, or NONE) chỉ ra nếu có hoạt động làm trong suốt void setDstBlendFunction(int blendFunction) <new in 1.2> Lập địa chỉ chức năng pha trộn được sử dụng để trộn độ trong suốt và chống răng cưa. void setSrcBlendFunction(int blendFunction) <new in 1.2> Lập tài nguyen hàm trộng sử dụng để trộn độ trong suốt và chống răng cưa. RenderingAttributes RenderingAttributes điều khiển 2 hoạt động dựng hình trên từng pixel: kiểm định độ sâu đệm, và kiểm tra alpha. Hoạt động quét (Geometry) xác định xem việc dựng hình pixel ảnh hướng đến màn ảnh thế nào. Mặc định là bỏ chọn Geometry thường được sử dụng trong hầu hết các trường hợp Độ sâu đệm là tập hợp các giá trị độ sâu của những pixel được dựng. Nó được dùng đề xác định pixel được nhìn thấy hay bị khuất để chúng có thể được dựng. Độ sâu đệm sử dụng khác khi dựng đối mờ và trong suốt. Kết quả là đối tượng trong suốt không cập nhập giá trị độ sâu đêm không bình thường. Có thể vô hiệu hóa hoặc dùng tính năng này đối với một đối tượng thành phần RenderingAttributes. Việc vô hiệu hóa đảm bảo đối tượng luôn luôn nhìn thấy, tuy nhiên mặc định là để nó enable. RenderingAttributes Constructors RenderingAttributes() Tạo một đối tượng thành phần định nghĩa việc dựng trên pixel với việc kích hoạt kiểm tra độ sâu đệm và vô hiệu hóa tính năng kiểm tra alpha.

http://tailieuhay.com

306

Lập trình đồ họa trên Java 2D và 3D RenderingAttributes(boolean depthBufferWriteEnable, alphaTestFunction) Trong đó depthBufferEnable bật tắt so sánh độ sâu đệm (kiểm tra độ sâu), depthBufferWriteEnable bật và tắt để ghi vào depth buffer, alphaTestValue được sử dụng để kiểm tra. Đối với các nguồn alpha đi vào , and alphaTestFunction là một trong những ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, hoặc GREATER_OR_EQUAL, chỉ rõ loại alpha test nào được kích hoạt. Tạo một đối tượng thành phần định nghĩa việc dựng trên pixel cho so sanh độ sâu đệm và kiểm tra alpha. RenderingAttributes(boolean depthBufferWriteEnable, alphaTestFunction, boolean visible, boolean ignoreVertexColors, boolean GeometryOpEnable, int GeometryOp) <new in 1.2> Tạo một đối tượng RenderingAttributes với giá trị cho trước. depthBufferEnable, float alphaTestValue, boolean int depthBufferEnable, float alphaTestValue, boolean int

RenderingAttributes Methods void setDepthBufferEnable(boolean state) turns on and off the depth buffer testing. void setDepthBufferWriteEnable(boolean state) turns on and off writing to the depth buffer. void setAlphaTestValue(float value) specifies the value to be used for testing against incoming source alpha values. void setAlphaTestFunction(int function)

http://tailieuhay.com

307

Lập trình đồ họa trên Java 2D và 3D where function is one of ALWAYS, NEVER, EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, or GREATER_OR_EQUAL, which denotes what type of alpha test is active. If function is ALWAYS (the default), then the alpha test is effectively disabled. void setDepthBufferEnable(boolean state) <new in 1.2> Enables or disables depth buffer mode for this RenderingAttributes component object. void setDepthBufferWriteEnable(boolean state) <new in 1.2> Enables or disables writing the depth buffer for this object. void setIgnoreVertexColors(boolean ignoreVertexColors) <new in 1.2> Sets a flag that indicates whether vertex colors are ignored for this RenderingAttributes object. void setGeometryOp(int GeometryOp) <new in 1.2> Sets the Geometry operation function for this RenderingAttributes component object. void setGeometryOpEnable(boolean GeometryOpEnable) <new in 1.2> Sets the GeometryOp enable flag for this RenderingAttributes component object. void setVisible(boolean visible) <new in 1.2> Sets the visibility flag for this RenderingAttributes component object. Appearance Attribute Defaults Hàm tạo Appearance khởi tạo đối tượng Appearance với các thuộc tính tham chiếu đến các giá trị null. Bảng 2-1 là danh sách các giá trị mặc định cho những thuộc tính tham chiếu đến giá trị null. Attributes Class
http://tailieuhay.com

Parameter

Default Value
308

Lập trình đồ họa trên Java 2D và 3D

ColoringAttributes

color shade model

white (1, 1, 1) SHADE_GOURAUD 1.0 PATTERN_SOLID false 1.0 false CULL_BACK false POLYGON_FILL 0.0 0.0 true true ALWAYS 0.0 true false false ROP_COPY REPLACE black (0, 0, 0, 0) identity NICEST null
309

LineAttributes

line width line pattern line antialiasing enable

PointAttributes

point size point antialiasing enable

PolygonAttributes

cull face backFaceNormalFlip polygon mode polygonOffset polygonOffsetFactor

RenderingAttributes

depthBufferEnable depthBufferWriteEnable alphaTestFunction alphaTestValue visible ignoreVertexColors GeometryOpEnable GeometryOp

TextureAttributes

textureMode textureBlendColor transform perspectiveCorrectionMod e

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D textureColorTable TransparencyAttributes transparencyMode transparencyValue srcBlendFunction dstBlendFunction NONE 0.0 SRC_BLEND_ALPHA

BLEND_ONE_MINUS_ALPHA

2.6.4 Example: Back Face Culling Đa giác có 2 mặt. Với nhiều đối tượng quan sát không chỉ một mặt của đa giác cần được dựng. Để giảm công việc tính toán cần thiết phải dựng bề mặt của đa diện, hệ thống dựng hình có thể chọn lọc những mặt không cần thiết. Bề mặt trước của một đối tượng có thể là mặt cho các đỉnh được định nghĩa theo thứ tự ngược chiều kim đồng hồ. TwistStripApp.java tạo một đối tượng dải xoắn và quay nó quanh trục y. Khi dải xoắn quay các phần của nó xem như biến mất tuy nhiên những mẩu biến mất có thể dễ dàng thấy ở hình 2-22. Thực tế chương trình định nghĩa 2 đối tượng quan sát với cùng một hình. Một đối tượng được dựng dưới dạng khung dây còn đối tượng còn lại dựng với bề mặt liền. Qua đó khi quay chúng ta có thể quan sát được như vậy.

http://tailieuhay.com

310

Lập trình đồ họa trên Java 2D và 3D

Lí do có mất các đa giác là chế độ chọn lọc không chỉ ra, vì thế nó để mặc định là CULL_BACK. Các tam giác của bề mặt biến mất khi phần lưng của nó (phần sau) đối mặt với màn ảnh. Tính năng này cho phép hệ thống dựng hình tránh không phải dựng phần bề mặt tam giác vốn không cần thiết. T uy nhiên trong một số trường hợp việc chọn lọc lại gây vấn đề, như trong ví dụ TwistStripApp. Vấn đề có một cách giải quyết đơn giản đó là tắt bỏ chế độ chọn lọc. Như đoạn mã trong hình 2-10: public class TwistStripApp extends Applet { // ////////////////////////////////////////// ///// // // create Twist visual object // public class Twist extends Shape3D {

http://tailieuhay.com

311

// create triangle strip for twist int N = 80. stripCounts). } // end of twist constructor Geometry createGeometry() { TriangleStripArray twistStrip.setAppearance(createAppearance()). http://tailieuhay. 1.com 312 . | blue = new Color3f(0.0f. this.0f.setGeometry(createGeometry()).Lập trình đồ họa trên Java 2D và 3D // ////////////////////////////////////// //// // // create twist subgraph // public Twist() { this. double a. Color3f 0. TriangleStripArray. twistStrip = new TriangleStripArray( N.COORDINATES TriangleStripArray.COLOR_3.0f). int stripCounts[] = { N }.

7 * Math.setCoordinate(v.Lập trình đồ họa trên Java 2D và 3D int v. twistStrip. 0. blue).7 * Math.sin(a).0. Point3d(0. Math.7 * Math.cos(a))).2 * Math.2 * Math.setCoordinate(v new Point3d(0.2 * 0. v < N.cos(a))). v += 2.sin(a).PI / (N .sin(a) + 0.cos(a) 0.com 313 .2)) { twistStrip. for (v = 0.2 * Math.sin(a) -0.cos(a) + 0. a = 0.setColor(v blue). a = v * 2.7 * Math. 0.3 * Math.3 * Math. new http://tailieuhay. creates The the default line of Appearance for the commented code containting + 1.cos(a).cos(a). } return twistStrip.0 * Math. + 1. 0.setColor(v. twistStrip. } // create Appearance for Twist Strip // // // this twist method strip. twistStrip.

setPolygonAttributes(polyAttrib).Lập trình đồ họa trên Java 2D và 3D // the setCullFace will fix the problem of half of the // Twisted Strip disappearing. twistAppear. } } // end of class Twist // ////////////////////////////////////////// ///// // // create scene graph branch group // public BranchGroup createSceneGraph() { polyAttrib = new twistAppear = new http://tailieuhay.com 314 .CULL_NON E).setCullFace(PolygonAttributes. // polyAttrib. return twistAppear. PolygonAttributes PolygonAttributes(). Appearance createAppearance() { Appearance Appearance().

Add it to the root of the subgraph.setCapability(TransformGroup. objSpin = new contentRoot = new objSpin. objSpin. contentRoot. // Duplicate the twist strip geometry and set the // appearance of the new Shape3D object to line mode // without culling. // Add the POLYGON_FILLED and POLYGON_LINE strips // in the scene graph at the same point.addChild(objSpin). The PolygonOffset is set to prevent stitching.Lập trình đồ họa trên Java 2D và 3D BranchGroup BranchGroup(). http://tailieuhay. Shape3D twist = new Twist().com 315 .ALLOW_TRANSF ORM_WRITE).addChild(twist). // This will show the triangles of the original Mobius strip that // are clipped. TransformGroup TransformGroup(). // Create the transform group node and initialize it to the // identity.

objSpin. RotationInterpolator(rotationAlpha.getGeometry(). polyAppear.CULL_NON E).setPolygonAttributes(polyAttrib). // a bounding sphere specifies a region a behavior is active // create a sphere centered at the origin with radius of 1 BoundingSphere BoundingSphere(). polyAppear)). bounds = new rotator = new rotationAlpha = new Alpha(-1.POLYG ON_LINE). polyAttrib.addChild(new Shape3D(twist. Appearance polyAppear = new Appearance(). http://tailieuhay. polyAttrib = new polyAttrib.setCullFace(PolygonAttributes.001f). polyAttrib.setPolygonMode(PolygonAttributes.com 316 . Alpha 16000).Lập trình đồ họa trên Java 2D và 3D PolygonAttributes PolygonAttributes(). RotationInterpolator objSpin).setPolygonOffset(0.

BranchGroup scene = createSceneGraph().0f. objSpin. } // end of CreateSceneGraph method of TwistStripApp // Create a simple scene and attach it to the virtual universe public TwistStripApp() { setLayout(new BorderLayout()).com 317 . Canvas3D canvas3D = new Canvas3D(null). // make background white Background background = new Background(1.setApplicationBounds(bounds). canvas3D).addChild(background).0f. return contentRoot. contentRoot. background. 1. 1. // Let Java 3D perform optimizations on this scene graph. add("Center". // Utility class SimpleUniverse is a Convenience http://tailieuhay.compile().Lập trình đồ họa trên Java 2D và 3D rotator.0f).setSchedulingBounds(bounds). contentRoot.addChild(rotator).

System.out. ")."). simpleU. System.out.print("In visual objects rotate. simpleU = new simpleU.setNominalViewingTra nsform().println("This demonstrates back face culling.println("TwistStripApp .print("See with the Java 3D API\"").out.com 318 .getViewingPlatform(). System.Lập trình đồ họa trên Java 2D và 3D SimpleUniverse SimpleUniverse(canvas3D).out.addBranchGraph(scene). } // end of TwistStripApp constructor // The following method allows this to be run as an application public static void main(String[] args) { System. this program two program \"Getting Started http://tailieuhay.println(" (section 2.6)"). System.out.Java 3D API version 1.1"). // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed.

http://tailieuhay. Frame frame = new MainFrame(new wire frame is TwistStripApp().com 319 . System.print("The visible only when components").out.").Lập trình đồ họa trên Java 2D và 3D System.out. } // end of main method of TwistStripApp } // end of class TwistStripApp Trong hình 2-23 việc vô hiệu hóa chọn lọc bề mặt rõ ràng đã điền đầy vùng bị vỡ.println("one wireframe and one solid surface. System. 256.out. 256).println(" of the surface are culled."). Bây giờ thì tất cả các đa giác đều được dựng dù hướng quay của nó là gì chăng nữa.

9 mô tả mỗi đối tượng hành vi có một vùng riêng. Điều này thường liên quan đến “luật tay phải”.com 320 . Nếu bất kì thành phần nào của một đối tượng quan sát giao với luồng sáng thì đối tượng sẽ bị ảnh hưởng bởi luồng sáng Phần về Bounds được đặt ở phần 1. Hình 2-24 chỉ ra một ví dụ sử dụng luật tay phải) 2. Một hành vi chỉ được kích hoạt khi biên giới của nó giao với phần nhìn. BoundingPolytope. Đặc biệt một Scope là một tập các đối tượng Group (chừng hạn BranchGroup). BoundingBox. mỗi nguồn sáng định nghĩa một vùng ảnh hưởng gọi là vùng biên giới quét .7 Bounds and Scope Bound định nghĩa một không gian.Lập trình đồ họa trên Java 2D và 3D Phần mặt phía trước của một đa giác là mặt dùng để các đỉnh xuất hiện theo chiều quay ngược kim đồng hồ. một vùng cho mỗi nút. Bounds được định nghĩa các đối tượng như BoundingSphere. Scope chỉ ra một nhóm các đối tượng đồ thị khung cảnh bằng vị trí của chúng trong đồ thị khung cảnh. Một node có thể chỉ ra các đối http://tailieuhay. Luật này dùng để xác định phần mặt trước của một dải hình học (chẳng hạn dải tam giác hoặc dải hình vuông thay thế cho mỗi thành phần trong dải. Để tiếp tục với ví dụ ánh sáng .

Trong khi Bounds và scope cung cấp các tính năng khác nhau nhưng chúng lai hoạt động theo những cách khác nhau.1 Bounds Node Components Một đối tượng biên giới Bound được tham chiếu đến bởi các đối tượng cần định nghĩa biên giới biên giới cho phép người lập trình đa dạng hóa các hành động và bề mặt hoặc âm thanh trong một vung đất ảo. và BoundingSphere Khi lựa chọn một đối tượng Bound không phụ thuộc vào chi tiết của ứng dụng. Một vùng biên giới độc lập với vị trí của một đối tượng trong đồ thị khung cảnh.7. BoundingPolytope. http://tailieuhay. BoundingSphere là dễ nhất trong khi đó BoundingPolytope là khó nhất. Bound cũng cho phép hệ thông dựng hình của Java 3D hoạt động hiệu quả hơn. như sương mù. Đối tượng Bound định nghĩa các vùng lồi kín. Trong khi đó một phạm vi độc lập với đối tượng quan sát trong môi trường ảo. nhớ rằng những hoạt động nhỏ lẻ khác nhau trong một biên giới sẽ được tính toán trong vùng giao nhau.com 321 . đối với các nút AlternativeAppearance. được sử dụng trong rất nhiều tương tác và chọn lọc. Nếu bạn có rất nhiều đối tượng Bound đang sử dụng.Chúng được sử dụng trong nhiều ứng dụng. 3 lớp mở rộng của nó là BoundingBox. và nên làm như vậy khi tạo các vùng biên giới. 2. Bound là lớp trừu tượng là lớp cơ sở cho các lớp biên giới. âm thanh sẽ được nói phần sau của chương này. thêm vào đó ánh sáng và các hành vi được sử dụng.Lập trình đồ họa trên Java 2D và 3D tượng đồ thị khung cảnh khác nhau khi chúng ảnh hưởng bởi một tầm quan sát. những hoạt động nhỏ cũng có thể thêm vào và gây ra khác biệt rõ ràng đến toàn bộ hiệu năng của ứng dụng. Các vùng biên giới được định nghĩa băng một số lớp. Cuối cùng phải nhớ rằng với các vùng biên giới nhỏ thì hành động càng ít.

và BoundingSphere Bounds closestIntersection(Bounds[] boundsObjects) Tìm đối tượng trong biên giới gần nhất mà giao với vùng biên giới này. void combine(Bounds boundsObject) Kết nối đối tượng bị bao này với đối tượng bao. boolean intersect(Bounds boundsObject) Kiểm tra sự giao nhau giữa các đối tượng bao.Lập trình đồ họa trên Java 2D và 3D Bounds Method Summary (partial list) Bounds là lớp trừu tượng. do đó các phương thức liệt kê dưới đây là tất cả các phương thức trừu tượng và cụ thể của BoundingBox.Object Bounds) Chỉ ra khi nào đối tượng bao này tương đương với đối tượng bao khác. boolean isEmpty() Tests whether the Bounds is empty. double radius) Tạo và định giá trị cho một BoundingSphere với bán kính và tâm cho trước http://tailieuhay. BoundingSphere BoundingSphere Constructor Summary (partial list) BoundingSphere() Tạo và định giá trị cho một BoundingSphere với bán kính bằng 1 tại 0 0 0 BoundingSphere(Point3d center. void transform(Transform3D trans) Biến đổi đối tượng được bao dựa trên ma trận đưa ra. Kiểm tra khi nào các biên giới bao bị rỗng. boolean equals(java. void set(Bounds boundsObject) Lập giá trị cho đối tượng bao.com 322 . Ta có 2 phương thức sau. BoundingPolytope.lang.

BoundingBox(Point3d lower. BoundingBox() Thiết lập và khởi tạo một hình hộp bao kích thước 2 tâm ở gốc.y. BoundingSphere(Bounds[] boundsObjects) Tạo và định giá trị cho một BoundingSphere từ một mảng các đối tượng bao BoundingSphere Method Summary (partial list) void setCenter(Point3d center) Lập vị trí của vùng bao cầu từ một điểm void setRadius(double r) Lập bán kính của hình cầu bao.Lập trình đồ họa trên Java 2D và 3D BoundingSphere(Bounds boundsObject) Tạo và định giá trị cho một BoundingSphere từ đối tượng cho trước. BoundingBox(Bounds[] Bounds) Lập một hình hộp bao với một mảng các đối tượng bao. http://tailieuhay. BoundingBox(Bounds boundsObject) Thiết lập một hình hộp bao từ một hình sẵn có. Point3d upper) Thiết lập và khởi tạo một hình hộp bao biết trước điểm thấp điểm cao trên x. BoundingBox BoundingBox Constructor Summary Lớp này định nghĩa một hình hộp bao thẳng trục được sử dung cho vùng bao.com 323 . z.

BoundingPolytope(Bounds[] boundsObjects) http://tailieuhay. Kết quả là địng nghĩa BoundingPolytope dựa vào danh sách các mặt phẳng mà tạo nên một vùng đóng. double ymin.com 324 .Lập trình đồ họa trên Java 2D và 3D BoundingBox Method Summary (partial list) void setLower(double xmin. double zmax) Lập góc trên của hình hộp bao. BoundingPolytope(Bounds boundsObject) Tạo một BoundingPolytope ngoại tiếp một mặt bao cho trước. void setUpper(Point3d p1) Lập góc trên của hình hộp bao. y. Lập góc dưới của hình hộp bao. Một nửa không gian là một vùng không gian bao quanh một mặt qua một mặt phẳng. BoundingPolytope Constructor Summary BoundingPolytope() Tạo một BoundingPolytope định nghĩa nó dựa trên tập 6 mặt phẳng giống như hình lập phương -1 <= x. void setLower(Point3d p1) Lập góc dưới của hình hộp bao. void setUpper(double xmax. BoundingPolytope(Vector4d[] planes) Tạo một BoundingPolytope sử dụng các mặt cho trước. BoundingPolytope Một đối tượng BoundingPolytope định nghĩa một vùng đa diện sử dụng phép giao giữa 4 hoặc hơn một nửa không gian. double ymax. z <= 1. double zmin) Sets the lower corner of this bounding Box.

Đây không phải là câu trả lời tốt nhất cho mọi trường hợp. http://tailieuhay. Kết quả trong đồ thị khung cảnh là đối tượng Bound di chuyển với đối tượng tham chiếu đến nó. Một cách để nắm bắt điều này là làm cho vùng bao rộng đủ để chứa tất cả những nơi mà đối tượng di chuyển đến. Điều này là tố cho nhiều ứng dụng tuy nhiên có một vài trường hợp lại cần vùng bao di chuyển độc lập với đối tượng sử dụng vùng bao Ví dụ như nếu một thế giớibao gồm nguồn sáng cố định chiếu sáng vào đối tượng đang di chuyển thì vùng biên giới của ánh sáng phải bao gồm cả đối tượng di chuyển. 2. void setPlanes(Vector4d[] planes) Lập các mặt phẳng cho bao này.com 325 . BoundingPolytope Method Summary (partial list) int getNumPlanes() Trả về số mặt phẳng của đối tượng BoundingPolytope.7. Hình 2-25 chỉ ra một đồ thị khung cảnh với một nguồn sáng sử dụng BoundingLeafa. Một cách giải quyết tốt hơn là sử dụng BoundingLeafa. void getPlanes(Vector4d[] planes) Trả về giới hạn của các mặt phẳng cho bao đa diện này. Đặt trên đồ thị khung cảnh với đối tượng quan sát đối tượng BoundingLeafa di chuyển với đối tượng quan sát và độc lập với nguồn sáng.2 BoundingLeafa Node Các biện giới bình thường sử dụng một đối tượng bao để chỉ ra một vùng được bao quanh.Lập trình đồ họa trên Java 2D và 3D Tạo một BoundingPolytope vây quanh một mảng các bao.

không gây cảm giác lặp lại thông tin trên cả vùng.Lập trình đồ họa trên Java 2D và 3D Khi các ứng dụng cho BoundingLeafa bao gồm ApplicationBounds của đối tượng Background.3.4 tạo đối tượng BoundingLeafa. và PlatformGeometry. http://tailieuhay. đồng thời làm cho đối tượng BoundingLeafa trở thành con của PlatformGeometry. và InfluencingBounds của Lights. Một trong những ứng dụng khá hay của đối tượng BoundingLeafa là đặt một BoundingLeafa trên viewPlatform. BoundingLeafa này có thể sử dụng liên tục trên một vùng bao cho các hành vi hoặc luôn luôn chấp nhận các ứng dụng bao như nền hoặc sương mù. Đối tượng PlatformGeometry được thêm vào nhánh hình thức của đồ thị khung cảnh ở dòng 6. Dòng 2.Ví dụ trong đoạn mã 2-11 sử dụng nguyên tắc đó.com 326 . SchedulingBounds của Behaviors.

an activation region.Lập trình đồ họa trên Java 2D và 3D BoundingLeafa Class Các phi tham số của hàm tạo cho BoundingLeafa tạo một đơn vị hình cầu bao. BoundingLeafa() Tạo một nút BoundingLeafa với một đối tương đơn vị hình cầu BoundingLeafa(Bounds region) Tạo một nút BoundingLeafa với vùng định trước.3 Scope Như đã giới thiệu ở phía trên. or a scheduling region. một vùng kích hoạt hoặc một vùng danh mục. BoundingLeafa Constructor Summary The BoundingLeafa node defines a bounding region object that can be referenced by other nodes to define a region of influence.7. 2. Nút BoundingLeafa dùng để định nghĩa một đối tượng vùng bao có thể được tham chiếu đến bằng các nút khác nahu để định nghĩa một vùng ảnh hưởng. Lập vùng bao của nút BoundingLeafa.com 327 . Điều đó có nghĩa là http://tailieuhay. BoundingLeafa Method Summary Bounds getRegion() Nhật vùng BoundingLeafa. void setRegion(Bounds region) Sets this BoundingLeafa node's bounding region. định nghĩa một scope (tầm quan sát) là một cách để giới hạn ứng dựng hay ảnh hưởng của một nút. Nút định nghĩa một phạm vi quan sát có thể ảnh hưởng tới đối tượng của của đồ thị con có gốc tại đối tượng Group. Khi không có một phạm vi quan sát cho một nút ta gọi nút đó có phạm vi quan sát toàn cầu.

Lập trình đồ họa trên Java 2D và 3D nút đó có thể quan sát hoàn toàn trong môi trường ảo và chỉ bị giới hạn bởi môi trường ảo. Ngọn đèn có một bóng. Đồ thị khung cảnh trong hình 2-26 là một giải pháp. Chỉ định các nhóm được chiếu sáng bao gồm cả đối tượng được rọi sán. Một nút không có phạm vị sẽ không ảnh hưởng được các đối tượng khác. Thực tế. Nếu chỉ sử dụng vùng bao sẽ rất khó để chỉ ra ứng dụng ánh sáng đúng đắn khi đèn tắt và bật giữa các đối tượng gần nhau. Một khung cảnh chứa một ngọn đèn và một vài đối tượng quan sát trên bàn. Nếu 2 đối tượng quan sát chạm hoặc chồng lên nhau và một đối tượng có thể bao gồm vùng bao hoặc là đối tượng kia. cũng có những trường hợp sử dụng được . http://tailieuhay. vì thế không phải tất cả các đối tượng sẽ được chiếu sáng bởi chiếc đèn này. Có thể hiểu rằng khi sử dụng một vùng bao để phân biệt giữa các đối tượng mà nằm gần nhau là rất khó khăn.com 328 . Một phạm vi quan sát dùng để giới hạn ứng dụng của một nút khi sử dụng mình vùng bao sẽ rất khó khăn hoặc không thể làm. Thường thì không cần thiết phải tổ chức một đồ thị khung cảnh xung quanh vùng quan sát. Việc gọi lại một vùng bao để khi một thứ gì đó ứng dựng trên thế giới ảo. Đồ thị này chia ra các đối tượng được chiếu sáng và không được chiếu sáng thành 2 nhánh của đồ thị khung cảnh. Một vài nút cho phép chỉ ra cả vùng biên giới và phạm vi quan sát nhưng việc chỉ định một phạm vi quan sát không thể thay thế cho một vùng biên giới. Hiện tượng này không thường xảy ra như ví dụ dưới đây. Định nghĩa phạm vi giới hạn cho nguồn sáng dễ dàng hơn điều khiển ánh sáng trong khung cảnh. Đối với một nút có một hiệu ứng trên một đối tượng đối tượng cần phải có cả biên giới lẫn phạm vi quan sát.

Lập trình đồ họa trên Java 2D và 3D 2.com 329 .2 .2. Thứ nhất cho nhiều hình học trở thành các nút thành phần của một nút Shape3D. Phiên bản 1. Việc sao chép dữ liệu làm mất thời gian và công sức. 2. Việc sao chép dữ liệu chỉ thực hiện trong các phiên bản trước của 1.8 Hình học nâng cao Java 3D API phiên bản 1. Một tính năng khác là cho phép dữ liệu hình học có thể tham chiếu bằng đối tượng hình học thay vì phải sao chép. sử dụng việc tham chiếu trực tiếp tăng hiệu quả nhiều chương trình.1 giới thiệu Shape3D với định nghĩa của đối tượng quan sát và chỉ ra cách sử dụng cơ bản của đối tượng Shape3D. Tính năng này cho phép dựng hình hiệu quả hơn.1 Multiple Geometries in a Single Shape3D Chương 1 giới thiệu về lớp Shape3D phần 2.2 thêm rất nhiều phương thức tới lớp http://tailieuhay.8.2 đưa ra 2 mở rộng lớn đối với các lớp sử dụng các hình học.

Xem hình 2-27 Như trong đoạn mã 2-12 có thể thấy ta chỉ tạo một đối tượng Shape3D nhưng có thể tham chiếu đến 3 đối tượng thành phần hình học. Trong AxisApp.1 sử dụng 3 đối tượng LineArraty để vẽ các đường đại diện cho 3 trục tọa độ trong không gian. Tính năng mới này giảm thiểu số lượng đối tượng trong đồ thị khung cảnh. QuadArray} http://tailieuhay. ngoài ra trong chương trình có 3 đối tượng Shape3D tương đương với 3 đối tượng hình học. Sự cân bằng thể hiện đươi đây: Point GeometryArray: [Indexed]PointArray Line GeometryArray: [Indexed]{LineArray.java giới thiệu trong phần 2. Shape3D Geometry Equivalence Classes Nút là Shape3D chứa một danh sách 1 hoặc nhiều đối tượng thành phần hình học và một đối tượng thành phần giao diện. LineStripArray} Polygon GeometryArray: [Indexed]{TriangleArray.com 330 . nó tham chiếu đến nhiều đối tượng thành phần hình học khác. Danh sách đối tượng hình học có thể tương đương với các lớp và có cùng kiểu với các lớp hình học cơ bản.5. TriangleStripArray. TriangleFanArray.Lập trình đồ họa trên Java 2D và 3D Shape3D cho phép đối tượng Shape3D có thể tham chiếu đến nhiều đối tượng thành phần hình học. Tuy nhiên trong ví dụ AxisApp2.java có sử dụng 1 đối tượng Shape3D.

2> Trả về liệt kê danh sách các thành phần hình học. Geometry getGeometry(int index) <new in 1.2> Thay thế thành phần hình học tại vị trí chỉ mục cho trước trong danh sách với một thành phần khác. Một lần nữa 3 đối tượng lineArray định nghĩa hình cho hoặc AxisApp có thể thay thế bằng một đối tượng và một đối tượng Shape3D.com 331 .2. void setGeometry(Geometry Geometry.2> Gắn đối tượng hình học tới danh sách của nút Shape3D gồm các thành phần hình học java. http://tailieuhay.Enumeration getAllGeometries() <new in 1. Shape3D Method Summary (partial list. int index) <new in 1.2> Trả về số thành phần hình học trong danh sách. void removeGeometry(int index) <new in 1. int index) <new in 1. int numGeometries() <new in 1. see Section 2. void insertGeometry(Geometry Geometry.2> Loại bỏ thành phần hình học tại vị trí chỉ mục cho trước trong danh sách.2> Chèn thêm một thành phần hình học vào danh sách tại vị chí chỉ mục cho trước.1) void addGeometry(Geometry Geometry) <new in 1.util.2> Lấy các thành phần hình học tại vị trí index trong danh sách.Lập trình đồ họa trên Java 2D và 3D CompressedGeometry Geometry Text3D Với sự hạn chế của danh sách đối tượng Shape3D tới một lớp hình học tương đương cho thấy sự cải tiến này có vẻ không có gì là cải tiến.

http://tailieuhay. Những gợi ý và cảnh báo khi sử dụng BY_REFERENCE Nếu sử dụng BY_REFERENCE. Người lập trình phải có trách nhiệm đảm bảo cho kiểu dữ liệu đúng đắns. có 2 lí do sử dụng nó là: 1.Lập trình đồ họa trên Java 2D và 3D 2. màu . Và vì thế không có mảng bên trong đối tượng hình học. Một mảng các đối tượng trong Java 3D luôn luôn lưu trữ các tham chiếu hơn là giá trị thực vì chỉ các mảng có kiểu dữ liệu như thực mới lưu dữ liệu.2 GeometryArray Trong việc xây dựng hình các bước là tạo một đối tượng hình học.2 cho phép lời gọi BY_REFERENCE thay thế cho việc sao chép dữ liệu hình học. Nếu dữ liệu hình học cần sử dụng nhiều bộ nhớ Lí do lớn nhất để chọn phương pháp này là dữ liệu có thể thay đổi thậm chí đối tượng đang sống hoặc được dịch.. sử dụng setCoordRefFloat()thay vì setCoordRef3f()sử dụng mảng số thực cho phép truy cập trực tiếp hơn là sử dụng một mảng các đối tượng. cách khác là phân chia mảng sử dụng bởi đối tượng hình học. Với phiên bản 1. Nếu dữ liệu hình học là động 2. Nhớ rằng khi sử dụng BY_REFERENCE phương thức sử dụng khác với khi không sử dụng nó. rồi đăng kí giá trị cho nó để định nghĩa dữ liệu hình học (tạo độ. sử dụng phương thức set*RefFloat là tốt hơn cả..com 332 . Ví dụ. Sau đó khi dữ liệu hình học được đăng kí với GeometryArray nó được sao chép vào mảng này. Việc này khi ở phiên bản cũ là đối tượng sao chép GeometryArray được khởi tạo có một mảng private lưu giữ toàn bộ dữ liệu này bên trong đối tượng GeometryArray. Cách thay đổi hình chính là thay đối dữ liệu của nó. Khi đối tượng GeometryArray BY_REFERENCE được tạo người dùng tạo một mảng hình học và quản lí mảng này với dữ liệu hình học.8.) . Vậy khi nào cần sử dụng BY_REFERENCE.

• Điền đầy giá trị cho mảng TriangleStripArray Tham chiếu đến dữliệu người dùng với đối tượng GeometryArray. trong trường hợp này tạo độ và màu được người dùng tạo thành 2 mảng coord và color. Trong đoạn ma 2-13 được lấy từ chương trình TwistByRefApp.java.Lập trình đồ họa trên Java 2D và 3D Ví dụ GeometryArray BY_REFERENCE Sử dụng BY_REFERENCE Geometry với GeometryArray cho đối tượng hình học tĩnh không khó hơn sao chép Geometry. Thứ tự của các bước có thể thay đổi khi mảng sử dụng được khai báo trước khi chúng được tham chiếu hoặc điền giá trị và đối tượng GeometryArray được tạo trước khi mảng được tham chiếu. Trong trường hợp này đối tượng GeometryArray là một mảng TriangleStripArray. contentRoot = new http://tailieuhay. Việc dùng được thực hiện theo các bước sauL • Khai báo mảng để giữ các dữ liệu hình học • Tạo đối tượng GeometryArray mong muốn bằng tùy chọn định dạng đỉnh BY_REFERENCE. // ////////////////////////////////////////// ///// // // create scene graph branch group // public BranchGroup createSceneGraph() { BranchGroup BranchGroup().com 333 . sử dụng tham chiếu đến dữ liệu hình học thay vì cách cũ.

addChild(objSpin). objSpin = new objSpin. The PolygonOffset is set to prevent stitching.ALLOW_TRANSF ORM_WRITE). objSpin.addChild(twist). // Add the POLYGON_FILLED and POLYGON_LINE strips // in the scene graph at the same point. TransformGroup TransformGroup().setCapability(TransformGroup. contentRoot. polyAttrib = new http://tailieuhay. // Duplicate the twist strip geometry and set the // appearance of the new Shape3D object to line mode // without culling. PolygonAttributes PolygonAttributes(). Shape3D twist = new Twist(). Add it to the root of the subgraph.com 334 . // This will show the triangles of the original Mobius strip that // are clipped.Lập trình đồ họa trên Java 2D và 3D // Create the transform group node and initialize it to the // identity.

RotationInterpolator objSpin).Lập trình đồ họa trên Java 2D và 3D polyAttrib.setPolygonAttributes(polyAttrib). objSpin.com 335 .CULL_NON E).POLYG ON_LINE). bounds = new rotator = new rotationAlpha = new Alpha(-1.setPolygonOffset(0. polyAppear)).addChild(new Shape3D(twist.addChild(rotator). objSpin. http://tailieuhay.001f).getGeometry(). // a bounding sphere specifies a region a behavior is active // create a sphere centered at the origin with radius of 1 BoundingSphere BoundingSphere(). polyAttrib.setSchedulingBounds(bounds). RotationInterpolator(rotationAlpha. rotator.setCullFace(PolygonAttributes. Appearance polyAppear = new Appearance().setPolygonMode(PolygonAttributes. polyAttrib. Alpha 16000). polyAppear.

// Let Java 3D perform optimizations on this scene graph. Vì thế nó định nghĩa rất nhiều phương thức cho việc quản lí dữ liệu.0f. GeometryArray Methods for Referencing Geometry Data (partial list) This collection of methods set the references to Geometry data in user arrays.0f.Lập trình đồ họa trên Java 2D và 3D // make background white Background background = new Background(1.lập bit BY_REFERENCE trong trường định dạng đỉnh trong hàm tạo của đối tượng GeometryArray.Để sử dụng tham chiếu hình học. In each case.0f). Trong mỗi trường hợp phương thức sẽ đưa ra ngoại lệ nếu http://tailieuhay. Đây là các phương thức dùng để tham chiếu đến dữ liệu hình học trên mảng sử dụng.compile(). 1.setApplicationBounds(bounds). in other cases the data mode must not be INTERLEAVED. return contentRoot.addChild(background). the method will throw an exception if the data mode for this Geometry array object is not BY_REFERENCE. contentRoot.com 336 . In some cases the data mode must also be INTERLEAVED. contentRoot. 1. } // end of CreateSceneGraph method of TwistStripApp GeometryArray Lớp GeometryArray là lớp cơ sở của nhiều lớp hình học khác. background.

com 337 . void setCoordRef*(Point*[] coords) <new in 1.2> Sets the float coordinate array reference to the specified array. trong một số trường hợp chế độ dữ liệu có thể là INTERLEAVED. Point3f) array. void setNormalRef3f(Vector3f[] normals) <new in 1.2> Sets the texture coordinate array reference for the specified texture coordinate set to the specified TexCoord* (TexCoord2f.2> Sets the coordinate array reference to the specified Point* (Point3d.2> Sets the float color array reference to the specified array.2> Sets the color array reference to the specified Color* (Color3b. Color4b.2> Sets the interleaved vertices array reference to the specified array. or Color4f) array. void setColorRefByte(byte[] colors) <new in 1. void setColorRefFloat(float[] colors) <new in 1. void setColorRef*(Color*[] colors) <new in 1. void setNormalRefFloat(float[] normals) <new in 1. void setCoordRefFloat(float[] coords) <new in 1. void setTexCoordRef*(int texCoordSet. Color3f.2> Sets the byte color array reference to the specified array. trong một số trường hợp không được phép là INTERLEAVED. http://tailieuhay. TexCoord*[] texCoords) <new in 1.Lập trình đồ họa trên Java 2D và 3D chế độ dữ liệu không chọn là BY_REFERENCE.2> Sets the Vector3f normal array reference to the specified array.2> Sets the double coordinate array reference to the specified array. TexCoord3f) array. void setCoordRefDouble(double[] coords) <new in 1. void setInterleavedVertices(float[] vertexData) <new in 1.2> Sets the float normal array reference to the specified array.

com 338 . void setInitialTexCoordIndex(int texCoordSet. <new in 1.2> Sets the float texture coordinate array reference for the specified texture coordinate set to the specified array.2> Sets the initial coordinate index for this GeometryArray object. void setInitialNormalIndex(int initialNormalIndex) <new in 1. Tất nhiên nó chỉ có tác dụng nếu chế độ BY_REFERENCE.Lập trình đồ họa trên Java 2D và 3D void setTexCoordRefFloat(int texCoordSet. Dưới đây là các phương thức để thay đối giá trị dữ liệu hình học. http://tailieuhay.2> int initialTexCoordIndex) Sets the initial texture coordinate index for the specified texture coordinate set for this GeometryArray object. GeometryArray Methods for Setting Initial Location of Referenced Geometry Data (partial list) void setInitialColorIndex(int initialColorIndex) <new in 1.2> Sets the initial normal index for this GeometryArray object.2> Sets the initial color index for this GeometryArray object. This method is easily confused with the setInitialVetrexIndex method which is used when the Geometry is not BY_REFERENCE. float[] texCoords) <new in 1. Một cách đơn giản để thay đổi hình học sử dụng BY_REFERENCE là thay đối số giá trị sử dụng trong một mảng. Các phương thức này chỉ được cho phép hoạt động trên các đối tượng đang sống hoặc đang dịch khi khả năng ALLOW_REF_DATA_WRITE được lập. void setInitialCoordIndex(int initialCoordIndex) <new in 1.

This is only used in by-reference Geometry mode. It also enables writing the referenced data itself. only used in by-reference Geometry mode ALLOW_REF_DATA_WRITE <new in 1.2> Specifies that the position. Dữ liệu hình học trong bất cứ mảng nào được tham chiếu đến bởi một đối tượng GeometryArray sống hoặc đang được dịch có thể thay đổi thông qua phương thức updateData của nó. and texture coordinate data for this GeometryArray are accessed via a single interleaved.2> allow write access to the Geometry data reference information for this object.2> allow read access to the Geometry data reference information. Các ứng dụng đều phải quan tâm tránh để vi phạm luật này.Lập trình đồ họa trên Java 2D và 3D GeometryArray Capabilites BY_REFERENCE <new in 1. color. normal. ALLOW_COUNT_READ | WRITE <new in 1. http://tailieuhay.com 339 . color. and texture coordinate data for this object are accessed by reference INTERLEAVED <new in 1. floating-point array reference. via the GeometryUpdater interface. normal.2> allow write access to the count or initial index information for this object ALLOW_REF_DATA_READ <new in 1.2> Specifies the position. This is only used in by-reference Geometry mode.

2 mô tả làm thế nào có thể chia sẻ một gói giao diện giữa các đối tượng Shape3D.4 AlternateAppearance <new in 1. Thứ 2 phải có một giới hạn quan sát trên ứng dụng của nó.com 340 .6.2> Như đã thấy trong phần 2. Tạo một phạm vi quan sát cho AlternateAppearance AlternateAppearance theo vào ý đồ mình. Thứ 3 chỉ những đối tượng quan sát cho phép giao diện của nó được ghi đề đưa ra cho AlternateAppearance Sử dụng AlternativeAppearance Node Để sử dụng AlternateAppearance đầu tiện phải tạo gói giao diện để sử dụng phép thay thế và tham chiếu đến gói giao diện bằng đối tượng AlternativeAppearance. Một AlternateAppearance cho phép người phát triển ứng dụng có thể phát triển các phương thức thay thế cho việc chia sẻ một gói giao diện giữa các đối tượng Shape3D. Xem hình 2-20 và 2-37. Gói giao diện này định nghĩa các thuộc tính quan sát của đối tượng Shape3D. Thứ nhất đối tượng phải nằm trên trên vùng bao của AlternateAppearance. Nó là một cách thay thế cho việc chia sẻ gói giao diện – đưa ra cách dễ dàng hơn để tạm thời thay đổi giao diện.Lập trình đồ họa trên Java 2D và 3D updateData method of GeometryArray public void updateData(GeometryUpdater updater) <new in 1.6. Sau đso lập vùng ảnh hưởng thông qua đối tượng Bounds hoặc BoundingLeafa. Phần 2. Có 3 cách. 2.1 đối tượng Shape3D có thể có một tham chiếu đến nút thành phành Appearance. appearanceOverrideEnable trên đối tượng Shape3D.2> Cập nhật mảng dữ liệu được truy cập thông qua tham chiếu. thị Đừng quên lập thêm cờ khung cảnh. Phương thức gọi updateData của đối tượng GeometryUpdater để đồng bộ cập nhật với dữ liệu đỉnh được tham chiếu bởi đối tượng GeometryArray.8. http://tailieuhay.

2> Khởi tạo một nút AlternateAppearance với các tham số mặc định: Appearance.2> Tạo một nút AlternateAppearance với giao diện cho trước.2> Các phần dưới là danh sách hàm tao cho lớp AlternateAppearance AlternateAppearance Constructor Summary AlternateAppearance() <new in 1. scope.Lập trình đồ họa trên Java 2D và 3D Shape3D setAppearanceOverrideEnable() Method void setAppearanceOverrideEnable(boolean flag) <new in 1.2> cho phép truy cập đọc/ghi tới cờ appearanceOverrideEnable AlternativeAppearance Class <new in 1. influencingBounds.2> Gắn một nút Group cho trước tới danh sách nút AlternateAppearance của phạm vi quan sát. và influencingBoundingLeaf = null AlternateAppearance(Appearance Appearance) <new in 1. Shape3D Capabilities (partial list.com 341 . Phương thức này có thể gọi khi đối tượng đang sống hoặc dịch tùy theo khả năng nó được lập thế nào. see Section 2.1) ALLOW_APPEARANCE_OVERRIDE_READ | WRITE <new in 1. AlternateAppearance Method Summary (partial list) void addScope(Group scope) <new in 1. http://tailieuhay.2> Lập cờ chỉ ra khi nào một giao diện của một nút được ghi đè bằng một nút AlternativeAppearance.2.

2> Chèn vào một nút Group cho trước vào danh sách tại chỉ số cho trước.2> Lập giao diện cho nút AlternateAppearance void setInfluencingBoundingLeaf(BoundingLeafa region) <new in 1.Lập trình đồ họa trên Java 2D và 3D java.2> Lập vùng ảnh hưởng của AlternateAppearance tới vùng bao cho trước.com 342 .util. void insertScope(Group scope. void setScope(Group scope. int index) <new in 1. int index) <new in 1. void setAppearance(Appearance Appearance) <new in 1. int numScopes() <new in 1.2> Sets the AlternateAppearance's influencing region to the specified bounding leaf.2> Loại bỏ nút tại vị trí cho trước trong danh sách.2> Trả về bảng liệt kê danh sách nút AlternateAppearance của phạm vi quan sát. void removeScope(int index) <new in 1. Lập vùng ảnh hưởng của AlternateAppearance tới lá bao cho trước. void setInfluencingBounds(Bounds region) <new in 1.Enumeration getAllScopes() <new in 1.2> Thay thế vị trí của nút tại vị trí chỉ mục trong danh sách với một nút Group cho trước. Những khả năng của lớp AlternateAppearance AlternativeAppearance Capabilities ALLOW_APPEARANCE_READ | WRITE allow read (write) access to its Appearance information ALLOW_INFLUENCING_BOUNDS_READ | WRITE allow read (write) access to its influencing Bounds and bounding leaf information http://tailieuhay.2> Trả về số nút trong danh sách.

Lí do thì có rất nhiều. phần này đưa ra các vấn đề cơ bản nhất trong việc cắt hình . 2.com 343 . Trong một số trường hợp bạn sẽ bắt gặp hoàn cảnh mà một đối tượng quan sát không được dựng hình. Điều này là không hợp lệ nhưng nó cũng không được khuyến khích.Lập trình đồ họa trên Java 2D và 3D ALLOW_SCOPE_READ | WRITE allow read (write) access to its scope information at runtime 2. Ví dụ khi môt hình mở rộng đến vùng biên nên nó bị cắt đi vì thế một số hình không xem được. ngoài đối tượng có thể nằm ngoài vùng frustum (hình cụt). Cắt xén là một chủ đề phức tạp.9 Clipping – Cắt xén Chủ đề của Clipping không thực sự là việc tạo hình nhưng một trong những nhân tố ảnh hưởng đến hình ảnh trong như thế nào.9. Chú ý rằng mặt phẳng cắt phía trước(front clipping plane) nằm đằng sau màn ảnh(image plate).1 View Defines a Frustum Trong chương 1 giới thiệu về hệ tọa độ ảo và mô tả vị trí của mắt liên quan đến nó. Vùng này là nơi đối tượng quan sát và các phần của đối tượng quan sát khác được hiển thị. http://tailieuhay. Hình 2-29 sẽ đưa ra cho bạn định nghĩa rõ hơn về vùng frustum.

http://tailieuhay. Nên để (back clip distance) / (front clip distance) < 3000.Lập trình đồ họa trên Java 2D và 3D Phần chóp cụt này được định nghĩa thông vị trí mắt nhìn và 2 mặt phẳng cắt trước và sau. Dưới đây là một trong số đó. View Methods for Adjusting the Frustum (partial list) Đối tương View trong phần đồ thị hình thức của đồ thị khung cảnh Java 3D định nghĩa rất nhiều tham số về hình ảnh. Tuy nhiên thực thế tỉ lệ này thường là từ 100 đến 1000 là hợp lí nhất. khoảng cách này phải lớn hơn 0.0 và nhỏ hơn khoảng cách sau. void setBackClipDistance(double distance) Lập khoảng cách mặt cắt sau với mô hình quan sát. void setFieldOfView(double fieldOfView) Lập trường ngang mô hình quan sát dạng radians. void setFrontClipDistance(double distance) Lập khoảng cách mặt cắt trước với mô hình quan sát.com 344 . Giá trị mặt định tương đối hợp lí tuy nhiên người lập trình có thể thay đổi khoảng cách này. khoảng cách này phải lớn hơn với khoảng cách của mặt trước.

ApplicationBounds và applicationBoundingLeaf = null Clip(double backDistance) Tạo một Clip node với tham số backDistance Clip Method Summary void setApplicationBoundingLeaf(BoundingLeafa region) Lập vùng ứng dụng cắt tới đối tượng bao lá.khoảng cách mặt sau của đối tượng Clip được sử dụng để dựng.Lập trình đồ họa trên Java 2D và 3D 2.com 345 . mặt trước định nghĩa bởi đối tượng View không ảnh hưởng. Mỗi Clip định nghĩa một vùng ứng dụng chỉ ra một đối tượng vùng bao hoặc lá bao. http://tailieuhay.9. Khi vùng bao này giao với khu vực quan sát . Dưới đây là danh sách các hàm tạo và phương thức: Clip Constructor Summary Clip() Tạo một Clip Node với tham số mặc định : backDistance = 100. void setApplicationBounds(Bounds region) Lập vùng ứng dụng cắt tới đối tượng bao.2 Clip Node Như đã nói ở phía trên khoảng cách của hình chóp cụt có thể thay đổi. Nút cắt là một đối tượng thực hiện điều này. void setBackDistance(double backDistance) Lập khoảng cách sau với giá trị cho trước. Việc sử dụng Clip làm tăng tốc độ xử lí đặc biệt trong những khung cảnh phức tạp.

Ảnh hưởng này của nút ModelClip được điều khiển thông qua các vùng được mô tả trước dựa trên ảnh hưởng và tầm quan sát.4 ModelClip Example Các bước sử dụng ModelClip • Thiết lập vùng ảnh hưởng cho đối tượng ModelClip • Chọn hoặc bỏ chọn các mặt cắt tùy theo ý mình • Lập hướng và vị trí cho mặt phẳng để sử dụng.com 346 .Lập trình đồ họa trên Java 2D và 3D Clip Field Summary ALLOW_APPLICATION_BOUNDS_READ | WRITE allow read (write) access to its application Bounds and bounding leaf at runtime.9. ALLOW_BACK_DISTANCE_READ | WRITE allow read (write) access to its back distance at runtime. Khi giữa các nửa mặt cắt có giao nhau chúng định nghĩa một vùng mà các điểm trong đó không được dựng. dù chúng ở trong hình chóp cụt nhìn thấy. Một đối tượng ModelClip định nghĩa một tập 6 mặt cắt với hướng tùy ý trong hệ tọa độ cơ bản. Mặt cắt định nghĩa một nửa không gian cho những đỉnh được lựa chọn để dựng. http://tailieuhay. 2. Nút ModelClip có thể cắt đối tượng quan sát ra theo nhiều cách. • Thêm đối tượng ModelClip vào đồ thị khung cảnh Mặc dù không thực hiện trong ví dụ này nhưng ModelClip có thể định nghĩa một phạm vi quan sát.

void removeScope(int index) <new in 1. ModelClip Constructor Summary ModelClip() <new in 1. boolean[] enables) <new in 1.2> Returns the number of nodes in this ModelClip node's list of scopes. ModelClip Method Summary (partial list) void addScope(Group scope) <new in 1.2> Tạo một nút ModelClip với tham số mặc định. ModelClip(Vector4d[] planes) <new in 1. ModelClip(Vector4d[] planes.2> Appends the specified Group node to this ModelClip node's list of scopes.2> http://tailieuhay. Kết quả là mảng Vertor4d được sử dụng trong hàm tạo phải có kich thước 6.com 347 .2> Tạo một nút ModelClip với mặt cho trước và có thiết lập các cờ. int index) <new in 1.2> Inserts the specified Group node into this ModelClip node's list of scopes at the specified index.2> Tạo một nút ModelClip với mặt cho trước.Lập trình đồ họa trên Java 2D và 3D Nhớ rằng luôn luôn có 6 mặt phẳng trong đối tượng ModelClip. void insertScope(Group scope. int numScopes() <new in 1.

void setPlane(int planeNum.2> Sets the clipping planes of this ModelClip node to the specified planes.2> Replaces the node at the specified index in this ModelClip node's list of scopes with the specified Group node.com 348 . void setEnables(boolean[] enables) <new in 1. int index) <new in 1. void setInfluencingBounds(Bounds region) <new in 1. void setInfluencingBoundingLeaf(BoundingLeafa region) <new in 1.Lập trình đồ họa trên Java 2D và 3D Removes the node at the specified index from this ModelClip node's list of scopes. void setPlanes(Vector4d[] planes) <new in 1. boolean enable) <new in 1. Vector4d plane) <new in 1. void setScope(Group scope.2> Sets the specified clipping plane of this ModelClip node.2> Set the ModelClip node's influencing region to the specified bounding leaf. ModelClip Field Summary ALLOW_ENABLE_READ | WRITE allow read (write) access to its enable flags at runtime ALLOW_INFLUENCING_BOUNDS_READ | WRITE allow read (write) access to its influencing Bounds and bounding leaf at runtime http://tailieuhay.2> Sets the specified enable flag of this ModelClip node.2> Sets the per-plane enable flags of this ModelClip node to the specified values. void setEnable(int planeNum.2> Set the ModelClip node's influencing region to the specified Bounds.

Lập trình đồ họa trên Java 2D và 3D ALLOW_PLANE_READ | WRITE allow read (write) access to its planes at runtime ALLOW_SCOPE_READ | WRITE allow read (write) access to its scope information at runtime http://tailieuhay.com 349 .

3 giới thiệu lớp Loader. Lớp này có khả năng tạo ra các dối tượng trực quan Java3D từ các tệp được tạo bởi các phần mềm 3D. lớp tiện ích này cung cấp khả năng tự động hóa trong việc tạo ra các đối tượng trực quan.2 sẽ giới thiệu lớp GeometryInfo. Bằng các phương pháp này công việc lập trình trơ nên buốn tẻ. và tinh chỉnh các đa giác này. Stripifier.Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 3 TẠO NỘI DUNG 3. Trong mục 3. AutoCad và các định dạng file 3D khác…Một đặc điểm quan trọng là ta có thể viết các lớp Loader riêng để phục vụ cho nhu cầu sử dụng.com 350 . http://tailieuhay. và NormalGeneration cho phep ta tạo ra cá đối tượng trực quan như là các đa giác hình học. Trong chương này chúng ta sẽ xem xét một phưong pháp khác để tạo ra các đối tượng trực quan. Lightwave. Các lớp này chuyển đổi đa giác thành tam giác.1 Nội dung chính Trong các chương trước chúng ta đã tìm hiểu cách tạo ra những đối tượng trực quan bằng các phương pháp đơn giản. Mục 3. Cụ thể lớp Loader có thể đọc các file VRML. Lớp GeometryInfo cũng với các lớp Triangulator.

Để nâng cao hiệu năng của hệ thống chúng ta có thể sử dụng đối tượng Stripifier để chai các tam giác thành các tam giác rời nhau. Khi bắt đầu vẽ một đối tượng hình học.com TRIANGLE_ARRAY. chúng ta sẽ xác định một đa giác bất kỳ phù hợp với dối tượng đó. ta sử dụng NormalGenerator để tính toán các vector bề mặt của đối tượng hình học. từ đó Java3D có thể render (tô_chát) .Lập trình đồ họa trên Java 2D và 3D Các mục tiếp theo chúng ta sẽ xem xét các kỹ thuật khởi tạo nội dung. 3. chúg ta cần chỉ rõ loại geometry cần dùng: POLYGON_ARRAY. QUAD_ARRAY. Sử dụng lớp GeometryInfo công việc sẽ trở nen dễ dàng và thuận tiên hơn. Đa giác này có thể là đa giác lõm. không phẳng … Đối tượng GeometryInfo và các lớp khác sẽ chuyển các đa giác này thành các tam giác nhỏ hơn. Để khởi tạo một đối tượng GeometryInfo. 3.1 Một ví dụ đơn giản về GeometryInfo Trong phần này chúng ta sẽ xem xét các khởi tạo và sử dụng đối tượng GeometryInfo. Nếu chúng ta muốn tạo bóng cho đối tượng hình học.1.2. http://tailieuhay. chúng ta phải tự làm hoàn toàn và việc code sẽ rất vất vả và nhàm chán.1 GeometryInfo Thông thường để vẽ một hình một đối tượng hình học bất kỳ. 351 .

gi. Nếu sử dụng cả NormalGenerator và Stripifier thì ta phải sử dụng NormalGenerator trước. Triangulator tr = new Triangulator().generateNormals(gi).setStripCounts(stripCounts). tr.triangulate(gi). st. stripcounts). chúng ta có thể sử dụng các lớp tiện ích khác như NormalGenerator.Lập trình đồ họa trên Java 2D và 3D TRIANGLE_FAN_ARRAY và TRAINGLE_STRIP_ARRAY. NormalGenerator ng = new NormalGenerator(). gi.getGeometryArray()). part. Khi khởi tọa chúng ta phải chỉ ra coordinate và strip counts. Chúng ta xét đoạn code dưới đây.2. ng.setAppearance(appearance).setCoordinates(coordinateData). Triangulator … bằng cách truyền tham số là đối tượng GeometryInfo.com . Shape3D part = new Shape3D(). part. - - Sau khi tạo ra đối tượng GeometryInfo. Stripifier st = new Stripifier(). GeometryInfo gi = new GeometryInfo(GeometryInfo. Normalgenerator và Stripifier đều chỉ sự dụng với các tam giác chỉ 352 http://tailieuhay.stripify(gi).POLYGON_ARRAY). - 3.setGeometry(gi.2 Sử dụng GeometryInfo Một số chú ý khi sử dụng đối tượng GeometryInfo. Khởi tạo đối tượng GeometryInfo và thiết lập các thông số cân thiết (coordinate.

sun.3 Một số lớp thông dụng có liên quan đến GeometryInfo Trong phần này chúng ta sẽ xem xét kỹ hơn một số lớp thông dụng nằm trong gói com. QUAD_ARRAY.j3d. chúng ta không cần quan tâm đến kiểu của GeometryInfo(POLYGON_ARRAY. Tuy nhiên các thành phần khác của dối tượng GeometryInfo sẽ bị thay đổi.2. STRIP_ARRAY… ).util. khi đó các dữ liệu này được chuyển đổi thành các tam giác chỉ mục. http://tailieuhay.com 353 . Sau khi thực hiện các tam giác chỉ mục này được gắn liền lại với nhau. 3. Khi sử dụng những lớp tiện ích này.Lập trình đồ họa trên Java 2D và 3D mục.geometry.

Hàm tạo GeometryInfo Gói: com.com 354 . các đa giác 2 chiều.Lập trình đồ họa trên Java 2D và 3D Lớp GeometryInfo có một hàm tạo duy nhất.geometry Lớp cha: java.lang.sun.Object Sử dụng: Chúng ta muốn chuyển các đối tượng hình học cho đối tượng GeometryInfo để có thể dùng các lớp tiện ích khác. khi khởi tạo một đối tượng cần chỉ rõ kiểu của đối tượng Gemetry và hệ trục tọa độ tương ứng. các lớp tiện ích sẽ sử dụng các dữ liệu trong đối tượng GeometryInfo để thực hiện các yêu cấu của chúng ta.3 chiều(đa http://tailieuhay.. GeometryInfo(int primitive) Giá trị của primitive: POLYGON_ARRAY diện) QUAD_ARRAY TRIANGLE_ARRAY TRIANGLE_FAN_ARRAY tương với mỗi tam giác rời : Tứ diện : Tam giác : Mảng StripCounts cho biết số đỉnh : Đa giác.j3d.utils. Khi chúng ta chuyển đối tượng hình học cần thể hiện cho đối tượng GeometryInfo.

các dữ liệu bề mặt. Gọi hàm này khi các thông tin về hệ trục tọa dộ không chính xác void reverse() Đảo ngược thứ tự của tất cả các danh sách void setColorIndices(int[] colorIndices) void setColors(Color3f[] colors) Đặt mảng mầu sắc void setColors(Color4f[] colors) Đặt mảng mầu sắc. void setContourCounts(int[] contourCounts) Đặt danh sách mầu viền void setCoordinateIndices(int[] coordinateIndices) Thiết lập mảng tỷ lệ của hệ trục tọa độ.com 355 . void setNormalIndices(int[] normalIndices) http://tailieuhay. mầu sắc. chỉ mục. Các phưong thức của lớp GeometryInfo void recomputeIndices() Thực hiện lại việc sắo xếo để đảm bảo các thông tin kết nối là chính xác. void setCoordinates(Point3d[] coordinates) Thiết lập mảng của hệ trục tọa độ. void setCoordinates(Point3f[] coordinates) Thiết lập mảng của hệ trục tọa độ. trong đó có các phương thức theíet lập hay lây thông tin về hệ trục toạ độ.Lập trình đồ họa trên Java 2D và 3D TRIANGLE_STRIP_ARRAY : Mảng StripCounts cho biết số đỉnh tương với mỗi tam giác rời Lớp GeometryInfo chứ nhiều phương thức.

void setNormals(Vector3f[] normals) void setNormals(float[] normals) void setStripCounts(int[] stripCounts) void setTextureCoordinateIndices(int[] texCoordIndices) void setTextureCoordinates(Point2f[] texCoords) Cách sử dụng các lớp tiện ích khác cũng như sử dụng với lớp GeometryInfo.Lập trình đồ họa trên Java 2D và 3D Thiết lập mảng các chú dẫn.com 356 . Stripifier và NormalGenerator. Sau đây chúg ta sẽ lần lượt xem xét hàm tạovà phương thức của các lớp Triangulator. http://tailieuhay. Trong đó lớp Triangulator chỉ làm việc với đối tượng hình học kiểu POLYGON_ARRAY. Đây cũng chính là thứ tự khi chúng ta làm việc với POLYGON_ARRAY.

j3d.utils.geometry Lớp cha: java.lang.geometry Lớp cha: java.Lập trình đồ họa trên Java 2D và 3D Hàm tạo lớp Triangulator nhằm tạo ra đối tượng tam giác.Object Lớp Stripfier có tiện ích đổi kiểu dũ liệu nguyên thuỷ của một đối tượng GeometryInfo sang kiểu Triangle Strips. Để cho kết quả tốt Normal Generation phải được thực hiệntrước khi quá trình tách nhỏ đối tượng hình học. Stripifier() Hàm tạo Pương thức của lớp Stripifier void stripify(GeometryInfo gi) http://tailieuhay. Hàm tạo lớp Stripifier nhằm tạo ra một đối tượng stripification Stripifier Constructor Summary Gói: com. Triangulator Constructor Summary Gói: com.sun.utils.com 357 .sun.lang.j3d.Object Triangulator() Hàm tạo lớp Triangulator Triangulator Method Summary void triangulate(GeometryInfo gi) Phươn thức chuyển đổi một đối tượng GeometryInfo tùe kiểu nguyên thuỷ là POLYGON_ARRAY sang kiểu nguyên thuỷ kiểu TRIANGLE_ARRY.

j3d.76794 radians.com 358 .utils. Các Phương thức NormalGenerator void generateNormals(GeometryInfo geom) double getCreaseAngle() Lấy giá trị góc gập void setCreaseAngle(double radians) Thiết lập góc gập Các phương thức của lớp NormalGenerator : một phương thức thiết lập. Sau đó đối tượng 3D này có thể http://tailieuhay.lang. Lớp NormalGenerator có hai hàm tạo. Hàm tạo thứ nhất tạo ra đối tượng NormalGenerator với góc gấp có giá trị mặc định.Lập trình đồ họa trên Java 2D và 3D Chuyển GeometryInfo có chứa đối tượng GeometryInfo vào mảng Triangle Strips. NormalGenerator(double radians) Khởi tạo một NormalGenerator với góc gập có giá trị là tham số đầu vào. Hàm tạo thứ hai cho phép thiết lập giá trị cho crease angle. or 44°).Object NormalGenerator() Khởi tạo một NormalGenerator với góc gập mặc định (0.geometry Lớp cha: java. một phương thức lấy giá trị crease angle … Loaders Một lớp Leader đọc các file 3D và tạo ra cácm đối tượng của Java3D với nội dung cảu file được đưa vào. NormalGenerator Constructor Summary Gói: com.sun.

Ta sử dụng lớp loader với các bước như sau: • Tìm một loader • Import lớp loader ứng với dịnh dạng fie tương ứng • Import những lớp cần thiết • Định nghĩa một biến khung cảnh • Tạo một đối tượng loader • Load nội dung của file trong khối catch.2/demo/java3d/ObjLoad.Lập trình đồ họa trên Java 2D và 3D được sử dụng như các đối tuwọng khác của Java3D. Trên thực tế ngày cáng có nhiều các định dạng file 3D từ các ứng dụng khác nhau.sun.j3d. và gán kết quả đọc được cho biến khung cảnh • Chèn đối tuwọng khung cảnh vào trong miền khung cảnh Ta có thể xem xét một ứng dụng mẫu của lớp ObjectFile trong jdk1. ma chỉ có phần giao diện dùng cho kỹ thuật loading được đưa vào. Một ví dụ đơn giản sử dụng leader. Để load vào nội dung một file. Class ObjectFile Gói: com.sun. công việc để load các file này không phải là công việc của Java3D hay của gói loaders.com 359 . Gói com.leaders cung cấp các phương thức load các file 3D từ các chuwong trình ứng dụng khác vào trong chuwong trình Java3D.j3d. chúng ta không nhất thiết phải sử dụng một lớp tiện ích để load file đó.loaders Thực thi: Loader http://tailieuhay.

Lập trình đồ họa trên Java 2D và 3D Lớp ObjectFile thực thi giao diện Loader với file có định dạng WaveFront.. Các loader phổ biến Trong Java3D chúng ta có thể tìm thây rất nhiều lớp Loader. Ta có bảng danh sach cụ thể dưới đây. File 3DS COB DEM DXF IOB LWS NFF OBJ PDB PLAY SLD VRT VTK Mô tả 3D-Studio Caligari trueSpace Digital Elevation Map AutoCAD Drawing Interchange File Imagine Lightwave Scene Format WorldToolKit NFF Format Wavefront Protein Data Bank PLAY Solid World Superscape VRT Visual Toolkit http://tailieuhay.2.obj. Chúng ta xem xét một ví dụ được thực hiện theo các bước đã nói ở trên.6 trong ví dụ trên đèu được hiện theo trình tự các bước ta phân tích. một định dạng chuẩn của file 3D đuwọc tạo ra bằng phần mêm WaveFront Advanced Víualizer. Chúng ta có thể thấy các bược 1.com 360 .

j3d. bằng các sử dụng cùng một đối tượng loader tạo ra nhiều đối tượng scene.j3d.loaders còn cung cấp các lớp cơ sở để thực thi những interface này. Đối tượng loader đọc. Scene The Scene interface is a set of methods used to extract Java 3D scene graph information from a file loader utility. Trong đó gói com. Trong một chương trình Java3D chúng ta có thể load được nhiều file định dạng khác nhau bằng các sử dụng các loader thích hợp.loaders. Chúng ta có thể load được nhiều scene từ nhiều file 3D.sun. http://tailieuhay.loaders Interface Summary Loader The Loader interface is used to specify the location and elements of a file format to load. và tạo ra phần thể hiện của Java 3D cho nội dung file 3D đó. Đối tượng scene lưu lại scene graph được tạo ra từ loader.j3d.sun.sun.3 Giao diện của gói Loader và lớp cơ sở Để load được các file 3D trong một ứng dụng Java. Một lớp loader thực thi loader interface và sử dụng một lớp thích hợp để thực thi scene interface.com 361 . phân tích.3.Lập trình đồ họa trên Java 2D và 3D WRL Virtual language Reality Modeling 3. com. Sau đây chúng ta sẽ xem xét cụ thể các interface có trong gói com. chuwong trình của chúng ta phải sử dụng đến đối tượng loader và đối tượng scene.

sun.j3d.loaders Giao diện Loader được sử dụng để chỉ rõ ra vị trí và các thành phần của một định dạng file cần load. Scene load(java.com 362 .Lập trình đồ họa trên Java 2D và 3D com. Interface Loader Method Summary Gói: com.URL url) Phương thức lấy ra nội dung của một file từ URL. Giao diện Scene sẽ được thực thi để cung cấp cho người dùng những giao diện phù hợp để lấp dữ liệu từ các file. và trả về một đối tượng scene có chứa khung cảnh void setBasePath(java.String pathName) Phương thức này thiiết lập đường dẫn cơ sở cho các file được dùng trong phương thức load(String) http://tailieuhay. Phần giao diện này cung cấp cho lớp Loader các định dạng file khác nhau.net. còn phần thực thi nằm trong các lớp loader mà người lập trình sử dụng.sun.io.String fileName) Phương thức lấy ra nội dung của một file từ tên file.Reader reader) Phương thức lấy ra thành phần Reader và trả về một đối tượng scenecó chứa khung cảnh. Scene load(java. và trả về một đối tượng scene có chứa khung cảnh Scene load(java. SceneBase Lớp SceneBase thực thi giao diện Scene và việc thừa kế lớp SceneBase giúp cho chúng ta dễ dàng sử dụng được các phương thức đã xây dựng Các phương thức được định nghĩa trong interface.lang.lang. Lớp đuợc thiết kế để chúng ta có thể thừ kế nếu muốn xây dựng các loader.loaders Class Summary LoaderBase Lớp này thực thi giao diện Loadẻ và thêm vào các hàm tạo.j3d.

.j3d..URL url) Phương thức này thiiết lập đường dẫn cơ sở cho các file được dùng trong phương thức load(URL) void setFlags(int flags) Phương thức thiết lập cờ load LOAD_ALL Cho phép load toàn bộ các đối tượng vào khung cảnh. LoaderBase() Khởi tạo đối tượng Loader với cá giái trị mặc định http://tailieuhay.net. LOAD_FOG_NODES Cờ cho phép load sương mù vào trong khung cảnh. LOAD_LIGHT_NODES Cờ cho phép load đối tượng ánh sáng vào trong khung cảnh. LoaderBase Constructor Summary Gói: com. Lớp Loader thực hiện phần thực thi 2 hàm tạo. LOAD_SOUND_NODES Cờ cho phép load đối tượng âm thanh vào trong khung cảnh.loaders Thực thi: Loader Lớp Loader thực thi giao diện loader.sun. LOAD_BEHAVIOR_NODES Cờ cho phép load các hành vi vào trong khung cảnh. LOAD_BACKGROUND_NODES Cờ cho phép load các đối tượng backgrround vào khung cảnh. Lớp loader cơ sở cung cấp phần thực thi với mỗi phương thức load (gồm 3 phương thức) được định nghĩa trong các loader interface. LOAD_VIEW_GROUPS Cờ cho phép load đối tượng view (camera) vào trong khung cảnh.com 363 .Lập trình đồ họa trên Java 2D và 3D void setBaseUrl(java..

loaders Thực thi giao diện Scene Lớp SceneBase thực thi giao diện Scene. SceneBase() Khởi tạo một đối tượng SceneBasse SceneBase Method Summary (partial list: loader users' methods) Background[] getBackgroundNodes() Behavior[] getBehaviorNodes() java. Khi thừa kế lớp loader cơ sở.com 364 .j3d. Lớp ScaneBase có chức năng lưu trũ và nhận dữ liệu được tạo ra bởi lớp Loader trong quá trình đọc file.sun. Trong quá trình viết một loader mới chúng ta cần xem xét việc thừa kế lớp SceneBase hoặc thực thi interface Scene một cách trục tiếp.sun.String getDescription() http://tailieuhay. công việc chú yếu của chúng ta là viết các phương thức để nhận ra format của file.lang.Lập trình đồ họa trên Java 2D và 3D LoaderBase(int flags) Khởi tạo đối tượng Loader với các cờ chỉ định Khi chúng ta viết một lớp loader mới. Các phương thức thực hiện việc lưu trữ (được cung cấp bởi những người viết ra Loader) có tên dạng add* . SceneBase Constructor Summary Gói: com. chúng ta có thể thừa kế lại lớp loader cơ sở trong gói com. Mỗi phương thức này tạo ra các thành phần scene graph tương ứng và lưu các dữ liệu này trong đối tượng scene. Các phương thức thu nhận dữ liệu (được người sử dụng lớp loader gọi ra) có tên dạng get*.j3d.loaders và sử dụng lớp SceneBase trong cùng gói này.

hiểu được việc thực thi của ObjectLoader. hiểu cách sử dụng GeometryInfo. Công việc của một loader Ngoài nhiệm vụ chính là đọc nội dung một file đồ hoạ. Viết một loader Công việc viết một loader là một công việc phức tạp và không phải người lập trình Java 3D nào cũng phải viết. • Tính toán bề mặt thông thường của các đa giác. • Thể hiện đối tượng đồ họa tại nguyên gốc • Chỉnh tỷ lệ của đối tượng hình học một cách thích hợp. lớp loader còn có các chức năng khác.Lập trình đồ họa trên Java 2D và 3D Fog[] getFogNodes() float[] getHorizontalFOVs() Light[] getLightNodes() java. Phần tiếp theo ta sẽ đi vào chi tiết việc viết một loader.com 365 . làm việc cảu một Loader sẽ giúp chúng ta hiểu rõ hơn khi nào thì sử dụng loader. Tuy nhiên việc nghiên cứu cách viết. tương ứng 1-1 trên mỗi trục • Làm mịn đối tượng hình học http://tailieuhay. tạo ra một đối tuợng scene graph thể hiện cho nội dung của file được load.util.Hashtable getNamedObjects() BranchGroup getSceneGroup() Sound[] getSoundNodes() TransformGroup[] getViewGroups() Qua những điểm trên ta có thể xây dựng được loader cho nhu cầu cảu mình.

com 366 . hoặc sử dụng LOD. có loại file đơn giản. Sau đây chúng ta xem xét tập các layer đơn giản. Hàm tạo lớp Loader Trong phần này chúng ta sẽ xem xét việc tao ra một đối tuwọng loader từ hàm tạo của lớp loader đã xaay dựng.Lập trình đồ họa trên Java 2D và 3D • Thể hiện đối tượng hình học một cách hiệu quả bằng việc phân nhỏ thành nhiều phần. có loại file phức tạp. Đó là cách tiếp cận chuẩn cho việc xây dựng một loader. Một khía cạnh khó khăn nữa là khi xây dựng một loader chúng ta phải quan tâm đến format của file. Một loader được xây dựng trên các lớp này có khả năng chọn được phần dữ liệu của file được sử dụng trong ứng dụng. Sử dụng khái niệm Layer. Số lượng các layer lại phụ thuộc nhiều vào format của file cần load. Nhìn chung việc xây dựng một lớp loader đồi hỏi những kiến thức liên quan đến định dạng của file cần load và phần luồng stream trong Java. Layer/leve l Tokenizer Chức năng Chuyển các ký tự thành các http://tailieuhay. Có nhiều cách tiếp caạn trong việc xây dựng một loader. chúng ta có thể dùng các lớp SceneBase và LoaderBase (đã trình bày ở các chương trước). việc xây dựng lớp loader trở nên dễ dàng hơn. có những file còn có sự liên quan đến các file cấu hình khác như file quy địng scene graph description. Nhiệm vụ chủ yếu của nó là tạo ra đối tướng hình học tương ứng với nội dung file được load vào. Tuy nhiên để có thể tận dụng được sự hỗ trợ của Java3D. Tuy nhiên không phải bất cứ loader nào cũng phải thực hiện đầy đủ các chức năng trên.

kết cấu hay bất cứ đối tượng khung cảnh nào trong Java3D. Tần này có nhiệm vụ chia nhỏ nội dung cảu file thành phần nhỏ hơn.Lập trình đồ họa trên Java 2D và 3D token Đối tượng Chuyển các token hình ảnh của file thành các đối tượng đồ hoạ (geometry. Ví dụ như file theo định dạng Open Inventor và OOGL List. lights. • Đối tượng Tầng object có nhiệm vụ tạo ra các đối tượng đồ họa từ các token được tạo ra theo nội dung của file. một từ. đa giác.com 367 . Một vài đối tượng có thể là đối tượng đỉnh. gọi là các token. Scene textures… ) Chuyển danh sách các đối tựong scene graph vào tong File khung cảnh đồ hoạ Liên quan đến các file hay các URL cần mở • Tokenizer Đây là tầng thấp nhất của loader trong việc xử lý các file đồ hoạ. Lấy ví dụ một token có thể là một số. ánh sáng. Những object này là các thành phàn của một khung cảnh • Scene Là tập hợp các đối tượng hình học. hay một ký tự đơn. Trừ truờng hợp ngoại lệ khi nó lớp loader có nhiệm vụ load một tệp đại diện cho một khung cảnh đồ họa. • File http://tailieuhay.Thông thường tầng scene trong Java3D đơn giản.

Viết một File Loader đơn giản Trong phần này chúng ta sẽ xem xét cụ thể hơn việc xây dựng một loader đơn giản.com 368 . ví dụ như họ OOGL (Object Oriented Graphics Library) Định dạng QUAD Bước đầu tiên để viết một Loader là biết được định dạng của file. Trong phần này chúng ta sẽ xem xét qua về cấu trúc file QUAD.có các khoảng trắng. Thông thường chúng ta sẽ chọn lự một họ các file co định dạng tương đương. Một file dạng QUAD là một tập hợp 4*n đỉnh. Các phần comment được bắt đầu sau dấu # . hình vuông này nằm trên mặt phẳng Oxy. ký tự…). Định dạng QUAD thuộc loại định dạng OOGL. Ví dụ duới đây cho thấy noọi dung một file QUAD. Định dạng QUAD mô tả một tập hợp các bộ quad. File này chứa thông tin về một hình vuông trên hệ không gian 3 chiều. Trong phần 4 chúng ta sẽ xem xét những vấn đề : Đa số các file OOGL đều có định dạng ASCII tự do. trông. các chi tiết cụ thể sẽ trình bày ở phần 4. Việc dầu tiên là chúng ta cần xác định định dạng file mà loader của chúng ta sẽ load. với thành phần z của hình vuông bằng 0. dòng mới… giữa các phần tử (số. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D File có chứa nội dung cần được load. tab. trong đó n là số các bộ quad.

Tầng/Lớp tokenizer Object scene file Thực thi QuadFileParser SimpleQuadObject chứa QuadFileParser SimpleQuadScene thừa kế lớp SimpleQuadObject SimpleQuadFileLoader thừa kế lớp SimpleQuadScene thực thi application lớp Loader SimpleQuadLoad chứa lớp SimpleQuadFileLoader Trong các phần tiếp theo chúng ta sẽ xem xét kỹ hơn ácc lớp này. thành phần và hoạt động của nó tỏng một ứng dụn loader.com 369 . tuy nhiên mục đích của chúng ta là tìm hiểu cách viết một loader đơn giản nên ta dựa trên file QUAD đơn giản.Lập trình đồ họa trên Java 2D và 3D Cấu trúc của một ile QUAD nói chung là phứuc tạp hơn nhiều so với ví dụ trên. chúng ta xây dựng lớp QuadFileParser thừ kế lớp StreamTokenizer. Tầng Tokenizer(Quản lý các phần tử) Bước đầu tiên để xây dựng một loader là xây dựng tokenizer. Trong bảng dưới đâu đưa ra danh sách các lớp và mối quan hệ giữa chúng để ta có thể xây dựng một lớp loader. Trong ví dụ này. Các phương thức trong lớp QuadFileParser http://tailieuhay. Điều này được thực hiện bằng cách chúng ta thừa kế lớp tiện ích StreamTokenizer. Lớp này đọc vào luồng các ký tự và chuyển đổi nó thành tập các phần tử. Cấu trúc chung của file QUAD được mô tả kỹ hơn trong phần 4.

Lập trình đồ họa trên Java 2D và 3D Phương thức Void setup() boolean getToken() Nhiệm vụ/hoạt động Chỉ ra các tham số cho tokenizer, hàm này được gọi trong hàm tạo Phương thức lấy ra token tiếp theo, phương thức sử dụng hàm lớp các token ra nextToken()của Void printToken() StreamTokenizer In giá trị của

System.out, dùng trng quá trình gỡ QuadFileParser(Reade r r) lỗi Hàm tạo gọi phương thức setup và liên kết các token với đối tượng reader. Những sự thay đổi mở rộng chủ yếu nằm trong phương thức setup. Những sự thay đổi này bao gồm: • Định nghĩa những ký tự đặc biệt, dấu xuống dòng, dấu comment. class QuadFileParser extends StreamTokenizer { // setup // Sets up StreamTokenizer for reading OOGL file formats. void setup() { resetSyntax(); // EOL chars are insignificant in QUAD file eolIsSignificant(false); wordChars('A','z'); // have StreamTokenizer parse numbers (makes double-precision)

http://tailieuhay.com

370

Lập trình đồ họa trên Java 2D và 3D parseNumbers(); // Comments begin with # to end of line commentChar('#'); // Whitespace characters delineate words and numbers // blanks, tabs, and newlines are whitespace in OOGL whitespaceChars('\t', '\r'); // ht, lf, ff, vt, cr whitespaceChars(' ', ' '); // space } // End of setup /* getToken * Gets the next token from the stream. Puts one of the four * constants (TT_WORD, TT_NUMBER, TT_EOL, or TT_EOF) and the token * value into ttype token object. * The value of this method is in the catching of exceptions in this * central location. */ boolean getToken() { int t; boolean done = false; try { t = nextToken(); } catch (IOException e) { System.err.println( "IO error on line " + lineno() + ": " + e.getMessage()); return false; } return true;
http://tailieuhay.com 371

Lập trình đồ họa trên Java 2D và 3D } // End of getToken // QuadFileParser constructor QuadFileParser(Reader r) { super(r); setup(); } // end of QuadFileParser } // End of file QuadFileParser.java Ta có thể thấy những thay đổi trong các phương thức getToekn(), printToken() .. là không đáng kể. Như vậy ta đã hoàn thành việc viết lớp QuadFileLoader, tiếp theo chung sta chuyển lên tầng trên, tầng object. Thực hiện tầng Object Nhiệm vụ của tầng Object là chuyển những token được cung cấp bởi tầng tokenizer sang các đối tượng hình học.Tỏng ví dụ của chúng ta thì điều này là đơn giản bời vì chúng ta chỉ có một đối tượng hình học duy nhất là tứ diện. Tuy nhiên chúng ta gặp phải một khó khăn trong việc xác định số lượng đối tượng hình học được cung cấp. Các phương thức trong lớp SimpleQuadObject Phương thức Boolean readVertex(QuadFileParser st) Nhiệm vụ Đọc đỉnh, mỗi đỉnh bao gồm tọa độ x,y,z hay các thông tin khác về mầu sắc, bề Boolean readQuad(QuadFileParser st) mặt… Đọc các tú diện bằng cách đọc các đỉnh từ file QUAD

http://tailieuhay.com

372

Lập trình đồ họa trên Java 2D và 3D Void readQuadFile(QuadFileParserst) Đọc file QUAD xác nhận các thẻ trong file, xác định tập các đỉnh và đọc ra cá tứ diện(tứ giác) Nhiệm vụ của tầng này là đọc ra các đối tượng hình học từ tập hợp các token. Trong trường hợp này các đối tượng hình học là các đỉnh. Tập các đỉnh này được lưu trữ trong một đối tượng ArrayList. Sử dụng ArrayList chó phép việc thay đổi kích thước cảu mảng tạo thời gian thực hiện. Tại tầng Scene, đối tượng kiểu ArrayList được chuyển đổi sang một Array và sau đó là sang đối tượng hình học. Chúng ta xem xét phần code chủ yếu trong tầng Object. Toàn bộ phần code đầy đủ nằm trong example.jar. import QuadFileParser; // many other imports omitted in tutorial text public class SimpleQuadObject { protected int flags; protected int fileType = 0; // what properties vertices have // constants for indicating file type protected static final int COORDINATE = GeometryArray.COORDINATES; // lists of points are read from the .quad file into this //array. . . protected ArrayList coordList; // Holds Point3f /** * readVertex reads one vertex's coordinate data */ boolean readVertex(QuadFileParser st) {
http://tailieuhay.com 373

Lập trình đồ họa trên Java 2D và 3D Point3f p = new Point3f(); st.getToken(); if(st.ttype == st.TT_EOF) return false; // reached end of file p.x = (float)st.nval; st.getToken(); p.y = (float)st.nval; st.getToken(); p.z = (float)st.nval; // Add this vertex to the array coordList.add(p); return true; } // End of readVertex /** * readQuad reads four vertices of the correct type (which in this * version is always just coordinate data). */ boolean readQuad(QuadFileParser st) { int v; boolean result = false; for(v=0; v < 4; v++) result = readVertex(st); return result; } // End of readQuad /* * readFile * * Read the model data from the file.
http://tailieuhay.com 374

Lập trình đồ họa trên Java 2D và 3D */ void readQuadFile(QuadFileParser st) { // verify file type st.getToken(); if(st.sval.equals("QUAD") || st.sval.equals("POLY")) fileType = COORDINATE; else throw new ParsingErrorException("bad file type: "+st.sval); // read vertices while (readQuad(st); } // End of readFile } // End of class SimpleQuadObject // End of file SimpleQuadObject.java Nếu trong chúng ta có các thông tin đi kèm với mỗi đỉnh như mầu săc, chữ .. các thông tin này cũng được luwu trong một ArrayList. Những thông tin thêm vào này cũng đựoc chuyển sang mảng thích hợp trong tầng scene. Đây là tầng thực hiện chủ yếu công việc của một loader. Tiếp đén là tầng Scene, tầng khung cảnh Thực hiện tầng Scene Tầng scene thực thi bởi lớp SimpleQuadScene. Các phương thưc lớp SimpleQuadScene Phương thức SceneBase makeScene() Nhiệm vụ Nhận dữ liệu từ một ArrayList do tầng dưới đưa lên, tạo ra các đối tượng hình học tương ứng và đưa
http://tailieuhay.com 375

Lập trình đồ họa trên Java 2D và 3D vào khung cảnh đồ họa

Point3f[] in) Scene load(Reader reader)

Chuyển đổi một ArrayList thành thức makeScene()để tạo ra các đối tượng hình học 1.Khởi tạo a một đối tượng QuadFileParser 2.Gọi QuadFileLoad(scene) 3.Gọi makeScene()

objectToPoint3fArray(ArrayList một mảng Point3f, dùng phương

class SimpleQuadScene extends SimpleQuadObject 2. { 3. // coordList is converted to an arrays for creating geometry 4. // 5. private Point3f coordArray[] = null; 6. 7. private Point3f[] objectToPoint3fArray(ArrayList inList) 8. { 9. Point3f outList[] = new Point3f[inList.size()]; 10. 11. for (int i = 0 ; i < inList.size() ; i++) { 12. outList[i] = (Point3f)inList.get(i); 13. } 14. return outList; 15. } // End of objectToPoint3fArray 16.
376

http://tailieuhay.com

Lập trình đồ họa trên Java 2D và 3D 17. 18. private SceneBase makeScene() 19. { 20. // Create Scene to pass back 21. SceneBase scene = new SceneBase(); 22. BranchGroup group = new BranchGroup(); 23. scene.setSceneGroup(group); 24. 25. // the model will be one Shape3D 26. Shape3D shape = new Shape3D(); 27. 28. coordArray = objectToPoint3fArray(coordList); 29. 30. QuadArray qa = new QuadArray(coordArray.length, fileType); 31. qa.setCoordinates(0, coordArray); 32. 33. // Put geometry into Shape3d 34. shape.setGeometry(qa); 35. 36. group.addChild(shape); 37. scene.addNamedObject("no name", shape); 38. 39. return scene; 40. } // end of makeScene 41. 42. public Scene load(Reader reader) throws FileNotFoundException, 43. IncorrectFormatException, 44. ParsingErrorException 45. {
http://tailieuhay.com 377

Lập trình đồ họa trên Java 2D và 3D 46. // QuadFileParser does lexical analysis 47. QuadFileParser st = new QuadFileParser(reader); 48. 49. coordList = new ArrayList(); 50. 51. readQuadFile(st); 52. 53. return makeScene(); 54. } // End of load(Reader) 55. } // End of class SimpleQuadScene 56. // End of file SimpleQuadScene.java Thực hiện tầng File Tầng này có nhiệm vụ thực hiện việc giao tiếp với File. Đa số phần code của tầng này cũng tươn tự như ở tầng Object. Lớp SimpleQuadFileLoader thừa kế lớp SimpleQuandScene và thực thi giao diện Loader. Xây dựng một Loader hoàn chỉnh Trong thực tế có rất nhiều thông tin chi tiết trong file QUAD mà loader đơn giản mà chúng ta vừa xây dựng không đáp ứng dược. Ví dụ như những ký hiệu khoa học trong một file QUAD, các thông tin về mầu săc… Lớp StreamTokenizer chúng ta xây dựng chưa đáp ứng nhu cầu đó. Một file QUAD cso thể chứa những thông tin về bề mặt, mầu sắc .. của mỗi đỉnh, mỗi đối tượng. Để nhận được các thông tin này chúng ta cần thay đổi tầng Object và tầng scene.

http://tailieuhay.com

378

Lập trình đồ họa trên Java 2D và 3D Một file QUAD có thể bao gồm nội dung của một file khác. Điều này làm tăng sự phức tạp của loader và đói hỏi việc thay đổi code tại tất cả các tầng. Một loader phức tập hơn có thể nhận ra và load được một họ các định dạng file, ví dụ như LightWave loader.

Text2D Có hai cách để thực hiện việc them chữ vào trong khung hình Java3D. Cách thứ nhất là sử dụng lớp Text2D, cách thứ hai là sử dụng Text3D. Sự khác nhau ở chỗ, lớp Text2D thực hiện các dòng chữ trong không gian 2 chiều còn Text3D thực hiện trong không gian 3 chiều. Đối tượng Text2D là các đa giác vuông trong đó các chữ được coi như là phần bề mặt. Đối tuwọng Text3D là những đối tượng hình học trong không gian 3 chiều. Là một lớp con của lớp Shpae3D, thể hiện của lớp Text2D có thể là con của đối tượng group. Để thêm vào dòng chữ 2D trong Java3D chúng ta cần tạo ra đói tượng Text2D sau đó thêm nó vào không gian đồ hoạ. Đối tượng Text2D được thực hiện sử dụng một đa giác và một texture.

http://tailieuhay.com

379

Lập trình đồ họa trên Java 2D và 3D 3.5.1 Ví dụ Text2D đơn giản Trong ví dụ dưới đây chúng ta xem xét việc tạo ra một dối tượng Text2D đơn giản. Bao gồmg bước tạo ra đối tượng Text2D và bước tiếp hteo là thêm đối tượng này vào không gian đồ họa. import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Frame; import java.awt.event.*; import java.awt.Font; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.geometry.Text2D; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; // Text2DApp renders a single Text2D object. public class Text2DApp extends Applet { public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); // Create a Text2D leaf node, add it to the scene graph. Text2D text2D = new Text2D("2D text is a textured polygon", new Color3f(0.9f, 1.0f, 1.0f), "Helvetica", 18, Font.ITALIC)); objRoot.addChild(text2D);

3.5.2 Lớp Text2D Lớp Text2D là lớp tiện ích thừ kế từ lớp Shape3D.
http://tailieuhay.com 380

int fontSize. java.String fontName.geometry Lớp Text2D tạo ra một khung chữ nhật được ánh xạ đến phàn nội dung text.0.com 381 .j3d. Color3f color. trực y Text2D(java.sun. int fontStyle) Trong hàm tạo Text2D ta có thể thay đổi tỷ lệ kích thứoc của đối tuwọng dòng chữ hiện ra so với kích thước điểm cố định. Kích thước của khung chữ nhạt được xác định phụ thuộc vào font được sử dụng(tham số của hàm tạo).String http://tailieuhay. hiẹn thị nội dung text được gửi bởi nguời dùng. Text2D Method Summary void setRectangleScaleFactor(float newScaleFactor) text.Lập trình đồ họa trên Java 2D và 3D Hàm tạo lớp Text2D.utils.lang.0) kéo dài theo chiều dương trục x. Kêt quả của đối tượng Shape3D trong suốt ngoại trừ hình chữ nhật chứa nội dung text được đặt tại vị trí (0. Text2D Constructor Summary Gói: com.lang.

trước hết đối tượng Text3D được tạo ra bằng cách sử dụng đối tượng hình học. Lớp Text3D là lớp con của lớp Geometry. Bước đầu tiên chúng ta phải tạo ra đối tượng Font3D bao gồm các thuộc tính bề mặt. và thêm ào không gian đồ hoạ Một ví dụ Text3D Các bước tạo ra và sử dụng đối tuwọng Text3D được minh hoạ trong ví dụ sau.com 382 . http://tailieuhay.lang. Trong đó đối tuwọng Font3D tạo ra với thuộc tính kiểu bề mặt là “Helvetica”. font chữ là 10.Lập trình đồ họa trên Java 2D và 3D Đặt giá trị tỷ lệ được sử dụng trong việc chuyển đổi chiều rộng/chiều dài của hình ảnh sang chiểu rộng/chiều cao tương ứng trong không gian đồ họa bắt đầu bằng thừa số 1/256 void setString(java. kích thứoc và kích cỡ của font. Khởi tạo một đối tượng Text3D bao gồm nhiều công việc hơn trong đối Text2D. Sau đó chúng ta tạo ra đối tượng Text3D tham chiếu đến một điểm trong không gian đồ họa.String text) <new in 1.2> Thiết lập giá trị dùng chữ hiện thị cho đối tượng Text2D Text3D Trong phần này chúng ta tìm hiểu vấn đề làm việc với lớp Text3D. nên đối tuwọng text3D là một đối tượng NodeComponent được tham chiếu bởi một hay nhiều đối tuwọng Shape3D. Các bước tạo ra đối tượng Text3D • Tạo mới đối tượng Font3D từ AWTFont • Tạo mới đối tượng Text3D sử dụng đối tượng Font3D. ta có thể chỉ định diểm tham chiếu tuỳ chọn • Tham chiếu đói tượng Shape3D.

applet.Frame.*. 10). http://tailieuhay. public class Text3DApp extends Applet { public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().j3d.utils. 0. import javax.media. Chúng ta xem hình dưới đây.*.applet.Lập trình đồ họa trên Java 2D và 3D import java. new String("3DText").awt. Font3D font3d = new Font3D(new Font("Helvetica".sun.MainFrame. Shape3D textShape = new Shape3D(textGeom). new Point3f(-2.awt.event. // Text3DApp renders a single Text3D object.Font.0f.0f)).universe.com 383 .*. import java.utils.Applet. import com.vecmath. import com. 0. objRoot. import java.awt. Text3D textGeom = new Text3D(font3d.addChild(textShape).sun.BorderLayout. import javax.j3d. Font. new FontExtrusion()).0f.*. import java.j3d.awt. import java.PLAIN.

Ta có thể “chiếu sáng” đối tượng Text3D theo nhiều hướng khác nhau. http://tailieuhay.com 384 . Trong bảng dưới đây cho ta minh họa về sự kết hợp này. Mỗi đối tượng Text3D có một điểm tham chiếu. Những lớp liên quan để tạo ra đối tượng Text3D Trong phần này chúng ta xem xét những lớp có liên quan để tạo ra đối tượng Text3D.Lập trình đồ họa trên Java 2D và 3D Để tạo ra chiều sâu (thể hiện bằng vùng mầu ghi) chúng ta sử dụng các đối tượng Material và đối tuwọng DirectionLight. Điểm tham chiếu là sự kết hợp của path và alignment của đối tượng Text3D. Để có thể chiếu nhiêug hướng khác nhau chúng ta sử dụng lớp Material.

0) alignment ALIGN_FIRST path PATH_RIGHT character spacing 0. Đối tượng Font3D xác định bề ngoài của đối tượng Text3D NodeComponent Text3D() Tạo ra đối tượng Text3D. Each Text3D object has a position . Text3D Constructor Summary A Text3D object is a text string that has been converted to 3D geometry.0. Các giá trị mặc định: appropriate.0 http://tailieuhay. The Font3D object determines the appearance of the Text3D NodeComponent object. The 3D text can be placed around this position using different alignments and paths.Lập trình đồ họa trên Java 2D và 3D Lớp Text3D bao gồm nhiều hàm tạo. Cho phép ta tạo ra đối tuwọn Text3D một cách linh hoạt. Một đối tượng Text3D là một xâu ký tự được chuyển đổi sang hình học 3D.com 385 .a reference point placing the Text3D object. are: font 3D null string null position (0.

int alignment. Mặc định điểm tham chiếu nằm về phía bên dưoiứ cùng bên trái của chữ cần hiển thị Text3D(Font3D font3D. int path) ALIGN_CENTER Căn lề giữa. Point3f position. Point3f position) Tạo ra đối tượng Text3D với cá tham số đối tượng Font3D. xâu ký tự. những phương thức lấy giá trị các tuộc tính của đối tượng Text3D(getXXX).Lập trình đồ họa trên Java 2D và 3D Text3D(Font3D font3D) Tạo ra đối tượng Text3D với đối tượng Font3D đã xác định Text3D(Font3D font3D. Những phương thức của lớp Text3D.. ALIGN_LAST alignment: ký tự cuối cùng của dòng chữ được đặt tại điểm tham chiếu. String string) Tạo ra đối tượng Text3D với đối tượng Font3D đã xác định và nội dung của xâu ký tự cần hiển thị Text3D(Font3D font3D.com 386 . tọa độ của điểm tham chiếu. String string. gồm những phương thức để thiết lập các thuộc tính của đối tượng Text3D (setXXX). String string. Text3D Method Summary void setAlignment(int alignment) Đặt canh lề cho đối tượng Text3D NodeComponent void setCharacterSpacing(float characterSpacing) http://tailieuhay. Xem thêm ví dụ ở bảng trên. ALIGN_FIRST alignment: ký tự đầu tiên của dòng chữ được đặt tịa điểm tham chiếu.

com 387 . Các chế độ của đối tượng Text3D. ALLOW_BOUNDING_BOX_READ ALLOW_CHARACTER_SPACING_READ | WRITE Cho phép đọc ghi các ký tự dấu cách.Lập trình đồ họa trên Java 2D và 3D Đặt ký tự dấu cách khi tạo ra đối tượng Text3D void setFont3D(Font3D font3d) Thiết lậo đối tượng Font3D được sử dụng bởi đối tượng Text3D NodeComponent void setPath(int path) Đặt đường dẫn của node void setPosition(Point3f position) Đặt điểm tham chiếu của node void setString(java. ALLOW_POSITION_READ | WRITE Cho phép đọc ghi giá trị vị trí của xâu http://tailieuhay.String string) Copies the character string from the supplied parameter into the Text3D node. Text3D Capabilities Summary ALLOW_ALIGNMENT_READ | WRITE Cho phép đọc ghi giá trị xâu ký tự.lang. ALLOW_FONT3D_READ | WRITE cho phép đọc ghi thông tin các thành phần Font3D ALLOW_PATH_READ | WRITE Cho phép đọc ghi giá trị xâu đường dẫn. Copy xâu ký tự từ tham só đầu vào cho đối tượng Text3D node.

Font3D Constructor Summary Lớp cha: java. Đối tuwonjg Font3D được thu hồi tự động (garbage collected) mà không ảnh hưởng đến đối tượng Text3D sử dụng chúng.Font font.Lập trình đồ họa trên Java 2D và 3D ALLOW_STRING_READ | WRITE Cho phép dọc ghi đối tượng xâu ký tự. FontExtrusion extrudePath) Font3D(java. FontExtrusion extrudePath) <new in 1. Một đối tượng Font3D có thể được dùng để tạo ra nhiều đối tượng Text3D khác nhau. ALLOW_STRING_READ | WRITE Cho phép đọc ghi đối tượng xau ký tự. Font3D(java.Font getFont() Returns the Java 2D Font used to create this Font3D object. Font3D Method Summary void getBoundingBox(int glyphCode.. Dưới đây là các phương thức get*.awt.com 388 . Mỗi đối tượng Text3D được tạo ra từ một đối tượng Font3D. Một đối tượng Font3D lưu các thông tin về bề dầy hình học của đối tượng Text3D.2> ALLOW_PATH_READ | WRITE Cho phép đọc ghi giá trị đường dẫn. Lớp Font3D không có những phương thức set* cụ thể.awt.Object Một đối tượng Font3D bao gồm Java 2D Font và chiều sâu. việc thiết lập các thuộc tính của đối tượng Font3D được thực hiện trong hàm tạo. double tessellationTolerance. Trả về đối tượng Java2D Font được sử dụng để tạo ra đối tượng Font3D http://tailieuhay. ALLOW_POSITION_READ | WRITE Cho phép đọc ghi giá trị vị trí.awt. BoundingBox bounds) java.Font font.lang.

Ta mô tả một hàm tạo lớp Font. DialogInput. Một tên logic cần phải là mộ trong các gía trị: Dialog. double getTessellationTolerance() <new in 1. kiểu. Serif. or Symbol. Thiết lập giá trị đối tượng FontExtrusion sử dụng để tạo ra đối tượng Font3D bằng giá trị cảu tham số đầu vào. ITALIC … size . Font Constructor Summary (partial list) Gói: java.the typeface name.Cỡ Font. Có thể là ten logic hoặc ten typeface. The extrusion path is used in conjunction with a Font2D object.awt public Font(String name. int size) Hàm tạo mới một đối tượng Font với tham số tên Font. The extrusion path defines the edge contour of 3D text. int style. This contour is http://tailieuhay. các hàm tạo còn lại có thể xem thêm trong javadoc.com 389 .Lập trình đồ họa trên Java 2D và 3D void getFontExtrusion(FontExtrusion extrudePath) Copies the FontExtrusion object used to create this Font3D object into the specified parameter. style Tham số kiểu có thể alf mộ trong các kiểu: BOLD. SansSerif.lang. Monospaced. Hàm tạo lớp FontExtrusion FontExtrusion Constructor Summary Lớp cha: java. kích cỡ name .2> Lớp Font được sử dụng trong việc tạ ra đối tượng Font3D.Object The FontExtrusion object is used to describe the extrusion path for a Font3D object.

The output is undefined for extrusions that cause intersections. Contour must be monotonic in x. <new in 1. The extrusion has its origin at the edge of the glyph with 1. FontExtrusion() Hàm tạo với giá trị mặc định FontExtrusion(java.awt.0 being the height of the tallest glyph.awt.2> double tessellationTolerance) http://tailieuhay.com 390 .Lập trình đồ họa trên Java 2D và 3D perpendicular to the face of the text.Shape extrusionShape) Hàm tạo đối tượng FontExtrusion với đối số shape truyền vào và tolerance = 0.01 FontExtrusion(java.Shape extrusionShape. User is responsible for data sanity and must make sure that extrusionShape does not cause intersection of adjacent glyphs or within single glyph.

Một dói tuợng background có thể là một mầu cụ thể. Các bước tạo ra nnè của không gian đồ họa: • Khởi tạo một đối tượng background mới chỉ định mầu sắc hoặc một hình ảnh nào đó.Shape extrusionShape) Sets the FontExtrusion's shape parameter.com . ảnh. ta có thể lựa chọn mầu sắc. double getTessellationTolerance() <new in 1. 391 http://tailieuhay.Shape getExtrusionShape() Gets the FontExtrusion's shape parameter. Tuy nhiên Java3D cung cấp cho chúng ta khả năng thay đổi nền của không gian đồ họa. mầu nền của không gian đồ họa là mầu đen sẫm.Lập trình đồ họa trên Java 2D và 3D Các phương thức lớp FontExtrusion FontExtrusion Method Summary java. các đối tượng hình học hay kết hợp các thành phần này lại để tạo thành nền của không gian đồ họa. một hình ảnh hay thậm chí môt đối tượng hình học. void setExtrusionShape(java. • Thêm vào một đối tượng hình học (tùy chọn) • Cung cấp một Application Boundary hoặc một BoundingLeaf • Thêm đối tượng background vào không gian đồ họa Một ví dụ background Như ta đã trình bày ở phần trước.awt. Nền không gian đồ họa Một cách mặc định.2> Return the tessellation tolerance with which this FontExtrusion object was created.awt.

100.setApplicationBounds(new Point3d(). Ta có thể xem một ví dụ hoàn chinh BackgroundApp. Ví dụ background là mầu nền Background backg = new Background(1.com 392 . //black background backg. // backg. Phương thức này trả về đối tượng BranchGroup.Lập trình đồ họa trên Java 2D và 3D tỏng ví dụ đầu tiên chúng ta sẽ xem xét đối tượng backgrond là mầu trắng. Ví dụ background là đối tượng hình học Background backg = new Background().setGeometry(createBackGraph()).0f).java trong thư mục examples/easyContent. Phương thức createBackGraph() bao gồm việc tạo ra đối tượng hình học làm nền. một thể hiện của lớp background là thành phần con thuộc đối tượng Group http://tailieuhay. BoundingSphere(new Lớp Background Trong phần này chúng ta xem xét cụ thể thành phần và họat dộng của lớp background Lớp background thừa kế lớp Leaf. objRoot. 1.addChild(backg). contentRoot.0f.addChild(backg). 1.setApplicationBounds(BoundingSphere()).0)).0f. ví dụ thứ hai ta thêm một đối tượng hinh học vào background. // add BranchGroup of background backg.

com 393 . Background(float r. It optionally allows background geometry to be referenced. Background(ImageComponent2D image) Constructs a Background node with the specified image. Background() Constructs a Background node with a default color (black). float g. Background geometry must be pre-tessellated onto a unit sphere and is drawn at infinity. float b) Constructs a Background node with the specified color. Background(Color3f color) Constructs a Background node with the specified color. Hàm tạo của lớp Background Background Constructor Summary The Background leaf node defines either a solid background color or a background image that is used to fill the window at the beginning of each new frame. It also specifies an application region in which this background is active.Lập trình đồ họa trên Java 2D và 3D Background có nhiều hàm tạo. Tham số trong hàm tọa cho biêt mầu sắc hoặc hình ảnh cho background. Các phương thức trong lớp background http://tailieuhay.

void setApplicationBounds(Bounds region) Set the Background's application region to the specified bounds. Các tham số cáu hình khác của đối tượng Background Background Capabilities Summary ALLOW_APPLICATION_BOUNDS_READ | WRITE allow read (write) access to its application bounds ALLOW_COLOR_READ | WRITE allow read (write) access to its color ALLOW_GEOMETRY_READ | WRITE allow read (write) access to its background geometry ALLOW_IMAGE_READ | WRITE allow read (write) access to its image 3.com 394 . void setImage(ImageComponent2D image) Sets the background image to the specified image.8 Dữ liệu người dùng: Các đối tượng SceneGraphObject có thể tham chiếu đến bất cứ đối tượng nào như là các dữ liệu người dùng. float b) Sets the background color to the specified color. void setColor(float r. Danh sách lớp con của lớp http://tailieuhay. void setGeometry(BranchGroup branch) Sets the background geometry to the specified BranchGroup node. float g. void setColor(Color3f color) Sets the background color to the specified color.Lập trình đồ họa trên Java 2D và 3D Background Method Summary void setApplicationBoundingLeaf(BoundingLeaf region) Set the Background's application region to the specified bounding leaf.

Geometry. di chuyển. http://tailieuhay. java. BranchGroup.lang.User Data Methods) SceneGraphObject is a common superclass for all scene graph component objects.Lập trình đồ họa trên Java 2D và 3D SceneGraphObject gòm có: Appearance.lang. Geometry. Behaviour. Lights.Object userData) Sets the userData field associated with this scene graph object. etc.com 395 . Mỗi đối tượng có thể có thể chứa những dữ liệu dạng text trong đối tượng dữ liệu người dùng. This includes Node. Background.Object getUserData() Retrieves the userData field from this scene graph object. void setUserData(java. Các phương thức lớp SceneGraphObject SceneGraphObject Methods (Partial List . một ứng dụng có thể có nhiều đối tượng có khả năng tương tác. Appearance. Shape3D và TransformGroup. Lấy ví dụ.

Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 4 TƯƠNG TÁC Trong chúng ta sẽ tìm hiểu về các vấn đề sau: • Tìm hiểu lớp Behaviour. Tương tác là khi các hình ảnh thay đổi phản ứng lại hành động cảu người dùng. Chúng ta sẽ xem xét lớp này chi tiét hơn trong các mục chủa chuwong này. Hoạt hình là những thay đổi của hình ảnh mà không cần sự tương tác trực tiếp của con người. cả tương tác và hoạt hình đều sử dụng lớp Behaviour. http://tailieuhay. Trong Java3D. Tuy nhiên điều thú vị cảu Java3D còn nằm ở vịec lập trình tương tác và hoạt hình. lớp cơ sở cho việc thực hiện tương tác và xây dựng hoạt hình Xây dựng một lớp Behaviour Phối hợp các đối tượng Behaviour vào trong thế giới ảo để thực hiện tưong tác • • • Sử dụng lớp tiện ích xử lý bàn phím • Sử dụng lớp tiến ích xử lý chuột • Sử lớp lớp tiệc ích picking Trong các chương trước chúng ta đa xem xét việc lập trình Java3D mọt cách hoàn toàn tĩnh.com 396 .

Tác nhân TransformGroup Người dùng Sự chạm va Đối quan tượng thay Tương tác Geometry SceneGraph Vie w dụng Di chuyển tượng Thể hiện hiện 397 Ứng dụng cụ Ứng thể trực Đối đổi trực cụ thể tượng Đối quan xuất http://tailieuhay. Đối tượng Behaviour trong một đồ thị khung cảnh có nhiệm vụ thây đổi đồ thị khung cảnh. liên kết với phần mã của người phát triển cung cấp nhằm làm thay đổi hình ảnh. và những thay đổi nằm trên dòng đầu.1. âm thanh trong không gian ảo. sắp lại lại các đối tượng … 4. cung cấp các kỹ thuật để thay đổi đồ thị khung cảnh. liệt kê nhưng tác nhân từ cột bên trái xuống phỉa dưới. Chúng ta chỉ liệt ke những khả năng đơn giản cảu Behaviour chứ không liệt kê đầy đủ tất cả các khả năng có thể của Behaviour.com . sự va chạm giữa các đối tượng… Những tác động này có thẻ thêm vào các đối tượng trong đồ thị khung cảnh hay loại bỏ cá đối tượng trong đồ thị khung cảnh. di chuyển chuột.Lập trình đồ họa trên Java 2D và 3D 4. hay phản ứng lại các kích thích.1 Hành vi: Cơ sở của tương tác và hoạt hình Cả tưong tác và hạot hình đều sử dụng đối tượng Behaviour. chúng ta gọi là ứng dụng cụ thể. Lớp Behaviour và các lớp dẫn xuất. Một kích thích.1 Ứng dụng của hành vi Trong bảng dưới đây chúng ta sẽ liệt kê những khả năng có thể của lớp Behaviour. Một vài sự kết hợp giữ các tác nhân và các thay đổi chỉ có ý nghĩa trong những trường hợp đặc biệ. thay đổi thuộc tính của đối tượng. hay tác động có thể là việc ấn một phím. Lớp Behaviour là một lớp cơ sở trừu tượng.

Picking được thực thi sử dụng các hành vi nhưng không được liệ kê ở trên. Hành vi định hướnggọi là billboard behavior. Nhưng sự vật ngoài tự nhiên. Lấy ví dụ biểu diễn một cái cây. cành . Kỹ thuật này http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D hướng hay vị trí thay đổi bề trong các va những noài trong chạm thay đổi trong va chạm Thời gian Khung nhìn Hoạt hình Bảng Hoạt hình Hoạt hình Hoạt các va chạm Tần các chi Ứng tiết (LOD) cụ thể hình dụng Ứng dụng cụ thể Bảmg trên chúng ta chỉ liệt kê những truờn hợp đơn giản những khả năng của lớp Behaviour. nếu khung nhìn là rất xa không đủ khả năng nhìn một cách rõ ràng và nổi bật cành cây.Một phương pháp khác được sử dụng là sử dụng kết cấu đa giác thay cho các đối tượng hình học. như một cái cây. trong đó chỉ có bè mặt cảu kết cấu đa diện được nhìn thấy.com 398 . Hướng tiếp cận billboard thực sự hiệu quả khi đối tượng được biểu diễn bởi texture có khoảng cách xa vì vậy các phần độc lập khác của đối tượng trực quan được biểu diễn bởi texture sẽ khó khăn. Kỹ thuật trên (texture polygon) thương được gọi là billboard approach. khi đó sẽ là rất vô lý và phí phạm khi tốn bộ nhớ và công việc xử lý để biể diên tưng chiếc lá. Điều này là hợp lý và đúng đắn khi một hành vi được sử dụng tự động định hướng textured polygon trực giao với khung nhìn. bao gồm một số lượng rất lơn các đối tượng hình học được thể hiện một cách chính xác như la.

lớp Behaviour được sủ dụng nhiều trong các ứng dụng Java3D theo nhiều cách khác nhau. Khi khung nhìn (viewer) càng gần các chi tiết được thể hiẹn càng rõ và khi khung nhìn ở xa. Trong mục này chúng ta sẽ tìm hiểu lớp Behaviour. chỉ rõ sự chuyên môn hoá của Behaviour trong Java3D API và các gói tiện ích. 4. các đối tượng trực quan được biểu diễn bởi rất nhiều đối tượng trực quan khác nhỏ hơn.com 399 . đưa ra cách thức để tạo ra một lớp Behaviour Behaviour.Lập trình đồ họa trên Java 2D và 3D được khuyến khích sử dụng trong các ứng dụng yêu cầu thể hiện các đối tượng trực quan ở khoảng cách xa.1. Cả billboard và LOD đều tương ứng với các lớp dẫn xuất từ lớp Behaviour 4. Hành vi LOD (level of detail) c ó nh ững ứng dụng liên quan. Với LOD. các đối tượng trực quan được biểu diễn ít chi tiết hơn. Behaviour LOD tự động chuyển đổi các chế độ trình diễn dựa vào khoảng cách giữa đối tượng với viewer.Việc tìm hiểu hoạt đọng và lập trình với lớp Behaviour là điều rất quan trọng.2 Tổng quan lớp Behaviour Trong bảng 4-1. của riêng mình và một ví sử dụng lớp http://tailieuhay. Trong phần này chúng ta sẽ lân lượt xem xét từng lớp trong bảng 4-1. chi tiết hơn.2 Cơ bản về hành vi Như đã đề cập trong các phần trước.

http://tailieuhay. để nó có khả năng tạo ra những hành vi thay đổi.com 400 . Trong hàm tạo. Ngoài ra một lớp Behaviour tự xây dựng cũng có ít nhất một àhm tạo và có các phương thức khác của riêng nó. Các Behaviour thông qua các đối tượng đồ hoạ.1 Viết một lớp Behaviour Trong phần này chúng ta sẽ tìm hiểu cách viết một lớp Behaviour. quá trình tham chiếu phải được thực hiện tại thời điểm đồ thị khung cảnh được tạo ra.2.Lập trình đồ họa trên Java 2D và 3D Sơ đồ các lớp con của lớp Behaviour 4. Nếu không. tỏng một phương thức khác cảu lớp Behaviour tự xây dựng phải chứa những thông tin này. có thể thiết lập tham chiếu đến đối tượng trong sự thay đổi.Mechanics của Behaviours Một lớp Behaviour thực thi quá trình khởi tạo và phương thức processStimulus của lớp cơ sở trừu tượng Behaviour. Đối tượng Behaviour cần một tham chiếu đến đối tượng có sự thay đổi. sẽ hành động trong một đồ thị khung cảnh nhằm tác động đến hành vi.

Phương thức processStimulus được gọi khi các trigger được kích hoạt. giải mã điều kiện xảy ra hành động của trigger.chỉ định các tiêu chuẩn kích hoạt ban đầu (trigger) Viết đè hàm public void processStimulus(). Viết hàm tạo. thiết lập lại các trigger. Phương thức processStimulus phản xạ lại các tác nhân.Lập trình đồ họa trên Java 2D và 3D Quá trình khởi tạo được gọi đến khi đồ thị khung cảnh chứa lớp Behaviour được tạo ra. Chúng ta xem xét ví dụ dưới đây. những Behaviour phức tạp đòi hỏi phải lập trình xử lý nhiều bước hơn. trong những điều kiện thích hợp. reset lại trigger nếu cần thiết. Các bước trên là các thức chúng ta tạo ra các lớp Behaviour đơn gaỉn. chứa tham chiếu đến đối tượng trong sự thay đổi Viết đè hàm khởi tạo public void initialization(). Phương thức khởi tạo có trách nhiêm cài đặt những trigger ban đầu để bắt các sự kiện của Behaviour và cái đặt những điều kiện ban đầu cho các dữ liệu tĩnh của đối tượng Behaviour. Phương thức processStimulus có trach nhiệm bắt và xử lý các sự kiện xảy ra. thường là sự thay đổi của các đối tượng. hay là sự kết hợp của các WakeupCondition . được thực hiện theo các bước đã nêu ở trên Ví dụ xây dựng lớp Behaviour : SimpleBehaviour http://tailieuhay. nó bao gồm cả việc giải mã các sự kiện. Các triggger thực chất là các đối tượng WakeupCondition (các điệu kiến thức dậy). Tiếp theo chúng ta xem xét các bước để viết một lớp Behaviour cho riêng mình. Nhiều sự kiện có thể có thể được mã hoá trong một đối tượng WakeupCondition (nhiều loại kích hoạt của bàn phím có thể được mã hoá trong WakeupOnAWTEvent).com 401 .

chúng ta chỉ cần lập trình theo các buwóc đã nêu ở trên. Phương thức initialization thiết lập cá thông số trigger ban đầu theo sự kiện WakeOnAWTEvent sự kiện. Như đã đề cập ở phần trên. và thiết lập góc nghiêng bằng 0. Behaviour có thể thay đổi các trigger của mình thạm chí trong suốt thời gian hoạt đọng cảu Behaviour để thay đổi các hành vi. trigger luôn luôn được thiết lập lại dưới tác động của phím bấm. Để tạo ra lớp Behaviour này. Khi đó việc quay đối tượng TransformGroup không còn là vấn đề khó khăn nữa.com 402 . từ đó ta có thể điều chỉnh sự thay đổi cảu đối tượng TransformGroup một cách thích hợp.util. làm quay một số thứ dưới sự điều khiển banừg bàn phím. chịu sự thay đổi) và một biến góc nghiêng. Trong phần 4. Để xây dựng một lớp Behaviour như vậy. goc nghiêng sẽ thay đổi và góc nghiêng của TransformGroup được thiết lập bằng với giá trị mới của góc nghiêng này.event dùng để xử lý tương tác với bàn phím. Hàm tạo sẽ chứa tham chiếu đến đối tượng TransformGroup của sự thay đổi.Lập trình đồ họa trên Java 2D và 3D Trong ví dụ dưới đây chúng ta xây dựng một lớp Behaviour thực hiện một hành vi đơn giản. Phương thức processStimulus thuwòng xuyên tăng biến góc nghiêng lên. tác nhân của một Behaviour được coi như một đối tượng WakeupCondition . Trong ví dụ dưới đây gói java. Phương thức processStimulus sẽ giải mã phím bấm đẻ có thể xác định được phím hay tổ hợp phím nào được ấn. Công việc cuối cùng của phương thức processStimulus là thiết lập lại các trigger. Gói java. Dưới sự kích hoạt của bàn phím. chúng ta cần một tham chiếu đến một TransformGroup (đối tượng chứa.enumeration WakeuponCondition cần thiết để giải mã đối tượng http://tailieuhay.3 chngs ta sẽ xem xét lớp WakeupCondition .awt. Trong ví dụ này.

rotated cube. } // called by Java 3D when appropriate Transform3D rotation = new stimulus occurs http://tailieuhay. } // initialize the Behavior // set initial wakeup condition // called when behavior becomes live public void initialize() { // set initial wakeup condition this. // create SimpleBehavior .targetTG = targetTG.KEY_PRESSED)). public class SimpleBehaviorApp extends Applet { public class SimpleBehavior extends Behavior { private TransformGroup targetTG. private Transform3D().0. private double angle = 0.Lập trình đồ họa trên Java 2D và 3D // SimpleBehaviorApp renders a single.com 403 .wakeupOn(new WakeupOnAWTEvent(KeyEvent.set TG object of change SimpleBehavior(TransformGroup targetTG) { this.

Một điểm để phát triển nâng cấp là khắc phục hiẹn tượng tràn của góc nghiêng.1. các hàm này phải trả về để cho phép việc tô trát được tiếp tục. Những sai lầm trong việc viết một lớp Behaviour • • void processStimulus(Enumeration Quên việc thiết lập và reset lại Behaviour trigger Không trả về từ phương thức của lớp Behaviour Một điều hiển nhiên là nếu không thiết lạp trigger thì hành vi sẽ không thể thực hiện được.wakeupOn(new WakeupOnAWTEvent(KeyEvent. góc quay và đối tượng TransformGroup cần được cập nhật một cách định kỳ.KEY_PRESSED)).setTransform(rotation). targetTG. } } }// end of class SimpleBehavior Lớp SimpleBehaviourApp chỉ thực hiẹn những chức năng chính cần thiết của một Behaviour đơn giản.Lập trình đồ họa trên Java 2D và 3D public criteria) { // do what is necessary in response to stimulus angle += 0. rotation. Ngoài ra trigger cũng càn phải được reset trước khi hành động tiếp theo lặp lại.com 404 . this. khi hành vi quay tròn được gọi. Khi cả hai phương thức initilization và processStimulus được gọi bởi hệ thống Java3D. http://tailieuhay. ví dụ ta có thể xet góc quay của trục quay có thể được thay đổi bởi các phương thức của lớp. Chungs ta có thể phát triển thêm các chức năng phong phú hơn.rotY(angle). Lấy ví dụ.

Bước dầu tiên để thêm vào hành vi bao gồm việc chắc chắn đồ thị khung cảnh có sự dự trũ cho hành vi. tham chiếu dến đối tượng cần chuyển động.Đọc và ghi các khả năng cho đối tượng đích http://tailieuhay.Chuẩn bị đồ thị khung cảnh 2.Bhv ch ỉ tr ở n ên active khi khung lịch của nó giao với sự hoạt động của ViewPlatform.Trong thực tế một đối tượng Behaviour không phải là một phần của đồ thị khung cảnh và sẽ trở thành “rác” và được dọn dẹp bởi garbage collection. Java3D sử dụng khung lịch để thực hiện execution culling. Chỉ có những Behaviour đã active mới có kảh năng nhạn được các tác nhân kích thích. Ví dụ.Người lập trình cần quản lý sự chọn lọc trong suốt quá trình chọn lựa lịch của các Behaviour.Lập trình đồ họa trên Java 2D và 3D 4. một thể hiện của lớp Behaviour phải được thêm vào đồ thị khung cảnh.com 405 . các tác nhân có thể bị một số Behaviour bỏ qua.2. thay đổi 3.Them Behaviour vào đồ thị khung cảnh. trong đồ thị khung cảnh phải có chứa đối tượng TransformGroup được chuẩn bị để quay. để sử dụng được lớp SimpleBehaviourApp trong phần trên . Thiết lập sự hỗ trợ cảu một Behaviour.Xác định một khung lịch (SchedulingBoundingLeaf) 4. trong khi đó đồ thị khung cảnh đòi hỏi một Behaviour là ứng dụng và Behaviour phụ thuộc. Bước cuối cùng để thêm vào một Behaviour là cung cấp một khung lịch cho Behaviour. Trong trường hợp đó. Rất nhiều Behaviour chỉ cần một đối tượng TransformGroup.2 Sử dụng một lớp Behaviour Trong phần này chúng ta sẽ tìm hiểu việc thêm vào hành vi cảu đối tượng trong chương trình. Để nâng cấp làm việc hiệu quả hơn. Các bước sử dụng một Behaviour 1.

addChild(myRotationBehavior).compile().com 406 . myRotationBehavior. SimpleBehavior myRotationBehavior = new SimpleBehavior(objRotate).4)). return objRoot.ALLOW_TRAN SFORM_WRITE).setSchedulingBounds(new BoundingSphere()).addChild(objRotate). } http://tailieuhay. objRoot. // Let Java 3D perform optimizations on this scene graph. objRotate = new objRotate. objRoot. TransformGroup TransformGroup().setCapability(TransformGroup.Lập trình đồ họa trên Java 2D và 3D Ví dụ dưới đây mô tả các bước sử dụng một Behaviour như đã trình bày ở trên public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().addChild(new ColorCube(0. objRotate. objRoot.

ta có thẻ quay bất kỳ đối tượng nào là con của đối tượng TransformGroup. hai bước thuwòng gây nhàm lẫn sai sót: • Không chỉ định khung lịch • Không thêm đối tượng Behaviour vào trong đồ thị khung cảnh Một điều chú ý là chúng ta nên chú ý hạn chế việc tạo lịch cho mỗi đối tượng Behaviour càng ít càng tốt để đảm bảo cho hiệu năng của toàn hệ thống. Đặt đối tượng Behaviour vào đồ thị khung cảnh Behaviour có thể được thêm vào bất cứ đau trong đồ thị khung cảnh.com 407 . Ví dụ trên chỉ có ý dịnh là điểm khởi đầu cho quá tnhf làm việc vói Behaviour. nhưng lớp Behaviour không chỉ giưoi hạn như vậy . Trong đồ thị khung cảnh tạo bởi SimpleBehaviourApp.Lập trình đồ họa trên Java 2D và 3D Hình trên mô tả mối quan hệ giữa đối tượng Behaviour và đối tượng chịu sự thay đổi. Ví dụ của chúng ta nhằm thực hiện quay một ColorCube. đối tượng TransformGroup. Tiêu chí lựa chọn vị trí thêm đối tượng Behaviour vào đồ thị khung cảnh phụ thuộc vào các yếu tố: hiệu quả của vịec đặt lịch. bảo trì code. http://tailieuhay. Những sai lầm trong việc sử dụng đối tượng Behaviour Trong ba bước sử dụng lớp Behaviour . đối tượng SimpleBehaviour và đối tượng ColorCube khong nằm trong cùng một hệ tọa độ địa phương. chứ không có ý định thực hiện những khả năng có thể của Behaviour.

người dùng có thể có khả năng tiếp tục biên dịch đối tượng đó. Khi đối tượng bound nằm trong đồ thị khung cảnh cùng với đối tượng Behaviour. Như vậy khi đó đối tượng chúng ta muốn tương tác có thể vẫn anừm trng view nhưng không active. nều đối tượng TransformGroup được dùng để biêc dịch đối tượng ColorCube.Lập trình đồ họa trên Java 2D và 3D Đối tượng TransformGroup chí có tác dụng quay đối tượng ColorCube vì vậy khung lịch của di myRotationBehaviour luôn đính kèm đối tượng ColorCube cho phép việc tương tác với đối tượng ColorCube khi nó visible. Miễn là sự kích hoạt quả view vẫn giao với kung lịch của đối tượng Behaviour. Chúng ta có thể tương tác với đối tượng trực quan không nằm trong view. lúc đó đối tượng Behaviour vẫn còn active. Điều này có thẻ thực hiện được trọn vẹn theo hình dưới đây.com 408 .Vấn đề là nếu như lúc đo view thay đổi và không còn giao với khung kế hoạch của của đối tượng Behaviour . Một là chúng ta thay đổi đồ thị khung cảnh để vẫn giữ được khung lịch của đối tượng Behaviour với đối tượng trực quan. Có hai giải pháp cho vấn đề này. Chúng ta sẽ xem xét lớp BoundingLeaf này trong phần 3. Phương pháp thứ hai là sử dụng đối tượng BoundingLeaf cho khung lịch.7 http://tailieuhay. khi dó đối tượng ColorCube có thể bị dịch chuyển ra ngoài của khung nhìn. Dù sao. khi đó đối tượng Behaviour là không active.

‘Memory burn’ là thuật ngữ dùng để chỉ việc tạo ra những đối tượng không cần thiết tỏng Java. 4. lớp Behaviour càn được thừa kế trước khi khởi tạo một đối tượng Behaviour. Việc sử dụng bộ nhớ quá mức . chúng ta sẽ sử dụng lại đối tượng cũ. Trong phần này chúng ta xem xét kảh năng để thiết lập các điều kiện trigger nhằm kích hoạc các Behaviour trong mỗi khung của quá trình tô trát. Là một lớp cơ sở trừu tượng. http://tailieuhay.2. Nếu như không có tác nhân gì kích hoạt Behaviour.Lập trình đồ họa trên Java 2D và 3D Những chú ý khi xây dựng lớp Behaviour Điều cần chú ý khi viết một Behaviour là hiệu năng của hệ thống. sẽ là không cần thiết nếu chúng ta gọi đến phương thức processStimulus. phương thức processStimulus sử dụng toán tử new trong qu á tr ình g ọi wakeupOn. Ví dụ như đoạn mã tỏng 4-1.3 Các hàm API trong lớp Behaviour Trong phần này chúng ta sẽ tìm hiểu chi tiết về các hàm API của lớp Behaviour. Các phương thức của lớp Behaviour thuwòng gây ra vấn đề ‘memmory burn’. thay bằng việc khởi tạo một đối tượng mới. đối tượng này trở thành ‘rác’ mỗi lần Behaviour được kích hoạt. Một điều cần chú ý khi viết mọt Behaviour là: memory burnvà những trigger điều kiện không cần thiết. i ều n ày khi ến cho m ột đối tượng mới được tạo ra mỗi khi phương thức này được gọi. Ví dụ trong đoạn code 4-3.com 409 . Một Behaviour không tốt sẽ làm giảm hiẹu năng của quá trình tô trát.chức năng.sẽ ảnh huwòng đến quá trình garbage collection và quá trình ô trát sẽ bị dưng lại. Tuy nhiên việc xác định và tránh xảy ra ‘memmory burn’ thường khá dễ dàng.

Các phương thức processStimulus và initialization cung cấp một gao diện để chúng Java3D có thể hợp tác các Behaviours trong không gian ảo. Lớp WakeupCondition và các lớp liên quan sẽ được trình bày trong phần 4. Phương thức postId cho phép một Behaviour có thể giao tiếp với các phương thức khác. http://tailieuhay.Tham số đầu vào của phương thức này là đối tượng WakeupCondition .com 410 . Đối tượng Behaviour có thể sử dụng phương thức postId để tạo ra sự cộng tác với điều kiện WakeupOnBehaviorPost thích hợp. thể hiện của một lớp thừa kế lớp Behaviour là con của một nhóm trong đồ thị khung cảnh.Lập trình đồ họa trên Java 2D và 3D Trong gói tiện ích của Java3D có sằn rất nhiều các lớp Behaviour. Các phương thức khác của lớp Behaviour đọc trình bày trong bảng dưới đây. Chúng ta xem xem xét lớp akeupOnBehaviorPost chi tiết hơn trong mục 4-16. Mộ trong những điều kiện wakeup là WakeupOnBehaviorPost. Phương thức wakeOn được dùng trong hai phương thức initialization và processStimulus để thiết lập trigger cho Behaviour. Đó là các lớp con của Leaf.3.

chúng ta có thẻ có nhiều view. Phương thức getView rất hiệu quả với Behaviour dựa trên thông tin của mỗi View (BillBoard. một Behaviour có thể được active bởi nhiều view.Lập trình đồ họa trên Java 2D và 3D Phương thức setEnable chung cấp một cách thức để vô hiệu hoá một Behaviour thậm chí ngay cả khi bounds làm cho nó active. Chúng ta không có phương thức setView. void initialize() Initialize this behavior. View getView() Returns the primary view associated with this behavior. Đối tượng View chính được định nghĩa là đối tượng View đầu tiên đọc gắn kèm với ViewPlatform.. Các hàm API của ViewPlatform Các Behaviour chỉ active (có khả năng kích hoạt được) chỉ khi khung lịch của nó giao với quá trình hoạt động của ViewPlatform .com 411 . Vì vậy một hành vi Billboard pahỉ hướng tới view chính. LOD.) và đối với những Behaviour nói chung chung. Phương thức này trả về tham chiếu tới đối tượng View chính hiện đang được kết hợp với Behaviour đó. void postId(int postId) Post the specified Id. Behavior Method Summary Behavior is an abstract class that contains the framework for all behavioral components in Java 3D. void processStimulus(java. trong trường hợp có nhiều view trong cùng một đồ thị khung cảnh. nếu chúng ta có nhiều View active.Enumeration criteria) http://tailieuhay.Tỏng một không gian ảo.util. Giá trị mặc định là true (đối tượng Behaviour được enable) Một đối tượng Behaviour chỉ active khi khung đặt lịch của nó giao với quá tình họat động của view.

là cơ sở của tất cả các lớp wakeup trong Java3D. các lớp còn lại kết hợp nhiềU điều kiện wakeup trong một điều kiện wakeup duy nhất. Lớp cơ sở trừu tượng.com 412 . Default activation radius = 62. void setActivationRadius(float activationRadius) Set the ViewPlatform's activation radius which defines an activation volume around the view platform. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D Process a stimulus meant for this behavior. float getActivationRadius() Get the ViewPlatform's activation radius. void setEnable(boolean state) Enables or disables this Behavior. void setSchedulingBounds(Bounds region) Set the Behavior's scheduling region to the specified bounds. void setSchedulingBoundingLeaf(BoundingLeaf region) Set the Behavior's scheduling region to the specified bounding leaf. void wakeupOn(WakeupCondition criteria) ViewPlatform Method Summary (partial list) These methods of the ViewPlatform class get and set the activation volume (sphere) radius. 4. tác nhân kích hoạt. một trong số dó là lớp cơ sở trừu tượng WakeupCriterion. Có 5 lớp thừa kế lớp WakeupCondition .3 Điều kiện kích hoạt: Cách kích hoạt các hành vi Những active Behaviour được kích hoạt bởi sự kiện của một hay nhiều tác nhân kích hoạt. Tác nhân wakeup cho một Behaviour được xác định sử dụng lớp con của lớp WakeupCondition .

com 413 .3. Phương thức còn lại.Phương thức đầu tiên.1 Điều kiện kích hoạt Lớp WakeupCondition cung cấp hai phương thức.Lập trình đồ họa trên Java 2D và 3D Một điều kiện wakeup của một đối tượng Behaviour được xác định như là sự kết hợp của các điều khiện khác sử dụng lớp kết hợp wakeup thích hợp. It provides the following two methods. Phần tiếp theo chúng ta mô tả lớp WakeupCondition và các lớp con của nó. allElements. Enumeration allElements() http://tailieuhay. triggeredElements. 4. trả về danh sách liệt kê các tác nhân wakeup của đối tượng WakeupCondition . li ệt k ê nh ững t ác nh ân wakeup có thể kích hoạt Behaviour. Phương thức này có thể rất hữu hiệu trong phương thức processStimulus. WakeupCondition Method Summary The WakeupCondition abstract class is the base for all wakeup classes.

http://tailieuhay. WakeupCriterion Method Summary boolean hasTriggered() Returns true if this criterion triggered the wakeup.3.3 Quy định lớp WakeupCriterion Trong bảng 4-2 đưa ra quy định 14 lớp WakeupCriterion.2 WakeupCriterion WakeupCriterion là phương thức trừu tượng cho phép 14 quy định lớp tác nhân wakeup. Chúng ta không cần thiết phải sử dụng phương thức này. vì phương thức triggeredElements của lớp WakeupCondition thực hiện điều này hộ chúng ta. Những lớp này được sự dụng để xác định những điều kiện wakup cho đối tượng Behaviour. CÓ những lớp chỉ gồm những hàm API đơn giản. 4. Chúng ta sẽ xem xét chi tiết các lớp này trong ngay sau đây.com 414 .3. Enumeration triggeredElements() Returns an enumeration of all triggered WakeupCriterion objects in this Condition. lớp WakeupOnActivation chỉ có một hàm tạo duy nhất. Tham số khung lịch của các điều kiện wakeup được chỉ định trong đối tượng Behaviour tương ứng. 4. WakeupCondition chỉ cung cấp một phương thức duy nhất: hasTriggered. Thể hiện của những lớp này được sử dụng một cách độc lập hay trong việc sử dụng kết hợp các điều kiện wakeup trong các lớp đã nói trong mục trước.Lập trình đồ họa trên Java 2D và 3D Returns an enumeration of all WakeupCriterion objects in this Condition.

WakeupCondition sẽ không kích hoạt thêm một nào nữa. ĐIều tương tự cũng đúng với một dãy các frame sau đó cho đến khi Java3D nhận biết được sự thay đổi quá trình giao nhau. Ta có những lớp WakeupCriterion theo từn cặp (Entry/Exit hay Activation/ Deactivation). WakeupOnActivation Constructor Summary extends: WakeupCriterion Class specifying a wakeup on first detection of a ViewPlatform's activation volume intersection with this object's scheduling region.Lập trình đồ họa trên Java 2D và 3D Những chú ý xung quanh WakeupCriterion Một số lớp WakeupCriterion được kích hoạt ngay trong “first detection” của một sự kiện. WakeupOnActivation Nếu khung lịch giao với quá trình active của ViewPlatform trong một thời gian đủ ngắn thì rất có thể là nó không được nhận ra. trong những trường hợp như vậy.com 415 . thì WakeupCondition mới có thể kích hoạt lần tiếp theo. WakeupOnAWTEvent http://tailieuhay. WakeupOnActivation is paired with WakeupOnDeactivation which appears on page 4-21. Những nhân tố này chỉ kích hoạt một cách xen kẽ giữa tunừg cặp Entry hoặc Activation. Behaviour sẽ không trở nên active. Khi đó cả Acivation và Deactivation đều khong được kích hoạt. Đều này có nghĩa là tác nhân sẽ chỉ một lần kích hoạt bởi sự kiện. Ví dụ đối tượng WakeupOnActivation sẽ kích hoạt sự giao nhau giữa quá trình vận động của ViewPlatform và vùng kung lịch của đối tượng Behaviour. WakeupOnActivation() Constructs a new WakeupOnActivation criterion. Khi sự giao nhau này vần còn.

Ví dụ WakeupOnAWTEvent có 2 hàm tạo và một phương thức. or one of many other event values.MOUSE_RELEASED. KeyEvent.MOUSE_PRESSED. Phương thức còn lại trả về mảng các sự kiện AWT liên tục nhau được kích hoạt bởi trigger/ WakeupOnAWTEvent Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một Behaviour được kích hoạt bởi một sự kiên AWT WakeupOnAWTEvent(int AWTId) Khởi tạo một đối tượng WakeupOnAWTEvent mới. hoặc các giá trị khác. MouseEvent. MouseEvent. Hàm tạo cho phép xác định các sự kiện AWT nhất định bằng cách sử dụng các hằn của lớp AWT. MOUSE_EVENT_MASK. KeyEvent.com 416 . WakeupOnAWTEvent Method Summary AWTEvent[] getAWTEvent() http://tailieuhay.MOUSE_CLICKED.KEY_PRESSED.và AWT EVENT_MASK với các giá trị: : KEY_EVENT_MASK. MouseEvent. WakeupOnAWTEvent(long eventMask) Khởi tạo một đối tượng WakeupOnAWTEvent sử dụng ORed EVENT_MASK.KEY_TYPED.MOUSE_DRAGGED. MouseEvent.Lập trình đồ họa trên Java 2D và 3D Nhiều lớp WakeupCriterion thực hiện kích hoạt trong những hàm tạo và các phương thức một cách phụ thuộc. MOUSE_MOTION_EVENT_MASK.MOUSE_MOVED. MouseEvent. trong đó AWTId là một trong các hằng số KeyEvent.KEY_RELEASED.

phương thức để xác định rõ các triggering post caàn thiết cho sự kiện trigger. kết hợp Behaviour với post ID. Với cách thức như vậy ngay cả những Behaviour phức tạp chúng ta có thể xây dựng một cách tương tự như vây. và một Behaviour khác đóng cửa.Lập trình đồ họa trên Java 2D và 3D Trả vể một mảng các sự kiên AWT liên tiếp. Các Behaviour khác có thể xác định được điều kiện kích hoạt của nó. sử dụng ID của một Behaviour xác định.com 417 . http://tailieuhay. int postId) Khởi tạo một đối tượng WakeupOnBehaviorPost Do WakeupCondition có thể chứa nhiều đối tượng WakeupCriterion. bao gồm nhiều hơn 1 WakeupOnBehaviorPost. WakeupOnBehaviorPost Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một Behaviour được kích hoạt khi một đối tượng Behaviour khác đưa ra một sự kiện WakeupOnBehaviorPost(Behavior behavior. những sự kiện kích hoạt lớp WakeupOnAWTEvent . WakeupOnBehaviorPost Lớp WakeupOnBehaviorPost cùng với phương thức the postID của lớp Behavior cung cấp một kỹ thuật qua đó một hành vi có thể được thực hiện. Điều này cho phép chúng ta có thể tạo ra một Behaviour mở cửa ra vào.Một đối tượng Behavior có thể post đưa ra một giá tri ID (kiểu số nguyên).

hoàn toàn giốnh hệt OpenBehaviour. Ví dụ mở và đóng cửa ra vào. và đaọn code tạo ra hai đối tượng Behaviour. điều kiện tráo đổi trong phương thức initialization (và Behaviour ngược lại được thực hiện) public class OpenBehavior extends Behavior { private TransformGroup targetTG. Đối tượng thứ hai là thể hiện của CloseBehaviour.com 418 WakeupCriterion WakeupCriterion . int getTriggeringPostId() Trả về thông tin postId kích hoạt Behaviour Đoạn code dưới đây của một chuwong trình đơn giản sử dụng Behaviour posting để hợp tác các Behaviour. private pairPostCondition. Trong lớp CloseBehaviour. private AWTEventCondition.Lập trình đồ họa trên Java 2D và 3D WakeupOnBehaviorPost Method Summary Behavior getBehavior() Trả về Behaviour xác định được thiết lập trong hàm tạo của đối tượng int getPostId() Nhận postId xác định của WakeupCriterion Behavior getTriggeringBehavior() Trả về behavior được kích hoạt bằng tác nhân. Ứng dụng bao gồm một lớp: OpenBehaviour. private WakeupCriterion wakeupNextFrame. http://tailieuhay.

setBehaviorObjectPartner(Behavior behaviorObject) http://tailieuhay. Transform3D t3D = new private Matrix3d rotMat = new Matrix3d().Lập trình đồ họa trên Java 2D và 3D private Transform3D().0.wakeupOn(AWTEventCondition).com 419 .KEY_PRESSED). } public { pairPostCondition } public void initialize() { this. void = = new new WakeupOnAWTEvent(KeyEvent. OpenBehavior(TransformGroup targetTG) { this. } = new WakeupOnBehaviorPost(behaviorObject. doorAngle = 0. AWTEventCondition wakeupNextFrame WakeupOnElapsedFrames(0). private double doorAngle.targetTG = targetTG. 1).

0f.6. = set y-axis rotation to get rotation and scale to void processStimulus(Enumeration http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D public criteria) { if (criteria.equals(pairPostCondition) ) { System. doorAngle = 0.out.m22 = rotMat.cos(doorAngle).wakeupOn(AWTEventCondition). // portion of transform targetTG.nextElement().6) doorAngle = 1. in either case: open if (doorAngle < 1.com 420 .getRotationScale(rotMat).println("ready open door").6) { doorAngle += 0. } else { // could be KeyPress or nextFrame. x and z scale) rotMat.getTransform(t3D).1. rotMat.m00 Math.m00. this. t3D. // doorAngle // (clobber any previous yrotation. if (doorAngle > 1.

setTransform(t3D).out.setRotation(rotMat). } } } } // end of class OpenBehavior Code 4-4: Sử dụng lớp OpenBehaviour và CloseBehaviour Đối tượng của hai lớp này sẽ thay phiên nhau phản hồi với tác nhân phím bấm. postId(1). rotMat.println("door open"). t3D.m02 Math.com 421 .sin(doorAngle).wakeupOn(wakeupNextFrame). signal other behavior System.Lập trình đồ họa trên Java 2D và 3D rotMat.Đối tượng open behavior mở cửa để trả lời lại tác nhân phím bấm.wakeupOn(pairPostCondition).m02.Đối tượng open behavior sẽ trả lời lại kích hoạt phím bấm đầu tiên đồng thời nó đánh dấu cho đối tượng close Behaviour biết và thiết lập điều kiện trigger của nó để có thể đựoc đối tượng close Behaviour nhân biêt. targetTG. this. } else { // finished opening is door.m20 = -rotMat.Đối tượng close behavior thiết lập trigger của nó như là một phím bấm để trả lời lại tín hiệu từ đối tượng open Behaviour = http://tailieuhay. this.

Quá trình nhạn biết va chạm Collision detectiontrong thực tế diễn ra rất phức tạp. có thể tham kahỏ thêm trong Java3D API specification. • WakeupOnCollisionMovement. Một WakeupOnCollisionEntry sẽ đựoc kích hoạt khi một đối tượng lần đầu va chạm. Tiếp đó phím bấm tiếp theo cũng được thực hiện tương tự. Hàm tạo WakeupOnCollisionEntry Thừa kế: WakeupCriterion Lớp xác định va chạm đầu tiên của một đối tượng xác định với một đối tượng khác trong đồ thị khung cảnh. WakeupOnCollisionEntry Java3D có khả năng tự động nhận ra sự va chạm giữa các đối tượng trong không gian ảo. Một cách hợp lý. Những va chạm diễn ra trong khoảng thời gian rất ngắn cũng không được nhận biêt. Java3D cung cấp 3 lớp WakeupCondition để xử lý sự va chạm của các đối tượng: • WakeupOnCollisionEntry. CollisionEntry và CollisionExit đều không đựoc kích hoạt.com 422 .Lập trình đồ họa trên Java 2D và 3D Phím bấm tiếp theo kích hoạt đối tượng close. Sau đó WakeupOnCollisionMovement sẽ được kích hoạt trong khi hai đối tượng trong va chạm Cuối cùng một đối tượng WakeupOnCollisionExit sẽ kích hoạt khi va chạm kết thúc Java3D chỉ có thẻ quản lý được một va chạm của một đối tượng tại một thời điểm. • WakeupOnCollisionExit. WakeupOnCollisionEntry(Bounds armingBounds) http://tailieuhay.Dù sao tron tài liệu này chúng ta không đi sâu vào collision detection. Đối tượng close lúc đo sẽ thực hiện chức năng tương tự đối tượng open : gửi đến một tín hiệu và thiết lập lại điều kiện kích hoạt của chính nó. Đối tượng close đóng cửa để trả lời sự kiện bấm phím.

WakeupOnCollisionEntry(Node armingNode) Tạo một đối tượng WakeupOnCollisionEntry mới. WakeupOnCollisionEntry(Node armingNode.speedHine WakeupOnCollisionExit(SceneGraphPath armingPath) Hàm tạo với tham sốarmingPath http://tailieuhay.com 423 .Lập trình đồ họa trên Java 2D và 3D Tạo một đối tượng WakeupOnCollisionEntry mới. int speedHint) Tạo một đối tượng WakeupOnCollisionEntry mới trong đó speedHint nhận một trong các giá trị: USE_BOUNDSvà USE_GEOMETRY WakeupOnCollisionEntry(SceneGraphPath armingPath) Tạo một đối tượng WakeupOnCollisionEntry mới với giá trị speed hint là USE_BOUNDS WakeupOnCollisionEntry(SceneGraphPath armingPath. WakeupOnCollisionExit WakeupOnCollisionExit Constructor Summary Thừa kế WakeupCriterion Lớp xác định khi một đối tượng xác định kết thúc va chạm với các đối tượng khác trong đồ thị khung cảnh WakeupOnCollisionExit(Bounds armingBounds) Hàm tạo với tham số Bound WakeupOnCollisionExit(Node armingNode) Hàm tạo với tham số armingNode WakeupOnCollisionExit(Node armingNode. int speedHint) Tạo một đối tượng WakeupOnCollisionEntry mới với giá trị speed hint là USE_BOUNDS hoặc USE_GEOMETRY. int speedHint) Hàm tạo với tham số armingNode.

int speedHint) Hàm tạo WakeupOnCollisionMovement trong đó speedHint nhận giá trị: http://tailieuhay. speedHint armingPath. int WakeupOnCollisionExit Method Summary Bounds getArmingBounds() Trả về đối tượng Bound được sử dụng trong việc xác địng va chạm SceneGraphPath getArmingPath() Trả về đường dẫn dùng trong va chạm xác định Bounds getTriggeringBounds() Trả về đối tượng Bounds gây ra va chạm SceneGraphPath getTriggeringPath() Trả về đường dẫn mô tả đối tượng gây ra va chạm WakeupOnCollisionMovement WakeupOnCollisionMovement Constructor Summary Thừ kế: WakeupCriterion Lớp xác định khi đối tượng xác định di chuyển trong va chạm với một đối tượng khác trong không gian ảo WakeupOnCollisionMovement(Bounds armingBounds) Hàm tạo WakeupOnCollisionMovement WakeupOnCollisionMovement(Node armingNode) Hàm tạo WakeupOnCollisionMovement WakeupOnCollisionMovement(Node armingNode.com 424 .Lập trình đồ họa trên Java 2D và 3D WakeupOnCollisionExit(SceneGraphPath speedHint) Hàm tạo với tham số armingPath.

com 425 . Bounds getTriggeringBounds() Trả về đối tượng Bounds gây ra va chạm SceneGraphPath getTriggeringPath() Trả về đường dẫn gây ra va chạm. int WakeupOnCollisionMovement Method Summary Bounds getArmingBounds() Trả về đối tượng bounds đựợc sử dụng trong collision condition.Lập trình đồ họa trên Java 2D và 3D USE_BOUNDS hoặc USE_GEOMETRY WakeupOnCollisionMovement(SceneGraphPath armingPath) Hàm tạo WakeupOnCollisionMovement. WakeupOnCollisionMovement(SceneGraphPath speedHint) Hàm tạo WakeupOnCollisionMovement. WakeupOnDeactivation WakeupOnDeactivation Constructor Summary Thừa kế: WakeupCriterion Lớp xác định va chạm đầu tiên khi quá trình hoạt động củ ViewPlatform không còn giao với khung lịch của đối tượng WakeupOnDeactivation() Hàm tạo đối tượng WakeupOnDeactivation http://tailieuhay. trong đó speedHint nhận một trong hai giá trị: USE_BOUNDS hoặc USE_GEOMETRY armingPath. SceneGraphPath getArmingPath() Trả về đương dẫn đựoc sủ dụng trong collision condition.

2> Hàm tạo WakeupOnElapsedFrames với tham số frameCount và tham số passive passive . một Behaviour chủ động sẽ làm cho hệ thống phải chạy một cách liêc tục khi một Behaviour bị động nó cho phép các sự kiện khác gây ra frame đuợc chạy. giá trị 0 cho biết Behaviour sẽ đựoc kích hoạt ngay sau frame hiện thời.Lập trình đồ họa trên Java 2D và 3D WakeupOnElapsedFrames Đối tượng WakeupOnElapsedFrames được sử dụng để kích hoạt một đối tượng active sau một số lượng frame nhất đinh trôi qua.cờ chỉ dẫn cho biết khi nào Behaviour trở nên bị động.Số luwọng các frames mà Java 3D vẽ ra trước khi kích hoạt một đối tượng Behaviour.2> Trả về trạng thái của cờ bị động. boolean passive) <new in 1. http://tailieuhay. WakeupOnElapsedFrames Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một kích hoạt sau một ố lượng frame nhất định WakeupOnElapsedFrames(int frameCount) Hàm tạo WakeupOnElapsedFrames. giá trị n cho biết sao n frame Behaviour sẽ đuợc kích hoạt. WakeupOnElapsedFrames Method Summary int getElapsedFrameCount() Trả về số lương các frameCount boolean isPassive() <new in 1. WakeupOnElapsedFrames(int frameCount. frameCount .com 426 .

WakeupOnElapsedTime(long milliseconds) Hàm tạo đối tượng WakeupOnElapsedTime WakeupOnElapsedTime Method Summary long getElapsedFrameTime() Trả về thời gian trôi qua của WakeupCriterion WakeupOnSensorEntry Trong Java 3D. WakeupOnElapsedTime Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một wakeup sau một khoang thời gian (ms) trôi qua. WakeupOnSensorEntry Constructor Summary Thừ kế: WakeupCriterion Lớp xác định một wakeup trong giai đaọn đầu tiên nhận biết sự giao nhau giưa một sensor nào đó với một boundary xác định WakeupOnSensorEntry(Bounds region) http://tailieuhay. bất kỹ thiết bị input nào (ngoại trừ chuột và bàn phím) đều là một sensor Mỗi sensor có một hotspot được xác định trong hệ thốnh của sensor.com 427 . Sự giao nhau giữa hotspt cảu môt sensor với một region có thể được nhận biết bởi lớp WakeupOnSensorEntry và WakeupOnSensorExit.Lập trình đồ họa trên Java 2D và 3D WakeupOnElapsedTime Java 3D không thể bảo đảm thời gian chính xác của trigger cho một tiêu chuẩn WakeupOnElapsedTime.

2> Trả về đối tượng Sensor gây ra wakeup.2> Trả về đối tượng sensor gây ra wakeup.Lập trình đồ họa trên Java 2D và 3D Hàm tạo đối tượng WakeupOnEntry. WakeupOnSensorExit(Bounds region) Hàm tạo đối tượng WakeupOnExit .com 428 . WakeupOnTransformChange http://tailieuhay. Sensor getTriggeringSensor() <new in 1. WakeupOnSensorExit Method Summary Bounds getBounds() Trả về bound của đối tượng xác định. Sensor getTriggeringSensor() <new in 1. WakeupOnSensorExit WakeupOnSensorExit Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một wakeup trong giai đoạn nhận biết đầu tiên khi không còn sự giao nhau giữa một đối tượng sensor trước đó với một boundary xác định. WakeupOnSensorEntry Method Summary Bounds getBounds() Trả về bound của đối tượng xác định.

http://tailieuhay. WakeupOnViewPlatformEntry(Bounds region) Hàm tạo đối tượng WakeupOnEntry. WakeupOnTransformChange Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một wakeup khi một đối tượng transform trong một nhóm TransformGroup xác định thay đổi. WakeupOnTransformChange Method Summary TransformGroup getTransformGroup() Trả về node TransformGroup sử dụng trong WakeupCriterion WakeupOnViewPlatformEntry Quá trình nhận biết sự giao nhau của ViewPlatform với một region xác định có thể được thực hiện bởi lớp WakeupOnViewPlatfomEntry và lớp WakeupOnViewPlatformExit.com 429 .Lập trình đồ họa trên Java 2D và 3D WakeupOnTransformChange rất hiệu quả trong việc nhận biết thay đổi vị trí hay hướng của các đối tượng trực quan trong đồ thị khung cảnh. Lớp này sử dụng phương thức postId để tạo ra các Behaviour hợp tác. WakeupOnViewPlatformEntry Constructor Summary Thừa kế: WakeupCriterion Lớp xác định một wakeup trong lần đầu tiên giao nhau của ViewPlatform với một boundary xác định. Điều này đặc biệt hiệu quả khi chúng ta muốn hợp tác với một Behaviour đã được xây dựng trước đó. WakeupOnTransformChange(TransformGroup node) Hàm tạo đối tượng WakeupOnTransformChange.

4 Thành phần của WakeupCondition Nhiều đối tượng WakeupCriterion có thể được kết hợp gắn với một WakeupCondition sử dụng 4 lớp được giới thiệu trong phần sau.Lập trình đồ họa trên Java 2D và 3D WakeupOnViewPlatformEntry Method Summary Bounds getBounds() Trả về bound của đối tượng xác định WakeupOnViewPlatformExit WakeupOnViewPlatformExit Constructor Summary Thừa kế : WakeupCriterion Lớp xác định một wakeup trong lần đầu tiên khi ViewPlatform không còn giao nhau với đối tượng boundary xác định WakeupOnViewPlatformExit(Bounds region) Hàm tạo đối tượng WakeupOnExit WakeupOnViewPlatformExit Method Summary Bounds getBounds() Trả về bound của đối tượng xác định 4.3. Hai lớp đầu tiên được gắn liền vào một WakeupCondition từ một tập WakeupCriterion mọt cách vật lý.com 430 .Lớp thứ ba và lớp thư tư cho phép kết http://tailieuhay.

. WakeupAnd Constructor Summary extends: WakeupCondition Class specifying any number of wakeup criterion logically ANDed together. WakeupAnd(WakeupCriterion[] conditions) Constructs a new WakeupAnd condition. WakeupAndOfOrs(WakeupOr[] conditions) Constructs a new WakeupAndOfOrs condition. WakeupAnd(WakeupCriterion[] conditions) Constructs a new WakeupOr condition.com 431 . WakeupOr Constructor Summary extends: WakeupCondition Class specifying any number of wakeup criterion logically ORed together. WakeupAndOfOrs Constructor Summary extends: WakeupCondition Class specifying any number of WakeupOr condition logically ANDed together. WakeupOrOfAnds Constructor Summary http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D hợp các thể hiện của hai lớp đầu tiên thành một đối tượng WakeupCondition phức tạp.

4 Lớp Behaviour tiện ích xử lý bàn phím Chúng ta đã xem xét viewer với vị trí và góc không đổi. Thay đổi viewer là một khả năng quan trọng trong rất nhiều ứng dụng 3D. Nếu như transform thay đổi. Trong hình dưới đây chúng ta có thể thấy nền transform. hướng của viewer. ảnh huwỏng tới dịch chuyển hoặc định hướng lại hoặc của viewer.com 432 . http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D extends: WakeupCondition Class specifying any number of WakeupAnd condition logically ORed together. Java3D cung cấp khả năng thay đổi vị trí. 4. Từ quan điểm này chúng ta có thể thấy thiết kế cơ bản của tương tác bàn phím: ta có một đối tượng Behaviour thay đổi nền view để đáp lại tác động của phím bấm. Đây chính cách mà là lớp tiện ích Java3D làm việc. WakeupOrsOfAnds(WakeupAnd[] conditions) Constructs a new WakeupOrOfAnds condition. trong phần còn lại chúng ta xem xét việc sử dụng lớp tương tác với bàn phím.

getViewingPlatform().thiết lập transform http://tailieuhay.addChild(createLand()). BranchGroup objRoot = new BranchGroup().4. objRoot.com 433 .1 Một ví dụ đơn giản Ví dụ KeyNavigatorApp sau đây nằm trong thư mục examples/Interaction Trong chương trình này chúng ta có thể thấy được các bước thực hiện bao gồm cả việc sử dụng lớp KeyNavigatorBehavior giống như việc sử dụng các lớp Behaviour khác. Tạo ra đối tượng KeyNavigatorBehaviour group 2. 4. Đặcbiệt đaọn cod dưới đây nhận được ViewPlatformTransform từ một đối tượng SimpleUniverse TransformGroup vpt = su. 1.getViewPlatformTransform (). Cung cấp một gới hạn KeyNavigatorBehavior public createSceneGraph(SimpleUniverse su) { // Create the root of the branch graph TransformGroup vpTrans = null. Từ đó chúng ta có thể di chuyển SimpleUniverse.Lập trình đồ họa trên Java 2D và 3D Cách dịch chuyển trong SimpleUniverse Lớp SimpleUniverse và các lớp liên quan cung cấp một sự kết hợp để nhận được đối tượng ViewPlatformTransform object. // create other scene graph content BranchGroup (hoặc BoundingLeaf) cho đối tượng . Thêm đối tượng KeyNavigatorBehavior vào đồ thị khung cảnh 3.

Trong trường hợp này . objRoot. trong phương thức createSceneGraph đòi hỏi việc truy cập vào nhóm ViewPlatform transform.Quá trình thực thi này truyền đối tượng SimpleUniverse vào phương thức createSceneGraph làm cho nó trở nên active để có thể truy cập vào các nhành view khác của hoặc SimpleUniverse. keyNavBeh. keyNavBeh = new = BoundingLeaf vào nhánh view. // 3 meter elevation T3D. thêm một đối như tượng PlatformGeometry.0)). đối tượng viewer được chuyển tới vị trí 0.0f.3 meters nằm trên vị trí http://tailieuhay.setTransform(T3D). return objRoot. 0. objRoot.getViewingPlatform().Lập trình đồ họa trên Java 2D và 3D vpTrans su. // used for initial position KeyNavigatorBehavior KeyNavigatorBehavior(vpTrans).getViewPlatformTransform ().addChild(keyNavBeh).0f).com 434 . // Let Java 3D perform optimizations on this scene graph.set( 0. Dòng 13-15 khởi tạo vị trí ban đầu của viewer.compile(). } Theo công thức các bước đã trình bày ở trên.setSchedulingBounds(new BoundingSphere(new Point3d(). 0. translate.3f. // set as translation vpTrans.setTranslation(translate).1000. ViewerAvatar.

Canvas3D canvas3D = new Canvas3D(null). add("Center".2 Lớp KeyNavigatorBehaviour và KeyNavigator http://tailieuhay. // Utility class SimpleUniverse SimpleUniverse(canvas3D). canvas3D). simpleU. } // end of KeyNavigatorApp (constructor) Cách xây dựng ứng dụng chung của một Behavior Như bất kỳ đối tượng Behaviour khác. scene = simpleU = new SimpleUniverse is a Convenience 4.Lập trình đồ họa trên Java 2D và 3D ban đầu của thế giới ảo. // The following allows this to be run as an application // as well as an applet public KeyNavigatorApp() { setLayout(new BorderLayout()).com 435 . KeyNavigatorBehaviour chỉ active khi khung lịch của nó giao nhau với giai đoạn active của một ViewPlatform. Đầy chỉ là vị trí ban đầu và chúng ta có thẻ thay đổi vị trí và góc của viewer sau này.addBranchGraph(scene).4. BranchGroup createSceneGraph(simpleU).

utils.Bảng dưới đây 4-3 chỉ ra tác dụng của từng phím bấm riêng biệt.sun. Lớp KeyNavigator thực thi sự vận động nhanh chóng. KeyNavigatorBehavior Constructor Summary Gói: com.Enumeration criteria) Hàm đè phương thức processStimulus của lớp Behavior để quản lý sự kiện http://tailieuhay. Đối tượng đầu tiên là đối tượng KeyNavigatorBehavior. Lớp thứ hai không cần thiết phải trình bày trong tài liẹu này. ngoài việc nó gọi đến đối tượng KeyNavigator để thực hiện phương thức perform the processStimulus.keyboard Thừa kế : Behavior Lớp là một behavior đơn giản that gọi đến KeyNavigator để thay đổi bề ngoài view platform KeyNavigatorBehavior(TransformGroup targetTG) Hàm tạo một node key navigator behavior mới có tác dụng trên nhóm transform xác định KeyNavigatorBehavior Method Summary void initialize() Hàm đè phương thức khởi tạo của lớp Behavior để thiết lập thông số wakeupvoid processStmulus(java.behaviors. Đối tượng KeyNavigatorBehavior thực hiện hầu hết tất cả các hàm chức năng truyền thống của mọt lớp Behaviour.Lập trình đồ họa trên Java 2D và 3D Lớp tiệc ích tương tác bàn phím thực thi hai lớp.util.j3d. Trong thời gian chạy chương trình có hai đối tượng.Lớp KeyNavigator nhận sự kiện AWTEvent và chuyển các sự kiện thành từng các phím bấm riêng biệt.com 436 . đối tượng thứ hai là KeyNavigator.

Bảng 4-4 tổng hợp lại 3 Behaviour xác định của trong việc tương tác với chuột the. phóng to/nhỏ và điều khiển quay các đối tượng trực quan theo sự di chuyển của chuột.Cung cấp khả năng đọc và ghi cho đối tượng đích transform group 2.Lập trình đồ họa trên Java 2D và 3D 4.com 437 . Thiết lập đối tượng đích đến transform group 4.behaviors. Cung cấp một giứoi hạn (or BoundingLeaf) cho đối tượng MouseBehavior 5. Thêm đối tượng MouseBehavior vào đồ thị khung cảnh Figure 4-10 Recipe for Using Mouse Behavior Classes Tuy nhiên các bước trên là kô bắt buộc phải thực hiện đầy đủ. Bước 2 và bước 3 có thể cung thực hiện trong một hàm tạo.j3d. Bao gồm các lớp để chuyển dịch.5 Lớp tiện ích tương tác với chuột Gói tiện ích Behaviour (com.5.1 Sử dụng lớp MouseBehaviour Sử dụng lớp mouse Behaviour cũng tương tự như ki sử dụng ácc lứop Behaviour khác. 4. Khởi toạ một đối tượng MouseBehavior 3. Lớp cơ sở trừu tượng và giao diện được sử dụng để tạo ra các Behaviour xác định của con chuột.sun. Các bước khi sử dụng lớp mouse Behaviour 1. Trong gói còn có chứa lớp cơ sở trừu tượng MouseBehavior class và giao diện MouseCallback .mouse) chứa những lớp Behaviour tỏng đó quản lý việc tương tác với chuột.utils. ví dụ dưới đây giới http://tailieuhay.

objRoot. objRotate. Đồ thị khung cảnh chứa đối tượng ColorCube. objRoot. objRotate = new objRotate. http://tailieuhay. Người dùng có thể quay đối tượng ColorCube sử dụng chuột và cả đối tượng MouseRotate trong đồ thị khung cảnh // MouseRotateApp renders a single.addChild(new ColorCube(0.Lập trình đồ họa trên Java 2D và 3D thiệu phương thức createSceneGraph từ ví dụ MouseRotateApp. TransformGroup TransformGroup().setCapability(TransformGroup.ALLOW_TRAN SFORM_WRITE).setCapability(TransformGroup.addChild(objRotate). interactively rotatable cube. public class MouseRotateApp extends Applet { public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().com 438 .4)).ALLOW_TRAN SFORM_READ). objRotate.addChild(new Axis()).

addChild(myMouseRotate).setSchedulingBounds(new BoundingSphere()). objRoot. // Utility class SimpleUniverse is a Convenience myMouseRotate = new http://tailieuhay. } // end of CreateSceneGraph method of MouseRotateApp // Create a simple scene and attach it to the virtual universe public MouseRotateApp() { setLayout(new BorderLayout()). myMouseRotate. canvas3D).Lập trình đồ họa trên Java 2D và 3D MouseRotate MouseRotate().compile(). BranchGroup scene = createSceneGraph(). return objRoot. Canvas3D canvas3D = new Canvas3D(null).setTransformGroup(objRotate).com 439 . // Let Java 3D perform optimizations on this scene graph. objRoot. myMouseRotate. add("Center".

simpleU = new simpleU. System.getViewingPlatform().Lập trình đồ họa trên Java 2D và 3D SimpleUniverse SimpleUniverse(canvas3D).print("MouseRotateApp. \n- http://tailieuhay.").println("Hold the mouse button while moving the mouse to make the cube rotate.out . // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed.setNominalViewingTra nsform(). System.addBranchGraph(scene). simpleU.out .").com 440 .out .println("utility behavior class to provide interaction in a Java 3D scene.java a demonstration of using the MouseRotate "). } // end of MouseRotateApp (constructor) // The following allows this to be run as an application // as well as an applet public static void main(String[] args) { System.

println("http://java.").Lập trình đồ họa trên Java 2D và 3D System.println("This is a simple example progam from The Java 3D API Tutorial. System. 256). Frame frame = new MainFrame(new MouseRotateApp().com 441 .out .out.sun. } // end of main (method of MouseRotateApp) } // end of class MouseRotateApp Code Fragment 4-7 Using the MouseRotate Utility Class Chương trình cho kết qủa: http://tailieuhay. System.com/pr oducts/java-media/3D/collateral").println("The Java 3D Tutorial is available on the web at:"). 256.out .

4. Ký thuật picking được xem xét trong phần 4.Mỗi đối tượng ColorCubes gắn liền với một đối tượng MouseRotate.6 chúng sẽ sử dụng các lớp thích hợp để có thể kết hợp các mouse Behaviour với picking cho phép người dùng tương tác với từng đối tượng trực quan tại một thời điểm. cả hai đối tượng ColorCubes cùng quay. Ví dụ MouseRotate2App tạo ra một đồ thị khung cảnh với hai đối tượng ColorCube nằm gần nhau. MouseTranslate.6 • Trong phần 4.Lập trình đồ họa trên Java 2D và 3D Một cách tương tự chúng ta có thể làm việc với hai lớp mouse Behaviour còn lại. ta có hai giải pháp • Thay đổi vị trí viewer hay thay đổi khung lịch của Behaviour sao cho chỉ có một Behaviour đuwọc active Sử dụng kỹ thuật picking cách ly Behaviour. Trong thực técả ba lớp này đều có thể dùng chung trong một ứng dụng tác động cùn vào một đối tượng trực quan Chúng ta cũng chỉ cần một đối tượng TransformGroup chung có cả 3 đối tượng mouse behaviors. Lớp cơ sở trừu tượng Mouse Behavior http://tailieuhay.2 Mouse Behaviour Foundation Các phương thức mouse Behaviour xác định (MouseRotate. Nếu chúng ta không muốn cả hai đối tượng cùng quay. Trong ví dụ tiếp theo chúng ta xem xét các thức hai mouse Behaviour cùng hành động trong một thế giới ảo. Khi cả hai đối tượng mouse behavior cùng active.5. và MouseZoom) là mở rộng của lớp cơ sỏ trưừ tượng MouseBehavior và thực thi giao diện MouseCallback .com 442 . lúc đo người dùng click và di chuyển chuột.

behaviors.sun. MouseCallback Interface Một lớp thực thi giao diện này cung cấp phương thức transformChanged.event. phương thức này sẽ được gọi khi đối tượng đich transform thay đổi theo một cách thức xác định.awt.Lập trình đồ họa trên Java 2D và 3D Lớp cơ sở trừu tượng được giới thiệu sau đây khi chúng ta muốn thừa kế nó đê viết các lớp mouse Behaviour của rieng mình. MouseBehavior Method Summary Lớp cơ sở cho tất cả các thao tác chuột mouse void initialize() Khởi tạo behavior. Chúng ta cũng có thể viết đè phương thức transformChanged của một trong số các lớp kia để xác định phương thức được gọi khi đối tượng transform thay đổi Các phương thức Interface MouseBehaviorCallback Gói: com. Transform3D transform) void setTransformGroup(TransformGroup http://tailieuhay.util.mouse void transformChanged(int type.Enumeration criteria) Tất cả các thao tác chuột phải thực thi phương thức này của lớp Behaviour TransformGroup) Thiết lập TransformGroup đích cho Behaviour void wakeup() Gọi đến phương thức wakeup. void processStimulus(java.com 443 . void processMouseEvent(java.j3d.MouseEvent evt) kiểm soat các sự kiện chuột.utils. cả 3 lớp mouse Behaviour đều phải thực thi giao diện này.

Để sử dụng lớp này.TRANSLATE. Chúng ta sẽ xem chi tiết trong các ví dụ MouseRotateApp. Giá trị của type: MouseCallback. và MouseBehaviorApp. 4.behaviors.5. MouseCallback. MouseRotate(TransformGroup TransformGroup) Hàm tạo một mouse rotate behavior gắn với TransformGroup MouseRotate(int flags) Khởi tạo một mouse behavior với cờ. giái trị của cờ: MouseBehavior.j3d.ZOOM. trước hết tạo ra một transform group mà hành động quay này tác động vào.Lập trình đồ họa trên Java 2D và 3D Lớp thực thi giao diện này đựơc dăng ký với một trong số các MouseBehaviors sẽ được gọi mỗi khi Behaviour cập nhật transform.ROTATE. MouseRotate() Hàm tạo một mouse rotate behavior mặc định.mouse Thừa kế : MouseBehavior MouseRotate là một Behaviour cho phép người dùng điều khiẻn việc quay đối tượng thông qua chuột.3 Các lớp MouseBehaviour Mouse Rotate Một đồ thị khung cảnh có chưa một đối tượng MouseRotate cho phép nguời dùng quay đối tượng truqj quan.INVERT_INPUT Cho phép đảo ngược đầu vào. Hàm tạo MouseRotate Constructor Gói: com.sun.com 444 . hoặc MouseCallback. người dùng có thẻ quay bất cứ đối tượng con nào của nhóm TransformGroup. http://tailieuhay. MouseRotate2App.utils.

double yFactor) void setupCallback(MouseBehaviorCallback callback) Phương thức transformChanged trong lớp callback sẽ đựoc gọi tự động mỗi khi transform được cập nhật void transformChanged(Transform3D transform) Chúng ta có thẻ chông hàm. khi đó hàm mới sẽ được gọi mỗi khi Behaviour cập nhật transform MouseTranslate Cho phép người dùng di chuyển đối tượng trực quan trong một mặt phẳng song song với mặt phẳng xác định trong không gian ảo.mouse Thừa kế : MouseBehavior MouseTranslate là một đối tượng Behaviour cho phép người dùng điều khiển sự chuyển động theo (X/Y) của một đối tượng bằn các sự dụng chuột phải MouseTranslate() Khởi tạo một Behaviour dịch chuyển mặc định MouseTranslate(TransformGroup TransformGroup) Khởi tạo một Behaviour dịch chuyển với tham số TransformGroup http://tailieuhay.MANUAL_WAKEUP Cho phép gọi Behaviour một cách chủ động Tổng hợp phương thức MouseRotate void setFactor(double factor) void setFactor(double xFactor.Lập trình đồ họa trên Java 2D và 3D MouseBehavior. MouseTranslate Constructor Summary Gói : com.utils.sun.behaviors.j3d.com 445 . Xem ví dụ MouseBehaviorApp.

Cờ nhận một trong các giá trị: MouseBehavior.com 446 .j3d.Xem them ví dụ MouseBehaviorApp. MouseBehavior.Lập trình đồ họa trên Java 2D và 3D MouseTranslate(int flags) Khởi tạo một Behaviour dịch chuyển với tham số cờ. double yFactor) void setupCallback(MouseBehaviorCallback callback) Phương thức transformChanged trong lớp callback sẽ đựoc gọi tự động mỗi khi transform được cập nhật void transformChanged(Transform3D transform) Chúng ta có thẻ chông hàm. khi đó hàm mới sẽ được gọi mỗi khi Behaviour cập nhật transform MouseZoom Cho phép người dùng di chuyển đối tượng trực quan trong một mặt phẳng trực giao với . Hàm tạo MouseZoom Gói: com.INVERT_INPUT Cho phép đảo ngược đầu vào.utils.MANUAL_WAKEUP Cho phép gọi Behaviour một cách chủ động MouseTranslate Method Summary void setFactor(double factor) void setFactor(double xFactor. MouseZoom() Tạo ra đối tượng mouse zoom behavior mặc định. http://tailieuhay.behaviors.mouse Thừa kế : MouseBehavior MouseZoom là một đối tượng behavior cho phép người dùng thay đổi vị trí của đối tượng truqjc uan theo trục Z bằn nút giữ của chuột.sun.

INVERT_INPUTS đối tượng mouse Behaviour đảo ngược lại thứ tự của input.INVERT_INPUT Cho phép đảo ngược đầu vào.Lập trình đồ họa trên Java 2D và 3D MouseZoom(TransformGroup TransformGroup) Tạo ra đối tượng mouse zoom behavior với tham số transform group.MANUAL_WAKEUP Cho phép gọi Behaviour một cách chủ động MouseZoom Method Summary void setFactor(double factor) void setupCallback(MouseBehaviorCallback callback) void transformChanged(Transform3D transform) Chúng ta có thẻ chông hàm. khi đó hàm mới sẽ được gọi mỗi khi Behaviour cập nhật transform 4. Đoạn code trong 4-8 trình bày phương thức createSceneGraph. MouseZoom(int flags) Khởi tạo một zoom Behaviour với tham số cờ.com 447 .5. Nhờ vậy ta các lớp mouse Behaviour có thể dùng để điều khiển chuyển hướng. Cờ nhận một trong các giá trị: MouseBehavior.Khi cờ có giá trị MouseBehavior. Đối tượng SimpleUniverse là tham số truyền http://tailieuhay. MouseBehavior.4 Mouse Navigation Trong số các hàm tạo của ba lớp mouse Behaviour đều có tham số flag. Đối tượng TransformGroup đích của mỗi đối tượng the mouse behavior objects là ViewPlatform transform.Xem ví dụ MouseNavigatorApp.

objRoot. BoundingSphere mouseBounds = null.Lập trình đồ họa trên Java 2D và 3D cho phương thức createSceneGraph vì vậy đối tượng ViewPlatform có thể được truy cập. objRoot.getViewPlatformTransform( MouseRotate(MouseBehavior. mouseBounds = new BoundingSphere(new Point3d().com 448 .4)).getViewingPlatform().addChild(new ColorCube(0. public createSceneGraph(SimpleUniverse su) { BranchGroup // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().addChild(new Axis()). vpTrans ). myMouseRotate.INVERT_INPUT). http://tailieuhay. objRoot.0). myMouseRotate.setTransformGroup(vpTrans).setSchedulingBounds(mouseBo unds). MouseRotate myMouseRotate = new = su. TransformGroup vpTrans = null. 1000.addChild(myMouseRotate).

objRoot.INVERT_INPUT).Lập trình đồ họa trên Java 2D và 3D MouseTranslate myMouseTranslate = new MouseTranslate(MouseBehavior.INVERT_INPUT). myMouseZoom. } // end of CreateSceneGraph method of MouseNavigatorApp Kết quả cho ta là: http://tailieuhay.com 449 .addChild(myMouseTranslate). myMouseTranslate.compile().setTransformGroup(vpTrans). objRoot. myMouseZoom.addChild(myMouseZoom). MouseZoom myMouseZoom = new MouseZoom(MouseBehavior. return objRoot.setSchedulingBounds(mouseBoun ds). objRoot.setTransformGroup(vpTran s). // Let Java 3D perform optimizations on this scene graph.setSchedulingBounds(mous eBounds). myMouseTranslate.

Đối tượng behavior được kích hoạt bởi sự kiện click chuột và thực hiện picking. http://tailieuhay. Sự giao nhau của ray với đối tượng trong không gian ảo được tính toán .Lập trình đồ họa trên Java 2D và 3D 4. Trong ví dụ đó cả hai đối tượng đều chưa có thể quay một cách đọc lập.com 450 . người dùng di chuyển chuột vào đối tượng trực quan và click chuột. Để picking một đối tượng. dưới sự kích hoạt của sự kiện click chuột. Đối tượng trực quan giao cắt với mặt phẳng khung hình gần nhất được clựa chọn để giao cắt. Một ray là một tia đựoc chiếu từ vị trí con trỏ chuột song song với projected. Picking được thực thi bởi một Behaviour.Kỹ thuật picking cho phép chúng ta tương tác với từng đối tượng trực quan trong đồ thị khung cảnh .6 Picking Object Trong ví dụ MouseRotate2App. cả hai đối tượng ColorCube đều quay khi gặp tác động của guời dùng.

Nói một cách khác nếu công việc picking kựa chọn đối tượng trực quan nhằm thay đổi mầu sắc của đối tượng.Lập trình đồ họa trên Java 2D và 3D Một pick ray trong không gian ảo Một cách tổng thể. đối tượng ColorCube không bị trực tiếp điều khiển mà thay vào đó là đối tượng TransformGroup nằm trên đối tượng ColorCube trong cùng path đến đối tượng ColorCube. Nếu chúng ta cần quay một đối tượng hìn lập phương 6 mặt . Lấy ví dụ để picking một đối tượng ColorCube object để điều khiển quay . http://tailieuhay. khi đó đối tượng hình lập phương sẽ cần phải giao cắt trực tiếp chứ không phải là đối tượng TransformGroup Việc quay đối tượng hình lập phương bằng việc tương tác đến đối tượng TransformGroup. là con của đối tượng BranchGroup trong đồ thị khung cảnh . mà làm việc với đối tượng chuyển hướng đồ thị khung cảnh đến đối tượng.com 451 . Việc xác định chính xác đối tượng được xử lý không phải là một công việc đơn giản.khi đó đối tượng trực quan phải được tác động một cách trực tiếp. quá trình giao cắt không thực hiện trực tiếp trên đối tượng được lựa chọn. mỗi mặt là một đối tượng Shape3D đọc lập được sapư xếp bởi 6 đối tượng TransformGroup .

Khả năng này chỉ áp dụng với một nhóm Node Method (partial list) Thừa kế : SceneGraphObject Lớp con: Group. picking đòi hỏi khả năng tính toán cao và làm tăng độ phức tạp của đồ thị khung cảnh.Lập trình đồ họa trên Java 2D và 3D Việc tính toán quá trình giao cắt là rất “tốn kém”.com 452 . những node không được xem xét đến khi tính toán giao cắt.Nó cung cấp một khung thông dụng trong việc xây dựng một http://tailieuhay. Một cách quan trọng là sử dụng khẳ năng và thuộc tính các node của đồ thị khung cảnh. Leaf Lớp Node là một lớp cơ sở trừu tượng cho tất cả các Group và Leaf Nodes. Một node. đặc điểm khác của lớp Node là khả năng ENABLE_PICK_REPORTING. trong Java3D cung cấp cho chúng ta những cách khác nhau để giới hạn số lượng tính toán phải thực hiẹn trong picking. Một node trong đồ thị khung cảnh có phương thức setPickable()đặt là false khi đó đối tượng node này và tất cả các đối tượng con của nó đều không thể picking Bởi vậy. Vì vậy.

Lập trình đồ họa trên Java 2D và 3D Java3D đồ thị khung cảnh., như specifically bounding volumes, picking và khả năng nhận biết collision void setBounds(Bounds bounds) Thiết lập một đối tượng hình học bao quanh một node. void setBoundsAutoCompute(boolean autoCompute) Bật tắt chế độ tự động tính toán tự động đối tượng hình học bao quanh mộ setPickable(boolean pickable) Đặt chế độ pick, nếu là true đối tượng Node này có thẻ pick, ngựoc lại đối tượng Node và các con của nó đều không thể pick được

Node Capabilities Summary (partial list) ENABLE_PICK_REPORTING Chỉ định Node có thể được thông báo trong SceneGraphPath nếu như quá trìh pick được thực hiện. Khả năng này chỉ có thẻ đuwọc định rõ cho các Group node, nó không áp dụng cho các node lá.Giá trị mặc định là false. ALLOW_BOUNDS_READ | WRITE Chỉ định Node được đọc/ghi đẻ truy cập các thông tin vào khung của nó. ALLOW_PICKABLE_READ | WRITE

Một cách khác để người lập trình có thể giảm thiểu việc tính toán trong qú trình picking là sử dụng thử nghiệm giao cắt của khung bao quanh thay vì việc sử dụng giao cắt của các đối tượng hình học. Rất nhìeu lớp có các hàm tạo và phương thức nhận tham số đầu vào USE_BOUNDS hoặc USE_GEOMETRY. Quyết định sử dụng khung baop quanh rõ ràng đã đem lại hiệu quả hơn nhiều (trong việc tính toán) đối với hầu hết vì vậy hiệu năng của chương trình tăng rõ rệt. Tuy nhiên

http://tailieuhay.com

453

Lập trình đồ họa trên Java 2D và 3D phương án này thực tế không phải lúc nào cũng tỏ ra hiệu quả và thực hiện đuợc. Một kỹ thuật thứ 3 để giảm những tính toán phức tạp trong quá trình picking la giới hạn phạm vi picking với những phần có liên quan trong đồ thị khung cảnh.

4.6.1 Using Picking Utility Classes Có hai cách tiếp cận trong quá tình sử dụng picking của java3D: sử dụng đối tượng của lớp picking, hoặc tạo ra lớp picking mới và sử dụng thể hiện của nó . Gói picking bao gồm các lớp để pick/rotate, pick/translate, và pick/zoom . Mỗi lớp picking sử dụng một phím chuột khác nhau để thực hiện quá trình điều khiển đối tượng với đầy đủ khả năng của các lớp picking trong cùng một ứng dụng. Trong phần này chúng ta giới thiệu và các lớp tiện ích PickRotateBehavior, PickTranslateBehavior, PickZoomBehavior.

Trong phần tiếp theo 4.6.2 chúng ta giới thiệu các lớp hay sử dụng trong việc tạo ra các lớp picking mới. Do mỗi đối tượng picking behavior object có khả năng thực hiện với bất kỳ đối tượng đồ thị khung cảnh, vì vậy chỉ cần một đối tượng picking behavior đẻ cung cấp khả năng picking Đoạn code dưới đây mô tả công việc cần thiết đẻ sử dụng các lớp picking behavior trong một chương trình Java 3D PickRotateBehavior behavior = new PickRotateBehavior(root, canvas, bounds); root.addChild(behavior);

http://tailieuhay.com

454

Lập trình đồ họa trên Java 2D và 3D Đối tượng behavior sẽ quản lí bất cứ sưk kiện picking nào diễn ra trong đồ thị khung cảnh (nằm dưới root) và xử lí các thao tác kéo thả chuột. Các bứoc sử dụng lớp picking 1. Khởi tạo đồ thị khung cảnh 2. Khởi tạo đối tượng picking behavior với root, canvas, và bounds xác định. 3. Thêm đối tượng behavior vào đồ thị khung cảnh. 4. Bật chức năng thích hợp cho đối tượng đồ thị khung cảnh Những sai sót hặygp phải khi sử dụng đối tượng Picking Sử dụng lớp picking behavior có thể dẫn đến các sai lầm hay gặp phải như khi lập trình với lớp behavior. Vấn đề thường gặp là: quên không bao gồm các đối tượng behavior trong đồ thị khung cảnh, và không thiết lập khung thích hợp cho đối tượng behavior Chương trình ví dụ MousePickApp. Đoạn code dưới đây trình bầy phương thức createSceneGraph của lớp MousePickApp. Chương trình sử dụng đối tượng PickRotate object để cung cấp quá trình tuơng tác. Đoạn code dưới đây tuân thủ các bước đã trình bày ở trên. public BranchGroup createSceneGraph(Canvas3D canvas) { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); TransformGroup objRotate = null;
http://tailieuhay.com 455

Lập trình đồ họa trên Java 2D và 3D PickRotateBehavior pickRotate = null; Transform3D Transform3D(); BoundingSphere BoundingSphere(); // PickRotateBehavior objects transform.setTranslation(new Vector3f(0.6f, 0.0f, -0.6f)); objRotate TransformGroup(transform); objRotate.setCapability(TransformGroup.AL LOW_TRANSFORM_WRITE); objRotate.setCapability(TransformGroup.AL LOW_TRANSFORM_READ); objRotate.setCapability(TransformGroup.EN ABLE_PICK_REPORTING); objRoot.addChild(objRotate); objRotate.addChild(new ColorCube(0.4)); pickRotate PickRotateBehavior(objRoot, behaveBounds); objRoot.addChild(pickRotate); // add a second ColorCube object to the scene graph = new = new create ColorCube and behaveBounds = new transform = new

canvas,

http://tailieuhay.com

456

Lập trình đồ họa trên Java 2D và 3D transform.setTranslation(new Vector3f( 0.6f, 0.0f, -0.6f)); objRotate TransformGroup(transform); objRotate.setCapability(TransformGroup.AL LOW_TRANSFORM_WRITE); objRotate.setCapability(TransformGroup.AL LOW_TRANSFORM_READ); objRotate.setCapability(TransformGroup.EN ABLE_PICK_REPORTING); objRoot.addChild(objRotate); objRotate.addChild(new ColorCube(0.4)); // Let Java 3D perform optimizations on this scene graph. objRoot.compile(); return objRoot; } // end of CreateSceneGraph method of MousePickApp = new

http://tailieuhay.com

457

Lập trình đồ họa trên Java 2D và 3D

Đoạn code trên cũng tuơng tự với ví dụ MouseRotate2App, tuy nhiên vẫn khác nhua trong một số trường hợp. Điều khác biệt chủ yếu là ứng dụng trên chỉ sử dụng một đối tượng behavior trong khi ứng dụng MouseRotate2App sử dụng h2 đối tượng behavior – cho mỗi đối tượng trực quan. Ngoài ra chức năng của các behavior cũng rất khác nhau. Ứng dụng của chúng ta chô phép người dùng pick một đối tượng để tương tác, trong khi ứng dụng MouseRotate2App làm quay cả hai đối tượng.

4.6.2 Các hàm API cơ bản trong các lớp Picking

Về cơ bản có 3 'levels' picking classes được cung cấp trong Java 3D. Các hàm Java 3D API cơ bản cung cấp các hàm chức năng ở tầng dưới cùng. Gói tiện ích picking cung cấp nhưng lớp picking behavior chung, phù hợp và dễ dàng thay đổi. Gói tiệc ích picking cũng cung cấp các lớp behavior có thể sử dụng trực tiếp trong chuwong trình Java3D. Những lớp nhân cơ bản bao gồm lớp PickShape và lớp SceneGraphPath, và các phương thức của BranchGroup và Locale.Những
http://tailieuhay.com 458

Lập trình đồ họa trên Java 2D và 3D lớp này cung cấp những kỹ thuật để xác định hưng hình đựoc sử dụng trong việc tương tác với các đối tượng trừu tượng. trong phần này chúng ta giứoi thiệu các hàm API của các lớp : PickShape and SceneGraphPath. Những lớp tiệc ích picking xác định sủ dụng các lớp chung để thực thi một picking behavior xác định. PickShape classes Lớp cơ sở trừu tượng chỉ cung cấp một cách trừu tượng 5 lớp con: PickBounds, PickRay, PickSegment, PickPoint, và PickCone. Thông thường , đối tượng hình học, là đích của picking, sẽ xác định sử dụng đối tượng pick shapes nào.Đối với các hình có dạng đa giác bất cứ pick shape nào cũng thỏa mãn được nhiệm vụ này. Tuy nhiên có sự khác nhau về hiêu năng sử dung giữa các lớp này.

Sơ đồ phả hệ PickShape PickShape Lớp con: PickBounds, PickRay, PickSegment, PickPoint, and PickCone PickBounds Đối tượng PickBounds thể hiện mọt khung cho pick testing.

http://tailieuhay.com

459

Lập trình đồ họa trên Java 2D và 3D

PickBounds Constructor Summary Thừa kế: PickShape Một khung để cung cấp cho phương thức BranchGroup Locale pick. PickBounds() Hàm tạo Pickbounds PickBounds(Bounds boundsObject) Hàm tạo với tham số bound.

PickBounds Method Summary Bounds get() Trả về đối tượng bound từ đối tượng PickBounds. void set(Bounds boundsObject) Thiết lập boundsObject trong đối tượng PickBounds. PickPoint Đối tượng PickPoint thể hiẹn cho điểm picking. Là lớp con của lớp PickShape, đối tượng PickPoint có thể được sử dụng với BranchGroup and Locale pick testing PickPoint Constructor Summary Thừa kế : PickShape Một điểm cung câp cho phương thức pick của BranchGroup và Locale PickPoint() Hàm tọa đối tượng PickPoint tại (0, 0, 0). PickPoint(Point3d location) Hàm tọa PickPoint với tham số location.

http://tailieuhay.com

460

Lập trình đồ họa trên Java 2D và 3D

PickPoint Method Summary void set(Point3d location) Thiết lập giá trị vị trí của PickPoint. PickRay Đối tượng PickRay thể hiện một ray trong picking. PickRay Constructor Summary Thừa kế : PickShape Đối tượng PickRay là một gói gọn các ray để truyền vào cho phương thức picking trong lớp BranchGroup và Locale PickRay() Hàm tạo với giá trị mặc định (0, 0, 0). PickRay(Point3d origin, Vector3d direction) Hàm tạo với tham số hướng.

PickRay Method Summary void set(Point3d origin, Vector3d direction) Thiết lập một tia đến một điểm từ vị trí với tham số tọa đọ và hướng. PickSegment Đối tượng PickSegment biểu diễn một đoạn thẳng (defined by two points) để picking. Lớp con lớp PickShape, đối tượng PickSegment được sử dụng với phương thức pick testing của BranchGroup và Locale

http://tailieuhay.com

461

Lập trình đồ họa trên Java 2D và 3D PickSegment Constructor Summary Thừa kế : PickShape PickSegment() Hàm tạo PickSegment. PickSegment(Point3d start, Point3d end) Hàm tạo PickSegment tham số điểm đầu điểm cuối.

PickSegment Method Summary void set(Point3d start, Point3d end) Thiết lạp một PickSegment tham số điểm đầu điẻm cuối. PickCone PickCone lớp mới trong API phiên bản 1.2. Lớp PickCone là lớp cơ sở trừu tượng với tất cả các khung hình nón. Khung hình nón sử dụng hiệu quả khi picking giữa các đối tượng hình học. Gồ hai lớp con: PickConeRay và PickConeSegment. Điểm khác biệt giữa chúng là độ dài. PickConeRay là một hình nón với độ dài is a cone of vô tận length trong khi PickConeSegment có độ dài giới hạn. Đối tượng PickConeRay đựoc xác định ởi một điểm ban đầu và hướng. Đối tượng PickConeSegment được định nghĩa hai điểm xác định cả độ dài và huwosng của hình nón.

PickCone Method Summary void getDirection(Vector3d direction) <new in 1.2>
http://tailieuhay.com 462

Lập trình đồ họa trên Java 2D và 3D Trả về hướng của đối tượng PickCone void getOrigin(Point3d origin) <new in 1.2> double getSpreadAngle() <new in 1.2> Trả về góc rộng của đối tượng PickCone.PickConeRay <new in 1.2>

PickConeRay Constructor Summary Thừa kế PickCone PickConeRay() <new in 1.2> Hàm tạo PickConeRay. PickConeRay(Point3d origin, Vector3d direction, <new in 1.2> double spreadAngle) Hàm tạo PickConeRay.

PickConeRay Method Summary void set(Point3d origin, Vector3d direction, double spreadAngle) Phương thức thiết lập các tham số của đối tượng PickCone PickConeSegment <new in 1.2> PickConeSegment Constructor Summary Thừa kế : PickCone PickConeSegment() <new in 1.2> PickConeSegment(Point3d origin, Point3d end, double spreadAngle) <new in 1.2>

PickConeSegment Method Summary void getEnd(Point3d end) <new in 1.2>

http://tailieuhay.com

463

2> Lớp PickCylinder và lớp con của nó cũng tưong tự như lớp PickCone và các lớp con của PickCone. Lớp PickCone là lớp cơ sở trừu tượng của hai lớp: PickCylinderRay và PickCylinderSegment. PickCylinder Method Summary void getDirection(Vector3d direction) <new in 1. double getRadius() <new in 1. double spreadAngle) <new in 1.2> Trả về điểm khởi đầu của đối tượng cylinder. Điểm đầu đuwojc nhận từ phương thức của lớp cha. void set(Point3d origin.2> PickCylinder <new in 1. Point3d end.com 464 .Lập trình đồ họa trên Java 2D và 3D Trả về điểm cuối của đối tượng PickConeSegment. void getOrigin(Point3d origin) <new in 1.2> http://tailieuhay.2> Trả về hướng của đối tượng PickCylinder.2> PickCylinderRay Constructor Summary Thừa kế : PickCylinder PickCylinderRay() <new in 1.2> Trả về goc ban đầu của đối tượng cylinder PickCylinderRay <new in 1.

double radius) <new in 1. double radius) <new in 1.2> Phương thức thiết lập giá trị cho các thuộc tính của đối tượng PickCylinderRay. double radius) <new in 1. Vector3d direction.2> double radius) Hàm tạo với tham số điểm ban đầu và hứong. Point3d end. void set(Point3d origin.Lập trình đồ họa trên Java 2D và 3D Hàm tạo PickCylinderRay. PickCylinderSegment(Point3d origin. <new in 1.2> Hàm tạo PickCylinderSegment. Vector3d double) đẻ thiết lập các giá trị của htuộc tính PickCylinderRay(Point3d origin.com 465 .2> SceneGraphPath http://tailieuhay.2> PickCylinderSegment Constructor Summary Thừa kế : PickCylinder PickCylinderSegment() <new in 1. Vector3d direction. Point3d end. Sử dụng phương thức set(Point3d. PickCylinderSegment <new in 1.2> Trả về điểm cuối đối tượng PickCylinderSegment.2> PickCylinderRay Method Summary void getEnd(Point3d end) <new in 1. PickCylinderRay Method Summary void set(Point3d origin.

Điều này là do quá trình picking thuwongf xuyên bao gồm quá trình tìm đừong đi trong đồ thị khung cảnh có chứa đối tượng cần tương tác.Object o1) Trả về true nếu đối tượng o1 có kiêu SceneGraphPath và các dữ liệu thành phần của đối tượng o1 tương ứng bằng với các thành phần dữ liệu của đối tượng SceneGraphPath và néu giá trị của transforms cũng bằng nhau Transform3D getTransform() Trả về bản copy của transform gắn liền với đối tượng SceneGraphPath.Lập trình đồ họa trên Java 2D và 3D Lớp SceneGraphPath được sử dụng trong hầu hết các ứng dụng picking. Một đối tượng SceneGraphPath thể hiện một đường đi trong đồ thị khung cảnh. int nodeCount() Trả về số node của đừong đi. trả về null nếu không có transform. Node newNode) void setNodes(Node[] nodes) void setObject(Node object) http://tailieuhay.lang. int hashCode() boolean isSamePath(SceneGraphPath testPath) Xác định hai đối tượng đại diện cho cùng một đường đi hay không.com 466 . void set(SceneGraphPath newPath) void setLocale(Locale newLocale) Thiết lập đường đi là đường đi từ đối tượng Locale đến một đối tượng Locale.xác định void setNode(int index. SceneGraphPath Method Summary (partial list) boolean equals(java.

có thể pick và có giao cắt với đối tượng PickShape. BranchGroup and Locale picking methods for use with PickShape SceneGraphPath[] pickAll(PickShape pickShape) Trả về mảng tham chiếu các node nằm duới BranchGroup.Lớp này còn rất hiệu quả trong việc xây dựung các picking class sau này bằng việc thừa kế nó.6.lang. PickMouseBehavior Class Lớp cơ sở cung cấp các phương thức picking behavior.3 Các lớp picking Những lớp picking nói chung được dùng hiệu quả trong việc tạo ra các picking behavior . PickMouseBehavior Method Summary http://tailieuhay. Các lớp : PickMouseBehavior. SceneGraphPath[] pickAllSorted(PickShape pickShape) Trả về một mảng các có thứ tự tham chiếu đến các thành phần có thể pick đựoc và có giao cắt với đối tượng pickShape.String toString() Các phương thức picking của BranchGroup và Local Picking Đây là tầng thấp nhất trong việc tính toán picking được cung cấp trong Java 3D API. Phần tử [0] tham chiếu đến thành phần nằm gần đối tượng PickShape nhất SceneGraphPath pickClosest(PickShape pickShape) SceneGraphPath pickAny(PickShape pickShape) 4.com 467 .Lập trình đồ họa trên Java 2D và 3D void setTransform(Transform3D trans) java.và PickCallback. PickObject.

com 468 .Object PickObject(Canvas3D c.sun.continued) http://tailieuhay.j3d. int ypos) Khởi tạo một đối tượng PickRay bắt đầu từ vị trí của viewer và trỏ tới điểm xác địnhtheo huwonsg xác định.Enumeration criteria) void updateScene(int xpos. void processStimulus(java. PickObject Constructor Summary Gói: com.utils. PickShape generatePickRay(int xpos.util. int ypos) PickObject Class Lớp PickObject cung cấp các phương thức xác định đối tượng nào đựoc chọn bởi hành động pick của người dùng.picking Thừa kế : java.utils. PickObject Method Summary (partial list) Lớp PickObject có nhiều phương thức đẻ tính toán sự giao cắt của một đối tượng pickRay với đối tượng đồ thị khung cảnh.j3d.behaviors.. PickObject Method Summary (partial list .sun.picking Thừa kế : Behavior void initialize() Phương thức này cần được viết đè để cung cấp các trạng thái ban đầu và các đièu kiện trigger ban đầu.Lập trình đồ họa trên Java 2D và 3D Gói : com.lang. BranchGroup root) Hàm tạo PickObject.behaviors.

PickObject.BRANCH_GROUP.MORPH. xác định giá trị của kiểu node: PickObject. PickingCallback Interface Giao diện PickingCallback cung cấp một khng làm việc để thừa kế một lớp picking đã có trước. Node pickNode(SceneGraphPath sgPath.PRIMITIVE. int ypos) Trả về tham chiếu đến một đối tượng nằm dưới BranchGroup có giao cắt với một ray bắt đầu từ vị trí viewer và trỏ tới khung hình theo hướng và đỉem tới xác định SceneGraphPath pickClosest(int xpos. PickObject.Lập trình đồ họa trên Java 2D và 3D SceneGraphPath[] pickAll(int xpos. int ypos) Tương tự phương thức trên nhưng mảng trả vè được sắp xếp theo thứ tự. PickObject. int occurrence) PickObject. SceneGraphPath pickAny(int xpos.GROUP. PickObject.SWITCH.SHAPE3D.LINK. Interface PickingCallback Method Summary http://tailieuhay.TRANSFORM_GROUP. int node_types. int ypos) Trả về một mảng tham chiếu tất cả các thành phần nằm dưới BranchGroup có giao cắt với một ray bắt đầu từ vị trí viewer và trỏ tới khung hình theo hướng và đỉem tới xác định SceneGraphPath[] pickAllSorted(int xpos. PickObject. int node_types) Trả về một đối tượng Node có kiểu xác định và có chưa đối tượng SceneGraphPath PickObject. int ypos) Node pickNode(SceneGraphPath sgPath.com 469 .

boolean pointAndPoint(PickPoint point.Lập trình đồ họa trên Java 2D và 3D Gói: com.Object Intersect() Hàm tạo Intersect. Lien đuợc xác định bởi tham số đầu vào.j3d. TransformGroup tg) Lớp Intersect Lớp cung cấp các phương thức để kiểm tra việc qiao cắt của một đối tượng PickShape (core class) với một đối tượng geometry primitives. int index) Trả về true nếu như đối tượng PickPoint và đối tượng Line giao nhau.utils. Point3d pnt. Intersect Constructor Summary Gói: com. int index. Intersect Method Summary (partial list) boolean pointAndLine(PickPoint point.sun. Point3d pnt) Tra về true néu đối tượng PickPoint và đối tượng Point3d giao cắt nhau. Point3d[] coordinates.behaviors. int index. boolean rayAndLine(PickRay ray. Point3d[] coordinates. double[] dist) boolean rayAndQuad(PickRay ray.com 470 .lang.j3d. Point3d[] coordinates.sun.utils. double[] dist) boolean rayAndPoint(PickRay ray. http://tailieuhay.behaviors. double[] dist) boolean rayAndTriangle(PickRay ray. int index.picking void transformChanged(int type. Point3d[] coordinates.picking Thừa kế : java.

Point3d pnt. int index.Lập trình đồ họa trên Java 2D và 3D double[] dist) boolean segmentAndLine(PickSegment segment.j3d. double[] dist) Intersect Method Summary (partial list .j3d. Point3d[] coordinates.6. int index. double[] dist) boolean segmentAndTriangle(PickSegment segment. Point3d[] coordinates. Canvas3D canvas.sun.picking Thừa kế : PickMouseBehavior Thực this: PickingCallback PickRotateBehavior(BranchGroup root.behaviors. Bounds bounds) http://tailieuhay. Point3d[] coordinates. double[] dist) 4.4 Các lớp Picking Behavior Gói com.com 471 . PickRotateBehavior Constructor Summary Gói: com. int index.utils.sun.behaviors. double[] dist) segment.continued) boolean boolean segmentAndPoint(PickSegment segmentAndQuad(PickSegment segment.utils.picking cung cấp các lớp PickRotateBehavior Lớp PickRotateBehavior cho phép người dùng tưong tác pick và rotate đối tượng trực quan.

all geometry objects in the scene graph intended to be available for picking must have their ALLOW_INTERSECT bit set.com 472 .USE_BOUNDS hay PickObject. int pickMode) Giáptrị PickMode : PickObject.sun. int ypos) PickTranslateBehavior Lớp PickTranslateBehavior cho phép người dung tương tác pick và translate đối tượng trực quan.utils. Một thể hiện của lớp PickTranslateBehavior có thể đuợc sử dụng kết hợp với các đối tượng tcủa các lớp picking khác.USE_GEOMETRY.USE_GEOMETRY.USE_BOUNDS hay PickObject. void setupCallback(PickingCallback callback) void transformChanged(int type. PickTranslateBehavior Constructor Summary Gói : com.USE_GEOMETRY.j3d. PickRotateBehavior Method Summary void setPickMode(int pickMode) Thiết lập giá trị pickMode: nhạn một trong các giá trị PickObject. Transform3D transform) void updateScene(int xpos.picking Thừa kế : PickMouseBehavior http://tailieuhay. Canvas3D canvas. Note: If pickMode is set to PickObject.Lập trình đồ họa trên Java 2D và 3D PickRotateBehavior(BranchGroup root.behaviors. Bounds bounds.

Một thể hiện của lớp PickZoomBehavior có thể đuợc sử dụng kết hợp với các đối tượng tcủa các lớp picking khác. PickTranslateBehavior Method Summary void setPickMode(int pickMode) Thiết lạp giá trị thành phần pickMode void setupCallback(PickingCallback callback) Đăng kí lớp callback được gọi mỗi khi đối tượng được kích họat. int ypos) PickZoomBehavior Lớp PickZoomBehavior cho phép người dung tương tác pick và zoom đối tượng trực quan. Transform3D transform) void updateScene(int xpos.behaviors. root.picking Thừa kế : PickMouseBehavior Thực thi: PickingCallback http://tailieuhay.sun.utils. Canvas3D canvas.Lập trình đồ họa trên Java 2D và 3D Thực thi: PickingCallback PickTranslateBehavior(BranchGroup Bounds bounds) Khởi tạo hành vi pick/translate chờ sự kiện từ chuột trong đồ thị khung cảnh PickTranslateBehavior(BranchGroup Bounds bounds. PickZoomBehavior Constructor Summary Gói: com. Canvas3D canvas. int pickMode) root.j3d.com 473 . void transformChanged(int type.

void transformChanged(int type. void updateScene(int xpos. void setupCallback(PickingCallback callback) Đăng kí lớp callback được gọi mỗi khi đối tượng được kích họat.Lập trình đồ họa trên Java 2D và 3D PickZoomBehavior(BranchGroup root. CHƯƠNG 5 Hoạt Hình http://tailieuhay. Canvas3D canvas. Canvas3D canvas. Bounds bounds) Khởi tạo hành vi pick/zoom chờ sự kiện từ chuột trong đồ thị khung cảnh PickZoomBehavior(BranchGroup root. int ypos) Cập nhật khung cảnh . int pickMode) PickZoomBehavior Method Summary void setPickMode(int pickMode) Thiết lạp giá trị thành phần pickMode .com 474 . Transform3D transform) Phương thức Callback từ lớp MouseZoom. Bounds bounds.

Chiếc đồng hồ chính là một ví dụ về hoạt ảnh.com 475 . nó có thể hoạt động mà không cần tương tác của người dùng. Ngược lại. có rất nhiều đối tượng trực quan thay đổi độc lập với hành động của con người. Trong thế giới ảo. Vậy hoạt ảnh là những thay đổi xảy ra trong vũ trụ ảo mà không có tương tác trực tiếp của con người. những thay đổi xảy ra trong vũ trụ ảo mà là kết quả trực tiếp của hành động người dùng thì được gọi là tương tác (chúng ta đã xét trong chương 4). chúng tôi sẽ trình bày các vấn đề cơ bản sau: • Sử dụng các lớp Alpha và Interpolator đơn giản để thêm các hoạt ảnh • Sử dụng các lớp LOD và Billboard để giảm khối lượng tính toán khi tạo các hoạt ảnh • Sử dụng đối tượng Morph với các đối tượng hành vi tùy chỉnh để tạo hoạt ảnh từ các khung hình chính • Tạo đối tượng hình học động để tạo Behavior hiệu chỉnh dữ liệu BY_REFERENCE. Ví như một chiếc đồng hồ ảo chẳng hạn. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D Trong chương này.

Mục 5. hoạt ảnh trong Java 3D cũng được cài đặt nhờ sử dụng đối tượng Behavior (hành vi).Hoạt hình: Tương tự như phần tương tác. Java 3D API cung cấp một tập các lớp cho phép tạo hoạt ảnh mà không phải tạo một lớp mới. Mục 5. Đối tượng Alpha cung cấp cơ chế định thời gian. Tuy nhiên. lớp hoạt ảnh được đưa vào Java 3D API từ phiên bản v1. Bất cứ hoạt ảnh nào cũng có thể tạo ra được với các đối tượng hành vi. Đối tượng Interpolator cùng với một đối tượng Alpha điều khiển một vài thông số của đối tượng đồ thị khung cảnh để tạo ra hoạt ảnh dựa thời gian.com 476 .2. http://tailieuhay.5 Một vài lớp hoạt ảnh không kế thừa từ lớp Behavior như: OrientedShape3D và Morph . lớp hoạt ảnh được sử dụng cả trong các ứng dụng hoạt ảnh và nội suy. Hai lớp hành vi sẽ được xét kĩ hơn trong các mục 5.2 như một sự thay thế cho hành vi Billboard trong các phiên bản trước đó. Một tập các lớp hoạt ảnh khác trong Java 3D tạo hoạt ảnh cho các đối tượng trực quan nhờ đáp ứng sự thay đổi về khung nhìn. Java 3D cung cấp một tập các lớp hoạt ảnh có vai trò như những bộ nội suy (Interpolator ). Tập các lớp này (bao gồm: lớp OrientedShape3D. Các lớp này đều kế thừa lớp Behavior. Chi tiết về hai lớp đối tượng này sẽ được bàn đến trong mục 5.Lập trình đồ họa trên Java 2D và 3D Animation .4 sẽ trình bày về OrientedShape3D.3 và 5. các lớp hành vi Billboard và Level Of Detail (LOD )) không được điều khiển bởi các khoảng thời gian mà bởi vị trí và hướng của khung nhìn.6 trình bày về Morph .

Với các bộ giá trị tham số nhất định. Trong phần 5. kể cả hai đầu mút. hướng. Nội suy bao gồm sự thay đổi vị trí. chúng ta sẽ xét một ví dụ sử dụng lớp nội suy RotationInterpolator. Các hành vi nội suy có thể được cài đặt bằng cách tạo ra một lớp hành vi tùy chỉnh.Lập trình đồ họa trên Java 2D và 3D Hình 5-1. Alpha Đối tượng Alpha sinh ra một giá trị.2. tuy nhiên.3. Đồ thị dạng sóng của đối tượng Alpha có bốn đoạn: Alpha tăng. Sơ đồ phân cấp các lớp hoạt ảnh kế thừa Behavior Đối tượng Interpolator và Alpha với hoạt ảnh dựa thời gian Đối tượng Alpha sinh ra một giá trị nằm trong khoảng từ 0 đến 1 tùy thuộc vào thời gian và các tham số của đối tượng Alpha. Alpha giảm và Alpha bằng 0. Giá trị Alpha thay đổi theo thời gian như đã định sẵn bởi các tham số của đối tượng Alpha. chúng ta sẽ được một dạng sóng mà đối tượng Alpha sinh ra. Thực thể nội suy (Interpolator ) là các đối tượng hành vi tùy chỉnh sử dụng một đối tượng Alpha để sinh hoạt ảnh cho các đối tượng trực quan.com 477 . đối tượng Alpha chỉ sinh ra một giá trị Alpha duy nhất. độ lớn. Alpha bằng 1. Bốn đoạn này tạo thành một http://tailieuhay. tại thời điểm cụ thể.0. nằm trong khoảng từ 0. màu sắc hoặc độ trong suốt của đối tượng. Biểu diễn bằng đồ thị giá trị Alpha so với thời gian. được gọi là giá trị Alpha. sử dụng lớp nội suy cho phép tạo hoạt ảnh dễ dàng hơn nhiều.0 và 1.

Vì thế tuy các đối tượng Alpha được tạo ra ở các thời điểm khác nhau. TriggerTime xác định khoảng thời gian từ lúc đối tượng Alpha khởi động cho đến khi bắt đầu hoạt động. Sau khoảng thời gian xác định bởi tham số PhaseDelayDuration tính từ thời điểm kích hoạt TriggerTime.Lập trình đồ họa trên Java 2D và 3D chu kì của dạng sóng Alpha và tương ứng với bốn tham số của đối tượng Alpha. Kết quả là. chu kì của dạng sóng đầu tiên bắt đầu. Các tham số này được thể hiện trong hình 52. Dạng sóng của các đối tượng Alpha có thể bắt đầu ở những thời điểm khác nhau.com 478 . loopCount dương qui định số chu kì. ngoại trừ giai đoạn trễ. nhưng chúng đều có chung một thời điểm khởi động. loopCount bằng –1 xác định vòng lặp không dừng. Việc định thời gian của các đối tượng Alpha có liên hệ với thời điểm khởi động chúng. đơn vị tính là mili giây. Thời gian của một chu kì được xác định bằng một số nguyên. Thời điểm khởi động của tất cả các đối tượng Alpha đều được lấy từ thời điểm khởi động hệ thống. tiếp tục quay vòng với số lần xác định hoặc sẽ quay vòng không dừng. Hình 5-2 biểu diễn bốn đoạn của dạng sóng Alpha. Số chu kì của sóng xác định bởi tham số loopCount. tất cả các giai đoạn trên đều được lặp lại. tất cả các đối tượng nội suy mặc dù dựa trên các đối tượng Alpha khác nhau nhưng đều được đồng bộ hóa. Chu kì dạng sóng đầu tiên của một đối tượng Alpha có thể bị trễ do việc sử dụng một trong hai hoặc cả hai tham số: TriggerTime (thời điểm kích hoạt) và PhaseDelayDuration (thời gian trễ). Dạng sóng của đối tượng Alpha có thể quay vòng một chu kì. Nếu dạng sóng Alpha quay vòng hơn 1 chu kì. http://tailieuhay.

chỉ định sử dụng cả bốn giai đoạn. Đối tượng Alpha có hai kiểu chỉ định các tập con giai đoạn được sử dụng.com 479 . hai. Một vài dạng sóng cơ sở được tạo với đối tượng Alpha http://tailieuhay. Kiểu INCREASING_ENABLE chỉ định sử dụng các giai đoạn Alpha tăng và giai đoạn Alpha bằng 1. Hình 5-3 biểu diễn một số dạng sóng tạo bởi một. hai hoặc ba giai đoạn. Hình 5-3. Kiểu thứ ba là kết hợp của cả hai kiểu trên. Kiểu DECREASING_ENABLE chỉ định sử dụng giai đoạn Alpha giảm và Alpha bằng 0. Các giai đoạn của dạng sóng Alpha Dạng sóng Alpha có thể không sử dụng tất cả bốn giai đoạn trên mà có thể được tạo thành từ một.Lập trình đồ họa trên Java 2D và 3D Hình 5-2. ba hoặc bốn giai đoạn.

Ví dụ. tuy nhiên. Điểm khác biệt lớn nhất so với cách sử dụng đối tượng hành vi chính là việc gộp cùng với đối tượng Alpha. Mặc dù bất kì một dạng sóng nào cũng có thể xây dựng được bằng cách cho khoảng thời gian tồn tại của các giai đoạn không cần thiết bằng 0. tạo đối tượng đích với các khả năng thích hợp tạo đối tượng Alpha tạo đối tượng Interpolator tham chiếu đến đến đối tượng thêm các giới hạn cho đối tượng Interpolator thêm đối tượng Interpolator vào đồ thị khung cảnh Alpha và đối tượng đích 4. Sử dụng các đối tượng Interpolator và Alpha: Cách thức sử dụng các đối tượng Interpolator và Alpha rất giống với cách thức sử dụng đối tượng hành vi. Công thức sử dụng các đối tượng Interpolator và Alpha để tạo hoạt ảnh Ví dụ sử dụng lớp Alpha và RotationInterpolator: ClockApp. DecreasingAlphaRampDuration và AlphaAtZeroDuration sẽ bị bỏ qua. khi kiểu là INCREASING_INABLE.java là một ví dụ sử dụng lớp RotationInterpolator.Lập trình đồ họa trên Java 2D và 3D Các đặc tả về kiểu của đối tượng Alpha sẽ vô hiệu các thiết lập tham số khoảng thời gian. 3. Chiếc đồng hồ này được điều khiển quay http://tailieuhay. 5. Hình 5-4. Khung cảnh là mặt một chiếc đồng hồ. 2.com 480 . thì các tham số DecreasingAlphaDuration. Công thức sử dụng các đối tượng Interpolator và Alpha có thể tóm tắt như sau: 1. việc đặc tả chính xác kiểu sẽ làm tăng hiệu quả của đối tượng Alpha.

Hai đối tượng này kết hợp với nhau sẽ làm cho đối tượng trực quan (đối tượng đích) quay một vòng hoàn chỉnh trong 1 phút. đích của đối tượng ColorInterpolator là một đối tượng Material. Trong chương trình này. đối tượng đích là một đối tượng TransformGroup. Chương trình đầy đủ xin xem phần phụ lục. public BranchGroup createSceneGraph() { http://tailieuhay. Đoạn mã sau định nghĩa phương thức createSceneGraph trong chương trình ClockApp.Lập trình đồ họa trên Java 2D và 3D mỗi phút một lần bởi hai đối tượng RotationInterpolator và Alpha. Các đối tượng Interpolator khác nhau sẽ hoạt động trên các đối tượng đích khác nhau.java. Đối tượng Interpolator thiết lập giá trị của đối tượng đích dựa vào các giá trị của đối tượng Alpha và các giá trị do chính nó lưu giữ. Kết quả là chiếc đồng hồ dường như quay không ngừng chứ không phải là quay một vòng rồi bắt đầu lại một vòng khác. Yêu cầu đối tượng này phải được thiết lập khả năng ALLOW_TRANSFORM_WRITE.000 mili giây). Đối tượng Interpolator định nghĩa điểm kết thúc của hoạt ảnh. Đối tượng Alpha điều khiển hoạt ảnh tương ứng với thời gian và cách mà Interpolator dịch chuyển từ điểm này đến một điểm khác bằng đặc tả các giai đoạn của dạng sóng Alpha. Ứng dụng này sử dụng thiết lập mặc định cho đối tượng RotationInterpolator với góc bắt đầu là 0 và góc kết thúc là 2Π (một vòng quay hoàn chỉnh). Đối tượng Alpha được thiết lập ở chế độ quay không dừng (loopCount = -1) với quãng thời gian là 1 phút (60. đối tượng này xác định góc quay bắt đầu và kết thúc. Trục quay mặc định là trục y. ở đây chúng tôi chỉ trích rút một phần để tập trung vào vấn đề chính. Trong trường hợp của RotationInterpolator. Đoạn mã này được đánh dấu các bước tương ứng với công thức đưa ra trong hình 5-4. Chu trình này được tiếp diễn và lặp lại ngay lập tức. Ví dụ.com 481 .

// create Alpha that continuously rotates with a period of 1 minute Alpha alpha = new Alpha (-1.setApplicationBounds(new BoundingSphere()). objSpin).ALLO W_TRANSFORM_WRITE).com 482 . // create target TransformGroup with Capabilities TransformGroup TransformGroup(). 1. objSpin = new http://tailieuhay. objSpin. objRoot. // create rotation about y-axis RotationInterpolator rotInt = new RotationInterpolator (alpha.setColor(1. rotInt. 60000).addChild(objSpin). background. objRoot.addChild(rotInt).0f. objSpin.addChild(background).0f. background.addChild(new Clock()).0f).Lập trình đồ họa trên Java 2D và 3D // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). Background background = new Background(). objRoot.setSchedulingBounds(new BoundingSphere()).setCapability(TransformGroup. 1.

} ClockApp Hình 5-5 là một cảnh được tạo ra bằng chương trình ClockApp tại 4:30. thì cách này cho phép vật thể chuyển động chậm dần hoặc nhanh dần trông giống thật hơn. người lập trình còn có thể xác định các sườn thoải cho giai đoạn Alpha tăng và Alpha giảm. Làm trơn dạng sóng Alpha Ngoài khoảng thời gian của 4 giai đoạn như đã trình bày. giá trị Alpha thay đổi dần dần. Trong đoạn thoải này.Lập trình đồ họa trên Java 2D và 3D // Let Java 3D perform optimizations on this scene graph. // end of CreateSceneGraph method of http://tailieuhay. objRoot. Trong trường hợp lập trình cho vật thể chuyển động. return objRoot. Mặt đồng hồ trông bị nghiêng đi là do cả mặt đấy quay theo trục thẳng đứng.compile().com 483 . nên đoạn này lớn nhất chỉ bằng một nửa của cả giai đoạn. Vì giá trị của đoạn dốc thoải tác động đến cả phần bắt đầu và kết thúc của giai đoạn.

Lập trình đồ họa trên Java 2D và 3D Hình 5-5. Sự khác biệt về giá trị sẽ được đánh giá trực quan qua việc quan sát chuyển động của 3 chiếc ô tô. Làm trơn dạng sóng Alpha AlphaApp. còn chiếc ở http://tailieuhay. Một cảnh sinh bởi chương trình ClockApp tại 4:30 Hình 5-6 biểu diễn một dạng sóng Alpha được thiết lập cả Hình 5-6.com 484 . Cả 3 chiếc này xuất phát tại cùng một tọa độ x và di chuyển song song với nhau. Chiếc xe trên cùng không có đoạn giá trị Alpha thoải. chiếc dưới cùng có đoạn thoải với giá trị lớn nhất (bằng một nửa của giai đoạn Alpha tăng hoặc giảm).java (xem phụ lục) là một chương trình ví dụ về tác động của việc thiết lập IncreasingAlphaRampDuration trên một dạng sóng Alpha.

Mỗi xe cần 2 giây để chuyển động qua khung nhìn.4s Time ~ 0. Quan sát chương trình.2s Time ~ 1.6s Hình 5-7.8s Time ~ 1. Tác dụng của IncreasingAlphaRampDuration trên một dạng sóng Alpha Hình 5-7 biểu diễn 4 cảnh sinh ra từ chương trình AlphaApp. Time ~ 0.Lập trình đồ họa trên Java 2D và 3D giữa có đoạn thoải với giá trị bằng một nửa giá trị lớn nhất (tức là bằng ¼ giai đoạn Alpha tăng hoặc giảm). chúng ta có thể nhận thấy rằng: ban đầu chiếc xe trên cùng (không có đoạn thoải) chuyển động nhanh hơn và giữ nguyên tốc http://tailieuhay.com 485 .

Đến thời điểm 1 giây sau khi khởi động. khi hết 2 giây. Alpha(int loopCount. thiết lập chế độ INCREASING_ENABLE và gán giá trị 0 cho tất cả các tham số còn lại (ngoại trừ StartTime). vị trí của 3 chiếc xe bị đảo ngược với chiếc dưới cùng chạy nhanh nhất nhưng chậm dần. long increasingAlphaDuration. trả về một giá trị nằm trong đoạn [0. Vì vậy. Ứng dụng thông thường của Alpha là cung cấp giá trị Alpha cho các hành vi Interpolator . 1]. StartTime được thiết lập bằng thời gian khởi động của chương trình. long phaseDelayDuration. hai chiếc phía dưới chuyển động chậm hơn nhưng nhanh dần. long increasingAlphaRampDuration. long triggerTime. tất cả các tham số khác = 0. có thể nói đối tượng Alpha là một hàm của thời gian.com 486 . Alpha(int loopCount. 4 phương thức khởi tạo chủ yếu sau xuất hiện trong hầu hết các ứng dụng Alpha: Alpha() Khởi tạo đối tượng Alpha với mode = INCREASING_ENABLE. Cuối cùng. Trong một nửa quãng đường còn lại. ngoại trừ thời gian khởi động: StartTime. Các phương thức API của lớp Alpha có thể tùy biến một cách dễ dàng để sử dụng trong các ứng dụng bằng cách tác động vào các tham số của chúng. 3 chiếc xe lại bắt kịp nhau. loopCount = -1. http://tailieuhay. long increasingAlphaDuration) Khởi tạo đối tượng Alpha với hai tham số loopCount và increasingAlphaDuration là tùy biến của người dùng. Alpha API: Lớp Alpha có vai trò chuyển đổi một giá trị thời gian về một giá trị Alpha (giá trị nằm trong khoảng từ 0 đến 1.Lập trình đồ họa trên Java 2D và 3D độ. increasingAlphaDuration = 1000. cả 3 chiếc đều đi được quãng đường giống nhau. kể cả hai đầu mút).

int mode. long increasingAlphaDuration.com . void setAlphaAtZeroDuration(long alphaAtZeroDuration) Thiết lập giá trị xác định cho thuộc tính alphaAtZeroDuration của đối tượng Alpha hiện thời. Chú ý rằng mỗi phương thức set (phương thức thiết lập) đều có một phương thức get (không tham số) trả về một giá trị cùng kiểu với kiểu của tham số có mặt trong phương thức set tương ứng. long phaseDelayDuration. void setDecreasingAlphaDuration(long decreasingAlphaDuration) Thiết lập giá trị xác định cho thuộc tính decreasingAlphaDuration của đối tượng Alpha hiện thời. boolean finished() Kiểm tra xem đối tượng Alpha hiện thời đã kết thúc mọi hoạt động của nó hay chưa. long alphaAtOneDuration. long alphaAtZeroDuration) Khởi tạo đối tượng Alpha theo các tham số định nghĩa của người dùng. long increasingAlphaRampDuration. void setAlphaAtOneDuration(long alphaAtOneDuration) Thiết lập thuộc tính alphaAtOneDuration của đối tượng Alpha hiện thời đến giá trị xác định.Lập trình đồ họa trên Java 2D và 3D long alphaAtOneDuration) Khởi tạo đối tượng Alpha ở chế độ INCREASING_ENABLE Alpha(int loopCount. cho phép người dùng tuỳ biến các đặc tính của đối tượng Alpha. Chúng tôi liệt kê ở đây một vài phương thức phổ dụng nhất. Lớp Alpha cung cấp rất nhiều các phương thức hữu ích. long decreasingAlphaDuration. long triggerTime. void setDecreasingAlphaRampDuration(long decreasingAlphaRampDuration) Thiết lập giá trị xác định cho thuộc tính 487 http://tailieuhay.

INCREASING_ENABLE . void setMode(int mode) Thiết lập chế độ xác định bởi đối số mode cho đối tượng Alpha hiện thời. void setTriggerTime(long triggerTime) Thiết lập giá trị triggerTime của đối tượng Alpha hiện thời bằng giá trị cho trong đối số. hay là hoặc của hai giá trị. mode có thể là INCREASING_ENABLE hoặc DECREASING_ENABLE. startTime quy định mốc cho mọi tính toán thời gian tương đối.chỉ định sử dụng giai đoạn 1 và 2 void setPhaseDelayDuration(long phaseDelayDuration) Thiết lập giá trị phaseDelayDuration của đối tượng Alpha hiện thời bằng giá trị cho trong đối số. http://tailieuhay. void setIncreasingAlphaDuration(long increasingAlphaDuration) Thiết lập giá trị xác định cho thuộc tính increasingAlphaDuration của đối tượng Alpha hiện thời. Giá trị mặc định của startTime là thời điểm khởi động hệ thống.com 488 . void setStartTime(long startTime) Thiết lập giá trị startTime của đối tượng Alpha hiện thời bằng giá trị cho trong đối số. void setIncreasingAlphaRampDuration(long decreasingAlphaRampDuration) Thiết lập giá trị xác định cho thuộc tính increasingAlphaRampDuration của đối tượng Alpha hiện thời. void setLoopCount(int loopCount) Thiết lập giá trị xác định cho thuộc tính loopCount của đối tượng Alpha hiện thời.Lập trình đồ họa trên Java 2D và 3D decreasingAlphaRampDuration của đối Alpha tượng hiện thời.chỉ định sử dụng giai đoạn 3 và 4 DECREASING_ENABLE .

Hình 5-8. hiệu chỉnh đối tượng đích dựa trên các giá trị này rồi xác lập lại cơ chế kích hoạt để “đánh thức” khung ảnh tiếp theo (trừ phi đối tượng Alpha kết thúc hoạt động). Hình 5-8 biểu diễn mối quan hệ của các lớp Interpolator cơ sở (ô sáng màu) trong Java 3D cùng các gói tiện ích (ô sẫm màu). Có khoảng hơn 10 lớp con Interpolator cơ bản. kế thừa lớp hành vi Behavior để cung cấp các phương thức chung cho các lớp con nội suy. Biểu đồ phân cấp lớp đối tượng Interpolator cơ sở trong Java 3D và các tiện ích Mỗi đối tượng nội suy Interpolator là một đối tượng hành vi Behavior tùy biến có cơ chế kích hoạt để “đánh thức” mỗi khung ảnh. 1] dựa trên giá trị atTime và đối số time-to-Alpha được thiết lập cho đối tượng Alpha đang xét. Các lớp hành vi Interpolator : Interpolator là một lớp trừu tượng. Một http://tailieuhay. đối tượng Interpolator kiểm tra giá trị của đối tượng Alpha liên hợp với nó.Lập trình đồ họa trên Java 2D và 3D float value() Trả về một giá trị nằm trong đoạn [0.com 489 . 1] dựa trên thời gian hiện thời và đối số time-to-Alpha được thiết lập cho đối tượng Alpha đang xét. float value(long atTime) Trả về một giá trị nằm trong đoạn [0. Trong phương thức processStimulus.

không hề có quá trình nội suy. đối tượng Interpolator kiểm tra giá trị Alpha của đối tượng Alpha liên hợp với nó rồi tạo ra các hiệu chỉnh quay thích hợp cho đối tượng đích TransformGroup của nó. Đối tượng SwitchValueInterpolator lựa chọn một nút con trong nhóm các nút đích Switch. nên trong lớp này. thì giá trị kia sẽ được sử dụng. Tuy rằng các lớp Interpolator rất giống nhau. Ví dụ. chúng cũng mang một vài chi tiết khác nhau dễ nhận ra. chúng ta lần lượt sẽ đi sâu hơn về 7 lớp này. dựa trên giá trị Alpha rồi sử dụng kết quả để điều chỉnh đối tượng đích. Nếu giá trị Alpha nằm trong khoảng từ 0 đến 1. Trong các phần sau. Bảng sau so sánh các đặc điểm khác nhau của 7 lớp Interpolator cơ bản. Mô tả chung chung về các đối tượng Interpolator như vậy không đúng lắm với các lớp SwitchValueInterpolator và PathInterpolator.Lập trình đồ họa trên Java 2D và 3D vài phương thức này được cung cấp bởi lớp trừu tượng Interpolator .com một đối tượng lớp trừu tượng TransformGroup thay đổi vị trí TransformGroup của đối tượng thay đổi chuyển TransformGroup 5-20 5-14 5-15 490 . nếu giá trị Alpha là 1. còn hầu hết các hành vi còn lại được cài đặt trong mỗi lớp Interpolator đơn lẻ. đối tượng nội suy RotationInterpolator lưu trữ hai góc là giới hạn quay do nó điều khiển. Với mỗi khung ảnh. lớp Interpolator ColorInterpolator chức năng thay đổi kiểu đối tượng đích màu Material Trang 5-12 khuyếch tán của PathInterpolator PositionInterpolator RotationInterpolator http://tailieuhay. Nếu giá trị Alpha là 0 thì một trong hai giá trị sẽ được sử dụng. Mỗi đối tượng Interpolator chứa 2 giá trị được sử dụng như các điểm giới hạn cho các hành động được nội suy. đối tượng Interpolator sẽ nội suy tuyến tính giữa hai giá trị.

và đối tượng trực quan được tạo ra bởi các đối tượng PositionInterpolator. RotationInterpolator. Trong chương trình này. độ lớn. Các thay đổi về vị trí. và SwitchValueInterpolator tương ứng. http://tailieuhay. nên không có đối tượng đích. mỗi đối tượng Interpolator được điều khiển bởi một đối tượng Alpha đơn. Tuy nhiên.Lập trình đồ họa trên Java 2D và 3D động quay (hướng) của đối ScaleInterpolator tượng thay đổi kích cỡ TransformGroup 5-16 5-17 của đối tượng SwitchValueInterpolator lựa chọn một Switch thay đổi (switch) trong một bộ các đối tượng TransparencyInterpolator thay đổi mức độ TransparencyAttributes 5-19 trong suốt của đối tượng Bảng 5-1. ColorInterpolator. Tóm tắt các lớp Interpolator cơ bản Chú ý: PathInterpolator là một lớp trừu tượng.java (chi tiết ở phần phụ lục). ScaleInterpolator.com 491 . quay. hãy xem ví dụ InterpolatorApp. bất cứ lớp nào thừa kế lớp này đều có đối tượng đích thuộc kiểu Transformation. độ trong suốt. màu sắc. TransparencyInterpolator. Để hiểu thêm hiệu ứng của các Interpolator này.

import com.j3d.j3d.applet.java Mã của chương trình Interpolator.sun.utils.j3d.utils. InterpolatorApp. import java.utils.universe.media.java package Animation.applet.BorderLayout.com 492 . http://tailieuhay. import javax.*.ColorCube.Applet.Frame.awt.Lập trình đồ họa trên Java 2D và 3D Hình 5-9.awt. import java. import com. import com.*.j3d. import java.geometry.sun.MainFrame.sun.

Point3f(xScale* 0.vecmath.0f)). boolean createNormals.35f. 2. QuadArray carGeom = null.com 493 .10f.*.22f. Point3f(xScale* 0. = new QuadArray(16. carGeom. 0. 0.Lập trình đồ họa trên Java 2D và 3D import javax. http://tailieuhay. if (createNormals) carGeom GeometryArray. 0.0f)).COORDINATES). else carGeom GeometryArray. yScale*0. yScale*0. 1.setCoordinate( carGeom.22f. // InterpolatorApp renders an public class InterpolatorApp extends Applet { Shape3D createCar(float xScale.20f.COORDINATES | GeometryArray. yScale*0.25f.NORMALS).setCoordinate( 0. new new new = new QuadArray(16.0f)). boolean assignColoring) { Shape3D car = new Shape3D(). Point3f(xScale*-0.setCoordinate( carGeom. float yScale.

0.setCoordinate( 3. carGeom.00f.com 494 . Point3f(xScale* 0.0f)). 0. yScale*0. yScale*0. carGeom. Point3f(xScale* 0. Point3f(xScale*-0. carGeom. yScale*0.0f)).0f)).20f.23f.setCoordinate( carGeom.00f. 0.0f)).0f)).20f. 0.00f. yScale*0. 9. http://tailieuhay. 6. Point3f(xScale* 0.0f)).18f. Point3f(xScale*-0. new new new new new new new new new new new new new Point3f(xScale*-0. carGeom.setCoordinate(11.28f. 0.setCoordinate(14. Point3f(xScale*-0.0f)).10f. yScale*0. 5.26f.setCoordinate( carGeom.12f.10f. 7.Lập trình đồ họa trên Java 2D và 3D carGeom.25f. 0.12f.35f.45f. if (createNormals){ int i.00f.setCoordinate(15.setCoordinate( carGeom.50f. yScale*0.setCoordinate(13. 0.0f)). carGeom.48f.16f. yScale*0. Point3f(xScale*-0.50f. yScale*0. 4.12f. 0.setCoordinate(10.setCoordinate(12. yScale*0. Point3f(xScale*-0. 0.setCoordinate( carGeom. Point3f(xScale*-0.0f)).33f.setCoordinate( carGeom. yScale*0. 0. yScale*0. 8. yScale*0. yScale*0. Point3f(xScale* 0.setCoordinate( carGeom. 0.20f. Point3f(xScale* 0.0f)). carGeom.0f)).0f)). 0.12f.35f. 0. Point3f(xScale* 0.0f)).

setAppearance(carAppear). } car. normal).setNormal(i. 0.6f. i <16.0f. for(i = 0.8f).com 495 . Transform3D t3d = new Transform3D().setNormal(i. normal). } public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). 1. 0. 0. i++) carGeom.5f. car. 0. ColoringAttributes. for(i = 8.setGeometry(carGeom). Appearance Appearance(). i < 8.set(new Vector3f(0.0f.5f. return car. carAppear. } if (assignColoring){ ColoringAttributes colorAttrib = new ColoringAttributes(0.Lập trình đồ họa trên Java 2D và 3D Vector3f normal = new Vector3f(0.0f.NICEST).5f)).6f. 0. i++) carGeom. carAppear = new http://tailieuhay.setColoringAttributes(color Attrib). normal.

objColor. objMove.ALLOW_COM PONENT_WRITE). objRotate. objScale.setCapability(TransformGroup.com 496 . // create target TransformGroup with Capabilities TransformGroup TransformGroup().AL LOW_TRANSFORM_WRITE). create target Material with objScale = new objRotate = new objMove = new bounds = new http://tailieuhay.setCapability(TransformGroup.setCapability(TransformGroup.Lập trình đồ họa trên Java 2D và 3D BoundingSphere BoundingSphere().ALLO W_TRANSFORM_WRITE).ALL OW_TRANSFORM_WRITE). // create target TransformGroup with Capabilities TransformGroup TransformGroup(). // create target TransformGroup with Capabilities TransformGroup TransformGroup(). // Capabilities Material objColor = new Material().setCapability(Material.

DECREASING_ENABLE.setTransparencyMode(Transparenc yAttributes. 1000. 2000. // create rotation interpolator http://tailieuhay.BLENDED). posInt. objTransp. // create position interpolator PositionInterpolator posInt = new PositionInterpolator (alpha. 0. posInt. objMove). objSwitch. 2000. objTransp.Lập trình đồ họa trên Java 2D và 3D // create target Transparency with Capabilities TransparencyAttributes objTransp = new TransparencyAttributes(). 0. // create target Switch with Capabilities Switch objSwitch = new Switch(). 0. 0.0f). 1000). // create Alpha Alpha alpha = new Alpha (-1.ALLOW_VALUE_WRITE).setStartPosition(-1.setSchedulingBounds(bounds).com 497 .ALLOW_SWIT CH_WRITE).setCapability(TransparencyAttri butes.INCREASING _ENABLE + Alpha. Alpha.setCapability(Switch.

0f)).Lập trình đồ họa trên Java 2D và 3D RotationInterpolator rotInt = new RotationInterpolator (alpha. objTransp). scaInt.0f)).setSchedulingBounds(bounds). // create color interpolator ColorInterpolator colInt = new ColorInterpolator (alpha. colInt.0f.setSchedulingBounds(bounds). // create transparency interpolator TransparencyInterpolator traInt = new TransparencyInterpolator (alpha.setSchedulingBounds(bounds).0f. 0. rotInt. objSwitch).setSchedulingBounds(bounds). // create scale interpolator ScaleInterpolator scaInt = new ScaleInterpolator (alpha. traInt. objScale).0f.setEndColor(new Color3f(0. swiInt. 0.com 498 . // create switch value interpolator SwitchValueInterpolator swiInt = new SwitchValueInterpolator (alpha.setStartColor(new Color3f(1. http://tailieuhay. colInt. 1. 0.0f. objRotate). objColor).setSchedulingBounds(bounds). colInt.

true)).setTranslation(new Vector3f(0.addChild(createCar(0.setTranslation(new Vector3f(0.addChild(objMove).4f. objScalePos = new objRotPos = new objMovePos = new http://tailieuhay. TransformGroup TransformGroup(t3d). objRoot.4f.addChild(rotInt). objRoot.addChild(scaInt).addChild(objScale).0f)). objMovePos. false. 0. objScalePos. t3d.4f. 0.addChild(objScalePos).addChild(objMovePos).setTranslation(new Vector3f(0.2f.0f. 0. objRoot. objRotate.addChild(posInt).4f.addChild(createCar(0. 0.com 499 . true)). 0.4f.addChild(objRotPos). TransformGroup TransformGroup(t3d). objRotPos. false.5f.0f)). objRoot. t3d. 0.addChild(objRotate). objMove. 0.4f. TransformGroup TransformGroup(t3d). objScale.0f)). objRoot. 0.Lập trình đồ họa trên Java 2D và 3D t3d.8f.0f. objRoot. false. 0. true)).0f.addChild(createCar(0.

-0. Shape3D transpCar = createCar(0. TransformGroup TransformGroup(t3d).4f.setTranslation(new Vector3f(0. TransformGroup TransformGroup(t3d).addChild(transpCar).4f.0f)).addChild(objTranspPos). colorCar. 0.addChild(colInt). objColorPos. Appearance Appearance(). true.com 500 .4f.setAppearance(materialAppear). objRoot. -0.addChild(traInt).setMaterial(objColor). objTranspPos. materialAppear.2f. objRoot.5f. 0.0f)).4f. objRoot. 0. transpAppear.getAppearance(). false.addChild(colorCar).0f. 0.addChild(objColorPos). objRoot.setTranslation(new Vector3f(0.0f. false). transpAppear = objTranspPos = new materialAppear = new objColorPos = new http://tailieuhay. Shape3D colorCar = createCar(0.Lập trình đồ họa trên Java 2D và 3D t3d. Appearance transpCar.setTransparencyAttributes(ob jTransp). true). t3d.

Lập trình đồ họa trên Java 2D và 3D t3d.setTranslation(new Vector3f(0.0f, -0.8f, 0.0f)); TransformGroup TransformGroup(t3d); objRoot.addChild(objSwitchPos); objSwitch.addChild(createCar(0.4f, 0.4f, false, true));; objSwitch.addChild(new ColorCube(0.1f)); objSwitchPos.addChild(objSwitch); objRoot.addChild(swiInt); swiInt.setLastChildIndex(2);// since switch made after interpolator DirectionalLight DirectionalLight(); // lightD1.setDirection(new Vector3f(-0.7f,lightD1.setInfluencingBounds(bounds); objRoot.addChild(lightD1); Background background = new Background(); background.setColor(1.0f, 1.0f, 1.0f); background.setApplicationBounds(new BoundingSphere()); objRoot.addChild(background); // Let Java 3D perform optimizations on this scene graph. objRoot.compile(); 0.7f,0.0f)); lightD1 = new objSwitchPos = new

http://tailieuhay.com

501

Lập trình đồ họa trên Java 2D và 3D

return objRoot; } // end of CreateSceneGraph method of InterpolatorApp // Create a simple scene and attach it to the virtual universe public InterpolatorApp() { setLayout(new BorderLayout()); Canvas3D canvas3D = new Canvas3D(null); add("Center", canvas3D); BranchGroup scene = createSceneGraph(); // SimpleUniverse is a Convenience Utility class SimpleUniverse SimpleUniverse(canvas3D); // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. simpleU.getViewingPlatform().setNominalVi ewingTransform(); simpleU.addBranchGraph(scene); } // end of InterpolatorApp (constructor) simpleU = new

http://tailieuhay.com

502

Lập trình đồ họa trên Java 2D và 3D // // The following allows this to be run as an as well as an applet

application

public static void main(String[] args) { System.out.print("InterpolatorApp.java \n- a demonstration of using Interpolator "); System.out.println("objects to provide animation in a Java 3D scene."); System.out.println("This is a simple example progam from The Java 3D API Tutorial."); System.out.println("The Java 3D Tutorial is available on the web at:"); System.out.println("http://java.sun.com/p roducts/java-media/3D/collateral"); Frame frame = new MainFrame(new InterpolatorApp(), 256, 256); } // end of main (method of InterpolatorApp) } // end of class InterpolatorApp Những nhầm lẫn thường gặp khi lập trình với Interpolator Các đối tượng Interpolator là dẫn suất có quan hệ rất gần gũi với các đối tượng hành vi. Vì vậy, việc sử dụng các đối tượng Interpolator cũng sẽ phải đối mặt với các lỗi thường gặp như khi sử dụng các đối tượng hành vi. Thêm vào đó, cũng có các bẫy lỗi khác, chung cho các Interpolator và các bẫy lỗi riêng cho mỗi Interpolator . Một nhầm lẫn thường gặp gây ra bởi việc không nhận thấy rằng các đối tượng Interpolator thay đổi thường xuyên giá trị các đối tượng đích
http://tailieuhay.com 503

Lập trình đồ họa trên Java 2D và 3D của chúng. Người lập trình có thể nghĩ rằng đối tượng đích TransformGroup của đối tượng RotationInterpolator có thể được sử dụng để tịnh tiến đối tượng đó ngoài hoạt động quay mà đối tượng RotationInterpolator cung cấp. Điều này là hoàn toàn sai. Tập các biến đổi của đối tượng đích TransformGroup được ghi lại mỗi lần tại khung ảnh mà đối tượng Alpha hoạt động. Điều này cũng có nghĩa rằng: hai đối tượng Interpolator không thể có cùng một đối tượng đích. Một lỗi khác cũng hay xảy ra khi người lập trình quên không thiết lập các khả năng thích hợp cho đối tượng đích. Kết quả là gây ra lỗi runtime error. Core Interpolator API: Interpolator là một lớp trừu tượng, nó chỉ được sử dụng khi cần tạo một lớp con mới. Lớp Interpolator chỉ cung cấp duy nhất một hàm cho người sử dụng các lớp con của nó: void setAlpha(Alpha Alpha) Thiết lập đối tượng Alpha cho đối tượng Interpolator hiện hành . ColorInterpolator Đối tượng ColorInterpolator có đối tượng đích thuộc kiểu Material. Interpolator này cho phép thay đổi thành phần màu khuyếch tán của vật liệu đích. Khả năng này vừa là điểm mạnh lại cũng là điểm hạn chế của ColorInterpolator. Điểm mạnh thể hiện ở khả năng cho phép nhiều hơn một đối tượng trực quan dùng chung một đối tượng vật liệu Material. Vì vậy, một đối tượng ColorInterpolator cùng với một đối tượng đích Material có thể tác động tới nhiều đối tượng trực quan khác nhau. Hạn chế ở chỗ các đối tượng trực quan với chất liệu Material NodeComponent chỉ có thể nhìn thấy khi được chiếu sáng. Sự nhầm lẫn thường xảy ra ở đây chính là do sự phức tạp trong việc tạo độ bóng cho hình ảnh. Việc sử dụng ánh sáng trong đồ họa là khá rắc

http://tailieuhay.com

504

Lập trình đồ họa trên Java 2D và 3D rối, vì vậy nó được trình bày chi tiết trong một chương riêng, chương 6. Màu sắc của thực thể trực quan là sự kết hợp của 3 thành phần: phản xạ, khuyếch tán và màu xung quanh. ColorInterpolator chỉ thay đổi một trong 3 thành phần, đó chính là thành phần khuyếch tán. Một lỗi khác cũng hay xảy ra khi gắn đối tượng đích Material cho đối tượng Shape3D. Hình 5-10 biểu diễn một phần biểu đồ đồ thị khung cảnh của đối tượng ColorInterpolator với đối tượng đích Material NodeComponent.

Hình 5-10. Một phần biểu đồ đồ thị khung cảnh của đối tượng ColorInterpolator với đối tượng đích Material NodeComponent Lớp ColorInterpolator có dạng của phương thức get khác với các Interpolator khác. Phương thức get của ColorInterpolator không phải là phương thức không tham số. ColorInterpolator là một hành vi hiệu chỉnh màu khuyếch tán của đối tượng material đích bằng cách nội suy tuyến tính giữa một cặp màu cho trước, sử dụng giá trị sinh ra bởi đối tượng Alpha xác định. Lớp ColorInterpolator có các phương thức khởi tạo sau: ColorInterpolator(Alpha Alpha, Material target) Khởi tạo đối tượng Interpolator màu thường với đối tượng đích cho trước. Giá trị màu nội suy nằm trong khoảng từ màu đen tới màu trắng.

http://tailieuhay.com

505

Lập trình đồ họa trên Java 2D và 3D

ColorInterpolator(Alpha Alpha, Material target, Color3f startColor, Color3f endColor) Khởi tạo đối tượng Interpolator màu với đối tượng đích, màu bắt đầu, màu kết thúc cho trước. Các phương thức thường dùng khác: void setEndColor(Color3f color) Thiết lập thuộc tính endColor cho đối tượng Interpolator hiện thời. Phương thức get tương ứng: void getEndColor(Color3f color) void setStartColor(Color3f color) Thiết lập thuộc tính startColor cho đối tượng Interpolator hiện thời. Phương thức get tương ứng: void getStartColor(Color3f color) void setTarget(Material target) Thiết lập đối tượng thành phần chất liệu (material) đích cho Interpolator hiện thời Phương thức get tương ứng: Material getTarget() PositionInterpolator Đối tượng PositionInterpolator thay đổi vị trí của đối tượng trực quan theo một trục tọa độ. Hai điểm dừng sử dụng cho phép nội suy được cho dưới dạng hai giá trị thực dấu phảy động cùng trục tọa độ tịnh tiến. Trục tịnh tiến mặc định là trục x. Các phương thức khởi tạo: PositionInterpolator(Alpha Alpha, TransformGroup target) Khởi tạo đối tượng nội suy vị trí Interpolator thường với đối tượng đích cho trước, trục tịnh tiến mặc định là x, vị trí bắt đầu startPosition là 0.0f, vị trí kết thúc endPosition là 1.0f. PositionInterpolator(Alpha Alpha, TransformGroup target,
http://tailieuhay.com 506

Lập trình đồ họa trên Java 2D và 3D Transform3D axisOfTranslation, float startPosion, float endPosition) Khởi tạo đối tượng Interpolator vị trí biến đổi thành phần tịnh tiến của đối tượng TransformGroup đích theo một trục tịnh tiến nhất định. Các phương thức khác: void setAxisOfTranslation(Transform3D axisOfTranslation) Thiết lập trục tịnh tiến cho đối tượng Interpolator hiện thời. void setEndPosition(float position) Thiết lập vị trí kết thúc endPosition cho đối tượng Interpolator hiện thời. void setStartPosition(float position) Thiết lập vị trí bắt đầu startPosition cho đối tượng Interpolator hiện thời. RotationInterpolator Đối tượng RotationInterpolator biến đổi hướng quay của đối tượng trực quan xung quanh một trục. Hai điểm sử dụng trong phép nội suy được cho dưới dạng hai giá trị góc dấu phảy động và trục quay. Giá trị nội suy sẽ được sử dụng để sinh chuyển động quay quanh trục quay. Trục quay mặc định là trục y dương. Các phương thức khởi tạo: RotationInterpolator(Alpha Alpha, TransformGroup target) Khởi tạo đối tượng nội suy quay Interpolator thường với đối tượng đích cho trước, sử dụng trục quay mặc định (+Y), góc nhỏ nhất là 0.0f, góc lớn nhất là 2*pi radian. RotationInterpolator(Alpha Alpha, TransformGroup target, Transform3D axisOfRotation, float minimumAngle, float maximumAngle) Khởi tạo đối tượng Interpolator biến đổi thành phần quay của một đối tượng transform đích.
http://tailieuhay.com 507

Lập trình đồ họa trên Java 2D và 3D Các phương thức khác: void setAxisOfRotation(Transform3D axisOfRotation) Thiết lập trục quay cho đối tượng Interpolator hiện thời. void setMaximumAngle(float angle) Thiết lập giá trị góc lớn nhất maximumAngle theo radian cho đối tượng Interpolator hiện thời. void setMinimumAngle(float angle) Thiết lập giá trị góc nhỏ nhất minimumAngle theo radian cho đối tượng Interpolator hiện thời. void setTarget(TransformGroup target) Thiết lập nút TransformGroup đích cho đối tượng Interpolator hiện thời. ScaleInterpolator Lớp ScaleInterpolator định nghĩa một hành vi biến đổi thành phần tỉ lệ kích thước (giữ nguyên các tính chất khác) của đối tượng TransformGroup đích bằng cách nội suy tuyến tính giữa một cặp giá trị tỉ lệ cho trước (sử dụng giá trị của đối tượng Alpha xác định). Giá trị tỉ lệ nội suy được sử dụng để sinh ra biến đổi tỉ lệ trong hệ tọa độ địa phương của đối tượng Interpolator hiện thời. Các phương thức khởi tạo: ScaleInterpolator(Alpha Alpha, TransformGroup target) Khởi tạo đối tượng nội suy tỉ lệ biến đổi nút TransformGroup đích giữa hai giá trị Alpha xác định, sử dụng đối tượng Alpha và một ma trận đồng nhất cho trước, với tỉ lệ phóng bé nhất minimum scale = 0.1f và tỉ lệ phóng lớn nhất maximum scale = 1.0f. ScaleInterpolator(Alpha Alpha, TransformGroup target, Transform3D axisOfScale, float minimumScale, float maximumScale)

http://tailieuhay.com

508

Lập trình đồ họa trên Java 2D và 3D Khởi tạo đối tượng scaleInterpolator biến đổi thành phần tỉ lệ nút TransformGroup đích giữa hai giá trị tỉ lệ (minimumScale và MaximumScale). Các phương thức khác: void setAxisOfScale(Transform3D axisOfScale) Thiết lập biến đổi AxisOfScale cho đối tượng nội suy Interpolator hiện thời. void setMaximumScale(float scale) Thiết lập tỉ lệ phóng lớn nhất maximumScale cho đối tượng Interpolator hiện thời. void setMinimumScale(float scale) Thiết lập tỉ lệ phóng nhỏ nhất minimumScale cho đối tượng Interpolator hiện thời. void setTarget(TransformGroup target) Thiết lập đối tượng TransformGroup cho đối tượng Interpolator hiện thời. SwitchValueInterpolator Đối tượng SwitchValueInterpolator không nội suy giữa các giá trị như các đối tượng Interpolator khác. Nó chỉ lựa chọn một trong các con của đối tượng Switch. Giá trị ngưỡng để chuyển tới một con khác được xác định bằng cách chia đoạn [0.0, 1.0] cho số con mà đối tượng Switch có. Chú ý rằng, đối tượng Interpolator không tự động cập nhật khi số con của đối tượng Switch thay đổi. Các giá trị chuyển đổi (switching value) được xác định ngay khi tạo đối tượng SwitchValueInterpolator. Nên nếu ban đầu đối tượng Switch không có con, hoặc khi số con của nó thay đổi sau khi đối tượng Interpolator đã được tạo thì số các con trong đối tượng Interpolator phải được cập nhật. Điểm thuận lợi khi sử dụng đối tượng này là người lập trình có thể xác định một tập con các chỉ mục

http://tailieuhay.com

509

Lập trình đồ họa trên Java 2D và 3D để đối tượng Interpolator sử dụng. Tập con này bị giới hạn bởi tập các chỉ mục tuần tự. Các phương thức khởi tạo: SwitchValueInterpolator(Alpha Alpha, Switch target) Khởi tạo đối tượng hành vi SwitchValueInterpolator biến đổi chỉ mục con của nút Switch đích trong khoảng từ 0 đến n-1, trong đó, n là số con của nút Switch đích. SwitchValueInterpolator(Alpha Alpha, Switch target, int firstChildIndex, int lastChildIndex) Khởi tạo đối tượng hành vi SwitchValueInterpolator biến đổi chỉ mục con của nút Switch đích giữa hai giá trị firstChildIndex và lastChildIndex cho trước. Các phương thức khác: void setFirstChildIndex(int firstIndex) Thiết lập chỉ mục con đầu tiên firstChildIndex của đối tượng Interpolator hiện thời. void setLastChildIndex(int lastIndex) Thiết lập chỉ mục con cuối lastChildIndex của đối tượng Interpolator hiện thời. void setTarget(Switch target) Thiết lập đối tượng Switch đích cho đối tượng Interpolator hiện thời. Trong các tham số của phương thức khởi tạo SwitchValueInterpolator có đối tượng Switch. Vậy Switch là gì? Switch Lớp Switch kế thừa từ lớp Group và là cha của 0 hay nhiều nhánh con đồ thị khung cảnh. Đối tượng Switch lựa chọn một trong các con của nó để biểu diễn. Nó định nghĩa một giá trị lựa chọn (switch value) có thể

http://tailieuhay.com

510

Lập trình đồ họa trên Java 2D và 3D chọn 1 hoặc chọn 0 hay nhiều con của nó và nhờ sử dụng một mặt nạ để xác định xem con nào được biểu diễn. Đối tượng Switch có thể sử dụng độc lập không cần đối tượng Interpolator hay LOD . Các phương thức khởi tạo: Switch() Khởi tạo một nút Switch với các tham số mặc định. Switch(int whichChild) Khởi tạo và gán giá trị ban đầu cho một nút Switch sử dụng chỉ mục lựa chọn con thích hợp. CHILD_ALL CHILD_MASK chọn con thích hợp CHILD_NONE - không có con nào được biểu diễn Switch(int whichChild, java.util.BitSet childMask) Khởi tạo và gán giá trị đầu cho một nút Switch sử dụng chỉ mục lựa chọn và mặt nạ cho trước. Các phương thức khác: void setChildMask(java.util.BitSet childMask) Thiết lập mặt nạ lựa chọn con. void setWhichChild(int child) Thiết lập chỉ mục lựa chọn con xác định con nào được biểu diễn. Khả năng có thể thiết lập cho Switch: ALLOW_SWITCH_READ | WRITE Chỉ định rằng nút Switch này cho phép đọc lựa chọn nút con, các giá trị mặt nạ và các con hiện thời của nó. TransparencyInterpolator Lớp TransparencyInterpolator định nghĩa đối tượng hành vi biến đổi mức độ trong suốt của đối tượng đích thuộc lớp TransparencyAttributes - chỉ thị tất cả các con được biểu diễn - sử dụng mặt nạ childMask (kiểu BitSet) để lựa

http://tailieuhay.com

511

float maximumTransparency) Khởi tạo đối tượng nội suy độ trong suốt biến đổi độ trong suốt chất liệu của đối tượng đích giữa hai giá trị minimumTransparency và maximumTransparency. Nhiều hơn một đối tượng trực quan có thể chia sẻ một đối tượng TransparencyAttributes. TransparencyAttributes target) Khởi tạo đối tượng nội suy độ trong suốt với đối tượng đích cho trước.0f. Các phương thức khác: void setMaximumTransparency(float transparency) Thiết lập giá trị maximumTransparency cho đối tượng Interpolator hiện thời. void setTarget(TransparencyAttributes target) Thiết lập đối tượng đích TransparencyAttributes cho đối tượng Interpolator hiện thời. void setMinimumTransparency(float transparency) Thiết lập giá trị minimumTransparency cho đối tượng Interpolator hiện thời. Các phương thức khởi tạo: TransparencyInterpolator(Alpha Alpha. vì vậy một đối tượng TransparencyAttributes có khả năng tác động cùng lúc đến nhiều đối tượng trực quan khác nhau.Lập trình đồ họa trên Java 2D và 3D bằng cách nội suy tuyến tính giữa một cặp giá trị độ trong suốt cho trước (sử dụng giá trị sinh bởi đối tượng Alpha cho trước). float minimumTransparency. TransparencyAttributes target. Chú ý rằng các chế độ trong suốt khác nhau có thể ảnh hưởng đến chất lượng biểu diễn và sự hiện diện của các đối tượng trực quan.com 512 . độ trong suốt tối thiểu là 0. http://tailieuhay. TransparencyInterpolator(Alpha Alpha.0f và tối đa là 1.

Phần giữa của hình ánh xạ vị trí của đối tượng trực quan với các giá trị Alpha từ 0.0.Với mỗi điểm mút thì có một giá trị tham số xác định làm đại diện. khi giá trị Alpha thay đổi. Giá trị các điểm này nằm trong khoảng từ 0. Các mút còn lại được lưu trữ theo trật tự giá trị tăng dần trong đối tượng nội suy đường. theo đó.0. được sử dụng theo từng cặp để nội suy. nó có thể chứa hai hay nhiều hơn hai giá trị để nội suy. Giá trị Alpha có vai trò xác định giá trị hai điểm nào sẽ được sử dụng. vừa nội suy vị trí. các điểm mút sẽ được sử dụng theo từng cặp kề nhau. và tỉ lệ thích hợp cho các đối tượng con của nó. đối tượng này thay đổi vị trí. Phía bên trái của hình 5-11 biểu diễn các giá trị điểm mút cho một đối tượng Path Interpolator nội suy vị trí. hoặc vừa nội suy vị trí. Path Interpolator cung cấp các khả năng nội suy vị trí (Position Interpolation). nội suy quay (Rotation Interpolation). vừa nội suy quay.com 513 .Lập trình đồ họa trên Java 2D và 3D Các lớp đối tượng nội suy đường: Path Interpolator (nội suy đường) khác với các lớp nội suy khác ở chỗ. Với mục đích minh họa. Các giá trị của một điểm mút là tương ứng với các giá trị tham số biến (ví dụ như vị trí hay góc quay) được sử dụng trong phép nội suy. Các điểm mút được xác định theo một trật tự. nội suy quay và nội suy tỉ lệ (Scale Interpolation). Đích của đối tượng nội suy là một đối tượng TransformGroup.0 tới 1. bao gồm cả hai đầu mút.0. hay các điểm mút.0 tới 1. Điểm mút có giá trị lớn nhất bằng hoặc nhỏ hơn giá trị Alpha và giá trị của điểm mút tiếp theo sẽ được sử dụng. còn điểm mút cuối cùng phải có giá trị là 1. Phía bên phải là các giá trị điểm mút được sử dụng tương ứng với các giá trị Alpha khác http://tailieuhay. hướng.0. tương ứng với khoảng giá trị của đối tượng Alpha. chúng tôi chỉ xét vị trí trong không gian 2 chiều. Điểm mút đầu tiên phải có giá trị là 0. Một đối tượng Path Interpolator chứa một tập các giá trị.

và mảng của các giá trị thiết lập 5. Kết hợp các giá trị điểm mút và tham số Alpha sẽ xác định hoạt ảnh.java sử dụng đối tượng RotPosPathInterpolator để tạo hoạt ảnh cho một khối hộp ColorCube qua một tập các giá trị vị trí và quay. Quan hệ giữa giá trị các điểm mút và giá trị Alpha cho vị trí trong không gian 2 chiều Ví dụ sử dụng PathInterpolator Sử dụng đối tượng nội suy đường tuân theo công thức sử dụng các đối tượng nội suy khác. Đối tượng RotPosPathInterpolator chứa tập các giá trị quay (mảng Quat4f). đối tượng đích.Lập trình đồ họa trên Java 2D và 3D nhau của ví dụ này. vị trí (mảng Point3f). thêm danh giới cho đối tượng nội suy 6. Công thức sử dụng có thể tóm tắt trong hình sau: 1. Sự khác biệt là ở số lượng biến được sử dụng để khởi tạo đối tượng nội suy đường. http://tailieuhay. Hình 5-11. tạo các mảng điểm mút và các giá trị khác 4. tạo đối tượng Alpha 3. tạo đối tượng nội suy đường tham chiếu đến đối tượng Alpha. thêm đối tượng nội suy đường vào đồ thị khung cảnh Hình 5-12. tạo đối tượng đích với khả năng thích hợp 2. Chi tiết của ví dụ này xin xem thêm phần phụ lục. và các giá trị điểm mút (mảng giá trị thực). Công thức sử dụng đối tượng nội suy đường Chương trình RotPosPathApp.com 514 .

0f. 0. Transform3D Transform3D().0f. axis = new axisOfRotPos = new target = new http://tailieuhay. quats[1] = new Quat4f(1.0f.0f. 1. 10000).0. 1.2f.0f. 0. 1.ALLOW _TRANSFORM_WRITE). 0.8f.0f. 0.0. AxisAngle4f AxisAngle4f(1. Point3f[] positions = new Point3f[9]. 0.0f.0f. 0.0. target.6f. axisOfRotPos.0f.3f. quats[0] = new Quat4f(0. 1.0f).0f).0f.9f. quats[2] = new Quat4f(0.0f).com 515 . float[] knots = {0. 0.Lập trình đồ họa trên Java 2D và 3D public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). 0. 0.1f. TransformGroup TransformGroup(). 0.0f. 0. 0.4f.0f). 0.set(axis). Alpha alpha = new Alpha(-1.0f}.setCapability(TransformGroup. Quat4f[] quats = new Quat4f[9].0f.0f.

0f. 1. positions[3]= new Point3f( -4. 0.0f. 1.0f).0f.0f). -5.0f.0f.0f. positions[5]= new Point3f( -6. 0. positions[4]= new Point3f( -2. positions[7]= new Point3f( -4. 1.0f.0f).0f). positions[8]= positions[0].0f. -1.0f). quats[6] = new Quat4f(1.0f.0f. 0. 1. 1. 1. -1.0f.com 516 . 1. quats[5] = new Quat4f(0. 0. 0. 0. positions[1]= new Point3f( -2.0f.0f.Lập trình đồ họa trên Java 2D và 3D quats[3] = new Quat4f(0. -3. positions[2]= new Point3f( -1.0f. 2.0f.0f).0f. positions[6]= new Point3f( -3.0f. quats[7] = new Quat4f(1. 0. 0. 0.0f).0f). positions[0]= new Point3f( -1. 0.0f. 2.0f).0f. 3.0f.0f.0f). 0. http://tailieuhay.0f.0f).0f. 0. quats[8] = quats[0]. 1.0f.0f. quats[4] = new Quat4f(0.0f.0f. 1.0f.0f.0f).0f.0f.0f). 0. -1. -7.

addChild(target). background.setColor(1.0f.addChild(rotPosPath). background. 1. points_coloring. quats.0f. rotPosPath. GeometryArray.0f. target.Lập trình đồ họa trên Java 2D và 3D RotPosPathInterpolator rotPosPath = new RotPosPathInterpolator( alpha. objRoot. objRoot.0f). 0.addChild(background).setCoordinates(0. points_appear = new http://tailieuhay. 1. objRoot. knots. ColoringAttributes points_coloring = new ColoringAttributes(). PointArray point_geom = new PointArray(9. positions). target.setApplicationBounds(new BoundingSphere()).4)). 0. axisOfRotPos. point_geom. positions).COORDINATES).0f).setColor(1.setSchedulingBounds(new BoundingSphere()). Appearance Appearance().com 517 . Background background = new Background().addChild(new ColorCube(0.0f.

return objRoot. PointAttributes points_points = new PointAttributes(4.addChild(points). http://tailieuhay. Hình 5-13 là một cảnh trong chương trình RotPosPathApp.Lập trình đồ họa trên Java 2D và 3D points_appear. nên trong hình.java để bạn đọc có hình dung sơ qua về cách sử dụng một đối tượng nội suy đường: RotPosPathInterpolator.setColoringAttributes(point s_coloring). Các bước thực hiện đã được đánh số từ 1-6 tương ứng với các bước trong công thức. chúng ta chỉ thấy có 8 điểm.compile(). } // end of CreateSceneGraph method of RotPosPathApp Đoạn mã trên được trích không toàn vẹn từ phương thức createSceneGraph trong chương trình RotPosPathApp. objRoot. points_appear). objRoot. Điểm đầu tiên được dùng 2 lần.setPointAttributes(points_p oints). true).com 518 .0f. với các điểm màu đỏ biểu diễn vị trí của 9 điểm mút. Shape3D points = new Shape3D(point_geom. points_appear.

khối hộp ColorCube di chuyển từ vị trí điểm mút này đến vị trí của điểm mút khác. còn có một cặp các lớp liên quan trong gói tiện ích. hoạt ảnh xuất hiện không tự nhiên chủ yếu là do sự kết hợp vị trí các điểm mút được chọn. Một cảnh trong chương trình RotPosPathApp Khi chương trình RotPosPathApp được thực hiện. thì ngay lập tức chuyển động của nó thay đổi để đến được điểm mút tiếp theo. lớp PathInterpolator có rất nhiều các lớp con khác nhau. Như đã nói bên trên. chuyển động của tất cả các vật đều có tính ì nhất định. Lớp TCBPathSplineInterpolator là một lớp tương tự với lớp PathInterpolator.com 519 . hoạt ảnh kết quả phụ thuộc vào sự kết hợp giữa các giá trị đối tượng nội suy với các tham số Alpha được sử dụng. đồng thời tự quay để đến được các điểm mút khác nhau. Trong chương trình RotPosPathApp. http://tailieuhay. Giống như tất cả các đối tượng nội suy khác.Lập trình đồ họa trên Java 2D và 3D Hình 5-13. Di chuyển như vậy không tự nhiên do trong thế giới thực. Ngoài các lớp con trong hạt nhân của Java 3D. Khi khối hộp ColorCube di chuyển đến mỗi vị trí điểm mút xác định. Lớp này có một lớp con nằm trong gói tiện ích (tham khảo hình 5-8 để hình dung được quan hệ giữa các lớp nội suy).

Đường cong này bắt chước chuyển động của đối tượng trong thế giới thực. Chương trình ví dụ.0. void setKnots(float [] knots) Thiết lập (thay thế) tất cả các điểm mút cho đối tượng Interpolator hiện thời.java. float knot) Thiết lập điểm mút tại chỉ mục xác định bởi index cho đối tượng Interpolator hiện thời. Điểm mút trung gian với chỉ mục k phải có giá trị lớn hơn giá trị của bất cứ điểm mút nào có chỉ mục nhỏ hơn k. PathInterpolator PathInterpolator là một lớp trừu tượng cung cấp giao diện và chức năng cơ bản cho các lớp con của nó. Tham số currentInterpolationValue được tính toán bằng cách nội suy tuyến tính trong chuỗi các điểm mút đã được định nghĩa trước (sử dụng giá trị sinh bởi đối tượng Alpha xác định). Các đối tượng PathInterpolator lưu trữ các giá trị điểm mút và tính toán chỉ mục của các giá trị này để sử dụng dựa trên giá trị Alpha và thời gian hiện thời (currentInterpolationValue). bạn đọc có thể tìm trong đĩa chương trình kèm theo. nhưng làm trơn đường đi của đối tượng thành một đường cong dựa trên vị trí các điểm mút.0 và điểm mút cuối cùng phải có giá trị là 1. Trong chuyển động này. SplineAnim.Lập trình đồ họa trên Java 2D và 3D TCBPathSplineInterpolator là một tiện ích cung cấp các hành vi và chức năng tương tự lớp PathInterpolator. http://tailieuhay.com 520 . Một số phương thức cung cấp bởi lớp PathInterpolator: int getArrayLengths() Trả về độ dài của mảng các điểm mút void setKnot(int index. đối tượng trực quan có thể không đi qua toàn bộ hoặc không hề đi qua bất cứ điểm mút nào. Điểm mút đầu tiên phải có giá trị là 0.

Chú ý rằng mỗi mảng tham số phải có cùng độ dài trong đối tượng khởi tạo hiện tại và các đối tượng PathInterpolator khác trong chương trình. Trong phương thức khởi tạo. Point3f[] positions) Khởi tạo đối tượng Interpolator mới biến đổi chuyển động quay và tịnh tiến của đối tượng đích TransformGroup. Transform3D axisOfRotPos. void setPosition(int index. void getQuats(Quat4f[] quats) Sao chép giá trị các quantenion của đối tượng Interpolator hiện thời vào mảng quats. tất cả các giá trị và đối tượng liên quan đều phải được xác định. RotPosPathInterpolator(Alpha Alpha. Một số phương thức cung cấp bởi lớp RotPosPathInterpolator: void getPositions(Point3f[] positions) Sao chép các giá trị vị trí của đối tượng Interpolator hiện thời vào mảng positions.Lập trình đồ họa trên Java 2D và 3D RotPosPathInterpolator RotPosPathInterpolator là một lớp đối tượng hành vi. void setAxisOfRotPos(Transform3D axisOfRotPos) Thiết lập trục của giát trị RotPos cho đối tượng Interpolator hiện thời. sử dụng giá trị sinh bởi đối tượng Alpha xác định. TransformGroup target. Quat4f[] quats. biến đổi thành phần quay và tịnh tiến của đối tượng đích thuộc lớp TransformGroup bằng cách nội suy tuyến tính giữa chuỗi các cặp điểm mút/vị trí và điểm mút/hướng. Mảng quats phải đủ lớn để chứa dữ liệu. Point3f position) http://tailieuhay. Mảng positions phải đủ lớn để chứa dữ liệu. Vị trí và hướng nội suy được sử dụng để sinh một dịch chuyển trong hệ tọa độ địa phương của đối tượng Interpolator này. float[] knots. Xét về mặt giao diện lập trình ứng dụng thì phương thức khởi tạo là quan trọng nhất đối với lớp đối tượng này.com 521 .

Billboard làm việc được với hình ảnh cây cối bởi cây cối có dạng gần giống nhau khi nhìn từ đằng trước. Lớp Billboard : Thuật ngữ “Billboard ” được sử dụng trong đồ họa máy tính để ám chỉ công nghệ quay tự động một đối tượng trực quan 2 chiều sao cho nó luôn đối mặt với người quan sát. Quat4f quat) Thiết lập quantenion tại chỉ mục xác định cho đối tượng Interpolator hiện thời. Sự phát sinh lớp hành vi Billboard xuất phát từ ý tưởng sử dụng các bề mặt đơn giản thay thế cho cho các hình khối phức tạp. void setQuat(int index. nó còn được dùng cho các mục đích khác. công nghệ Billboard được cài đặt bởi một lớp con của lớp hành vi Behavior. Nhưng nếu cái cây đó tự định hướng lại sao cho luôn đối mặt với người quan sát thì nó dường như có dạng 3 chiều. đằng sau hay từ bất cứ góc nhìn http://tailieuhay. void setTarget(TransformGroup target) Thiết lập đối tượng đích TransformGroup cho đối tượng Interpolator hiện thời. người ta vẫn hay dùng thuật ngữ “hành vi Billboard ” để chỉ công nghệ này.com 522 . ngoài ra. nếu cái cây chỉ giữ một hướng cố định thì khi góc nhìn thay đổi. Một ví dụ kinh điển sử dụng hành vi behavior là ứng dụng biểu diễn cây cối dưới dạng hình 2 chiều. vì vậy. Trong Java 3D. Tất nhiên. Hiệu quả của hiệu ứng này càng cao nếu cái cây đó nằm ở hình nền của khung cảnh hoặc là nằm ở phía đằng xa so với vị trí quan sát. ví dụ như làm cho dòng văn bản có thể được nhìn thấy từ mọi góc độ trong môi trường ảo. Hành vi Billboard thông thường được dùng cho mục đích này. người quan sát sẽ phát hiện ra hình dạng 2 chiều của cây.Lập trình đồ họa trên Java 2D và 3D Thiết lập vị trí tại chỉ mục xác định cho đối tượng Interpolator hiện thời.

Sử dụng đối tượng Billboard Việc sử dụng đối tượng Billboard tương tự việc sử dụng đối tượng Interpolator . tháp nước. ngoại trừ rằng không cần dùng đối tượng Alpha để điều khiển hoạt ảnh. Hình 5-14. nên nó rất thích hợp sử dụng cùng với ảnh 2 chiều để tạo đối tượng 3 chiều có dạng hình học đối xứng qua trục y như các tòa nhà hình trụ. hay bất kì đối tượng hình trụ nào. Đối tượng Billboard còn có thể sử dụng cho các đối tượng 3 chiều không có dạng đối xứng khi chúng được quan sát từ một khoảng cách đủ lớn để che dấu dạng 2 chiều. Hình 5-15 biểu diễn các bước sử dụng Billboard . Chi tiết việc lập trình sẽ được trình bày trong phần dưới đây. Biểu đồ đồ thị khung cảnh sử dụng đối tượng Billboard http://tailieuhay. Thông thường hai nút TransformGroup được sử dụng. Hoạt ảnh của đối tượng Billboard được điều khiển bởi vị trí tương đối của người quan sát trong thế giới ảo. Billboard làm cho đối tượng trực quan xuất hiện hoàn toàn giống nhau từ bất cứ góc nhìn nào. Nút TransformGroup phía dưới được dùng để định hướng đối tượng và được thao tác bởi đối tượng Billboard .com 523 .Lập trình đồ họa trên Java 2D và 3D nào. Hình 5-14 biểu diễn một phần của đồ thị khung cảnh được xây dựng để sử dụng nút Billboard . Nút TransformGroup phía trên được dùng để định vị trí đối tượng trực quan và có thể là tĩnh.

2 giới thiệu lớp OrientedShape3D để vượt qua giới hạn này. Có một giới hạn khi sử dụng lớp Billboard : trong các ứng dụng với nhiều hơn một quan sát. Nếu đối tượng đích không được thiết lập thuộc tính ALLOW_TRANSFORM_WRITE khi chương trình được thực thi sẽ phát sinh lỗi runtime. đối tượng TransformGroup này không thể sử dụng để định vị đối tượng trực quan. Nếu danh giới làm việc không được thiết lập hay thiết lập không chính xác thì đối tượng Billboard sẽ không điều khiển được đối tượng trực quan. Lỗi thứ nhất xảy ra do đối tượng đích TransformGroup thiết lập lại hoàn toàn giá trị của nó mỗi khi được cập nhật. đặc điểm này là một giới hạn lớn. Nếu dùng đối tượng đích để định vị.com 524 . Với một vài ứng dụng thì khả năng cung cấp của Billboard là đảm bảo. tuy nhiên. Công thức sử dụng đối tượng Billboard tạo hoạt ảnh Các lỗi thường gặp khi sử dụng Billboard Mặc dù việc sử dụng đối tượng Billboard không hề phức tạp. tạo đối tượng đích với khả năng ALLOW_TRANSFORM_WRITE 2. mỗi đối tượng Billboard chỉ điều khiển hoạt ảnh chính xác cho chỉ một quan sát. Java3D API phiên bản 1.Lập trình đồ họa trên Java 2D và 3D 1. thêm danh giới làm việc cho đối tượng Billboard 4. hiệu ứng Billboard vẫn hoạt động. thông tin vị trí của đối tượng đích sẽ bị mất và đối tượng trực quan sẽ được hiển thị tại vị trí ban đầu. nhưng cũng có hai lỗi lập trình thường gặp sau. Do đó. Danh giới làm việc thông thường được xác định bởi đối tượng BoundingSphere với phạm vi làm việc đủ lớn để bao gồm đối tượng trực quan. Đối tượng OrientedShape3D cung cấp các chức năng giống với chức năng của đối tượng Billboard http://tailieuhay. lắp ghép đồ thị Hình 5-15. tạo đối tượng Billboard tham chiếu đến đối tượng đích TransformGroup 3. trong lần cập nhật quay đầu tiên. còn với các ứng dụng khác.

Một đối tượng TransformGroup. Billboard quay quanh một trục hoặc một điểm. Giá trị của TGT không bị thay đổi trong thời gian thực thi của ứng dụng.Lập trình đồ họa trên Java 2D và 3D nhưng có thêm khả năng xử lý nhiều quan sát cùng một lúc. z) thì đơn giản Billboard không làm gì cả. public createSceneGraph(SimpleUniverse su) { // Create the root of the branch graph TransformGroup vpTrans = null. đơn giản chỉ dịch các cây thành tọa độ vị trí trong ứng dụng. 0. TGR. TGR là đối tượng đích của Billboard . Mặc dù cây cối trong chương trình này được tạo bởi các hình thô (hình tam giác phẳng) nhưng chúng không hề hiển thị như các đối tượng 2 chiều. Hai đối tượng TransformGroup được sử dụng cho mỗi cây trong ví dụ này. điều khiển hoạt động quay của cây.com 525 . Do Billboard hướng trục z+ của đối tượng đích về phía người quan sát nên nó không thể dùng để quay vật thể quanh trục z. Vì lý do này. BranchGroup http://tailieuhay. Vector3f translate = new Vector3f(). BranchGroup objRoot = new BranchGroup(). Chương trình ví dụ sử dụng Billboard Chương trình ví dụ BillboardApp tạo một thế giới ảo với cây cối sử dụng kĩ thuật Billboard . đối tượng Billboard điều khiển một đối tượng TransformGroup sao cho trục z dương của đối tượng TransformGroup và các con của nó luôn đối diện với người quan sát. nếu một trục quay của đối tượng được xác định là (0. Đối tượng TransformGroup thứ hai. Trong trường hợp sử dụng khác. TGT.

0f.0f.0f }.0f.0f. 0. 0.0f. SharedGroup share = new SharedGroup(). { }. 30. 0. TGR = new TransformGroup(). -10.setTranslation(translate).0f { 13. T3D.0f.0f. -13. 0. 0.set(position[i]). 23. 0. objRoot. bSphere = new -3.0f. 6.0f. Billboard billboard = null.addChild(createTree()).0f }. { 6.0f }.Lập trình đồ họa trên Java 2D và 3D Transform3D T3D = new Transform3D(). i++) { translate.addChild(createLand()). -30. 3. 0.0f } }. i < position. 0.com 526 .0f.0f.0f. TGT = new TransformGroup(T3D).0f.length.0f.0f }. -13. share. { { 13.0f }.0f. for (int i = 0.0f }. TransformGroup TGT = null. 0. BoundingSphere BoundingSphere(). { 6. http://tailieuhay. float[][] position = { { 0. { 3. TransformGroup TGR = null.0f.

setAlignmentMode(Billboard.3f.0f.setCapability(TransformGroup. keyNavBeh .0f). // billboard. background. TGT.Lập trình đồ họa trên Java 2D và 3D TGR.3f. 0.setColor(0.addChild(keyNavBeh).addChild(new Link(share)). 0.com 527 .0f).getViewingPlatform(). vpTrans. billboard. } vpTrans ). KeyNavigatorBehavior KeyNavigatorBehavior(vpTrans).setSchedulingBounds(bSphere).setTransform(T3D). Background background = new Background(). translate.0)). 1000. 1.ROTATE_ABOUT _POINT). 0. objRoot.set(0. objRoot.3f. billboard = new Billboard(TGR). TGR.addChild(billboard).getViewPlatformTransform( http://tailieuhay.setSchedulingBounds(new BoundingSphere(new Point3d().addChild(TGT). objRoot.setTranslation(translate).ALLOW_TRANSFORM_ WRITE).addChild(TGR). keyNavBeh = new = su. T3D.

http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D background. objRoot.addChild(background). Biểu đồ đồ thị sử dụng đối tượng Billboard BillboardApp.setApplicationBounds(new BoundingSphere()). } // end of mã CreateSceneGraph trên được trích từ method phương of thức BillboardAppĐoạn createSenceGraph của chương trình BillboardApp. Hình 5-16.compile().java trong Hình 5-17 hiển thị một cảnh sinh bởi chương trình ví dụ BillboardApp.java với các kí hiệu đánh dấu tương ứng với các bước thực hiện được liệt kê trong hình 5-15.com 528 . return objRoot. objRoot. // Let Java 3D perform optimizations on this scene graph.

4. Nên. Xin xem lại phần 4.Lập trình đồ họa trên Java 2D và 3D Hình 5-17. do đó. Một chế độ thay thế là quay đối tượng trực quan quanh một điểm.java cung cấp KeyNavigatorBehavior cho phép người dùng di chuyển xung quanh và quan sát các cây từ các vị trí và hướng nhìn khác nhau.com 529 . http://tailieuhay.2 của chương 4 để biết thêm chi tiết về lớp đối tượng này. đối tượng trực quan luôn được quan sát trực diện từ bất cứ vị trí quan sát nào. Trong chế độ này. Giao diện lập trình ứng dụng của Billboard (Billboard API) Trong ví dụ BillboardApp phía trên. hình ảnh 2 chiều được điều khiển quay quanh 1 điểm. Một ảnh của BillboardApp với tất cả “cây” 2 chiều đều hướng về phía người quan sát BillboardApp. đối tượng Billboard hoạt động với chế độ mặc định là quay đối tượng trực quan xung quanh trục y. dạng 2 chiều của nó sẽ bị lộ. Một ứng dụng dễ thấy là biểu diễn mặt trăng hay các vật thể hình cầu ở khoảng cách xa dưới dạng một hình tròn. nếu các cây trong ví dụ này được quan sát từ phía trên hay từ phía dưới.

Billboard (TransformGroup tg. Billboard (TransformGroup tg.Lập trình đồ họa trên Java 2D và 3D Các phương thức khởi tạo của Billboard Billboard Khởi tạo một Billboard Billboard (TransformGroup tg) Khởi tạo một đối tượng Billboard với các tham số mặc định hoạt động trên đối tượng TransformGroup xác định. Point3f point) Khởi tạo đối tượng Billboard với tâm quay và chế độ xác định. void setAlignmentMode(int mode) Thiết lập chế độ canh chỉnh. axis = (0. int mode. float y. 1. void setAlignmentAxis(float x. hoạt động trên đối tượng đích TransformGroup xác định. Một vài phương thức khác cung cấp bởi lớp Billboard : void setAlignmentAxis(Vector3f axis) Thiết lập trục canh chỉnh.com 530 () với tham số mặc định: mode = ROTATE_ABOUT_AXIS. Vector3f axis) Khởi tạo đối tượng Billboard với trục quay và chế độ hoạt động xác định điều khiển đối tượng TransformGroup xác định. int mode. float y. float z) Thiết lập trục canh chỉnh. 0).Chỉ định quay xung quanh một . trong đó mode có thể là ROTATE_ABOUT_AXIS trục xác định ROTATE_ABOUT_POINT . . float z) Thiết lập tâm quay http://tailieuhay.Chỉ định quay xung quanh một điểm xác định và chỉ định rằng trục Y của đối tượng con phải phù hợp với trục Y của đối tượng được quan sát void setRotationPoint(Point3f point) Thiết lập tâm quay void setRotationPoint(float x.

Vì lí do này nên trục quay không được song song với trục z. có nghĩa là. Đối tượng OrientedShape3D cũng yêu cầu sử dụng ít mã hơn.com 531 . OrientedShape3D Đối tượng OrientedShape3D được sử dụng để thực hiện các chức năng giống như đối tượng Billboard trong mục trước. nên không có ý nghĩa gì nếu quay vật thể quanh trục z. Trong cả hai trường hợp. Do OrientedShape3D hướng trục z+ của các vật thể về phía người quan sát. Nếu một trục song song với z được chỉ định. đối tượng OrientedShape3D tự định hướng bản thân nó sao cho trục z+ của các con của nó luôn đối diện với người quan sát. OrientedShape3D đơn giản sẽ không http://tailieuhay. Điểm khác biệt chủ yếu giữa hai lớp đối tượng như đã được nhắc đến ở phần trên là ở chỗ OrientedShape3D có khả năng làm việc với nhiều hơn một quan sát còn Billboard thì không. người lập trình cũng không cần quan tâm đến giới hạn hoạt động. OrientedShape3D không phải là một đối tượng hành vi do đó. 0. z) với bất cứ giá trị nào của z. Đối tượng OrientedShape3D quay xung quanh một trục hoặc một tâm. cũng như khả năng chia sẻ sử dụng chỉ có ở OrientedShape3D. Nguyên nhân duy nhất để không loại bỏ lớp Billboard khỏi Java3D API chính là khả năng tương thích ngược với các ứng dụng đang tồn tại. OrientedShape3D không hiệu chỉnh đối tượng đích TransformGroup. mà để mở khả năng này cho mã chương trình thực hiện.Lập trình đồ họa trên Java 2D và 3D void setTarget(TransformGroup tg) Thiết lập đối tượng đích TransformGroup cho đối tượng Billboard hiện thời. trục quay không được định nghĩa là (0. Với so sánh trên thì dễ thấy OrientedShape3D là sự lựa chọn hiển nhiên cho các ứng dụng dùng hiệu ứng Billboard .

thành phần xuất hiện. OrientedShape3D(Geometry geometry. Appearance appearance. chế độ và trục quay xác định. trong khi đó. Point3f point) Khởi tạo đối tượng OrientedShape3D với thành phần hình học. Appearance appearance. thành phần xuất hiện. chế độ và tâm quay xác định. Nếu chế độ biểu diễn được thiết lập là ROTATE_ABOUT_POINT thì vật thể sẽ quay xung quanh một điểm xác định. Trong trường hợp này. Giao diện lập trình ứng dụng của OrientedShape3D Giao diện lập trình ứng dụng của OrientedShape3D là tương tự với giao diện lập trình của lớp Billboard . Ví dụ như không có phương thức khởi tạo với chỉ một tham số Geometry. Sự khác biệt phát sinh chủ yếu do sự khác nhau về cấu trúc phân cấp lớp đối tượng. cũng có vài điểm khác biệt. Danh sách các phương thức khởi tạo của OrientedShape3D không nhiều như của lớp Shape. Không có giới hạn cho giá trị được sử dụng để làm tâm quay. Các phương thức khởi tạo: OrientedShape3D() Khởi tạo đối tượng OrientedShape3D với các tham số mặc định OrientedShape3D(Geometry geometry. ngoài ra.Lập trình đồ họa trên Java 2D và 3D làm gì cả. Lúc đó coi như là đối tượng TransformGroup được thiết lập ma trận đồng nhất. int mode. các phương thức khởi tạo không kế thừa lớp cơ sở. Một ứng dụng có thể sử dụng phương thức khởi tạo không tham số và một vài phương thức khác để tạo ra đối tượng OrientedShape3D cần thiết. Billboard lại kế thừa từ Behavior. OrientedShape3D kế thừa từ lớp Shape3D.com 532 . http://tailieuhay. Vector3f axis) Khởi tạo đối tượng OrientedShape3D với thành phần hình học. int mode.

public BranchGroup createSceneGraph(SimpleUniverse su) { 2.com . 533 http://tailieuhay. ALLOW_MODE_READ | WRITE Cho phép đọc (ghi) thông tin chế độ canh chỉnh. Xem chi tiết ở phần “Giao diện lập trình ứng dụng của Billboard ”. float y. Các khả năng có thể thiết lập cho OrientedShape3D: ALLOW_AXIS_READ | WRITE Cho phép đọc (ghi) thông tin trục canh chỉnh. float y.Lập trình đồ họa trên Java 2D và 3D Một số phương thức khác cung cấp bởi OrientedShape3D: void setAlignmentAxis(float x. Xét chương trình ví dụ OrientedShape3DApp. BranchGroup objRoot = new BranchGroup(). float z) void setRotationPoint(Point3f point) Các phương thức này có các tham số và chức năng giống với các phương thức cùng tên của Billboard . // Create the root of the branch graph 3. float z) void setAlignmentAxis(Vector3f axis) void setAlignmentMode(int mode) void setRotationPoint(float x. Ví dụ sử dụng OrientedShape3D Việc sử dụng OrientedShape3D rất dễ dàng. Mỗi cây là một con của một đối tượng OrientedShape3D. 1. ALLOW_POINT_READ | WRITE Cho phép đọc (ghi) thông tin tâm quay. đối tượng này tạo hiệu ứng Billboard cho cây.java. bất cứ chỗ nào sử dụng đối tượng Shape3D đều có thể thay thế đơn giản bằng đối tượng OrientedShape3D. Ứng dụng này tạo một phong cảnh ảo với các cây Billboard 2 chiều.

{ 1.0f. Transform3D T3D = new Transform3D().addGeometry(treeGeom). 16. i++){ 19.com 534 . http://tailieuhay. 23.0f. 8.setTranslation(translate). Có thể nhận thấy tính dễ dùng của OrientedShape3D so với Billboard . 9. 25. 11. for (int i = 0. 26.0f}. positionTG. OrientedShape3D orientedShape3D = null. 17. TransformGroup positionTG = null.0f}. 7. translate.0f. orientedShape3D. // for the positions in the array create a OS3D 18. 24. positionTG = new TransformGroup(T3D).length. 0. 27.Lập trình đồ họa trên Java 2D và 3D 4. 22. -2.set(position[i]). 12. 23. 28. 15. 14. 0.0f. orientedShape3D = new OrientedShape3D(). Vector3f translate = new Vector3f().0f. 21. 0. 6. //specify the position of the trees 13. -3.5f}}. 10. Geometry treeGeom = createTree(). {-13. 20. i < position. T3D. 5.addChild(positionTG).0f. } Đoạn mã trên được trích từ phương thức createSceneGraph của chương trình OrientedShape3DApp. float[][] position = {{ 0.java.addChild(orientedShape3D). objRoot.

Ứng dụng thường gặp của kĩ thuật này là thay đổi mức chi tiết của đối tượng dựa trên khoảng cách đối với người quan sát. hay mức độ chi tiết có thể được điều khiển với các thiết lập của người dùng. Con đầu tiên của đối tượng đích thông thường là đối tượng trực quan chi tiết nhất. Do vậy. Khi khoảng cách tới đối tượng trực quan càng tăng thì càng ít chi tiết của đối tượng đó được hiển thị. khi đó. tốc độ của vật thể.Lập trình đồ họa trên Java 2D và 3D Hoạt ảnh mức chi tiết (Level Of Detail Animations) Mức chi tiết (Level Of Detail – LOD ) là một thuật ngữ chỉ kĩ thuật biến đổi lượng chi tiết trong một đối tượng trực quan dựa trên một vài giá trị của thế giới ảo. con đầu tiên của đối tượng đích sẽ được sử dụng. việc lựa chọn con của đối tượng đích Switch được điều khiển bởi khoảng cách của đối tượng DistanceLOD đối với người quan sát. Đối tượng Switch là một nhóm đặc biệt bao gồm không. được tính bằng số khung hình / giây) để giữ tỉ lệ khung hình là thấp nhất.com 535 . Ngưỡng khoảng cách được xác định trong một mảng bắt đầu với khoảng cách xa nhất. Khi khoảng cách của đối tượng DistanceLOD đối với http://tailieuhay. Việc giảm bớt lượng chi tiết của đối tượng khi chúng ở khoảng cách xa so với người quan sát sẽ làm giảm khối lượng tính toán để tô trát. một hoặc nhiều hơn các con của chúng trong đồ thị khung cảnh được dùng để hiển thị. Mỗi đối tượng LOD có một hoặc nhiều hơn các đối tượng Switch đóng vai trò đối tượng đích. việc giảm độ phức tạp của đối tượng có thể không ảnh hưởng đến kết quả hiển thị. Lớp DistanceLOD cung cấp đối tượng hành vi LOD dựa trên khoảng cách của vật thể đối với người quan sát. dựa trên một tập các ngưỡng khoảng cách. Trong trường hợp sử dụng DistanceLOD. Một ứng dụng khác của LOD có thể là thay đổi lượng chi tiết dựa trên tốc độ tô trát (hay tốc độ hiển thị. Nếu kĩ thuật này được áp dụng tốt sẽ có thể tiết kiệm được đáng kể số lượng công thức tính toán mà vẫn không làm mất đi nội dung của vật thể.

Hoạt ảnh của đối tượng LOD được điều khiển bởi khoảng cách tương đối của nó đối với người quan sát trong thế giới ảo.com 536 . số lượng con của đối tượng đích là nhiều hơn số ngưỡng khoảng cách. Có nghĩa là các con của các đối tượng đích Switch có cùng chỉ mục sẽ được lựa chọn đồng thời.Lập trình đồ họa trên Java 2D và 3D người quan sát lớn hơn ngưỡng thứ nhất. Các ngưỡng khoảng cách sau phải lớn hơn ngưỡng khoảng cách trước và xác định khoảng cách mà con tiếp theo của đối tượng đích được sử dụng. ngoại trừ việc không có đối tượng Alpha nào cần sử dụng để điều khiển hoạt ảnh. Sử dụng đối tượng DistanceLOD cũng cần phải thiết lập các ngưỡng khoảng cách. tạo đối tượng DistanceLOD sử dụng mảng các ngưỡng khoảng cách 4. 1. tạo danh sách mảng các ngưỡng khoảng cách cho đối tượng DistanceLOD 3. Sử dụng đối tượng DistanceLOD Việc sử dụng đối tượng DistanceLOD tương tự việc sử dụng đối tượng nội suy Interpolator . tạo các đối tượng Switch đích với khả năng ALLOW_SWITCH_WRITE 2. Theo cách làm này. đối tượng trực quan phức tạp có thể được biểu diễn bởi nhiều đối tượng hình học là con của các đối tượng Switch khác nhau. thiết lập đối tượng Switch đích cho đối tượng DistanceLOD http://tailieuhay. việc sử dụng đối tượng DistanceLOD giống với việc sử dụng đối tượng Billboard . theo cách này. các đối tượng đích Switch sẽ được sử dụng song song. Do đó. con thứ hai của đối tượng switch sẽ được sử dụng. Nếu có nhiều hơn một đối tượng Switch được thêm vào với tư cách là đích của đối tượng LOD . Hình 5-18 biểu diễn các bước để sử dụng DistanceLOD.

nếu giới hạn hoạt động không được thiết lập. Lỗi thường xảy ra nhất là không gộp đối tượng Switch đích vào đồ thị khung cảnh. Công thức sử dụng DistanceLOD để tạo hoạt ảnh Các lỗi thường gặp khi sử dụng LOD Mặc dù việc sử dụng đối tượng LOD không phải là phức tạp. thiết lập giới hạn hoạt động cho đối tượng DistanceLOD 6. nhưng cũng có hai lỗi lập trình thường gặp sau. xin xem http://tailieuhay. “lắp ghép” đồ thị khung cảnh. Thiết lập đối tượng Switch là đích của đối tượng DistanceLOD không tự động gộp nó vào đồ thị khung cảnh. Ví dụ sử dụng DistanceLOD Đoạn mã sau được trích từ phương thức createSceneGraph trong chương trình DistanceLODApp. Chi tiết về chương trình này.Lập trình đồ họa trên Java 2D và 3D 5.com 537 . Còn nữa. Nếu chương trình có nhiều hơn một quan sát. nếu không gộp LOD vào đồ thị khung cảnh thì chương trình cũng sẽ không báo lỗi. LOD chỉ có thể điều khiển hoạt ảnh chính xác cho chỉ một trong số các quan sát đó. Có một giới hạn mà lớp LOD không vượt qua được chính là số lượng quan sát mà chương trình có thể làm việc được. Giới hạn hoạt động thông thường được quy định bởi một đối tượng BoundingSphere với bán kính đủ lớn để điều khiển được đối tượng trực quan. Tương tự như các đối tượng hành vi khác. Nếu khả năng ALLOW_SWITCH_WRITE không được thiết lập cho đối tượng Switch đích thì khi chương trình được thực thi sẽ phát sinh lỗi runtime. hoặc thiết lập không chính xác thì LOD không điều khiển được đối tượng trực quan. bao gồm cả việc thêm các con cho các đối tượng Switch Hình 5-18.

DECREASING_ENABLE.set(axisOfTra). 1000.Lập trình đồ họa trên Java 2D và 3D thêm phần phụ lục và đĩa chương trình kèm theo. Đoạn mã này đã được đánh số tương ứng với các bước trong công thức sử dụng ở hình 5-18. 5000.PI/-2.com .setCapability(TransformGroup. Alpha.0f.0f. objMove.1. 1000. 1000). public BranchGroup createSceneGraph() { BranchGroup objRoot = new BranchGroup().(float)Math.ALLO W_TRANSFORM_WRITE).INCREASING_ENABLE + Alpha. // specify the axis of translation AxisAngle4f axisOfTra = new AxisAngle4f(0. 0. // create position interpolator 538 bounds = new objMove = new http://tailieuhay. // create Alpha Alpha alpha = new Alpha (-1. // create target TransformGroup with Capabilities TransformGroup TransformGroup(). BoundingSphere BoundingSphere(). 1000. Transform3D axisT3D = new Transform3D(). 5000. 0. axisT3D.0f.0.0f).

8f. 0. 0.setColoringAttributes(spher eCAa). axisT3D.setColoringAttributes(spher eCAb). -35. Appearance Appearance().setColor(0. // create DistanceLOD target object Switch targetSwitch = new Switch(). sphereCAb.1f). ColoringAttributes ColoringAttributes().8f.setColor(0.0f.1f. sphereAppearA. sphereCAa.ALLOW_S WITCH_WRITE). 0. objMove.com 539 . 0.setCapability(Switch. sphereAppearB. targetSwitch.Lập trình đồ họa trên Java 2D và 3D PositionInterpolator posInt = new PositionInterpolator (alpha. ColoringAttributes ColoringAttributes(). posInt. // add visual objects of various levels of detail to the target switch Appearance Appearance(). sphereCAb = new sphereAppearB = new sphereCAa = new sphereAppearA = new http://tailieuhay. 0.0f).setSchedulingBounds(bounds).1f).1f.

0. 0. 0. 10. 4.out.numDistan ces()).numChildren()-1) != dLOD.40f.println("DistanceLOD not initialized properly").addChild(new Sphere(. sphereAppearB)). 25. System. dLOD.numDistances()){ System. sphereAppearA)). 10.Lập trình đồ họa trên Java 2D và 3D targetSwitch.addSwitch(targetSwitch). targetSwitch. if((targetSwitch.addChild(new Sphere(.0f. 15. new Point3f()). sphereAppearA)). targetSwitch.40f.out.n umChildren()).addChild(new Sphere(. // create DistanceLOD object float[] distances = { 5. dLOD.addChild(new Sphere(. System. sphereAppearB)).0f.setSchedulingBounds(bounds). } // assemble scene graph http://tailieuhay.40f. 20.println(dLOD.out. 0.println(targetSwitch. targetSwitch.com 540 .40f.0f}. DistanceLOD dLOD = new DistanceLOD(distances.

0f.0f. 0. sphereAppearB)). TransformGroup TransformGroup(t3d). objRoot. objRoot.// must add target switch to scene graph too // make // add // target // show a level 3 object up close for comparison Transform3D t3d = new Transform3D().40f.0f)).0f)).0f. 4. the bounds move with visual object objMove.addChild(new Sphere(.set(new Vector3f(0. tga.6f. t3d. // show a level 0 object at a distance for comparison t3d. TG of position interp to move vo objRoot.addChild(targetSwitch). tgb. sphereAppearA)). 0. tgb = new Vector3f(-5.addChild(objMove).addChild(new Sphere(.addChild(dLOD).addChild(tga).Lập trình đồ họa trên Java 2D và 3D objRoot. tga = new http://tailieuhay. 0. 0. TransformGroup TransformGroup(t3d). position interpolator objMove.set(new -35. 0.com 541 .40f. 25.addChild(posInt).addChild(tgb).

0f.Lập trình đồ họa trên Java 2D và 3D // a white background is better for printing images in tutorial Background background = new Background().0f). Chú ý rằng. background. Cả hai quan hệ này đều cần được xác lập. 1. objRoot.compile(). // Let Java 3D perform optimizations on this scene graph. } // end of CreateSceneGraph method of DistanceLODApp Hình 5-19 biểu diễn biểu đồ đồ thị khung cảnh được tạo ra trong ví dụ trên. return objRoot.setColor(1. background. http://tailieuhay. objRoot. 1.com 542 .0f.setApplicationBounds(new BoundingSphere()). đối tượng Switch đích vừa là con của đối tượng TransformGroup vừa được tham chiếu đến bởi đối tượng DistanceLOD.addChild(background).

Khối cầu dịch chuyển được biểu diễn bằng một đối tượng DistanceLOD với 4 khối cầu có độ phức tạp hình học khác nhau. Hai khối cầu này được hiển thị để làm mốc so sánh. Nếu không sử dụng các khối http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D Hình 5-19. Khi đối tượng DistanceLOD dịch chuyển ra xa người quan sát. Khối cầu lớn màu đỏ là khối cầu kém chi tiết nhất của đối tượng DistanceLOD và ở khoảng cách cực tiểu. Mỗi ảnh này có 2 khối cầu tĩnh và một khối cầu dịch chuyển (trong hình bên phải. Một phần biểu đồ đồ thị khung cảnh cho chương trình DistanceLODApp Hình 5-20 là hai cảnh được sinh từ chương trình DistanceLODApp.com 543 . đối tượng DistanceLOD được biểu diễn bởi các khối cầu có màu sắc khác nhau để minh họa quá trình chuyển đổi. nó sẽ chuyển đối tượng trực quan để hiển thị. Trong chương trình này. Một đối tượng nội suy vị trí PositionInterpolator được sử dụng để dịch chuyển đối tượng DistanceLOD theo hướng vuông góc với màn hình. Khối cầu nhỏ màu xanh là khối cầu chi tiết nhất được sử dụng bởi đối tượng DistanceLOD ở khoảng cách cực đại. khối cầu bên trái nhất đã bị che khuất).

Dựa vào khoảng cách thực từ người quan sát đến nút DistanceLOD. n giá trị khoảng cách [0. Một mảng n giá trị khoảng cách đơn điệu tăng. Giao diện lập trình ứng dụng DistanceLOD API DistanceLOD định nghĩa một nút đối tượng hành vi LOD dựa khoảng cách. n]. hoạt động trên một nút nhóm Switch để lựa chọn một trong số các con của nút Switch đó dựa vào khoảng cách của nút đối tượng LOD so với người quan sát. Nếu gọi khoảng cách từ người quan sát đến nút LOD thì phương trình để xác định mức chi tiết (con của nút Switch) được lựa chọn là: 0 nếu d <= distances[0] 1.Lập trình đồ họa trên Java 2D và 3D cầu có màu sắc khác nhau sẽ rất khó khăn để nhận biết khi nào thì đối tượng trực quan được chuyển. được xác định sao cho thành phần đầu tiên distances[0] tương ứng với mức chi tiết cao nhất và thành phần cuối cùng distances[n-1] tương ứng với mức chi tiết thấp nhất. Hai cảnh được sinh ra từ DistanceLODApp.com 544 . i 2. n-1] lựa chọn n+1 mức chi tiết [0. n nếu distances[i-1] < d <= distances[i] nếu d > distances[n-1] http://tailieuhay. Hình 5-20.

0. Tuy nhiên. Một số phương thức cung cấp bởi DistanceLOD: int numDistances() Trả về số lượng các ngưỡng khoảng cách. void setDistance(int whichDistance. Point3f position) Khởi tạo và khởi gán cho nút DistanceLOD với mảng các giá trị khoảng cách và vị trí xác định. Morph Các lớp nội suy thay đổi các thuộc tính trực quan khác nhau trong thế giới ảo. lớp Morph giống với các lớp nội suy. http://tailieuhay. nó còn không kế thừa lớp hành vi Behavior. Lớp Morph mở rộng từ lớp Node. Khả năng này do lớp Morph cung cấp. 0). Đối tượng Morph tạo hình dạng cho một đối tượng trực quan thông qua việc nội suy từ một tập các đối tượng GeometryArray. DistanceLOD(float[] distances. Các phương thức khởi tạo: DistanceLOD() Khởi tạo và khởi gán cho nút DistanceLOD giá trị mặc định. Morph không phải là lớp nội suy. DistanceLOD(float[] distances) Khởi tạo và gán giá trị ban đầu cho nút DistanceLOD với mảng các giá trị khoảng cách xác định và vị trí mặc định (0. thậm chí. không có lớp nội suy nào cung cấp các khả năng thay đổi hình dạng hình học của các đối tượng trực quan.Lập trình đồ họa trên Java 2D và 3D Chú ý rằng cả vị trí và mảng các giá trị khoảng cách đều được xác định trong hệ tọa độ địa phương của nút hiện thời. Tuy nhiên. Theo đặc điểm này. void setPosition(Point3f position) Thiết lập vị trí của nút LOD . double distance) Thiết lập ngưỡng khoảng cách LOD xác định.com 545 .

Chương trình ví dụ tạo hoạt ảnh cho bàn tay. biến một kìm tự tháp thành hình hộp. các ứng dụng Morph phải tự xây dựng lớp hành vi riêng. Sử dụng đối tượng Morph Để hiểu được cách sử dụng đối tượng Morph .java cũng có thể tìm thấy trong đĩa chương trình kèm theo. Hạn chế về số lượng đỉnh không phải là hạn chế lớn của Morph . trước hết. Chương trình ví dụ thứ 3. Hạn chế duy nhất là các đối tượng hình học sử dụng cho việc nội suy phải cùng thuộc một lớp và là lớp con của lớp GeometryArray.Lập trình đồ họa trên Java 2D và 3D Trong chương 4. Morph không quá phức tạp. chúng ta đã làm quen với phương thức processStimulus của đối tượng Behavior để thực hiện các thay đổi đối với đồ thị khung cảnh thực hay đối với các đối tượng trong đồ thị khung cảnh thực. hoặc biến đổi bất kì hình dạng hình học nào thành một dạng hình học khác. Đối tượng Morph cũng có thể được sử dụng để tạo hoạt ảnh cho các đối tượng trực quan (ví dụ: làm cho một người đi lại được. Các đối tượng GeometryArray có thể được coi như là các http://tailieuhay. hay làm cho bàn tay có thể cầm nắm được vật dụng…). bạn đọc có thể thấy chương trình Pyramid2Cube. với cùng số lượng các đỉnh. Đối tượng Morph lưu trữ một mảng các đối tượng GeometryArray với mỗi đối tượng định nghĩa đặc tả hình học hoàn chỉnh cho một đối tượng trực quan. làm cho một dạng hình que đi lại được sẽ được trình bày chi tiết trong phần sau. Do không có lớp hành vi chuyên biệt sử dụng với đối tượng Morph .java. Đối tượng Morph có thể được sử dụng để biến kim tự tháp thành hình khối hộp. Morphing. Lớp Morph được coi như một lớp hoạt ảnh hay lớp tương tác phụ thuộc vào sự mô phỏng hành vi tương tác với đối tượng Morph .com 546 . mèo thành chó. trong đĩa chương trình kèm theo. cần phải biết các thức đối tượng Morph làm việc.

Tất nhiên. sử dụng đối tượng Morph thường có nghĩa là viết một lớp hành vi. Do đó. Công thức sử dụng đối tượng Morph Như đã trình bày. Cách viết lớp hành vi đã được trình bày trong phần 4. tạo một mảng các đối tượng GeometryArray 2. tuy nhiên. lắp ghép đồ thị khung cảnh. …cung cấp bởi đối tượng GeometryArray. 1. Hoạt ảnh và tương tác được cung cấp thông qua một đối tượng hành vi. một đối tượng Morph còn có một mảng các trọng số. Ngoài mảng các đối tượng GeometryArray. nhưng nó sẽ không thể tạo ra được hoạt ảnh. Sử dụng các đối tượng GeometryArray cùng với các trọng số.com 547 .1. màu sắc. bao gồm cả việc thêm các con cho đối tượng đích Switch Hình 5-21. hay chính xác hơn. nên ở đây không nói chi tiết. các bước này đúng cho cả hoạt ảnh và tương tác.Lập trình đồ họa trên Java 2D và 3D khung ảnh chính trong hoạt ảnh. tạo một đối tượng Morph với khả năng ALLOW_WEIGHTS_WRITE 3. đây chính là các biến số trong phương trình. Ví dụ sử dụng Morph Chương trình Morph này sử dụng một đối tượng hành vi tùy chỉnh để sinh hoạt ảnh. http://tailieuhay. đối tượng Morph khởi tạo một đối tượng mảng hình học sử dụng giá trị trọng số trung bình của tọa độ. Bước đầu tiên trong quá trình phát triển sẽ là xây dựng lớp hành vi này. là các hằng số trong phương trình tính toán để tạo ra một đối tượng GeometryArray mới.2. Morph hoàn toàn có thể sử dụng mà không cần đối tượng hành vi. sử dụng đối tượng Morph không khó. Thay đổi các trọng số sẽ làm thay đổi hình dạng hình học.

} public void initialize(){ // set initial wakeup condition this. 0. 0}. Hoạt động này xảy ra tại mỗi khung ảnh được tô trát khi điều kiện kích hoạt đã được thỏa mãn. phương thức processStimlus thay đổi trọng số của đối tượng Morph . Trong ví dụ này processStimulus thiết lập các giá trị trọng số dựa vào giá trị Alpha của một đối tượng Alpha. Đoạn mã sau là đoạn mã xây dựng đối tượng hành vi tùy biến trong chương trình MorphApp.com 548 . Alpha alpha){ this.targetMorph = targetMorph. 0. private Alpha alpha. private WakeupCondition trigger = new WakeupOnElapsedFrames(0). // create MorphBehavior MorphBehavior(Morph targetMorph.alpha = alpha. // the following two members are here for effciency (no memory burn) private double[] weights = {0.wakeupOn(trigger). } http://tailieuhay. public class MorphBehavior extends Behavior{ private Morph targetMorph. this.Lập trình đồ họa trên Java 2D và 3D Trong đối tượng hành vi được sử dụng để tạo hoạt ảnh cho đối tượng Morph .

weights[1] = 0.setWeights(weights).com 549 .(double)alphaIndex.0. } } // end of class MorphBehavior = 1. targetMorph.0 weights[alphaIndex].value() .Lập trình đồ họa trên Java 2D và 3D public void processStimulus(Enumeration criteria){ // don't need to decode event since there is only one trigger // do what is necessary weights[0] = 0. weights[2] = 0.wakeupOn(trigger). int alphaIndex = (int) alphaValue. weights[alphaIndex] = (double) alphaValue . weights[3] = 0. // set next wakeup condition this. float alphaValue = 4f * alpha.0 - http://tailieuhay.00001f. else weights[0] weights[alphaIndex]. if(alphaIndex < 3) weights[alphaIndex + 1] = 1.

nhưng thực tế. Hình 5-22 biểu diễn các hình vẽ tay được sử dụng làm khung ảnh chính cho chương trình ví dụ.com 550 . Các đối tượng khung ảnh chính GeometryArray được tạo ra bởi một số phương thức khác. Sự khác nhau là ở thứ tự các đỉnh được xác định.java với các số đánh dấu các bước được chỉ ra trong hình 5-21. Hình 5-22. một đối tượng MorphBehavior. Trong phương thức này. Lớp này thích hợp cho tất cả các hoạt ảnh sử dụng 4 khung ảnh chính và có thể thay đổi dễ dàng để khớp với số lượng khung ảnh chính khác nhau. một đối tượng Alpha và một đối tượng Morph được tạo ra. Muốn xây dựng các khung ảnh đẹp hơn. mỗi cái được lặp lại một lần. có thể sử dụng các gói 3D.Lập trình đồ họa trên Java 2D và 3D Lớp MorphBehavior tạo khung hoạt ảnh chính bằng cách sử dụng các đối tượng GeometryArray hai lần tại một thời điểm theo một quá trình có tính tuần hoàn. mọi việc còn lại chỉ là tạo khung ảnh chính sử dụng cho hoạt ảnh. Đoạn mã sau được trích từ phương thức createSceneGraph của chương trình MorphApp. Các hình có màu đen trông giống như là hai khung hình chính. rồi được gộp vào đồ thị khung cảnh. Các hình khung ảnh chính của MorphApp với đường quỹ đạo của một đỉnh (đường mờ) public BranchGroup createSceneGraph() { http://tailieuhay. Toàn bộ chương trình có thể tìm thấy trong đĩa chương trình kèm theo. chúng là bốn khung hình chính riêng biệt. Với lớp hành vi tùy chỉnh vừa viết.

setCapability(Morph. Transform3D t3d = new Transform3D(). t3d.set(new Vector3f(0f. 0. // create alpha object Alpha alpha = new Alpha(-1. 0. alpha). geomArray[0] = createGeomArray0().5f.Lập trình đồ họa trên Java 2D và 3D // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(). -0. // create morph object Morph morphObj = new Morph(geomArray). geomArray[2] = createGeomArray2(). // create morph driving behavior MorphBehavior MorphBehavior(morphObj. 0f)). geomArray[1] = createGeomArray1(). TransformGroup TransformGroup(t3d). 1.ALLOW_WEIGHT S_WRITE). geomArray[3] = createGeomArray3().com 551 . 0. morphObj. // create GeometryArray[] (array of GeometryArray objects) GeometryArray[] GeometryArray[4]. 0. morphBehav = new geomArray = new translate = new http://tailieuhay. 0. 0). 2000. 100.

1f).addChild(translate). return objRoot.addChild(morphBehav). objRoot. background.compile(). Hình 5-23 biểu diễn một cảnh sinh ra bởi Morph3DApp. objRoot. và “Broken”.setApplicationBounds(new BoundingSphere()).com 552 .setSchedulingBounds(new BoundingSphere()). Chúng được gọi lần lượt (từ trái qua phải) là “In Place”. objRoot. background. 1f. 3 lớp hành vi khác nhau tạo hoạt ảnh dựa trên một số hoặc tất cả đối tượng GeometryArray của MorphApp.addChild(background).setColor(1f. // Let Java 3D perform optimizations on this scene graph. } MorphApp Một chú ý thú vị rút ra từ ví dụ trên là nhiều hoạt ảnh khác nhau có thể được tạo ra. Background background = new Background(). “Tango”.Lập trình đồ họa trên Java 2D và 3D morphBehav. Trong chương trình này. // end of CreateSceneGraph method of http://tailieuhay. sử dụng chính các khung hình chính được xây dựng ở trên.addChild(morphObj). //assemble scene graph objRoot. với các lớp hành vi khác nhau. translate.

Một số phương thức khác cung cấp bởi Morph : void setAppearance(Appearance appearance) Thiết lập thành phần hiển thị bề ngoài cho nút Morph . Một cảnh trong chương trình Morph3App Giao diện lập trình ứng dụng Morph API Các phương thức khởi tạo: Morph (GeometryArray[] geometryArrays) Khởi tạo và khởi gán giá trị cho đối tượng Morph với một mảng đối tượng GeometryArray xác định và một đối tượng null thuộc kiểu Appearance.com 553 .Lập trình đồ họa trên Java 2D và 3D Hình 5-23. Appearance appearance) Khởi tạo và khởi gán giá trị cho đối tượng Morph với một mảng đối tượng GeometryArray và một đối tượng Appearance xác định. void setAppearanceOverrideEnable(boolean flag) Thiết lập cờ để có nút lá AlternateAppearance làm bề ngoài hiển thị cho nút Morph . http://tailieuhay. void setGeometryArrays(GeometryArray[] geometryArrays) Thiết lập thành phần geometryArrays cho nút Morph . Morph (GeometryArray[] geometryArrays.

kể cả các hoạt ảnh sử dụng kĩ thuật Billboard . ALLOW_WEIGHTS_READ | WRITE Xác định rằng nút hiện thời cho phép đọc (ghi) vector trọng số Morph của nó. Java 3D API giới thiệu giao diện GeometryUpdater. sinh bóng mờ tự động hay các hiệu ứng đặc biệt như chớp… Do GeometryUpdater cho http://tailieuhay. Giao diện GeometryUpdater Trong các phần trên.com 554 . Giao diện GeometryUpdater có tính mềm dẻo cao. Với giao diện GeometryUpdater. Các khả năng có thể thiết lập cho Morph : ALLOW_APPEARANCE_READ | WRITE Xác định rằng nút hiện thời cho phép đọc (ghi) thông tin appearance của nó. giao diện này cùng với BY_REFERENCE geometry (chương 2) cho phép thay đổi hình dạng hình học trong thời gian thực thi chương trình. Ngoại trừ Morph tạo ra hình nội suy từ các hình cho trước. Các ứng dụng có thể sử dụng GeometryUpdater bao gồm các kĩ thuật hoạt ảnh chuẩn như kiến tạo các hệ động. các hệ phân tử. chứ không thay đổi hay tạo ra hình mới. người lập trình ứng dụng có thể tạo ra bất cứ loại hoạt ảnh nào phụ thuộc vào việc thay đổi thông tin về dạng hình học. level of detail và Morph . cho phép người lập trình tạo được nhiều hiệu ứng hơn so với các kĩ thuật trên. hoạt ảnh được tạo ra chủ yếu bằng cách di chuyển các khối hình hình học.Lập trình đồ họa trên Java 2D và 3D void setWeights(double[] weights) Thiết lập vector trọng số Morph cho nút Morph hiện thời. ALLOW_GEOMETRY_ARRAY_READ | WRITE Xác định rằng nút hiện thời cho phép đọc (ghi) thông tin dạng hình học của nó.

rồi tạo một lớp hành vi tùy biến và cũng lấy ra một đối tượng thuộc lớp đó. Công việc này không quá phức tạp như nhìn nhận ban đầu. Sử dụng GeometryUpdater Để sử dụng được đối tượng GeometryUpdater cho các ứng dụng hình học động. phương thức này sẽ gọi phương thức được cài đặt trong lớp GeometryUpdater. Đối tượng hành vi lập lịch gọi đối tượng GeometryUpdater trong ứng dụng. Công việc tạo đối tượng hình học BY_REFERENCE không làm gì nhiều hơn ngoài việc tạo ra một đối tượng hình học khác.com 555 .Lập trình đồ họa trên Java 2D và 3D phép truy cập đến dữ liệu từng đỉnh của đối tượng hình học nên khả năng tạo hoạt ảnh là không có giới hạn. Đối tượng GeometryUpdater có nhiệm vụ hiệu chỉnh đối tượng hình học khi được gọi. void updateData(GeometryUpdater updater) http://tailieuhay. Phương thức updateData() thứ nhất phải được cài đặt chi tiết trong lớp định nghĩa GeometryUpdater trong ứng dụng. tạo một lớp GeometryUpdater và lấy ra một đối tượng thuộc lớp đó. Hai phương thức này có cùng tên là updateData(). Mặc dù có thể hiệu chỉnh dữ liệu đối tượng hình học BY_REFERENCE mà không cần sử dụng đối tượng GeometryUpdater. nhưng cách làm này cho kết quả hoặc là không thể dự đoán được hoặc là không ổn định. void updateData(Geometry geometry) Cập nhật dữ liệu hình học có thể truy cập bởi tham chiếu. trước hết cần tạo đối tượng hình học BY_REFERENCE với các khả năng thích hợp. Chúng ta xem xét qua hai phương thức quan trọng của giao diện GeometryUpdater. Phương thức updateData() thứ hai là phương thức của GeometryArray.

Trong ảnh này. một vài phần của mã chương trình sẽ có thành phần ngẫu nhiên để tránh cho các phân tử hoạt động hoàn toàn giống nhau. Các phân tử thông thường được biểu diễn dưới dạng điểm hoặc đường. Trong hình này có khoảng 500 phần tử nước hoạt động. các dạng hình học khác cũng có thể được sử dụng.com 556 . có hai tham số thiết kế cơ bản: các phân tử sẽ có dạng như thế nào. các hạt nước được biểu diễn dưới dạng các đoạn thẳng nhỏ với chuyển động tuân theo các quy luật vật lý (cụ thể là chúng được gia tốc bởi trọng trường). Mỗi đoạn thẳng được xác định bởi 2 điểm. Hình ngoài cùng bên phải là ảnh đài phun khi đã hoạt động một khoảng thời gian. khói. Hình 5-24 là một chuỗi các ảnh thu được từ chương trình ví dụ ParticleApp. Ảnh phía bên trái là đài nước trước khi các phân tử nước được khởi tạo.Lập trình đồ họa trên Java 2D và 3D Phương thức này gọi phương thức updateData của đối tượng GeometryUpdater xác định để đồng bộ hóa cập nhật dữ liệu đối tượng hình học được tham chiếu bởi đối tượng GeometryArray hiện thời. Ảnh ở giữa là khi cột “nước” được khởi tạo trong đài phun. tuy nhiên. Việc cập nhật chuyển động có thể mô phỏng được hành vi tự nhiên của các đối tượng (cụ thể hơn là mô phỏng các định luật vật lý) hay các chuyển động mong muốn khác. vị trí và hướng của nó sẽ được cập nhật ra sao. Thông thường. Trong chương trình ví dụ. pháo hoa và các hiện tượng giống dạng lỏng khác. Chương trình ví dụ hệ thống phân tử đài phun nước sử dụng GeometryUpdater Các hệ thống phân tử thông thường được sử dụng để mô hình nước. http://tailieuhay. Trong một hệ thống phân tử. có tất cả khoảng 300 phần tử hoạt động.

Ba trường (hay 3 thuộc tính) được định nghĩa gần thẻ . Cụ thể. do cả hai lớp Behavior và Geometry đều chỉ được sử dụng cho riêng ứng dụng này. Các đoạn mã sau tương ứng định nghĩa các đối tượng hình học. Tuy nhiên.Lập trình đồ họa trên Java 2D và 3D Hình 5-24.java. Hơn nữa. Có thể dùng một vài cách khác để thiết kế hoạt ảnh như trên. Trường waterLines và baseElevation được sử dụng trong một vài phương thức khác nhau nên chúng được khai báo là các thuộc tính của lớp Fountain. cả đài phun được quay quanh trục để thể hiện tính 3 chiều tự nhiên của hoạt ảnh. Đoạn mã đầu tiên đưa ra định nghĩa cho lớp Fountain. baseElevation là giá trị toạ độ y của http://tailieuhay. nó định nghĩa một vài trường và tạo ra đối tượng hình học được dùng để biểu diễn nước. waterLines là một tham chiếu đến đối tượng hình học LineArray. Ba đoạn mã này là thành phần chính tạo nên hoạt ảnh trong ParticleApp. Lớp hành vi tuỳ biến Behavior và lớp GeometryUpdater là các lớp trong của lớp Fountain. nên chẳng có lí do gì để cho phép chúng được sử dụng bởi các lớp khác bên ngoài Fountain.com 557 . Chuỗi hình ảnh thu từ chương trình ParticleApp Trong chương trình ParticleApp. sử dụng các lớp này như là lớp trong sẽ biến Fountain trở thành một đối tượng đồ hoạ hoạt ảnh hoàn chỉnh. đối tượng hình học của phần tử nước. hành vi và geometryUpdater cho ứng dụng ParticleApp.

Càng nhiều phần tử được sử dụng để tạo hoạt ảnh thì thời gian để xây dựng một khung hình hiển thị càng lớn.Lập trình đồ họa trên Java 2D và 3D chân đài phun. bởi mỗi phần tử (mỗi đoạn thẳng) cần một đỉnh bắt đầu và một đỉnh kết thúc. Chú ý rằng định dạng đỉnh bao gồm cả BY_REFERENCE. Phụ thuộc ứng dụng và cách đối tượng GeometryUpdater được thiết kế. Việc này chỉ có thể thực hiện được nếu khả năng thích hợp được thiết lập. Ví dụ. Phương thức này có định nghĩa một biến nguyên N .com 558 thứ 2 chịu trách nhiệm thiết lập khả năng đọc số lượng . Ứng dụng này đòi hỏi như vậy. Trong hầu hết các ứng dụng sử dụng GeometryUpdater. Khả năng này cần phải được thiết lập cho bất cứ ứng dụng nào sử dụng GeometryUpdater. Dòng mã dán nhãn đầu tiên thiết lập khả năng cho phép ghi dữ liệu đỉnh. Dòng mã tiếp sau hai dòng mã gán nhãn đỉnh. nếu đối tượng GeometryUpdater không “biết” được số đỉnh được sử dụng thì giá trị này phải được đọc từ đối tượng Geometry đã được truyền cho nó. Các phần tử nước được tạo hoạt ảnh bằng cách thay đổi giá trị toạ độ đỉnh cho các đoạn thẳng tương ứng. khả năng đọc cũng cần phải được thiết lập. http://tailieuhay. thông tin dạng hình học nhất định ngoài dữ liệu đỉnh có thể cần để thiết lập đối tượng Geometry. đối tượng LineArray được tạo ra trên dòng mã gán nhãn . N là số lượng các phần tử nước (số các đoạn thẳng của LineArray) được dùng để biểu diễn nước. Tất nhiên. Phương thức thứ nhất của lớp Fountain là createWaterGeometry(). Dòng mã dán nhãn có nhiệm vụ thiết lập khả năng đọc dữ liệu giá trị đỉnh. Giá trị 1400 được gán cho N trong đoạn mã không có gì đặc biệt ngoại trừ việc nó làm cho hoạt ảnh trông có vẻ hợp lý hơn. Trong phương thức createWaterGeometry(). Gần như bất cứ giá trị nào cũng có thể gán cho N. Trường thuộc tính thứ 3 giữ một tham chiếu đến đối tượng WaterUpdater được tạo ra tại đây với mục đích là không làm tràn bộ nhớ. thông tin này chỉ có thể đọc được nếu khả năng thích hợp được thiết lập. Số lượng các đỉnh là N*2.

do đó ban đầu.COORDINATES | LineArray.45f.setCapability(GeometryArray. protected float baseElevation = -0. không có phần tử nào được nhìn thấy.BY_REFERENCE). // number of 'drops' waterLines LineArray.com 559 . http://tailieuhay.ALLOW_REF_ DATA_WRITE). Mỗi đỉnh được khởi tạo toạ độ (0. protected GeometryUpdater geometryUpdater = new WaterUpdater(). 0). public class Fountain extends BranchGroup { protected LineArray waterLines = null. baseElevation. waterLines.setCapability(GeometryArray.ALLOW_REF_ DATA_READ). = new LineArray(N * 2.Lập trình đồ họa trên Java 2D và 3D Các dòng mã còn lại trong đoạn mã sau khởi tạo toạ độ cho N đỉnh. Geometry createWaterGeometry() { int N = 1400. waterLines.

float[] coordinates = new float[N * 3 * 2].setCapability(GeometryArray.0f. } the following statements would be * 3 + 4] = * 3 + 1] = http://tailieuhay. // redundant // waterLines.setInitialCoordIndex(0). return waterLines.ALLOW_COUN T_READ). } waterLines. coordinates[p * 3 + 2] = 0. coordinates[p * 3 + 3] = 0. coordinates[p baseElevation.Lập trình đồ họa trên Java 2D và 3D waterLines. coordinates[p baseElevation.com 560 .0f.0f. coordinates[p * 3 + 5] = 0. p += 2) { // for each particle coordinates[p * 3 + 0] = 0. for (p = 0.setCoordRefFloat(coordinates). p < N. // waterLines.0f.setValidVertexCount(N*2). int p.

} // end processStimulus } // end class UpdateWaterBehavior public class WaterUpdater implements void processStimulus(Enumeration class UpdateWaterBehavior extends GeometryUpdater { Random random. public WaterUpdater() { random = new Random(). http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D abstract Behavior { WakeupOnElapsedFrames w = null.updateData(geometryUpdater). public UpdateWaterBehavior() { w = new WakeupOnElapsedFrames(0). } public void initialize() { wakeupOn(w). wakeupOn(w). } public critiria) { waterLines.com 561 .

getCoordRefFloat().coords[i * 3 + 4] . // y1 coords[i coords[i x2 * * 3 3 + + 2] 3] += = coords[i * 3 + 2] . geometryArray.coords[i * 3 + 5]. float[] int coords N = = geometryArray.getValidVertexCount().com 562 .coords[i * 3 + 3].Lập trình đồ họa trên Java 2D và 3D } public void updateData(Geometry geometry) { GeometryArray (GeometryArray) geometry. for (i = 0. // x1 coords[i * 3 + 1] . // z1 (coords[i * 3 + 0] + coords[i * 3 + 3]) / 2. // geometryArray = http://tailieuhay. int i. i < N.01f.0. i += 2) { // for each particle if (coords[i * 3 + 1] > baseElevation) { // update active // particles coords[i coords[i * * 3 3 + + 0] 1] += += coords[i * 3 + 0] .

0.8) { // randomly start a drop 0. // z2 } } else { // an inactive particle if (random. // * 3 + 4] = (coords[i * 3 + 1] + coords[i * 3 + 4] + 0. // y1 coords[i 0.com 563 . // x1 * 3 + 5] = * 3 + 4] = * 3 + 3] = * 3 + 2] = * 3 + 1] = * 3 + 0] = http://tailieuhay.nextFloat() .5f). // z1 coords[i 0. // x2 coords[i baseElevation.// y2 coords[i z2 if (coords[i * 3 + 1] < * 3 + 5] = (coords[i * 3 + 2] + coords[i * 3 + 5]) / 2.0f.03f * (random.0f.01f) / baseElevation) { // if particle // below base coords[i 0.nextFloat() coords[i * 3 + 0] > = 0.0f.Lập trình đồ họa trên Java 2D và 3D coords[i 2.0f. // x1 coords[i baseElevation. // y2 coords[i 0.

. // z1 * 3 + 1] = http://tailieuhay. Định nghĩa lớp UpdateWaterBehavior bao gồm trường w – một tham chiếu đến đối tượng WakeupOnElasedFrames . Đối tượng WakeupOnElasedFrames được tạo trong phương thức khởi tạo của UpdateWaterBehavior bắt đầu từ dòng mã được dán nhãn .14f * random. Đây là đoạn mã dễ nhất trong ứng dụng GeometryUpdater.nextFloat() .được sử dụng để kích hoạt đối tượng hành vi.nextFloat() + baseElevation. Phương thức processStimulus(). bắt đầu từ dòng mã thức ban đầu cho đối tượng hành vi. Lớp Behavior điều khiển hoạt ảnh bằng cách gọi phương thức updateGeometry của đối tượng hình học được tạo hoạt ảnh khi phương thức processStimulus của nó được gọi. bắt đầu từ dòng mã gán nhãn . // y1 coords[i } // end if } // end if-else } // end for loop } } } Đoạn mã sau định nghĩa lớp UpdateWaterBehavior. định nghĩa các hành động của đối tượng hành vi đáp ứng lại các sự kiện đánh thức nó.Lập trình đồ họa trên Java 2D và 3D coords[i 0.0. thiết lập điều kiện đánh * 3 + 2] = 0.03f * (random. Phương thức initialize() của lớp UpdateWaterBehavior.com 564 . phương thức updateData() được gọi và truyền tham số geometryUpdater cho waterLines.5f). một lớp mở rộng từ lớp Behavior. Trong trường hợp này.

com 565 . } public void initialize() { wakeupOn(w). } public critiria) { waterLines. } // end processStimulus } // end class UpdateWaterBehavior Đoạn mã sau định nghĩa lớp GeometryUpdater.updateData(geometryUpdater). Trong hàm khởi tạo. void processStimulus(Enumeration class UpdateWaterBehavior extends http://tailieuhay. GeometryUpdater dịch chuyển các phần tử nước bằng cách thay đổi dữ liệu tọa độ của chúng. public UpdateWaterBehavior() { w = new WakeupOnElapsedFrames(0). nhãn phương thức updateData(). Lớp GeometryUpdater trong ứng dụng này có một hàm khởi tạo và một phương thức. . một đối tượng Random được tạo ra để sử dụng trong phương thức thường duy nhất của lớp. wakeupOn(w).Lập trình đồ họa trên Java 2D và 3D abstract Behavior { WakeupOnElapsedFrames w = null.

Tọa độ đỉnh đầu tiên của một phần tử được gán các giá trị thích hợp để mô hình chuyển động. Mỗi lần updateData() được gọi. Xét hệ phần tử này một thời gian ngắn sau khi khởi động. Tuy nhiên. Với mỗi phần tử hoạt động (xác định bằng cách so sánh tọa độ y của nó với baseElevation). khi này. Phần tử nào không hoạt động sẽ có tọa độ y trùng với tọa độ y của chân đài phun (baseElevation). Nếu điều kiện này thỏa mãn. chương trình sẽ tính toán chuyển động cong dạng parabol của nó.com 566 . tiến trình hoạt ảnh sẽ thu thập thông tin liên quan về đối tượng hình học để cập nhật. Thông thường. tham số Geometry được ép kiểu . phương thức updateData() xét mỗi phần tử tại một thời điểm nào đó trong vòng lặp . tạo hoạt ảnh cho các phần tử nước. Dòng . đã có một vài phần tử hoạt động. nhãn . Trên dòng mã thành GeometryArray. Chú ý rằng. ứng dụng này có thể chạy hiệu quả hơn bằng cách tính toán các thông tin này một lần rồi lưu trữ nó trong các trường của đối tượng. phần tử đó sẽ ngừng hoạt động bởi chương trình cập nhật giá trị tọa độ cả hai đỉnh của nó về giá trị ban đầu. hiệu quả đạt được cũng chỉ hạn chế và làm cho đoạn mã không sử dụng lại được. tọa độ cũ của đỉnh thứ nhất sẽ được gán cho đỉnh thứ hai. Trên dòng mã độ đỉnh được lấy ra. phần tử này không di chuyển. giá trị xác định phần tử không hoạt động. http://tailieuhay. Nếu một phần tử có tọa độ y bằng với baseElevation. số còn lại thì chưa. không phải tất cả các phần tử đều hoạt động tại cùng một thời điểm. sau đó. nó được coi là không hoạt động và vì thế. một tham chiếu đến dữ liệu tọa thu thập số lượng đỉnh.Lập trình đồ họa trên Java 2D và 3D Phương thức updateData(). Lớp Geometry này có thể được sử dụng cho đài phun với các kích thước khác nhau. Ban đầu. Câu lệnh if trên dòng kiểm tra xem phần tử đã vượt qua baseElevation hay chưa. tất cả các phần tử nước đều không hoạt động. Khi đã có những bước chuẩn bị thích hợp.

} public void updateData(Geometry geometry) { GeometryArray (GeometryArray) geometry. float[] int coords N = = geometryArray. Trong ví dụ này. một lượng trung bình khoảng 20% các phần tử không hoạt động sẽ được GeometryUpdater { Random random. được ngẫu nhiên khởi tạo bởi điều kiện trên dòng khởi tạo.Lập trình đồ họa trên Java 2D và 3D Một phần các phần tử không hoạt động. for (i = 0. public class WaterUpdater implements . int i.getCoordRefFloat(). i < N.com .getValidVertexCount(). phần else của điều kiện trên dòng . geometryArray. i += 2) { // for each particle if (coords[i * 3 + 1] > baseElevation) { // update active 567 geometryArray = http://tailieuhay. public WaterUpdater() { random = new Random().

0f. // x1 coords[i * 3 + 1] . // z1 * 3 + 2] = * 3 + 1] = * 3 + 0] = http://tailieuhay. // y1 coords[i 0. // x1 coords[i baseElevation.// y2 coords[i z2 if (coords[i * 3 + 1] < * 3 + 5] = (coords[i * 3 + 2] + coords[i * 3 + 5]) / 2.Lập trình đồ họa trên Java 2D và 3D // particles coords[i coords[i * * 3 3 + + 0] 1] += += coords[i * 3 + 0] .01f) / * * 3 3 + + 2] 3] += = coords[i * 3 + 2] .0. // y1 coords[i coords[i x2 coords[i 2.0f.01f. // z1 (coords[i * 3 + 0] + coords[i * 3 + 3]) / 2.com 568 . // * 3 + 4] = (coords[i * 3 + 1] + coords[i * 3 + 4] + 0. // baseElevation) { // if particle // below base coords[i 0.coords[i * 3 + 3].coords[i * 3 + 4] .coords[i * 3 + 5].

việc làm này có thể phải trả giá bởi tốc độ xử lý hoạt ảnh. Việc này có thể thực hiện được bằng cách thêm đối tượng LineAttributes với setLineAntialiasedEnable(true) vào thành phần Appearance của phần tử nước.0.nextFloat() .5f).0f.8) { // randomly start a drop * * 3 3 + + 0] 1] 0.03f * (random.com 569 * * * 3 3 3 + + + 3] 4] 5] = = = > = = 0.5f).nextFloat() coords[i coords[i 0. lưu ý rằng. // y2 coords[i 0. // x2 coords[i baseElevation. Tuy nhiên. // x1 * 3 + 2] = 0.nextFloat() .0.03f * (random.nextFloat() + baseElevation.Lập trình đồ họa trên Java 2D và 3D coords[i 0. // z2 } } else { // an inactive particle if (random.0f. // z1 . http://tailieuhay. // y1 coords[i } // end if } // end if-else } // end for loop } } Cột nước trong hoạt ảnh trông sẽ đẹp hơn nếu các đoạn thẳng biểu diễn mỗi phần tử loại bỏ được răng cưa.14f * random.

Lập trình đồ họa trên Java 2D và 3D http://tailieuhay.com 570 .

html 4. The 2D Text Tutorial. The Java 2D Demo. The Java 3D document at: http://java.Lập trình đồ họa trên Java 2D và 3D Tài liệu tham khảo Trong quá trình làm cuốn tutorial về lập trình đồ họa trong Java 2D & 3D chúng em có tham khảo các tài liệu sau: 1. 2nd Volume.com/developer/onlineTraining/Graphics/2 DText/ 3.sun. Available from the Java 2D website: http://java. The Java 2D Sample Programs.com/products/java-media/2D/index.sun. The Java Tutorial.com/products/java-media/2D/samples/index. 2.sun. Available online at: http://java.sun.sun.com 571 .Lê Tấn Hùng.com/developer/onlineTraining/java3d/ http://tailieuhay. Available online at: http://java. Available online from the Java Developer Connection: http://developer. Slide bài giảng Kĩ thuật đồ họa và hiện thực ảo của ThS.java.com/docs/books/tutorial/2d/index.html 5.html 3.

Sign up to vote on this title
UsefulNot useful