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

Với Java 2 SDK. Tại tầng ứng dụng.1 User Space Hệ tọa độ này được chỉ ra trong hình 1-1. Các ứng dụng thường sủ dụng hệ tọa độ này.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.0) http://tailieuhay.com 12 . 1. 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ị. 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.1 Coordinate Systems Java 2D API bao hàm hai hệ tọa độ: 1.2. Không gian người sủ dụng là hệ tọa độ logic và độc lập với thiết bị.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. 1. Java 2D API còn hỗ trợp cho các môi trường đa màn hình (multi-screen environments). Không gian thiết bị là hệ tọa độ phụ thuộc thiết bị. 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.3 . 2. version 1.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. x (0.1. 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ị .2.ứng với từng loại thiết bị cuối mà có hệ tạo độ khác nhau.

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.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.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ị.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.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. 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.1.com 13 .

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ị.2. má in và các bộ đệm ảnh. and 800x600x256 colors.mỗi đối tượng GraphicsDevice có thể có 1 hay nhiều đối tượng kiểu GraphicsConfigurations.Lớp GraphicsEnvironment cũng bao gồm tập các font phù hợp trong môi trường đó. Tất cả các phép chuyển tọa độ.lấy tỉ lệ . Lớp GraphicsDevice mô tả thiết bị tô trát như màn hình hoặc máy in. 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ể.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). Ví dụ.Lập trình đồ họa trên Java 2D và 3D sử dụng sang không gian thiết bị.Một đối tượng kiểu GraphicsEnvironment có thể bao gồm 1 hay nhiều đối tượng GraphicsDevices. Ứ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 .com 14 . 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.đều được biểu diễn bởi đối tượng kiểu AffineTransform .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ột thiết bị hiển thị SVGA có thể thực hiện trong một số chế độ màu như : 640x480x16 colors. 1. Cũng có thể thêm đối tượng AffineTransform cho các dạng đồ họa bằng các phép xoay . Ngược lại .Các thiết bị sử dụng cho quá trình tô trát gồm có màn hình . 640x480x256 colors.Mỗi cấu hình phù hợp của thiết bị được biểu diễn bởi lớp GraphicsConfiguration.

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. 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. 1. 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 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. Trong Java 2D API. Một font có thể được xem như tập các glyph.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. Nhưng điều này lại khác với fần mềm JDK 1. Một font đơn có thể có rất nhiều kiểu khác nhau như kểi chữ đậm . 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.3 Fonts Một xâu thường được hiểu là tập các kí tự tao thành.vừa.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ị.nhóm các dạng font tao nên môt họ font .Khi một xâu được vẽ.1 .2.văn bản hay ảnh khi chúng được tô trát.Tuy nhiên.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. 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 đó. Trong Java 2D API.nghiêng .com 15 . hình dạng của nó sẽ được xác định bởi font mà chúng ta chọn.Lập trình đồ họa trên Java 2D và 3D . 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. Hay nói cách khác . 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.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 đó.ví dụ Helvetica Bold.

1.Các đối tượng Font được sử dụng để mô tả các hình dạng hiển thị của font.2. Sử dụng Java 2D API. và thường số lượng màu trong bảng màu sẽ ít hơn sovới ảnh thật. Một mảng hai chiều của điểm ảnh được gọi là một raster. 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.Định dạng này thường được dùng cho những ảnh có 256 màu.kich thước. 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.4 Images Ảnh được tạo nên từ tập các pixel . 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. và thông tin sắp xếp được lưu trong đối tượng TextLayout và TextAttributeSet . 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.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.Lập trình đồ họa trên Java 2D và 3D môi trường đang xét không.Như để tương thích cho điều đó . Trong ảnh màu hiển thị bằng chỉ số (indexed-color image). 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. nhưng chúng nhìn sẽ thật hơn . 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). và thâm chí cả ngôn ngữ khác nhau. những màu sắc của ảnh sẽ bị giới hạn bởi bảng mà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. 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 . 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.hình dạng.

5 Fills and Strokes Với Java 2D API. nên các xâu kí tự cũng có thể được vẽ và tô.awt. 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. 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 .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.Có thể xác định độ rộng cũng như các nét cho các đường thẳng và đường cong.2. 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. 1.awt. 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. Đố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.Các phương thức của ColorSpace trong java.color sẽ biẻu diễn các không gian màu sắc thông dụng.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. gồm có không gian màu RGB và gray scale. Vì các chữ xét cho cùng cũng được biểu diễn bằng tập các glyph.Ví dụ các thành phần màu đỏ là các daỉ màu trong ảnh RGB . Các kiểu tô được định nghĩa bởi các phương thức thuộc đối tượng Paint. Các kiểu bút được định nghĩa băng các đối tượng kiểu Stroke. 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. Gói 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 17 . 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 .

• 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.2. 1. Trong Java 2D. • 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.Lưu ý thực chất đối tượng drawString sẽ tô các glyphs mà được render. Java 2D API cung cấp thêm hai phương thức mới cho Paint là TexturePaint và GradientPaint. 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. Để 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 đó. Khi một chuỗi kí tự được render. 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. 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.com 18 .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ậ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). TexturePaint định nghĩa kiểu tô dùng mẩu ảnh đơn giản(simple image fragment ) mà được lặp như nhau. GradientPaint định nghĩa một kiểu tô màu loang(gradient) giữa hai màu. http://tailieuhay.

3. 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. 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.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. • paint • paintAll • update • print http://tailieuhay. Ví dụ.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ệ. Backward Compatibility and Platform independence Như đã nói. Graphics2D mở rộng các lớp Graphics trong JDK1. Để 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.1.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. 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.Java 2D™ API có sự tương thích đối với phần mềm JDK 1.com 19 .1 Backward Compatibility Để tương thích với các tính năng đã tồn tại trong đồ họa JDK .1 .

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. 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 .. và các lớp thừa kế được cập nhật để mở rộng các lớp cha mới. . g2. ..setTransform (t)..com 20 . 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 . 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.Lập trình đồ họa trên Java 2D và 3D • printAll • getGraphics JDK 1. • Một hay nhiều triển khai các interface được thêm vào lớp kế thừa . hay đúng hơn là mở rộng một lớp thừa kế. } Trong môt vài trường hợp . Ví dụ. Java 2D API khái quat hóa nó. 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. Để có thể truy nhập những chức năng được thực thi trong đối tượng Graphics2D.

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.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. 1. 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. Hai lớp cha được thêm vào phân cấp của lớp Rectangle là RectangularShape và Rectangle2D. 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ẻ.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.3. 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. Bây giờ mở rộng các lớp Rectangle2D mới và triển khai cả hai interface Shape và Serializable.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. 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ó.com 21 . Các Applet được viết cho phần mềm JDK 1. Rectangle là một đối tuợng mở rộng đơn giản. 1.hay là khi chúng được gởi tạo bằng lập trình. 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 ).Lập trình đồ họa trên Java 2D và 3D Trong phần mềm JDK 1.

font • java.awt.awt.image. (Rõ dàng là không phải tất cả các lớp trong java.awt.geom • java.awt.awt.com 22 .awt.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.renderable • java.awt.Lập trình đồ họa trên Java 2D và 3D • java.print Package java.awt • java.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.color • java.awt là các lớp của Java 2D ) Package java.image • java.

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. Gói java.awt. 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.image.image và java. http://tailieuhay.awt.awt.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.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.awt.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.

http://tailieuhay.awt.Để đảm bảo tính thống nhất.các lớp cho chế độ màu mới cũng có trong package java.awt.image tồn tại trong các version trước đó của AWT. Package java. 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.com 24 .awt.image .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 .awt.đồ họa và ảnh dựa trên công nghệ Java 2D.image package cho sự tương thích .Lập trình đồ họa trên Java 2D và 3D Package java.

com 25 .Graphics để tạo ra điều khiển tinh vi hơn về biểu diễn các hình .văn bản và ảnh .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ó. như là các kiểu đường thẳng và các phép biến đổi.hình và ảnh. Để tô trát văn bản .awt.được áp dụng cho các đối tượng đồ họa khi chúng được tô trát.Lập trình đồ họa trên Java 2D và 3D Chương 2: Rendering with Graphics2D Graphics2D mở rộng java. Các thuộc tính tạng thái Graphics2D . 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. http://tailieuhay.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.

Các lớp và mô tả sơ lược về chúng: Lớp AffineTransform (java.Các thao tác vẽ được tùy chọn bởi người lập Stroke trình. 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. Định nghĩa một môi trương tối ưu và độc lập cho việc vẽ. Đị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 . Mở rộng: Transparency Định nghĩa các màu sắc cho việc tô hoặc vẽ.awt. http://tailieuhay.com 26 .geom) Mô tả Miêu tả một phép biến đổi 2D affine .Lập trình đồ họa trên Java 2D và 3D 2.1 Các lớp và giao diện.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 phương thức BasicStroke. Tạo ra một đối tượng Shape mà các đường viền của nó đựoc tạo bóng.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. Được thực thi bởi đối tượng PaintContext Color. CompositeContex t Được thực thi bởi phương thức AlphaComposite.awt. 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. Hầu hết các lớp này là một phần của package java.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.

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.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).com 27 .Mẫu tô được tạo ra từu đối tượng BufferedImage. Color Thực thi: Paint Định nghĩa một kiểu tô màu đồng nhất cho đối tượng GradientPaint Shape.Text và Image.2 Rendering Concepts Để tô trát một đối tượng đồ họa sử dụng Java 2D™ API. Thực thi: Paint Định nghĩa một mẫu tô màu loang tuyến tính cho đối tượng Shape.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.Graphics Thực thi: Paint Định nghĩa một kiểu tô theo mẫu cho đối tượng Shape. 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. 2.awt. http://tailieuhay.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. 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.

xoay. Nếu đối tượng Shape được taọ nét .2. 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 .com 28 . thông tin về hình học . • 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.1 Rendering Process Khi một đối tượng đồ họa được render. 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 . • Chuyển đổi tọa độ . • Định nghĩa các màu và các kiểu để tô các hình.lấy tỉ lệ hoặc cắt cá đối tượng khi chúng được render.đố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 đó .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 . Ngữ cảnh Graphics2D cất giữ các tham chiếu tới các đối tương thuộc tính .thì cần phải gọi phương thức thiết lập phù hợp để khai báo ngữ cảnh. 2. 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 . 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 . Quá trình render cho một đối tượng Shape có thể được chia thành 4 bước : 1.ả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ị.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. http://tailieuhay.

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 . 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. 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 . 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). 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.com 29 . quality. Đối với ảnh thì có sự khác biệt . Đườ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. speed. http://tailieuhay.có thể thiết lập tùy chọn default :on hoặc off. 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. • Antialiasing . 4. Lớp RenderingHints hỗ trợ cá kiểu chỉ dẫn sau đây: • Alpha interpolation .2.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.Lập trình đồ họa trên Java 2D và 3D 3.có thể thiết lập tùy chọn default. 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. 2. 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.

• Dithering . • Text antialiasing .Lập trình đồ họa trên Java 2D và 3D • Color Rendering .có thể thiết lập tùy chọn nearest-neighbor. enable. 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 . hoặc speed. • Fractional Metrics . hoặc speed.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. Khi một chỉ dẫn được thiết lập măc định . Đ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) . bilinear. hoặc off.có thể thiết lập tùy chọn default. • Rendering . Đâ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. Thay vì sử dụng các điểm ảnh gẩn giống với các đường chéo và đường cong . 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. Để 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.com 30 . 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ị . quality.có thể thiết lập tùy chọn default: on hoặc off. http://tailieuhay.có thể thiết lập tùy chọn default:disable. quality.có thể thiết lập tùy chọn default. hoặc bicubic. • Interpolation. on. 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.có thể thiết lập tùy chọn default.môi trường tạo bóng mặc định sẽ được sử dụng .tăng mật độ các điểm ảnh bao quanh tới các vùng được tạo bóng.

Như ví du.và hình thứ hai sử dụng kiểu round join-style.Lập trình đồ họa trên Java 2D và 3D 2.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.2. BasicStroke đinh nghĩa các thuộc tính như độ rộng cuả nét vẽ . http://tailieuhay.com 31 . a round endcap style. Thuộc tính của Graphics2DStroke định nghĩa các tính chất của nét bút vẽ. Đố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.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. and a dashing pattern.ảnh đầu tiên trong hình 2-3 sử dụng miter join-style.

Ví dụ phương thức draw(myRectangle) được gọi: 1. Quá trình xử lý này được minh hạo trong hình 2-4: 2. Graphics2D. Thuộc tính của Stroke sẽ quy định cho đường nét của hình chữ nhật . 2.draw. drawOval.com 32 . drawLine.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.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. 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. http://tailieuhay.2. 3. drawRect. drawPolyline.drawString).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. Đố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. Khi một đối tượng Shape hay là các glyph được vẽ (bởi các phương thức Graphics2D. và drawRoundRect. 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. Các đường nét này sẽ được biến đổi thành một đối tượng kiểu Shape . drawPolygon.

com 33 .Color là phần triển khai (implementation) đơn giản nhất của giao tiếp Paint (Paint interface).fill). Để 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. http://tailieuhay.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 . Xác định màu cho mỗi điểm ảnh từ đối tựợng Paint.thì hệ thống sẽ: 1. 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ị. Xác định các điểm ảnh nào để thể hiện đối tượng đó. 2. 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. Khi một đối tượng Shape được tô màu (Graphics2D. đố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. 3. Khi gọi phưong thức fill để tạo bóng một đối tượng Shape. 4. 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 . Ghi các điểm ảnh ra thiết bị hiển thị đó.

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. Khi một khung nhìn là một phần của ngữ cảnh của đối tượng Graphics2D. 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.đối tượng ColorModel là nơi để tạo các màu sắc.com 34 . Đố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. Thông tin này passed to the next stage in the rendering pipeline.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 .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ị. 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. 2. Phương thức createContext method is passed the bounding boxes of thegraphics object being filled in user space and in device space. Quá trình xử lý theo phiên được thực hiện theo 2 bước: 1. Đố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ỳ. 2. Java 2D API tổ chức chúng theo từng phiên. 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.2. http://tailieuhay.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 . mà vẽ các màu đã được tạo bằng cách sử dụng đối tựợng Composite hiện thời . Phương thức createContext của đối tượng paint được gọi để tạo một đối tượng PaintContext.

hay translate. Để 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. 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. 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.tỉ lệ .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.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 . Phép biến đổi AffineTransform thực hiện các phép biến đổi cho đường như phép dịch.quay và cắt bỏ với tập các hình cơ bản.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. 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. 2. 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. 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 . Để 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. Bất kì đối tượng Shape cũng có thể được sử dụng để định nghĩa một khung nhìn. scale. shear.

Đ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.transform(.). 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.).com 36 . g2d. you pass an AffineTransform to Graphics2D. Phương thức setTransform sẽ ghi đè lên phép biến đổi hiện thời của đối tượng Graphics2D.Lập trình đồ họa trên Java 2D và 3D thực hiện đầu tiên. g2d.setTransform(aT).. Để tiếp nối một phép biến đổi với phép biến đổi hiện tại .getTransform().transform.draw(. 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.văn bản và ảnh đã được chuyển đổi: non-zero translation from its AffineTransform aT = g2d.. 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ố . g2d. Lớp Graphics2D cũng bao gồm phương thức setTransform .. • 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ả . 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 . Ảnh này được được vẽ như khi kết nối http://tailieuhay. • 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..

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 .hình và các ảnh khi chúng được tạo bó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 đó. 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).2.1 Constructing an AffineTransform http://tailieuhay.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.preConcatenate để thực hiện phép chuyển đổi có liên quan tới không gian các điểm ảnh. 2.6. 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. 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. 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 . 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.concatenate. AffineTransforms được sử dụng để biến đổi văn bản .com 37 .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.. Sự kết hợp này xem như là sự móc nối. Ví dụ có thể sử dụng phương thức AffineTransform. 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. 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 .

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. AlphaComposite. 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. 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 đó. 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. 2.com 38 . • 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. Có hai interface tạo các kiểu kết hợp cơ bản trong Java 2D là : Composite và CompositeContext. Mỗi đối tượng của http://tailieuhay. có hỗ trợ một số kiểu kết hợp khác nhau . 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.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. Để 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.2.và một triển khai(implementation) của interface Composite .

có thể xác định được giá trị alpha được thêm vào . Khi tạo một đối tượng AlphaComposite . 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ác ảnh lưu thông tin về giá trị alpha của chính nó . 2.7. 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 . 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.0) thì các màu tô đè lên chúng sẽ không được hiển thị.2.com 39 . trong khi đó các màu trong suốt (có giá trị alpha=0. Các màu tối (co giá tri alpha=1.0) cho phép các màu tô đè lên nó được hiển thị.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.. Khi thêm đối tượng AlphaComposite này tới ngữ http://tailieuhay.1 Managing Transparency Giá trị alpha của một màu là giá trị đo đọ trong suôt của màu đó .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. Một trong những luật kết hợp trong lớp AlphaComposite là SRC_OVER.

com 40 .Clipping path.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. 2.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 . Stroke.2. 2.Lập trình đồ họa trên Java 2D và 3D cảnh của Graphics2D . Để tạo các chỉ dẫn cho quá http://tailieuhay. Paint. and Transform.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.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.) .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 . 2.3.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ó. Composite.7. Thông tin này đựoc gọi là kênh alpha( alpha channel.

gồm có độ rộng và kiểu đường (dashing pattern).VALUE_ANTiALiAS_ON). 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.VALUE_RENDER_QUALiTY).thì khởi tạo một đối tượng BasicStroke và chuyền nó vào phương thức setStroke 2. RenderingHints.Lập trình đồ họa trên Java 2D và 3D trình tạo bóng 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.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.KEY_RENDERi NG.KEY_ANTiALiAS iNG.3. g2.2.put(RenderingHints.để làm thế nào các đoạn thẳng được kết hợp với nhau.thì cần tạo một đối tượng RenderingHints và chuyển nó vào lớp Graphics2D. 2.setRenderingHints(qualityHints).3. Để khởi tạo các thuộc tính về đường nét trong ngữ cảnh Graphics2D . qualityHints.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 . RenderingHints.com 41 .

Lập trình đồ họa trên Java 2D và 3D Trong ví dụ cho sau đây .3.2 Specifying Join and Endcap Styles Để khởi tạo cho các kiểu join và endcap .setStroke(roundStroke).độ 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. g2. BasicStroke. Trong ví dụ cho sau đây.JOiN_ROUND). BasicStroke.CAP_ROUND.0f. g2.0f). 2.cần tạo một đối tượng BasicStroke với các thuộc tính mong muốn .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.phải xác định 2 tham số để kiểm soát kiểu đường: • dash . http://tailieuhay.3. 2. 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 .độ 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.2.setStroke(wideStroke). phần tử thứ 1 biểu diễn khoảng trắng đầu tiên. Khi tạo một đối tượng BasicStroke . wideStroke = new BasicStroke(12.2. Phần tử 0 biểu diễn nét gạch đầu tiên.com 42 .là một mảng biểu diễn kiểu đường.

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

Gọi phương thức Graphics2D. 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ô.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. 3.setPaint. Khởi tạo đối tượng Shape. Khởi tạo đối tượng GradientPaint .3. 2. Trong ngôi sao thứ ba.cả hai điểm đều nằm trong cùng một hình. 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 .Lập trình đồ họa trên Java 2D và 3D 2. 2. minh họa trong hình 2-8.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.com 44 .3. Các bước cần thực hiện để tô loang theo hai màu: 1. http://tailieuhay. 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.3.

Gọi phương thức Graphics2D.setColor(Color. Bufferedimage Graphics2D big Bufferedimage.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. 50.f Re 50 50. g2 ill ct( .0f. 200). //5x5 Bufferedimage(5.setPaint. gp 50. = Color. Tạo đối tượng TexturePaint 2.TYPE_iNT_RGB). 3. 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 .Lập trình đồ họa trên Java 2D và 3D Trong ví dụ sau đây. Tạo đối tượng Shape.0f. // of Create size a buffered bi = = new image texture patch 5. big.3.0f. Khi tạo một đối tượng Bufferedimage để sử dụng như là một mẫu tô.green). GradientPaint GradientPaint(50. Gọi phương thức Graphics2D. 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. Để tô hình theo mẫu dệt: 1.com 45 .fill(shape). 200.3.green). http://tailieuhay.được chi ra trong hình 2-9. 2. 250. Trong ví dụ sau đây. bi. 4.createGraphics().setPaint(gp). .0f.blue new Color. g2. 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.

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

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

setColor(Color. 2.bởi vì setTransform sẽ ghi đè lên phép biến đổi hiện tại trong ngữ cảnh đồ họa 1.định vị Swing và các thành phần trong một cửa sổ. g2 ill ct( 0.transform để thêm vào các phép biến đổi mới cho đường ống biến đổi. Gọi phương thức Graphics2D.com 48 . 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 .h 2. Lấy phép quay bằng cách gọi AffineTransform. 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 . 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 . getRotateinstance. 3. Sau khi tạo bóng cho hình chữ nhật đã được biến đổi . 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. .Float .xâu văn bản. Gọi phươn thức Graphics2D.f Re 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.w ).magenta).draw để tạo bóng hình chữ nhật. 5. 4.5 Setting the Graphics2D Transform Để biến đổi đối tượng Shape.3. Ví dụ để vẽ một hình chữ nhật nghiêng 45 độ: 1. phép biến đổi được áp dụng khi đối tượng đồ họa được tạo bóng . . 4.Lập trình đồ họa trên Java 2D và 3D g2.

setTransform(aT).3. Trong ví dụ sau đây. // make // Apply room a for translation the t t ex .0) g2. // Define the rendering at transform = new AffineTransform AffineTransform(). g2. = new Rectangle2D.transform(rotate45).0. 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. AffineTransform Rectangle2D aT = rect g2. 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.getRotateinstance(Math.Float(1. g2.getTransform().Pi /4.com 49 . AffineTransform rotate45 = AffineTransform.2.0.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 . transform to rotated http://tailieuhay.0).0.1.draw(rect).

// Create the a text / of angles i < 4.0. 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 .0f .0) g2.0. 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. rotate at. http://tailieuhay. } 0.drawString(“Java”.0. g2.com 50 .setToTranslation(400. { 20.Pi // Render at four 90 i copies degree = 0. rotate45).transform(at).drawimage(myimage. .Pi /4.f.) the string rotation transform to 400. i++) 00) .0. “ a a” Jv for (n it g2. g2.setToRotation(Math.transform(at). thì chuyển AffineTransform sang drawimage: AffineTransform rotate45 = AffineTransform.0.0).getRotateinstance(Math.Lập trình đồ họa trên Java 2D và 3D at.

2. cần tạo một đối tượng AlphaComposite và chuyền nó vào phương thức setComposite. AlphaComposite ER).SRC_OV http://tailieuhay. Kiểu thông dụng nhất là SRC_OVER.thì vùng giao nhau đó sẽ có màu đỏ.6. Để sử dụng luật kết hợp SRC_OVER : 1.2 Increasing the Transparency of Composited Objects ac =AlphaComposite.setComposite(ac). Ví dụ . Hay nói cách khác .Lập trình đồ họa trên Java 2D và 3D 2.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). Gọi phương thức setComposite để thêm đối tuợng AlphaComposite cho ngữ cảnh của Graphics2D. Mỗi khi đối tượng kết hợp này được thiết lập .3. 2. g2.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 .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.đối tương mà được tạo bóng cuối cùng sẽ xuất hiện ở trên cùng .3.6.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.3. Để xác định các kiểu kết hợp cho ngữ cảnh Graphics2D . 2. 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 .com 51 .getinstance(AlphaComposite.

fillRect(0.100.getinstance(AlphaComposite. Ví dụ . a source over alpha composite object is created with an alpha of . // Create AlphaComposite http://tailieuhay.xác định một giá trị alpha là .com 52 .5: AlphaComposite ER.để 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% .Pi)/180).SRC_OV Trong ví dụ cho sau đây. public void g2 paint(Graphics = (Graphics2D) g) g. ac =AlphaComposite.5 and added to the graphics context. { Graphics2D g2.lang.Math.setTransform(new set // to identity a new ac alpha = composite AffineTransform()). g2. // radians=degree * pie / 180 g2.100).setColor(Color.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. g2. g2.red).rotate((45*java.0.5f).50). causing subsequent shapes to be rendered 50% transparent. .translate(100.

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 .SR C_OVER.5f).100).setColor(Color. g2.125.yellow). g2.blue).100.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. g2.100).4.setColor(Color.100.draw. • drawimage—tạo bóng các ảnh đã được xác định 2.pink). • fill—tô một đối tượng Shape bằng cách sử dụng đối tượng Paint trong ngữ cảnh Graphics2D .Lập trình đồ họa trên Java 2D và 3D AlphaComposite.com 53 . Text. } 2.75.setColor(Color.100). 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 .setColor(Color.0. g2. g2.fillRect(50.green).fillRect(125.fillRect(-25.100.75.setComposite(ac). g2.fillRect(50.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.getinstance(AlphaComposite. http://tailieuhay.100. g2. g2.0.

draw3DRect.draw(shape). drawRect. star using a general path object http://tailieuhay. Đối tượng BasicStroke cũng định nghĩa các thuộc tính endcap và join của đường thẳng . 4.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. Để tạo bóng cho các đường biên của đối tượng shape: 1.setStroke 3. public void g2 paint(Graphics = (Graphics2D) g) g. Khởi tạo cho đối tượng BasicStroke 2.thò có thể vẽ đường thẳng với độ rộng và mẫu nét gạch bất kì .com 54 . { Graphics2D // create and set the stroke g2. drawPolygon.drawPolyline. Khởi tạo cho đối tượng Shape. Gọi phương thức Graphics2D. 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 .0f)). Khi một đối tượng Shape được vẽ . Trong ví dụ sau.setStroke(new // Create a BasicStroke(4. drawOval. drawArc. drawRoundRect. 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 .

0f. 100.0f). or GradientPaint.fill có thể được sử dụng để tô bất kì đối tượng Shape. fillOval.closePath().0f. p. } 2. fill3DRect.translate(100. 0.0f).4.0f.lineTo(+ 100.NON_ZERO). 25. + + 25.lineTo(p. p.Lập trình đồ họa trên Java 2D và 3D GeneralPath p = new GeneralPath(GeneralPath. Xác định màu tô và kiểu tô trong ngữ cảnh đồ họa bằng cách sử dụng Graphics2D.0f. TexturePaint. Khi một đối tượng Shape được tô. // translate origin towards center of canvas g2. fillArc.draw(p). 100.setPaint. Để tô một đối tượng Shape: 1. 100. 0f. fillRoundRect.0f).setColor hay Graphics2D.0f). 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.0f).0f.lineTo(+ p.clearRect. http://tailieuhay.lineTo(+ p. fillPolygon.0f). 50. 100. 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. // render the sa' trs path g2.moveTo(p.2 Filling a Shape Phương thức Graphics2D.com 55 . 50. 100.

} 2.drawString. Khởi tạo đối tượng Shape.4.cần gọi Graphics2D.drawimage. Trong ví dụ sau đây .Lập trình đồ họa trên Java 2D và 3D 1.3 Rendering Text Để tạo bóng văn bản .com 56 . Gọi phương thức Graphics2D. g.4.green).phương thức setColor được gọi để định nghĩa màu tô là green fill cho một đối tượng Rectangle2D. 2.Float(25. Nhiều đối tượng http://tailieuhay.150). 2.ilr) 2fl(2. public void g2 paint(Graphics = (Graphics2D) g) g.150.25.fill để tạo bóng đối tựơng Shape. sau đó chuyển vào xâu mà bạn muốn tạo bóng .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 .cần gọi Graphics2D. sau đó chuyển vào xâu mà bạn muốn tạo bóng 2.setPaint(Color. { Graphics2D g2.4 Rendering images Để tạo bóng văn bản . Rectangle2D r2 = new Rectangle2D. 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.

6 Rendering in a Multi-Screen Environment TrongJavaTM 2 SDK.Một đối tượng GraphicsDevice có nhiều đối tượng GraphicsConfiguration kết hợp với nó .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.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. version 1. 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 .thiết bị ảo có thể có tọa độ âm . 0) của hệ tọa độ ảo . Khi hai hoặc nhiều màn hình được sử dụng để tạo một thiết bị ảo . Trong cả ba cấu hình.com 57 . JFrame. Dựa trên vị trí của màn hiển thị chính . 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. Java 2D API cho phép tạo các đối tượng Frame. Window.như trong hình 210: http://tailieuhay. 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.3. hoặc Jwindow .mỗi thiết bị hiển thị được biểu diễn bởi một đối tượng GraphicsDevice.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 đó .) 2.

Frame g) c.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. Cho ví dụ.com bounds = gc. thì môi trường đó chính là môi trường ảo.Vì vậy . 10) trong hệ tọa độ của màn hiển thị vật lý .Đ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. f = new Frame(GraphicsConfiguration Rectangle http://tailieuhay. 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.nếu một gốc tọa độ không phải vị trí (0. 58 .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ý . Vì vậy.các tọa độ của các đối tượng GraphicsConfiguration có quan hệ với hệ tọa độ ảo . 0). 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 .getBounds(). Trong môi trường thiết bị ảo .

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

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

trans. lineLabel. paint. stroke. paintLabel. JLabel primLabel. line. public static boolean no2D = false. static JComboBox primitive. TransPanel display. va rendering cung duoc lua chon boi nguoi su dung.Voi cac phuong * thuc paint.stroke. http://tailieuhay. ActionListener { /** * */ private static final long serialVersionUiD = -2514519718222913151L.com 61 . JButton redraw. transLabel. strokeLabel.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. */ /** * @author Administrator * */ public class Transform extends JApplet implements itemListener.

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

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

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

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

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

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

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

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

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

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

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

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

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

đường thẳng.chẳng hạn như điểm.1 Giao diện và lớp.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.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). Các lớp và giao diện của java.awt.awt.com 75 . 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.Những lớp hình học mới đó là một phần của gói java.Một giao diện mới Pathlterator.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.point và polygon.Một số.awt.như rectangle. 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.đường cong.awt.các lớp geometry có chứa trong các phiên bản trước đó của bộ JDK software.được chứa trong gói java.geom http://tailieuhay.awt. 3.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.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.hình chữ nhật.là thành phần của gói java. Các đối tượng hình học trong Java 2D API như GenneralPath.geom.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.Để có thể tương thích với các phiên bản cũ.chẳng hạn như Shape.awt.geom.

Double Mở rộng:RectangularShape Arc2D.Doubl Lớp thực thi:Shape.Được thực thi bởI GaneralPath và các lớp hình học khác.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. 76 CubicCurve2D. and http://tailieuhay.Float Implements: Shape Miêu tả các đoạn đường cong tham số bậc ba trong không gian tọa độ.Cloneable.Area Lớp thực thi:Shape.Việc thực thi chỉ rõ những đường cong trong kiểu số float và double.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. 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.Double.Lập trình đồ họa trên Java 2D và 3D Giao diện PathIterator Shape (java. Dimension2D Đóng gói cả chiều rộng và chiều cao.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.Double.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.góc ban đầu.và một kiểu đóng kín. CubicCurve2D e CubicCurve2D. Các lớp Arc2D Arc2D. Area Chính xác:Arc2D.Float CubicCurve2D.Float và Arc2D. 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.com .

Miêu tả một đoạn đường cong tham số bậc hai trong không gian tọa độ (x.Double Line2D.Float QuadCurve2D QuadCurve2D. Mở rộng: RectangularShape 77 http://tailieuhay. 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.Double. Thực thi đối tượng Shape.Được thực thi để xác đinh các điểm với độ chính xác float và double: Point2D.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.y) . Miêu tả một đoạn thẳng trong không gian tọa độ (x.Được thực thi để xác định các đường bậc hai với độ chính xác float Rectangle2D và double: QuadCurve2D.Double Point2D.Double.Float và 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.Double FlatteningPathIterator Trả về một flattened view của một đối tượng PathLterator.Float và Line2D.Float và Ellipse2D.Float đường thẳng và các đường bậc hai và bậc ba Thực thi đối tượng Shape.Double Ellipse2D.Float và Point2D.Float Point2D Point2D.Được thưc thi để xác định các đường thẳng với độ chính xác float và double:: Line2D.com .y).Lập trình đồ họa trên Java 2D và 3D Ellipse2D Ellipse2D.Doubl e QuadCurve2D.y). Một điểm miêu tả một vị trí trong không gian tọa độ (x.Double.Công cụ để chỉ rõ các đường cong elip vớI độ chính xác float và double: Ellipse2D.

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

hình elip.Để thuận lợi.Một clipping path xác định những điểm ảnh nào được đưa ra(render).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. học. clipping path là một phần của Graphics 2D. Một GeneralPath là một shape mà nó có thể được sử dụng java.bạn xem thêm phần “Setting the Clipping Path”.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.Bạn có thể tạo ra một đối tượng Area từ một số Shape.cung tròn và các đường cong.2.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. Để biết thêm thông tin.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. 3.com 79 . 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. 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.awt.

awt. 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.đó là getBounds và getBounds2D. http://tailieuhay.java * 1. một thể hiện của Rectangle .*.0 * 20/03/06 */ import java.com 80 .Cung cấp một độ chính xác cao hơn trong việc miêu tả shape’s bounding box.Phương thức getBounds2D trả về một đối tượng Rectangle2D .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. (contains ) • Một hình chữ nhật cụ thể phân cắt hình thể (intersects ) /* * Composite.2. 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ậ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.

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

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

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

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

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

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

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

Lập trình đồ họa trên Java 2D và 3D 150. 0).CAG có thể được sử dụng để tạo ra quả lê giống như hình 3-2 dưới đây: http://tailieuhay.tạo ra các Area để kết hợp lại. 2. null. } } Kết quả của chương trình : 3.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.subtract .intersect . g2.com 88 .Gọi các toán tử nhị phân thích hợp: add. exclusiveOr Ví dụ.Sử dụng các Shape.drawimage(buffimg. 100)). 0.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.

WindowEvent.Dimension.geom.awt.swing.swing.Ellipse2D. import java.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.Graphics2D.awt. import javax. import java.awt.0 27/03/06 http://tailieuhay. import java.geom.awt. import java. 1.awt.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ừ. Chương trình: /* * @(#)Pear.awt. import javax.com 89 .event. import java.Graphics. import java.event.java */ import java.Color.awt.JApplet.Area.WindowAdapter.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. import java.JFrame.awt.lapping Areas : circle và oval.

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

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

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

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

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. 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.awt.awt. 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.awt và java.bạn xem thêm phần java.bạn tham khảo thêm văn bản hướng dẫn về java.swing.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. Miêu tả các font kiểu mở(Open Type)và kiểu thực(True 94 http://tailieuhay.là một phần của gói java.như Font.text và “Using the JFC/Swing Packages” trong Java Tutorial. Để 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.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.awt.Nó còn bao gồm cả lớp Font và lớp TextLayout.font.1. 4.text và theo dõi phần “Writing Global Programs” trong bộ Java Tutorial.Đượ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. Để có thêm thông tin về phân tích văn bản.Hơn nữa. 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.com . 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.

Đó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. 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.độ ưu tiên. Một tập hợp các đường nét và các vị trí.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ó.Có thể phân lớp để thực thi kí tự tùy chọn để thay thế các graphic. 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. http://tailieuhay.như trọng lượng (chữ).Được thực thi bởi và ShapẻGaphicAttribute ImageGraphicAttribute.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. Cung cấp các phép đo cho một đường nét đơn. 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. Miêu tả các thông tin về đặc tính căn lề của một đường nét.Lập trình đồ họa trên Java 2D và 3D Type).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.sự GlyphMetrics GlyphVector GraphicAttribute thu hút và giới hạ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. Lớp Font (java.com 95 .

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.com 96 . 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. height. và font face name: http://tailieuhay. 4.2. leading. family name.chiều cao và thông tin đường cơ bản(ascent.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 font thương hay được sử dụng như font Helvet Bold và Courier Bold italic.Các thước đo bao gồm phần nhô lên.bao gồm cả các văn bản hai chiều.phần phía dưới. and baseline information).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. descent. 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).phần mũ. Có ba kiểu tên cho một đối tượng Font-đó là logical name.

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

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. và getLeading . • 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. 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. 4. • Ordering các đoạn text thích hợp.và các đường có thể liên quan đến các đường khác.Quá trình này được gọi là text layout. Trước khi một đoạn chữ có được hiển thị.Bạn cũng có thể truy xuất thông tin vê weight. • Đánh giá và bố trí các đoạn text. http://tailieuhay.com 98 .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. baseline và underline của Font thông qua LineMetrics. descender đến đỉnh của dòng tiếp theo.3 Các khái niệm về Text Layout.nhưng có một số kí tự có thể mở rộng về phía dưới của đường descender. getDescent.Lập trình đồ họa trên Java 2D và 3D descent.

3. và highlighting.phụ thuộc vào font và kiểu dáng(style).Hình dáng.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ụ.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. Phụ thuộc vào từng context. the context of a glyph must always be taken into account . Gyph(nét chữ) là một cách hiển thị trực quan cho một hay nhiều kí tự.và vị trí của glyph phụ thuộc vào văn cảnh của nó.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.chữ heh trong tiếng Ả Rập có bốn cursive form http://tailieuhay.các cursive form có tính bắt buộc trong chữ Ả Rập. hit detection.đặc biệt là chữ Ả Rập.kích thước.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.1 Vẽ chữ.Không giống tiếng Anh.các cursive form có thể khác nhau hoàn toàn về hình dáng.com 99 . Trong một số hệ thống văn bản. Để phát triển các phần mềm có thể triển khai trên toàn cầu. 4. Ví dụ như trong đoạn text viết bằng tay.

thay vì các kí tự kề nhau http://tailieuhay.Kiểu kết hợp này được gọi là ligature.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. Trong một số ngữ cảnh.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.com 100 .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.hầu hết các font tiếng anh chứa ligature như trong hình 43.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.

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.com 101 .Văn bản sử dụng kí tự mã hóa Unicode được lưu trữ trong bộ nhớ trong logical order.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.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. 4.Ví dụ.Khi các chữ ghép được tạo thành từ các kí tự Ả Rập. Visual order cho các glyph trong hệ thống ghi cụ thể(script) được gọi là script order. logical order là nơi mà trong đó các kí tự và các từ được đọc và ghi.mặc dú các http://tailieuhay.Ví dụ. 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.2 Ordering Text Trong ngôn ngữ lập trình Java.3.văn bản được mã hóa bằng cách sử dụng các kí tự mã hóa Unicode. logical order không nhất thiết phải giống như visual order. các số Arabic và Hebrew chạy từ trái qua phải.Ví dụ.hình dáng thay đổi một cách cơ bản hơn so với tiếng Anh.là nơi mà trong đó các glyph tương ứng được hiển thị.

Base direction là một script order của hệ thống ghi.miêu tả một nhóm từ Arabic nhúng vào một câu văn bản tiếng Anh.com 102 . Hình 4-5 Bidirectional Text Cho dù chúng là một phần trong một câu tiếng Anh.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).các từ Arabic được hiển thị trong các Arabic script. 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. base direction sẽ được chỉ định. 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.Các số bên dưới khung kí tự chỉ định insertion offsets.(Điều này có nghĩa Arabic và Hebrew.nếu văn http://tailieuhay.ngay cả khi không có các văn bản bằng tiếng Anh nhúng vào.Lập trình đồ họa trên Java 2D và 3D kí tự chạy từ phải qua trái.từ phải qua trái.Điều này được mô tả trong hình 4-5. 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ị.Ví dụ.

com 103 .Ví dụ.Đ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. 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. base direction là từ trái qua phải.Để có vị trí .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.thì base direction sẽ là từ phải qua trái.Bởi vì hình dáng và vị trí của các kí http://tailieuhay.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.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ố.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ự đó.Trong trường hợp này.Ngược lại. 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ị.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.các kí tự khác nhau trong kiểu font có chiều rộng khác nhau.Có ba hướng bố trí văn bản trong ví dụ này.3 Đo và định vị văn bản Trừ khi bạn làm việc với font đơn cách.và các văn bản khác chạy từ trái qua phải.Đẻ căn lề các cột một cách đúng đắn.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. 4. Để hiển thị các văn bản đúng trong nhiều ngôn ngũ chẳng hạn như Hebrew và Arabic. 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.như theo kiểu nét đậm và in nghiêng.văn bản tiếng Anh ở đoạn đầu của câu chạy từ trái qua phải.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.kích thước và render text chính xác.phụ thuộc vào cách nó thể hiện kiể u dáng.Trong ví dụ 5-4.các kí tự giống nhau có thể có các hình dáng khác nhau về chiều rộng.văn bản Arabic chạy từ phải qua trái.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. Để cho phép người dùng có thể sửa đổi text đã được hiển thị.dấu caret được sử dụng để hiển thị điểm chèn hiện tại.các dấu caret được thể hiện là các dấu ngoặc vuông. http://tailieuhay.3.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.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. • Làm nổi bật đoạn text được lựa chọn.Thông thường.đặc biệt là trong các text hai chiều.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.vị trí trong đoạn text nơi mà các kí tự mới sẽ được chèn vào.Điều này được miêu tả trong hình 46.một dấu caret được thể hiện là một thanh thẳng đứng nhấp nháy giữa hai glyph.Trong hình vẽ này. Việc tính toán vị trí dấu caret có thể rất phức tạp. 4.4 Hỗ trợ thao tác với văn bản.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.1 Hiển thị dấu nhắc Trong các text có thể chỉnh sửa được.com 104 .Kí tự mới được chèn vào và được hiển thị tại vị trí của dấu caret.4. • Phát hiện sự lựa chọn của người dùng(hit detection). 4.

Còn nếu người dùng muốn chèn một kí tự English.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.một dấu là chính (primary) còn một dấu là phụ (secondary).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ý.glyph của nó được hiển thị bên trái(phía sau) của dấu _.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.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 TextLayOut tự động hỗ trợ cả hai dấu caret.còn lớp JtextComponent thì không.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.Nếu người dùng muốn thêm một kí tự Arabic vào chỗ đó.glyph của nó được hiển thị bên phải(phía trước) của kí tự A. Để làm đươc điều này một số hệ thống hiển thị hai dấu caret.com 105 . Khi làm việc với văn bản hai chiều.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.

các phép đo glyph sẽ không cần thiết khớp với việc hiển thị.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.3. 4.Trong các văn bản hai chiều hoặc các văn bản có nhiều chữ ghép.com 106 .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..4.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. 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.Lập trình đồ họa trên Java 2D và 3D hiện tại đưa vào tính toán.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ó.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.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. 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.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. Để 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.2 Di chuyển dấu nhắc.

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.com 107 .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.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.Ví dụ.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 người sử dụng nhấn chuột vào văn bản được chọn.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. 4.Theo một cách logic.nó được chuyển ngược thành vị trí của dấu caret.thay vào đó dấu caret di chuyển qua các hiển thị của glyph một kí tự đơn.Ví dụ như. Khi bạn làm việc với văn bản hai chiều.3.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.3 Hit Testing Thông thường.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. 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.4.

Bạn có thể thực hiên hit testing bằng việc sử dụng lớp TextLayout.3.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.com 108 . 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.Với vùng sáng logic.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).bạn có thể có nhiều dải các kí tự được lựa chọ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. 4. • Visual highlighting(vùng sáng trực quan) . Vùng được tô sáng.Xem ví dụ về logical highlighting.xem hình 4-10.Ví dụ về visual highlighting.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ị. http://tailieuhay. 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 đó.4 Đánh dấu vùng lựa chọn.đó 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.nhưng vùng sáng thông thường liên tiếp nhau.4.giống như dấu caret.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.với visual highlighting.xem hình 411.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).Ngược lại.dải liên tiếp của các kí tự.hitTestChar.

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. • Nếu bạn muốn hiển thị một đoạn chuỗi kí tự đơn giản.3.nó sẽ thực hiện text layout cho bạn.bạn có thể gọi đối tượng Graphics2D.com 109 .5 Thực thi việc hiển thị văn bản trong ứng dụng Java™ . • 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. 2.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ũ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.drawString và yêu cầu Java 2D hiển thị chuỗi kí tự cho bạn. Phụ thuộc vào Java™ APIs mà bạn sử dụng.Để thêm thông tin về JtextComponent bạn xem thêm phần “Using the JFC/Swing Packages” của bộ Java Tutorial.các kí tự được lựa chọn thường liên tiếp nhau. 4.bạn có thể sử dụng JtextComponent.

và văn bản hai chiều. 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. 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. 3.bao gồm http://tailieuhay.com 110 .bạn xem thêm phần Managing Text Layout.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.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. •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í.bao gồm các xâu văn bản với việc pha trộn các kiểu Font.bạn xem thêm phần “implementing a Custom Text Layout Mechanism” .bạn không cần phải thực hiện text layout.Nếu ứng dụng của bạn yêu cầu những đặc tính trên. Quản lý việc hiển thị văn bản.bạn có thể sử dụng TextLayout để điều khiển việc hiển thị văn bản(text layout).hoặc bạn thích thực hiện việc chỉnh sửa văn bản của bạn.và hit detection.Để có thêm thông tin về cách thực thi công cụ text layput của bạn.pha trộn các kiểu ngôn ngữ.Cho hầu hết các ứng dụng.bạn có thể sử dụng Java 2D text layout APIs.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.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. • Nếu bạn muốn thực thi việc chỉnh sửa văn bản của bạn.bạn xem thêm phần “Rendering Graphics Primitives”.Tuy nhiên. 4.tô sáng( highlighting). Thông thường.Để có thêm thông tin về cách sử dụng TextLayout.Để có thêm thông tin về rendering text qua lớp Graphics2D.

Để shape và order một cách chính xác. 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.1 Trình bày văn bản.4.và cách ghép chữ(ligature information).các bảng co kéo(kerning tables).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.kể cả các văn bản một hướng(BiDi-bidirectional).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).com 111 . Lớp TextLayout sẽ đặt văn bản một cách tự động. 4.bypassing công cụ bố trí của hệ thống(bypassing the sys. ờng hợp. • Hiển thị và di chuyển dấu caret. 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ể xây dựng giải thuật của bạn để tính toán cách bố trí văn bản. • Thực hiện hit testing trên văn bản.tem’s layout mechanism).Để có thêm thông tin bạn xem thêm phần “implementing a Custom Text Layout Mechanism”. • Tô sáng vùng văn bản được lựa chọn.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ị).với việc tạo hình dáng(shaping) và ordering chính xác.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.Việc sử dụng các thông tin như các kích cỡ đường nét(glyph sizes). TextLayout phải biết toàn bộ ngữ cảnh của văn bản: http://tailieuhay.các đường nét phải miêu tả các đường(line) của văn bản.

Hiển thị dấu nhắc kép.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).như bạn thấy trong hình 412.bạn có thể xây dựng một đối tượng TextLayout trực tiếp từ văn bản. 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.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.lớp TextLayout sử dụng giải thuật của bảng mã hai chiều Unicode.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) . 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).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.và nhận được hướng cơ bản từ các kí tự bắt đầu trong đoạn.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. Hình 4-12 Angled Carets http://tailieuhay.Khi bạn vẽ dấu caret cho văn bản một chiều.vị trí và góc(angle). • 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.Nếu thuộc tính đó bị thiếu.com 112 .Bạn phải sử dụng đối tượng LineBreakMeasure để đáp ứng đủ các ngữ cảnh.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.

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.4.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. Trong ví dụ dưới đây.draw(caretShapes[1]).3 Di chuyển dấu nhắc. 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.bạn đơn giản chỉ là vẽ cả hai shape của dấu caret.com 113 . g2. 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.setColor(SECONDARY_CARET_COLOR).Để hiển thị cả hai dấu caret(dấu caret kép). g2.nếu chúng cùng tồn tại.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ụ.Dựa vào đối tượng TextHitinfo.setColor(PRiMARY_CARET_COLOR).getCaretShapes(hit).nó cho ta biết vị trí hiện tại của khoảng trống thêm vào.draw(caretShapes[0]).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.các dấu caret sẽ được render một cách tự động tại những vị trí chính xác.Đây là cách phổ biến để tạo sự khác biệt của hai dấu caret . Shape[] caretShapes = layout. if (caretShapes[1] != null){ g2. } 4. Nếu bạn muốn sử dụng shape của dấu caret một cách tùy thích.

Trong ví dụ dưới đây. draw caretShapes carets = layout.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.getNextRightHit(insertionOffset). TextHitinfo int hit = = layout.Đố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. TextHitinfo if { Shape[] // .getinsertindex().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. newinsertionOffset != = layout.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.getCaretShapes(newinsertionOffset).4.. hit.com 114 .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. insertionOffset } = newinsertionOffset. Trong ví dụ dưới đây.hitTestChar(x. insertindex http://tailieuhay. y).. (newinsertionOffset null) 4.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.4 Hit Testing Lớp TextLayout cho ta một công cụ đơn giản để hit testing văn bản.

fill(highlightRegion).drawString(layout.5 Đánh dấu vùng lựa chọn. http://tailieuhay. graphics. Đố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. advance. visible advance và bounding rectangle (giới hạn của khung hình chữ nhật). 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.descent. graphics.Các giá trị ascent và descent của toàn bộ kiểu font được sử dụng trong đối tượng TextLayout.com 115 .Lớp TextLayout hỗ trợ cả vùng sáng logic và vùng sáng trực quan.nó không có giá trị leading cực đại. Trong ví dụ dưới đây.setColor(HiGHLiGHT_COLOR). 4. graphics.4.Các phép đo đã có sẵn trong lớp TextLayout bao gồm ascent.Việc tính toán giá trị leading của đối tượng TextLayout thì phức tạp hơn nhiều.leading(khoảng cách giữa các dòng chữ so với dòng cơ sở). highlightRegion = layout.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ị. 0.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).Lập trình đồ họa trên Java 2D và 3D 4.getLogicalHighlightShape(hit1.4. 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).Đây là một cách đơn giản để hiển thị đoạn văn bản được tô sáng.

bounds.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.getY()-1.bạn có thể lấy một đoạn của văn bản. Lớp TextLayout còn có thể được sử dụng để hiển thị đoạn text mà nó có nhiều dòng. Để làm được điều nà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.Giá trị advance thường được chỉ định là total advance. 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í.drawRect(bounds..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. 4.4.Khung giới hạn có quan hệ với nguồn gốc của đối tượng TextLayout.7 Vẽ văn bản trên nhiều dòng.getX()-1. graphics. Rectangle2D bounds = 0.com 116 .không liên quan đến vị trí trên màn hình. bounds.getBounds(). graphics.getHeight()+2).(Một số trong đó có thể được lấy từ gốc hoặc gốc + advance).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.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.và hiển thị các đoạn như nhiều dòng của văn bản.văn bản trong một đối tượng TextLayout được vẽ bên trong một khung giới hạn.Ví dụ như.drawString(layout. bounds. Trong ví dụ dưới đây.chồng các line của văn bản đó một bề rộng nào đó.getWidth()+2. 0). layout.

event.awt.event.Vector.awt.WindowEvent.awt.FontMetrics.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ị.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. import java. http://tailieuhay.awt. import java.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.Color.WindowAdapter.awt.com 117 .java * 1.Graphics.awt.BorderLayout. import java.util. import java.Graphics2D.swing.GridLayout. import java.GraphicsEnvironment. import java. import java. import javax. import java.Lập trình đồ họa trên Java 2D và 3D văn bản trong một đoạn đã có sẵn.0 * 12/03/06 */ import java.event.Font.Dimension. Khi văn bản được hiển thị qua nhiều dòng.awt. import java.awt. import java. /* * FontSelection.awt. import java.awt.event.awt.itemEvent.awt.JApplet.itemListener. import java. import java.

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

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

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

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

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

f. fontSelection.com 123 . f.init().addWindowListener(new WindowAdapter() { public windowClosing(WindowEvent e) { System. Font thisFont.exit(0). } }).setSize(new Dimension(550. } } class FontPanel extends JPanel { /** * */ private static final long serialVersionUiD = 7850814263388447528L. f.CENTER). JApplet FontSelection(). BorderLayout. 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").setVisible(true). 250)).add(fontSelection. public FontPanel() { fontSelection = new void http://tailieuhay.getContentPane().

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

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

5.com 126 . 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. •Model khách chủ (producer/consumer) đã hỗ trợ trong phiên bản trước củan bản JDK.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. các lớp dữ liệu ảnh. 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ớ. •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. http://tailieuhay. •Model trung gian (immediate mode model) được giới thiệu tr ong Java™ 2 SDK release. các lớp model màu. các lớp thao toán tử ảnh.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. các ngoại lệ (exceptions). các lớp model mẫu. 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).

LookupOp và RescaleOp. ColorConvertOp.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. RescaleOp. ColorConvertOp. TileObserver Định nghĩa các đối tượng muốn được báo khi trang . Đị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. http://tailieuhay.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. 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.com 127 . ConvolveOp.1.Lập trình đồ họa trên Java 2D và 3D 5. ConvolveOp.1. LookupOp và 5. Được cài đặt bởi RasterOp AffineTransformOp. thái chỉnh sủa của một WritableRenderedimage thay đổi. BandCombineOp.

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.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. 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ột bộ đệm dữ liệu chứa các byte dữ liệu. 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. Một Raster chứa một DataBuffer và một SampleModel. Bao bọc một hay nhiều các mảng dữ liệu chứa dữ liệu điểm. 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.com . Mỗi mảng được gọi là “bank” Mở rộng DataBuffer. Mở rộng LookupTable Một LookupTable chứa các bye dữ liệu. (đã 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).

Lập trình đồ họa trên Java 2D và 3D 5. 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ài đặt BufferedimageOp. 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. RasterOp Dùng một Kernel để thực hiện cải thiện ảnh nguồn. RasterOp Thực hiên sự chuyển đổi dữ liệu màu điểm theo ConvolveOp điểm trong ảnh nguồn.3 image Operation Classes Clases Description AffineTransformOp Cài đặt : BufferedimageOp.com 129 . http://tailieuhay. 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. 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. Cài đặt BufferedimageOp. Cài đặt RasterOp Dùng một ma trận xác định.1. 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. 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.

Lập trình đồ họa trên Java 2D và 3D LookupOp Cài đặt BufferedimageOp.com 130 .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.1. 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). 5. RasterOp Thực hiện thao tác tham chiếu từ nguồn tới đích. 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à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. Với các Raster. các Bufferedimage. các thao tác tham chiếu trên các giá trị mẫu. thao tác tham chiếu RescaleOp trên thành phần màu và thành phần alpha.

com 131 . 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ư đỏ. xanh lá cây. một mảng các thành phần màu ứng với ColorSpace. blue). 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. và tất cả các phần tử trong bank SampleModel đơn của một DataBuffer. 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ộ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. Mở rộng ColorModel Một ColorModel có thể giữ một ColorSpace có thể thay đổi. 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. xanh da trời (red.

getRGBdefault DirectColorModel. 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. Đưa ra nếu một trong các phương thức BufferedimageOp hoặc RasterOp không thể xử lý ảnh. Mở rộng RuntimException. 132 RasterFormatException http://tailieuhay. PackedColorModel Extends: ColorModel Mở rộng ColorModel.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.1 . 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. 5. RGB như một ColorModel mặc định được trả về bởi ColorModel.com .6 Exception Classes Clases imagingOpException Description Mở rộng RuntimException.Lập trình đồ họa trên Java 2D và 3D DirectColorModel Mở rộng lớp PackedColorModel JDK1. rộng DirectColorModel indexColorModel PackedColorModel để hỗ trợ các điểm chứa SampleModel các thành phần màu RGB. Model màu này tương tự với một X11 TrueColor.

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 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. Như hình 5-1.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ớ. Bufferedimage cung cấp việc quản lý ảnh chung. Một đối tượng Bufferedimage chứa 2 đối tượng khác: một Raster và một ColorModel. 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.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 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ợ. 5.com 133 . Lớp Raster cung cấp quản lý dữ liệu ảnh. Nó biểu diễn toạ độ de-cac của ảnh và duy trì dữ liệu ảnh trong bộ nhớ. và cung cáp một cơ chế cho http://tailieuhay.

một DataBuffer và một SampleModel. 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. hoặc cả hai giao diện.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. giao diện RasterOp. 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ự. 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. 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). Một đới tượng Raster chứa hai đối tượng khác. MỖi thao tác xử lý ảnh được nhúng trong lớp cài đặt giao diện BufferedimageOp.com 134 . Hình 5-2 minh hoạ model cơ bản cho Java 2D™ API image xử lý ảnh. Lớp DataBuffer giữ dữ liệu điểm trong bộ nhớ. 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.

Dữ liệu điểm có thể được chứa trong một số cách. 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ó. 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. green và blue.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. Các mẫu . hỗ trợ hai trong Java 2D API đang được tụ họp và thêm vào. Lưu trữ tập hợp tổ chức dữ liệu ảnh bởi các dải (bands). Dải . Sự phân biệt giữa thành phần(component) và mẫu(sample) là hữu ích với indexColorModel. Ví dụ. 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.Samples: Các thành viên riêng biệt của các điểm của một ảnh. bạn chỉ cần hiểu lớp Bufferedimage và các lớp thao tác lọc.2. một điểm trong model màu RGB bao gồm 3 mẫu : red. 5.com 135 . 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ể. Mặt khác. 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ơi mà các thành phần điểm được đánh chỉ số sang LookupTable. Các thành phần .Components: Các giá trị của các điểm độc lập với sự biểu diễn màu. 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.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.Band: Tập tất cả các mẫu của một loại trong một ảnh. bạn cần phải hiểu các lớp liên quan với Bufferedimage.

width.createimaget. cung cấp các cách để lưu các dữ liệu điểm. null != || offimg. getSize(). Nó cũng quản lý mọt ảnh trong bộ nhớ.3.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. 5.Lập trình đồ họa trên Java 2D và 3D mảng đơn chứa tất cả các điểm. và blue.getHeight() http://tailieuhay. biểu diễn dữ liệu điểm. 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. 5. Ảnh được tạo là không rõ . 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ó. Graphics2D width height (offimg || getSize().getWidth() { 136 != width offimg. ví dụ model RGB dạng các giá trị màu từ các nguyên tố red.3 Using Bufferedimages Lớp Bufferedimage là lớp chính hỗ trợ mode tạo ảnh trung gian.height. Các nguyên tố . green. gọi Component. và đẩy dữ liệu điểm tới một Graphics hoặc ngữ cảnh Graphics2D.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.com height) . public g) int int if { Graphics2D g2 = = == = createDemoGraphics2D(Graphics null.1 Creating a Bufferedimage Để tạo một Bufferedimage. 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.

Tất cả các http://tailieuhay. nếu bạn muốn hiển thị`hình ảnh tinh vi trong vài lần.3.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ổ. } if g2 } // .createGraphics(). canvas .. g2. clear height). (offimg = != null) { = (Bufferedimage) createimage(width. 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. 0. g2.setBackground(getBackground()). 5. width.Lập trình đồ họa trên Java 2D và 3D offimg height). Java.clearRect(0. Ví dụ. 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.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.. 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ổ.com 137 . 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. offimg.

5.1 Creating an Offscreen Buffer http://tailieuhay. Thay vào việc vẽ lại hình tại mỗi vị trí. Ví dụ. 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ổ. Tương tự. Lần cuối cùng ảnh được sao chép. 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. 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.3. Các bộ đệm offscreen thường được dùng cho hoạt hoạ. 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.2. 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). nó đã được biến đổi.com 138 .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.

Trong http://tailieuhay. một kênh alpha được dùng để phân biệt các vùng được vẽ và không được vẽ. 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.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ó. 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 . Trong hình 5-3. Điều này cho phép hàm drawimage làm việc nhanh chóng. Đ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. image có thể được đưa tới (blitted) thiết bị đồ hoạ một cách hiệu quả. 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. và bố trí các điểm chính xác với cửa sổ trong đó bạn đang vẽ. sâu. một hình chữ nhật bóng).createimage.

width. 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. và render các hình ảnh khác trong image. 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.height.2. Gọi Bufferimage. có thể gọi tát cả các phương thức Graphics2D để vẽ các hình ảnh nguyên tố. (Bufferedimage)createimage(w. 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. bi. Dùng alpha ở nơi nó không cần làm chậm hiệu năng render.com 140 . như với một hình ảnh dạng bất thường biểu diễn trong hình 5-2. Chú ý : trừ khi bạn cần một dữ liệu ảnh alpha cho rõ ràng.createGraphics(). 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. dim. h).3. Đ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. if(firstTime){ dim. new Rectangle(dim). tra về một đối tượng Graphics2D. http://tailieuhay.createGraphics() .Lập trình đồ họa trên Java 2D và 3D vài trường hợp khác. bạn cần khởi tạo một đối tượng Bufferedimage thích hợp 5.2 Drawing in an Offscreen Buffer Để vẽ trong một bộ đệm ảnh. Với đối tượng này. bạn nên tránh tạo một bộ đệm offscreem alpha. getSize(). text.

big. image this). positioned buffer. big.clearRect(0. big. h/2-25). that was previously = false.white).setPaint(fillPolka). drawn.com 141 . big.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. // Draws and area.width.3. } 5. 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.draw(rect).3 Manipulating Bufferedimage Data Directly Cùng với việc vẽ ảnh trực tiếp trong Bufferedimage. to the screen.setLocation(w/2-50.Lập trình đồ họa trên Java 2D và 3D rect.height).0f)). buffered 0. 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. // Draws the big.fill(rect). Bạn cũng có thể dùng phương thức Bufferedimage.setStroke(new firstTime } // Clears the rectangle 0. fills to newly the rectangle big.setPaint(strokePolka). 0.drawimage(bi. g2.setColor(Color. BasicStroke(8. không có sự lay động khi bạn modify các http://tailieuhay. the area.

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. . Ví dụ khi rendering trong phương thức Component.width 0) return. { (offimg isShowing()) 0.Lập trình đồ họa trên Java 2D và 3D điểm một cách trực tiếp.3.drawimage(offimg.5 Rendering a Bufferedimage Để render một bộ đệm ảnh vào trong một ngữ cảnh cụ thể. g. 5.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. this). g2.3.paint. public if <= void paint(Graphics <= 0 g) || { getSize(). 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).height (getSize(). Graphics2D if } } Chương trình ví dụ: http://tailieuhay. bạn gọi drawimage() trên đối tượng đồ hoạ đã truyền cho phương thức. gọi hàm drawiamge của ngữ cảnh của đối tượng Graphics.com 142 g2 != = (Graphics2D) null && 0.

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

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

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

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

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

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

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

và gốc toạ độ.4.1 Creating a Raster Trong hầu hết các trường hợp. độ cao. return false. Tuy nhiên. } rect. } if (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. new_y). 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. 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.com 150 . } } 5.Lập trình đồ họa trên Java 2D và 3D new_y = area. Một đối tượng Raster tự nó dùng 2 đối tượng để quản lý dữ liệu điểm. bởi vì một Raster được cung cấp với bất cứ Bufferedimage bạn tạo trong bộ nhớ. không cần phải tạo một Raster trực tiếp. một DataBuffer và một SampleModel.49.độ rộng .setLocation(new_x. 5.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. http://tailieuhay.height .y < 0) { new_y = -1. 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.

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. 5.Lập trình đồ họa trên Java 2D và 3D 5.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. Cùng với các phương thức đó. Điều đó rất hữu ích khi khi bạn cài đặt giao diện RasterOp. 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. Phương thức Raster.4.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.4. 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.com 151 . Các phương thức Raster. Phương thức getSamples trả về một dải (band) cho một vùng cụ thể của một image. 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ể. Các phương thức Raster.getPixel cho phép lấy về một điểm riêng biệt. nó trả về như là một mẫu riêng biệt trong một mảng. Cha và các con của nó tham chiếu tới cùng một bộ đệm dữ liệu. Một con xác định cha của nó qua bằng hàm getParent().2 Parent and Child Rasters Lớp Raster kết hợp ý tưởng các raster cha và con. dùng phương thức Raster. Đ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. Raster liên kết với một Bufferedimage thực ra là một http://tailieuhay. 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).createSubRaster. Khi tạo một subraster. nó cung cấp bộ lọc cấp và xử lý dữ liệu của ảnh. 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.

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 xác định độ rộng và chiều cao trong các pixel. 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.com 152 . Khi bạn tạo một Raster trực tiếp hoặc qua các hàm tạo Bufferedimage. 5.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ù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. 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. Có 3 lớp con của DataBuffer. 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. http://tailieuhay.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ó. 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. 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ể.

• 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.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.awt. • 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 ). 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ể. Các phương thức SampleModel cung cấp dữ liệu ảnh như tập(collection) các điểm. 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ó . 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. java.Lập trình đồ họa trên Java 2D và 3D 5.com 153 . và cho việc mô tả số lượng các band và kiểu dữ liệu đệm.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. http://tailieuhay. • 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.

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. • 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 phương thức getPixel trả về cả một điểm trong một mảng. DirectColorModel model tương tự với một X11 TrueColor visual. DirectColorModel là một lớp con (subclass) của PackedColorModel.com 154 . trong dữ liệu ảnh đồ hoạ photo. Các phương thức getDataElement cung cấp truy cập tới dữ liệu thô. 5. Trong dữ liệu ảnh từ một thiết bị ảnh y tế. http://tailieuhay.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. với mỗi đầu vào cho mỗi mẫu. Gói java. 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.7 ColorModels and Color Data Cùng với Raster cho quản lý dữ liệu ảnh.Lập trình đồ họa trên Java 2D và 3D phụ thuộc vào dữ liệu nguồn. các mẫu có thể biểu diễn dữ liệu RGB. không thể hiện được chứa trong DataBuffer. Có ba category của các phương thức cho truy cập dữ liệu ảnh. 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ó. Ví dụ.awt. • 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. 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. • 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.

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

ConvolveOp cop ConvolveOp(kernel.0f.EDGE_NO_OP. Bufferedimage(bw.Bufferedimage.0f.0f}. -1.0f. -1. cop.0f. . null).0f. Hình 5-5 Xử lý Lookup-Table Đoạn code sau demo thao tác Lookup-table: http://tailieuhay. Hình 5 -5 demo xử lý bảng tham chiếu. Bufferedimage Kernel kernel = new = bimg Kernel(3. 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. 0.com 156 .0f...0f.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. elements 4.filter(bi. 0.bimg). -1. = { 0.TYPE_iNT_RGB).bh. new elements).f. new = 3. 0. ConvolveOp.

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

= array i < with 9. Đoạn mã sau minh hoạ cách dùng một trong các lớp xử lý hình ảnh.0f. 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 ConvolveOp.0f/9.5f.8. float float[] 2D // for } array fill (i = the 0.filter(bi. // create elements i++) elements[i] weight.0f.Lập trình đồ họa trên Java 2D và 3D RescaleOp null).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. 5. nine { equal elements weight = 1. rop. http://tailieuhay. Trong ví dụ này. 1.bimg).com 158 . = new float[9]. 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. Đ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.

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

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. bạn có thể thực hiện các kiểu convolution khác nhau bao gồm blurring (như Gaussian blur.0f. radial blur. một chương trình có thể tăng hoặc giảm cường độ của ảnh đích. và motion blur).0f.com . Mỗi giá trị tỏng nhân được tied tới các vị trí trong hình ảnh. Đối tượng Kernel. -1. Hình 5-8 Sharpening with Convolution Đoạn code dưới đây minh hoạ sharpening với float[] elements = { 0. và smoothing Hình 5-8 minh hoạ sharpening dùng Convolution. 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. 0. Với nhiều bộ lọc đơn giản. kernel là một ma trận vuông Convolution kernel trong ví dụ này liên quan đơn giản. 160 http://tailieuhay. xác định kiểu bộ lọc nó thực thi. Bởi việc đặt các gía trị khác.0f. 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. sharpening. được đặt trong khởi tạo của ConvolveOP .

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

Để vẽ một Shape với một màu.awt. 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..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.awt. Một ColorSpace biểu diễn cho một hệ thông cho việc định lượng màu. 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ể.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. Tiêu biểu như biểu diễn bằng 3 giá trị số(RGB) họăc các thành phần.com 162 . Color. ColorModel được định nghĩa trong java.image http://tailieuhay. 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. 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. chẳng hạn màu đỏ.ColorModel miêu tả một cách cụ thể những điểm được ánh xạ tới các màu. Color được đinh nghĩa trong java.

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. 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ạ. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D 6. BufferedImage.com 163 . 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. Extends: ColorSpace Represents device-independent and devicedependent color spaces based on the ICC ICC_Profile Profile Format Specification. Has methods to transform between RGB and ICC_ColorSpace CIEXYZ color spaces. or GraphicsDevice. 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. Image. Đ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ể. 6. Một ColorModel được sử dụng để biểu diễn một dữ liệu diểm trong ảnh.1 Các lớp Clases ColorSpace Description Identifies the color space of a Color object.2 Những định nghĩa về mầu sắc. Extends: ICC_Profile A representation of color space type gray.

tiêu biểu như việc sử dụng 3 giá trị số riêng biệt. 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 ).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. Một màu được xác định trong bất cứ http://tailieuhay.2. 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 . ĐirectColorModel trong JDK 1. 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. hoặc một GraphicsConfiguration. 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. 6.: 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. mỗi Color cũng có thể chuyển từ sRGB.(ColorSpace).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.1 release la một PackedColorModel.Ví dụ RGB. 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. của một imae . Vì mỗi Color chứa một đối tượng ColorSpace đặt tường minh hoặc mặc định.com 164 . một Bufferedimage. CMYK là các không gian màu. 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.1 release. 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 đó.

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. 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. thao tác trên toàn ảnh. với một Color một lúc. Hình 6-1 biểu diễn mapping qua sRGB. 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. 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. để giải quyết vấn đề này.( 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.com 165 . Tất nhiên. 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.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. Ví dụ. Những điêm màu sẽ không được http://tailieuhay. 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. 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). sRGB không thể biểu diễn mọi màu trong cả giải màu CiEXYZ. Như hình minh hoạ. lớp ColorSpace có thể ánh xạ các màu tới và từ không gian màu khác . Các phương thức được dùng cho quá trình này là toRGB() và fromRGB().

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. 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. Tiêu http://tailieuhay. 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.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.com 166 . ColorSpace la thực ra là một lớp trừu tượng. 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. màu được chuyển qua một cách đứng đắn. Khi CiEXYZ được sử dụng. 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.

html).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. 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. 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.máy in. màn hình. Vai hàm khởi tạo được định nghĩa bởi lớp Color http://tailieuhay. 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. Các đối tượng iCC_ColorSpace có thể được khởi tạo từ các iCC_Profile.(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. iCC profiles mô tả một không gian vào và không gian kết nối. 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). Cũng có thể sử dụng CMS để tìm sự ánh xạ tốt nhất giữa các profiles 6. 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 .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ể. iCC_ColorSpace là một sự cài đặt của lớp trừu tượng ColorSpace.2. và định nghĩa cách ánh xạ giữ chúng. 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.com 167 . W3. org/pub/www/Graphics/color/sRGB. 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.

Đối tượng ColorSpace xác định không gian màu. 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 đó. xanh da trời (Blue). Để hiển thị một hình chữ nhật đúng màu giống như màu cyan. 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. bạn cần một cách để mô tả màu này cho hệ thống. 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. http://tailieuhay. yellow. (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. Như bạn biết. 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. magenta. và sử dụng thể nghiệm mặc định của ColorSpace để biểu diễn cho không gian đó.Lập trình đồ họa trên Java 2D và 3D cho phép bỏ qua tham số ColorSpace. 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. Magenta. xanh lá cây (Green). Có một số cách khác nhau để mô tả một màu. black để tạo ra màu trên trang giây in . Black . 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.com 168 . Tương tự. 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). 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. 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). 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). xanh lá cây(green). xanh da trời(blue) hay tập hợp các thành phần(CMYK) Cyan. không phải là tham chiếu không gian màu cho sự chuyển đổi màu. quá trình in 4 màu dùng cyan.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 Để thích hợp vơi sự phổ biến của cả màn hình và máy in màu. Để đạ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. Tuy nhiê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. được định nghĩa bởi international Color http://tailieuhay. 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 .com 169 . 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ị. 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. 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. cả 2 loại không gian màu có một hạn chế là phụ thuộc thiết bị. Khi bạn xác định một màu dùng CiEXYZ. Thật không may mắn. 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. cả hai không gian màu RGB và CMYK được dùng để biểu diễn màu. không phải lúc nào cũng dùng không gian màu CiEXYZ. bạn được cách ly với độc lập thiết bị. Những thông tin thêm này được gọi là profile. 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). Tương tự. Mapping Colors qua sRGB và CiEXYZ Java 2D API dùng RGB và CMYK la 2 loại không gian màu. Tương tự. Không gian khác nhau . môt model máy in cũng có không gian CMYK của nó. 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ó.

và sau đó từ không gian đó sang không gian màu thiết bị ra. sự chuyển đổi được dùng để xác định toạ độ trong không gian http://tailieuhay. Khi API có một màu xác định một cách chính xác. 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. 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. như màn hình và máy in. Cả 2 trường hợp. y. phiên bản 3. Trong nhiều khía cạnh. 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. Org. Như bạn thấy trong 6-3 cả màu vào và ảnh có các profile được gắn vào. nó phải tạo lại màu trên thiết bị ra.4 trên trang http:// www. Ví dụ. 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. 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.color.Lập trình đồ họa trên Java 2D và 3D Consortium. Chi tiết xem iCC Color Format Specification. 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.com 170 .

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. Đ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. 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. thứ tự in. 4. cả Windows và Solaris.com 171 . 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. 3. Chương 7 In ấn Java Printing API cho phép ứng dụng cho: 1. và booklet printing. bao gồm đồ hoạ đa hợp (composited graphics) và hình ảnh. In với tất cả các platform. In với AWT và đồ hoạ Java 2D™ .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. 2. 7. Các hàm in xác định trợ giúp như in duplex (duplex printing) và stapling.1 Các giao diện và các lớp http://tailieuhay.

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

Describes the physical characteristics of a piece of paper. 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. không phụ thuộc trang nào hệ thống in yêu cầu. hệ thống in giông như window toolkit. display a print dialog to the user (optional). and to print the pages in the job.resented by Paper PrinterJob PageFormat. as well as the Paper used to print it.Lập trình đồ họa trên Java 2D và 3D printed. Ứng dụng phải cho phép tạo ra hình ảnh đúng của trang.com 173 . 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ự. http://tailieuhay. Ứ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. portrait and landscape paper orientations are rep. For example. Các định nghĩa về in Java Printing API dựa trên mô hình in callback trong đó hệ thông in. 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. The principal class that controls printing. Trong khía cạnh đó. The application calls PrinterJob methods to set up a job. không phải úng dụng sẽ điều khiển khi các trang được in.

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

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

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

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

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

 Xác định các đặc điểm của công việc để in cho PrinterJob. giống như số bản sao để in hay tên của công việc trên đầu đề trang. 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. với Pageable job. Chú ý một đối tượng Book là một mẫu truyền cho setPageable. 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. 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. Trên hầu hết các platform. Gọi hàm printDialog để hiển thị hộp thoại cho người dùng.getPrintJob  Xác định PageFormat để dùng cho việc in. Điều này là tuỳ chọn. gọi setPageable. gọi setPrintable. PrinterJob. Phương thức này khi trả về gọi print trên các page painter tương ứng.cancel được gọi.  http://tailieuhay. phương thức printDialog trả về FALSE.print để in. 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. Cho một Printable job.  Gọi Printerjob. 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). vòng lặp in sẽ bị chấm dứt và công việc bị huỷ bỏ. 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 .  Xác định các thuộc tính thêm cho việc in. 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 đó. Nếu người dùng huỷ việc in.com 179 .

các hộp thoại không cần thiết. Việc in thường không kêt thúc (finished) khi phương thức in tra về.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. ví dụ như. Không hợp lý yêu cầu các phương thức vào nhiều lúc. 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”. Ví dụ. thị một thể nghiệm của PageFormat được tạo(cloned). 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. 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. Nếu người dùng click vào nút OK trong hộp thoại. Tuy nhiên. Với các ứng dụng tương tác. nên dùng hộp thoại. Hộp thoại page setup được khởi tạo dùng tham số truyền cho pageDialog.com 180 . 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. 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. 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. 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 . Để hiển thị một hộp thoại page setup bạn gọi hàm PrinterJob.pageDialog. Do trạng thái của một PrinterJob thay đổi trong quá trình vòng đời của nó. và thay đổi http://tailieuhay. việc gọi setPageable sau khi bạn đã gọi hàm print là không hợp lý.illegalStatException. các ứng dụng in kết qủa(production printing application).

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

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

PAGE_EXiSTS. các số trang được đẩy ra dùng một hướng redgreen(red-green gradient). implements SimplePrint2D Color.awt.print.Lập trình đồ họa trên Java 2D và 3D if (pageindex >= 5) return Printable.setFont(fnt). class import java. g. g. 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. 183 http://tailieuhay.com .setColor(Color. 100.drawString("Page 100). g. import public Printable { private static Font fnt = new Font("Helvetica".red. Để làm điều này.awt. Paint pnt = new GradientPaint(100f. return } } Printable. private 100f. một GradientPaint được đặt trong ngữ cảnh Graphics2D.green).Font. " + (pageindex+1).PLAiN.*.24).*.NO_SUCH_PAGE. java.

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

com 185 .*. http://tailieuhay. (pageindex+1). above defined above 100f. import import import java. một danh sách các file văn bản được in. 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). return } } Printable. 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. 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. nó phải được sinh ra cùng đầu ra mỗi lần.setPaint(pnt). gradient " g2.*.PAGE_EXiSTS. để 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. Khi cùng trang được đây ra lần nữa.awt. g2. Trong ví dụ dưới đây.io. java.print.setFont(fnt). Ví dụ. 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ế.drawString("Page 100f).*. Tên của file được truyền như là đối số cho hàm main. con trỏ file được reset tới vị trí đã nhớ.3.Lập trình đồ họa trên Java 2D và 3D Graphics2D // // Use Use the the g2 = font (Graphics2D) defined color + g. 7.

// // if { // try catch */ } System. = of PrinterJob Ask portrait/landscape) PageFormat // // Specify job.setCopies(1). (Exception e) Print Put up 1 copy the dialog box job. PrintListingPainter. for page pf the Printable is also an instance format (e.setPrintable(new PrintListingPainter(args[0]).print(). http://tailieuhay. provide given PageFormat job. (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.defaultPage()).g.getPrinterJob()..com 186 .pageDialog(job.exit(0). } } Print { the job } { /* handle exception if the user didn't cancel printing job.printDialog()) pf).

boolean PrintListingPainter(String pageindex) PrinterException http://tailieuhay. raf. file) rememberedFilePointer fileName. "r"). (Exception e) { rememberedEOF = true. PrintListingPainter implements Printable Font. false. PageFormat pf. Open = file new RandomAccessFile(file. = -1.PLAiN. fnt = new Font("Helvetica".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. = file. RandomAccessFile String Font int long 10).com 187 . rememberedPageindex rememberedEOF = = -1.

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

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

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. Để thêm các trang vào một Book. Nhiều trang trong một Book có thể dùng chung cùng định dang và painter. 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. Một Book biểu diễn một tập các trang. Nếu bạn không biết tổng số trang trong một Book. Đ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. Phương thức này nhận 2 đối tượng PageFormat xác định (defines) cỡ trang. cùng hướng. bạn dùng phương thức append. trang bởi trang. http://tailieuhay. bạn có thể chuyển cho giá trị UNKNOW_NUMBER_OF_PAGES cho phương thức append. 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. 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. Khi một Book khởi tạo đàu tiên. hoặc page painter. Lớp Book là một cách thuận lợi để dùng các Pageable. số lượng các trang. 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. 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. Phần này chỉ cho bạn cách dùng Book. nó trống rỗng. vùng có thể in.com 190 . hướng và một page painter cài đặt giao diện Printable. Ví dụ. Các trang trong một book không phải cũng cỡ.

main(String[] java. 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. 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.print. PrinterJob. import import public Printable { private public { // // Book Get Set bk a up = PrinterJob job a new = book Book().24).awt.4. PrinterJob static static void Font fnt = args) new Font("Helvetica". có rất it lợi ích trong việc dùng một Pageable job thay cho một Printable job.awt. Hàm setPageablbe và hàm setPrintable là loại trừ nhau. java.PLAiN. Ban gọi setPageable và truyền trong Book để chuẩn bị cho việc in.com 191 .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.Font.*.1 Using a Pageable Job Ví dụ sau. 7.*. Trang để thay đổi được xác định (identified) bởi chỉ số trang cái chỉ ra vị trí của trang trong Book.getPrinterJob(). 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. class SimplePrintBook implements http://tailieuhay.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 .

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. http://tailieuhay.com 207 . việc dựng hình trong Java 3D cho phép làm song song. 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. 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. Đồ 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. Các chi tiết được dưng hình tự động. 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.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. Sử dụng lợi thế của các luồng trong java.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. 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. 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.

media. Gói javax. Chương này còn bao gồm ví dụ HelloJava3D hiển thi một khối lập phương quay.com 208 .awt định nghĩa các lớp AWT cho phép tạo cửa sổ cho việc dựng hình.awt và javax.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. Đồ http://tailieuhay.utils thường gọi là các lớp tiện dụng. 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”.Lập trình đồ họa trên Java 2D và 3D 1. một đồ thị khung cảnh được tạo nên bởi các instance của các lớp Java 3D. 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. 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. hỗ trợ xây dựng đồ thị khung cảnh. vector ma trận và những đối tượng toán học khác. chúng bổ sung thêm những tính năng hiệu quả và rất mạnh cho nhân.j3d những lớp này được coi như là những lớp cơ bản nhất của Java 3D.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. các lớp hình học. Từ object được sử dụng cho một instance của một lớp. 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. 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.vecmath định nghĩa các lớp cho điểm. Content tương ứng với những đối tượng quan sát trong một đồ thị khung cảnh. Lớp utility gồm 4 mục: content loader(nạp nội dung). Gói java. và các công cụ tiện ích. 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.vecmath.j3d.sun. 1.(chẳng hạn: một hình lập phương hay hình cầu).

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. Chỉ tồn tại một đường duy nhất từ gốc của cây đến một lá. Đường đi đó gọi là đường đi của đồ thị khung cảnh. 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. 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á. 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 nút còn lại được truy cập tới thông qua các cung đi từ nút gốc. hướng và bề ngoài về trực quan cũng như âm thanh của đối tượng.com 209 . Một quan hệ khác là quan hệ tham chiếu. âm thanh và ánh sáng. Trong cây này chỉ có một nút gốc. Các cung đại diện cho 2 dạng quan hệ giữa các instances của Java 3D. 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. và kích thước của đối tượng quan sát. http://tailieuhay. Một nút của đồ thị khung cảnh là một instance của một lớp Java 3D. 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ộ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. 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. 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. hướng. vị trí. 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. các cung trên cây không tạo thành chu trình. Đồ 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ỗ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á. 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ó.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.

sơ đồ đồ thị khung cảnh sẽ là tiêu chí của chương trình.com 210 . Nét đứt chỉ tham chiếu đến một đối tượng khác. 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). 3 biểu tượng tiếp theo đại diện cho các đối tượng của các lớp Group. 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.1 đại điện cho một đối tượng đơn lẻ khi sử dụng trong đồ thị khung cảnh. đồ thị khung cảnh được vẽ dựa trên những biểu tượng chuẩn. Sau khi việc thiết kế hoàn thành. 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. 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. Đối tượng được tham chiếu có http://tailieuhay. Leaf và NodeComponent.1. Đồ thị được vẽ từ chương trình minh chứng cho đồ thị mà chương trình tạo ra. Như vậy để thiết kế môi trường ảo. Mỗi một biểu tượng ở phía bên trái của hình 1. 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. Sau khi chương trình hoàn thà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. Đồ thị khung cảnh được vẽ trên các biểu tượng như hình 1.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.

Mà dựa trên các khái niệm.com 211 . Vấn đề nằm ở chỗ chỉ với 2 đối tượng TransformGroup có chung một đối tượng lá Shape3D là con. 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. 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.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. Dưới đây là một ví dụ (Hình 1. Tuy nhiên đây là một đồ thị không hợp lệ vì cung cha con http://tailieuhay. Đồ thị này sai bởi vì nó vi phạm những đặc tính của DAG. 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ị. Nhớ rằng một đối tượng lá chỉ có thể có 1 cha duy nhất.2) Rất dễ xây dựng một đồ thị khung cảnh sai. Một ví dụ sai đơn giản có thể xem ở hình 1-3. 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).

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

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. bề mặt. vì thế có thể định nghĩa nhiều hơn một môi trường ảo. 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. âm thanh.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. 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. 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.com 213 . địa điểm. Nhánh nội dung chỉ ra nội dung của môi trường ảo – hình học. 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. thể có nhiều môi trường ảo trong một chương trình Java 3D. 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à ánh sáng. Xa hơn. hành vi. Tuy nhiên. http://tailieuhay. 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. Theo ví dụ ở hình 1-2 có thể thấy đối tượng Locale có 2 nhánh đồ thị con từ nó.

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. 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 trình đồ họa trên Java 2D và 3D 1. 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 Leaf http://tailieuhay. 2 lớp con của là BranchGroup và TransformGroup. đị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ó.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. Lớp node Lớp node là lớp cha của 2 lớp Group và Leaf.com 214 .3.

com 215 . Những đối tượng này có thể không có lớp con nhưng phải tham chiếu đến NodeComponent. 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.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. và hành vi của đối tượng quan sát trong mội trường ảo. Behavior và Sound. http://tailieuhay. âm thanh. bề mặt. Lớp NodeComponent Lớp NodeComponent là lớp gốc sử dụng để mô tả về hình học. Một NodeComponent có thể được tham chiếu bới nhiều đối tượng Shape3D. texture và những thuộc tính của node Shape3D. Một vài lớp con của lớp này là Shape3D. Light.

Create a Locale object. 1. 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.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. Create a Canvas3D object 2. PhysicalEnvironment.3. attaching it to the VirtualUniverse object 4. Đây là công thức hữu ích để xây dựng các ứng dụng Java 3D. Create a PhysicalEnvironment object e. and Canvas3D objects to View object http://tailieuhay. Create a View object b. 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.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. PhysicalBody. Construct a view branch graph a.com 216 .4. 1.Lập trình đồ họa trên Java 2D và 3D 1.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. Create a PhysicalBody object d. Attach ViewPlatform. Mỗi instance của lớp này thực hiện các bước 2. Công việc thực sự khi viết một chương trình Java 3D là như vậy. và cấu trúc này đã sẵn có trong lớp SimpleUniverse. Create a VirtualUniverse object 3. Create a ViewPlatform object c.

http://tailieuhay.sun. Tuy nhiên nó không cho phép có nhiều view trong môi trường ảo của nó.j3d. Construct content branch graph(s) 6. ViewingPlatform và Viewer. 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. 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. Compile branch graph(s) 7.utils.universe chứa các lớp SimpleUniverse.com 217 .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. Gói com. 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.

Để rõ hơn chúng ta quan sát hình http://tailieuhay. Lớp này tạo nên các đối tượng Locale. 1.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 SimpleUniverse object which references the earlier Canvas3D object a.j3d. tạo các đối tượng cần thiết cho đồ thị nhánh hình thức. 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. có thể coi như là một bảng hình ảnh vậy. Create a Canvas3D Object 2. Customize the SimpleUniverse object 3. Compile content branch graph 5. Insert content branch graph into the Locale of the SimpleUniverse SimpleUniverse Constructor gói com. Các đối tượng này liên hệ với nhau để tạo nên đồ thị nhánh hình thức.sun. Đố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. Hình 1-8 đưa ra công thức đơn giản hơn trong đó các bước 2. 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. Construct content branc h 4.3. ViewingPlatform và Viewer (với tất cả các giá trị mặc định của chúng).com 218 .utils. VirtualUniverse.4 đã được thay bằng bước 2 của công thức mới. Đồ thị này bao gồm một bảng hình ảnh.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.

Lập trình đồ họa trên Java 2D và 3D ảnh dưới đây.sun.com 219 .utils.0. Vị trí của mắt là đằng sau bảng hình ảnh. môi trường ảo. 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. Lớp SimpleUniverse có một lớp thành viên là ViewingPlatform. Mặc định bảng hình ảnh đặt trung tâm của SimpleUniverse ban đầu. hướng mặc định là nhìn theo trục z. 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. 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..universe http://tailieuhay. 2.0) là tâm của bảng hình ảnh. Đối tượng quan sát đứng trước bảng hình ảnh được dựng trên bảng hình ảnh.41) nhìn từ phía âm của trục z so với vị trí ban đầu. 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. Lớp ViewingPlatform.j3d.0. 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. Thông thường thì vị trí (0. phương thức setNominalViewingTransform () Package: com. 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.

Đ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.utils.sun. void setNominalViewingTransform() Set tầm nhìn khoảng cách khoảng 2. Các phương thức SimpleUniverse Package: com. Đồ 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.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. nó được chèn vào môi trường sử dụng phương thức addBranchGraph của SimpleUniverse. 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.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. 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.j3d. bước tiếp theo là tạo đồ thị nhánh nội dung. Sau khi tạo xong đồ thị nhánh nội dung.com 220 . Phương thức này lấy một instance của BranchGroup như là tham số duy nhất. Đ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. ViewingPlatform getViewingPlatform() http://tailieuhay. 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. Sau khi tạo xong các đối tượng Canvas3D và SimpleUniverse.41 mét từ trong biến đổi tầm nhìn của một SimpleUniverse. 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).

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. http://tailieuhay. 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.com 221 . 1. 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.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”. Leaf. 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. 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. 2 phương thức của SceneGraphObject được mô tả dưới đây. và NodeComponent. 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.8.2).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. Khi các đối tượng BranchGroup được dịch (compiled). Những đối tượng sống là những đối tượng mà chuẩn bị được dựng hình. 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. Cơ sở của việc dịch và sống được bổ sung trong lớp SceneGraphObject.

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. http://tailieuhay. 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. 2 phương thức được trình bày dưới đây. Khi đã bắt đầu.com 222 . 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.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ó. 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.

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. public class HelloJava3Da extends Applet { public HelloJava3Da() { setLayout(new BorderLayout()). // Utility class SimpleUniverse is a Convenience http://tailieuhay. 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 1.tạo đối tượng Canvas3D (dòng 4 đến dòng 6). 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. được hoàn thành bằng lời gọi ở đến phương thức creatSceneGraph().com 223 . Trong ví dụ này phương thức như thế được đặt tên là creatSceneGraph(). Mọi bước theo công thức phía trên đều được thể hiện trong lớp HelloJava3Da. BranchGroup scene = createSceneGraph(). 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. Canvas3D canvas3D = new Canvas3D(null).java dưới đây ta cũng có lớp HelloJava3Da được mở rộng từ lớp Applet. add("Center". Trong ví dụ HelloJava3Da. Bước 4 dịch đồ thị nhánh nội dung được thực hiện trong dòng 10. Bước 2 tạo đối tượng SimpleUniverse hoàn thành ở dòng 17. canvas3D).Lập trình đồ họa trên Java 2D và 3D 1. Bước 3 tạo nhánh nội dung.

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

lang. từ java.com 225 . http://tailieuhay.applet.AppletContext.Frame và bổ sung thêm Hàm MainFrame(java.j3d. 256. MainFrame mở rộng từ java.awt.AppletStub.applet MainFrame giúp cho một applet có thể chạy như một ứng dụng.java. 256).applet. int width.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. 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ổ. MainFrame cung cấp AWT frame public static void main(String[] args) { Frame frame = new MainFrame(new HelloJava3Da(). int height) Tạo tạo đối tượng Mainframe cho phép applet chạy như ứng dụng độc lập. 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. Đoạn mã 1-3 bên dưới sẽ chỉ ra cách sử dụng trong HelloJava3Da. MainFrame ConStructor package: com.Runnable. 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. java. Tham số: Applet – Hàm tạo của một lớp thừa kế từ applet. 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.Applet applet.utils. và java.sun.

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

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

256. } // 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().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(). return objRoot.4)). 256). objRoot.addChild(new ColorCube(0. } // 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).com 228 .

con của nó có thể là Group hoặc Leaf. 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.Lập trình đồ họa trên Java 2D và 3D 1. BranchGroup constructor BranchGroup () Instance của BranchGroup được coi là gốc của một nhánh đồ thị.6. BranchGroup có thể có nhiều con.com 229 . http://tailieuhay. Mỗi instance của BranchGroup là gốc của một đồ thị con.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. Đối tượng BranchGroup chỉ được phép là con của đối tượng Locale.

com 230 . Nó là phần mở rộng của lớp AWT Canvas. quay. biến hình theo quy mô. 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. Đối tượng Transform3D không được sử dụng trong đồ thị khung cảnh. góc được thể hiện dưới dạng radians. 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. Những đối tượng này thường chỉ sử dụng để tạo một đối tượng TransformGroup. Sau đó TransformGroup được khởi tạo sử dụng Transform3D vừa tạo. có khả năng liên kết với các đối tượng Transform3D khác. Nó chỉ được dùng để chỉ ra sự biến hình của một đối tượng TransformGroup. Khi có hiện tượng quay. 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.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.hoặc là kết hợp các phương pháp trên lại. 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. 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. Đầu tiên đối Transform3D được khởi tạo.

void rotX(double angle) Phép quay với trục X ngược chiều kim đồng hồ. void set(Vector3f translate) Tạo giá trị biến đổi của ma trận cho giá trị của tham số Vertor3f.com 231 . với góc (angle) là giá trị radian. void rotY(double angle) Phép quay với trục Y ngược chiều kim đồng hồ.PI. 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. 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. 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.dịch phóng lớn thu nhỏ. nếu không thì có thể chỉ ra góc quay chính xác. Lớp TransformGroup Đây là lớp con của lớp Group. 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. Một cách để chỉ ra góc quay là sử dụng hằng Math. Đối tượng TransformGroup giữ giá trị biến hình. 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.Lập trình đồ họa trên Java 2D và 3D là 2 PI radians. void rotZ(double angle) Phép quay với trục Z ngược chiều kim đồng hồ. với góc (angle) là giá trị radian. 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. TransformGroup Constructors http://tailieuhay.

vecmath để định ra một vertor sử dụng 3 điểm số thực.0. float y.z) ColorCube http://tailieuhay. 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.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 . Đố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.y. 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. Vector3f Constructors Vector3f() Tạo và thiết lập các giá trị Vertor3f cho (0.0) Vector3f(float x. 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.

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

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

7. 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). sẽ được chỉ trên một đối tượng quan sát duy nhất. 2 đối tượng Transform3D với mỗi phép quay được tạo ra ở dòng 6 và 7. 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.Lập trình đồ họa trên Java 2D và 3D 1.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. 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. ở ví dụ của chúng ta là sẽ có 2 phép biến hình đồng thời. 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.com 235 .

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 trong những cách đó là. 1. 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. tuy nhiên mô tả của nó lại không hiệu quả. Hình 1-16 dưới đây đưa ra một mô tả mới hiệu quả hơn.1 Dịch các nội dung Đối tượng BranchGroup có một phương thức dịch. 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.8. 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.com 236 . http://tailieuhay. 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.Lập trình đồ họa trên Java 2D và 3D 1. Thêm vào đó.

Ví dụ như việc thay đổi giá trị của một đối tượng TransformGroup tạo hoạt họa.Lập trình đồ họa trên Java 2D và 3D 1. 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. 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”. 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. qua đó cũng tăng cao hiệu năng dựng hình. 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. 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 . Trừ phi có chỉ ra chi tiết của chương trình. 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.8.2 Khả năng Một khi đồ thị nhánh được làm cho sống và dịch. Mỗi đối tượng SceneGraphObject có một tập các bit năng lực.

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.com 238 . Như trong một ví dụ đã nói. 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. Tập các năng lực này biến đổi khác nhau trên các lớp. TransformGroup Capabilities khả năng dưới đây là một trong những khả năng được định nghĩa bởi TransformGroup. 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. Trong phần tớ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. Các khả năng như set. void clearCapability(int bit) Xóa các bit khả năng boolean getCapability(int bit) Phục hồi. http://tailieuhay. 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ó. 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. để có thể đọc được giá trị biến hình đại diện cho một đối tương TransformGroup. ALLOW_TRANSFORM_WRITE Cho phép ghi tới thông tin biến hình của đối tượng của nó.reset hay retrieve được địng nghĩa ở SceneGraphObject.Lập trình đồ họa trên Java 2D và 3D nó được dịch hay sống. Leaf và NodeComponent. Đối tượng TransformGroup.

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. http://tailieuhay. người lập trình tạo một đối tượng mà chỉ ra hành vi đó. 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. thì thật khó có thể nâng cao hiệu năng hoạt động được. 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. 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ó. thì cần một lượng tính toán rất lớn. 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. 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.9 Thêm vào các hành vi animation Trong Java 3D. 1.com 239 . Thực tế thì thường có 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. Để chỉ ra một hành vi cho một đối tượng quan sát. 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. Trong một môi trường ảo với rất nhiều hành vi. 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.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ó.

Specify a scheduling region Set the scheduling region for the behavior 5. màu sắc(ColorInterpolator) hoặc độ trong suốt(TransparencyInterpolator) của một đối tượng quan sát. Khu vực này được gọi là scheduling region. Make the behavior a child of the TransformGroup 1. 1.không có chỗ trong rừng để lá rơi thì sẽ không có lá rơi.com 240 .9. 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. 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 đó.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). Nói cách khác. hướng (RotationInterpolator). 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. Create an Alpha5 object Specify the time parameters for the alpha 3. kích cỡ(ScaleInterpolator). 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.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. Create the interpolator object Have it reference the Alpha and TransformGroup objects Customize the behavior parameters 4. Như đã nói ở phía trên Interpolator là các lớp hành vi được định nghĩa trước.

Đố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.com 241 . Lớp Alpha Lớp này được sử dụng để tạo hàm biến đổi theo thời gian.9.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. 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 đó. http://tailieuhay. góc quay ban đầu góc quay kết thúc. Giá trị này phụ thuộc vào thời điểm và thông số của đối tượng Alpha. 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. 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. 1..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. 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. 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. bằng đối tượng TransformGroup được chỉ ra bằng hành vi mặc định. Một đối tượng RotationInterpolator rất linh động trong việc chỉ ra trục quay. Lớp này cung cấp các giá trị giữa 0 và 1. 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.

hay bắn rocket. cửa mở. 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. 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. 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 . Điều này lặp đi lặp lại nhiều lần thông qua loopCount. 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. do đó giúp cho người lập trình sử dụng linh động.9. hoặc bouding polytope. 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. Đối tượng Alpha tạo ra cung cấp giá trị khởi đầu từ 0 lên 1.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.Lập trình đồ họa trên Java 2D và 3D Có 10 tham số cho Alpha.com 242 . cánh bay. Tham số: loopCount – số lần chạy đối tượng alpha này. 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. Các tùy chọn khác như bounding box. Behavior setSchedulingBounds method void setSchedulingBounds(Bounds region) http://tailieuhay.

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. bao gồm tất cả các vị trí mà đối tượng có thể ở đó. Bán kính sau đó được lựa chọn đủ sao cho hình cầu chứa đối tượng quan sát. Đối tượng TransformGroup tên là objSpin được tạo ở dòng 7.9.0. 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ó. 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.com 243 . Bounding Sphere Constructors BoundingSphere() Tạo một hình cầu bao mà tâm ở vị trí (0. Cách thường làm là để tâm của hình cầu ở vị trí trung tâm là (0. Khả năng của nó được thiết lập ở dòng thứ 8.0) với bán kính bằng 1 BoundingSphere(Point3d center.0). Đối tượng TransformGroup của môt hành vi sẵn có phải có khả năng ghi. 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. http://tailieuhay.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.0.

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

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

5 Phép biến hình và kết hợp các hành vi .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.com 246 . } // 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. Kết quả 1.Lập trình đồ họa trên Java 2D và 3D return objRoot. Trong đồ thị nhánh nội dung có những đối tượng http://tailieuhay.9.

TransformGroup TransformGroup(). // // // runtime. TransformGroup TransformGroup(rotate).PI/4. // rotate object has composited transformation matrix Transform3D rotate = new Transform3D(). Đồ thị khung cảnh public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().rotX(Math.mul(tempRotate). rotate. our TRANSFORM_WRITE modify it at capability so that behavior Add it to the objSpin = new // root of the subgraph. 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.rotY(Math. Create the transform Enable code the can group node and objRotate = new initialize it to the identity.PI/5. http://tailieuhay.com 247 .0d). tempRotate.0d). rotate.Lập trình đồ họa trên Java 2D và 3D objRotate và objSpin. Transform3D tempRotate = new Transform3D().

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

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

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. Hình 2-1 dưới đây chỉ ra hướng nhìn trong SimpleUniverse. http://tailieuhay. trục Y hướng dương chỉ lên trên. 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. 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. Với một đối tượng Locale trong SimpleUniverse có một hệ tọa độ duy nhất.com 251 .Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 2 Tạo các hình 2. Đố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. trục Z hướng dương chỉ vào người nhìn với đơn vị là mét.

2. biểu tượng hình tứ giác dùng để đại diện cho đối tượng ColorCube. Đồ 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. 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.1 giới thiệu lớp Chen code lai cho ro rang . sau khi đi vào những định nghĩa cơ bản về hình học trong gói tiện ích.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.Lập trình đồ họa trên Java 2D và 3D 2.2. 2. Đố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. Thông tin này được lưu trong đối tượng NodeComponent được chuyển đến bới đối tượng Shape3D.2 Visual Object Definition Basics Phần 2..2. Trong đồ thị khung cảnh Hellojava3D ở chương 1.2. còn lớp Chen code lai cho ro rang .com 252 . 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.được giới thiệu ở phần 2. http://tailieuhay. 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.

đối tượng Shape3D quy cho một nút Appearance. hoặc cả 2 dạng.com . hoặc chỉ với tham chiếu 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. Appearance Appearance) Khởi tạo và thiết lập chỉ với cả 2 thành phần. Với tùy chọn này. 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. 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.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.

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. http://tailieuhay. Phần 2-6 giới thiệu về Appearance NodeComponent.com 254 . Node và Leaf. 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. ALLOW_GEOMETRY_READ | WRITE ALLOW_APPEARANCE_READ | WRITE ALLOW_COLLISION_BOUNDS_READ | WRITE 2. void setGeometry(Geometry Geometry) void setAppearance(Appearance Appearance) Shape3D Capabilities Đối tượng Shape3D thừa kế các khả năng từ SceneGraphObject. 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. 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.

2. Hàm tạo có thể được gọi và những đối tượng http://tailieuhay.com 255 . Đ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ẻ.j3d. 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. Có nhiều cách để thiết kế một lớp để định nghĩa một đối tượng quan sát. 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.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. Mỗi người lập trình Java 3D sẽ tùy biến lớp VisualObject theo ý của họ. 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. 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.utils.Lập trình đồ họa trên Java 2D và 3D 2.sun.Geometry . Chúng ta có thêm xem một ví dụ đầy đủ về lớp ColorCube trong gói com.

và hình cầu cơ bản. Còn cách dễ nhất đương nhiên là dùng hình lập phương. 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(). Công nghệ này có thể có nhiều việc hơn nhưng lại dễ dàng để hiểu.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. Đ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á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. Trong đoạn mã dưới đây objRoot là một instance của Group. hình trụ. 2.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ã. Lớp này phải định nghĩa phương thức để trả về một tham chiếu đến gốc. Ngoài ra còn có các lớp khác trong gói về hình học như Box. vốn mở rộng từ Group. objRoot. Mỗi lớp mở rộng từ Primitive.addChild(new VisualObject()). 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. 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. 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. Cylinder và Sphere. Lớp ColorCube định http://tailieuhay. Cone. Các hình cơ bản này là cách dễ thứ hai để tạo một môi trường ảo. hình nón.com 256 . 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.

j3d.sun. Kết quả là mọi thứ xung quanh nó trở nên cố định trừ kích thước của nó.1 Box Lớp gốc Box (hình hộp) tạo đối tượng quan sát hình hộp 3D. Chiều dài chiều rộng chiều cao mặc định là 2 met. người lập trình không thể thay đổi hình học nhưng có thể thay đổi bề ngoài. Các lớp này được định nghĩa trong gói com. dưới đây là hình2-4 thể hiện cây thừa kế các lớp này.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.Geometry. 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.3. Chiều dài http://tailieuhay. Kích thước hình lập phương chỉ được xác định khi đối tượng được tạo.utils. 2. Trong các lớp tiện ích cơ bản hình học.com 257 . 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. với tâm ở gốc. Lớp cơ bản nhất của các lớp này là lớp Primitive.

float zdim.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à tâm ở gốc. 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.com 258 . dọc theo đường đồ thị khung cảnh tới Box.utils. và Cylinder được tập hợp từ nhiều đối tượng Shape3D. Tất nhiên TransformGroup. với nút thành phần hình học của nó. bề ngoài. mở rộng từ Primitive. một lớp khác trong gói com. and Cylinder Methods Package: com.j3d. Giá trị đưa ra để xác định nút thành phần nào được lấy.j3d.sun.Đối tượng Box. và Cylinder. tâm ổ gốc. void setAppearance(Appearance Appearance) http://tailieuhay. float ydim. Box(float xdim. Appearance Appearance) Thiết lập hình hộp với hướng.Geometry Box.j3d. Cone.utils. Cone.sun.sun.utils.Geometry Các phương thức này được định nghĩa trong mối lớp cơ bản: Box.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. 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. Box Constructors Package: com. Cone. 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.

j3d.utils. Appearance Appearance) Khởi tạo với bán kính.3. chiều cao là 2. Cylinder(float radius. đường kính là 2. chiều cao là 2. Cone(float radius. Cylinder Constructors Package: com.3. Cylinder(float radius.utils.Geometry Cone() Hàm khởi tạo mặc định với bán kính là 1. Cone Constructors Package: com.sun.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.sun.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. 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. http://tailieuhay.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.com 259 . float height. Bán kính là 1 và chiều cao là 2. float height) Khởi tạo với tham số bán kính và chiều cao. Giá trị mặc định là bán kính là 1.Geometry Cylinder() Hàm khởi tạo mặc định với bán kính là 1. chiều cao và bề mặt.j3d.

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

Cylinder và Sphere. Chúng ta phải dùng 2 http://tailieuhay. Cây thừa kế được chỉ ra trong hình 2-5. 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. 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ó. Lớp này mở rộng theo hướng thừa kế khác.com 261 .5 More About Geometric Primitives Các cơ bản chưa được định nghĩa về màu sắc. đối tượng quan sát sẽ có màu mặc định là trắng. 2.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. 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.3. Nếu không có tham chiếu đến nút thành phần bề mặt. mục tiêu của chương trình là dựng nên một con yo-yo.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.3. Cone. 2.3.Lập trình đồ họa trên Java 2D và 3D 2. nó là lớp con của Shape3D.

Lập trình đồ họa trên Java 2D và 3D hình nón để tạo nên được Yo-Yo. 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. theo đó là TransformGroup xác định phép quay và hủy đối tượng Cone. Nhánh đồ tị này bắt đầu bằng đối tượng BranchGroup được tạo bơi ConeYoyo. 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. 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. đườ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. Hướng của hình nón là hướng dương.com 262 . 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. đỉnh nằm trên trục Y. http://tailieuhay. 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.

http://tailieuhay. Lớp ConeYoyo được sửa lại như trong đoạn mã 2-2. Hình 2. Lỗi này không tồn tại trong ví dụ chương trình đưa ra. Phép biến đổi được mô tả đơn giản như dưới đây. Trong ví dụ hình 2-6 có một vài thay đổi. 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. Hình 2-8 chỉ ra một hình ảnh được dịch với ví dụ vừa qua. 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. Khi đối tượng Cone thừa kế từ Group. 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.com 263 . Đối tượng Shape3D của Cone là con của Group trong Cone. Một thay đổi khác là kết nối 2 đối tượng TransformGroup trong đối tượng ConeYoyo.đư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. Nút Shape3D của đối tượng Cone tham chiếu đến nút thành phần hình học.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.

264 rotate translate http://tailieuhay. // rotate object has composited = = new new the geometry is created in method create Shape3D with geometry and transformation matrix Transform3D Transform3D(). // ////////////////////////////////////// //// // // appearance // yoyoGeometry // the appearance is created in method yoyoAppearance // public ConeYoyo() { yoyoBG = new BranchGroup().com . Dòng 21 đến 34 thiết lập bề mặt cho 2 hình nón. 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. Transform3D Transform3D(). Dòng 12 tạo yoyoApear.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 . 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. Appearance app = new Appearance().

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

chia sẻ một nút thành phần hình học. Ví dụ như lớp Sphere có hàm khởi tạo Sphere (int). Cylinder. GEOMETRY_NOT_SHARED The Geometry created will not be shared by another node. GENERATE_NORMALS_INWARD Normals are flipped along the surface. và Spheres.com 266 . 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. 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. 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ỡ.compile(). Box.Lập trình đồ họa trên Java 2D và 3D yoyoBG. 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. 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. Mặc định tất các các primitives là cùng một kích thước. GENERATE_TEXTURE_COORDS Texture coordinates are generated. Danh sách các cờ ở dưới đây: GEOMETRY_NOT_SHARED Normals are generated along with the positions. Thiết lập cờ này để tránh http://tailieuhay.

mỗi thứ có tiềm năng sử dụng nút thành phần bề mặt của nó.com 267 . 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ơ. Appearance Appearance) Thiết lập bề mặt của các phần con. Cylinder và Sphere.Geometry Primitive mở rộng từ Group và là lớp cha của của các lớp Box. Cone.GEOMETRY_NOT_SHARED).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). Cone. 2.utils. Cone myCone = new Cone(Primitive. 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. void setAppearance(int partid. public void setNumVertices(int num) Thiết lập tổng số đỉnh trong primitive này. Cylinder được gom lại với hơn một đối tượng Shape3D.4 Các lớp toán học Để tạo đối tượng quan sát. như điểm đường thẳng và đa giác. 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. 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.j3d. Primitive Methods Package: com. cần cả lớp hình học và các lớp con của nó. Các đối tượng Box.sun.

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

Color2f.tùy thuộc vào các hình cơ bản được dựng hình như thế nào. Ví dụ như Tuple2f cung cấp cơ sở cho Point2f. Tât cả các lớp cần thiết được trình bày bên dưới đây. Tuple2f Constructors Package: 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*.vecmath đại diện cho tọa độ. TexCoord*. 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. float y) http://tailieuhay. 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. Các dữ liệu khác là tùy chọn . Vector*. Color*. 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. bề mặt bình thường (Vertor* object) là cần thiết. Tuple2f() Khởi tạo và thiết lập đối tượng Tuple với tọa độ (0. Nếu ánh ánh sáng được thiết lập.0). 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.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. 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.com 269 . màu bề mặt bình thường và bề mặt tọa độ.

float y) void set(float t[]) Lập giá trị của tuple này từ một giá trị định trước. 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. 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. 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. TexCoord*. Tuple2f t2) http://tailieuhay. Các phương thức của chúng cũng tương tự như vậy. void add(Tuple2f t1. Color*.y). Tuple2f t2) Lập giá trị của tuple này tới vertor tổng của nó và Tuple t1 và t2. Color2f. 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(float t[]) Khởi tạo và thiết lập đối tượng Tuple từ một mảng đặc biệt.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*. và TexCoord2f.com 270 . void set(float x. Ví dụ như Tuple2f cung cấp cơ sở cho Point2f.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.

nguồn âm thanh và các dữ liệu điểm khác.1 Point Classes Đối tượng Point* thường được đại diện cho tọa độ của một đỉnh. 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*.com 271 . 3 hoặc 4 không gian. Point3f Methods (partial list) Package: javax. void negate() Loại bỏ giá trị của một vertor. 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. Thêm vào các phương thức của Tuple*. 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. 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 .t1). lớp Point* có thêm các phương thức riêng của nó. 2. một điểm nguồn sáng. http://tailieuhay. float distance(Point3f p1) Trả về khoảng cách giữa điểm này và điểm p1. được chỉ ra dưới đây.vecmath Lớp Point* được thừa kế từ lớp Tuple*.t2). chẳng hạn như một vạch quét ảnh.4. Mỗi instance của lớp Tuple* đại diện cho một điểm đơn trong 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 .

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

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

2.2> Lập màu sử dụng mầu từ đối tượng AWT Color Color get() <new in 1. Again. the constructors for Vector* classes are similar to the Tuple* constructors. Vector* objects add many methods that are not found in the Tuple* classes.com 274 . Color4b.2> Lấy một màu coi là một màu của đối tượng AWT Color.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.Lập trình đồ họa trên Java 2D và 3D Color* Methods Package: javax. 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*. 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.4. Đố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. Color3f. Color4f) thừa kế từ lớp Tuple*. Vector3f Methods (partial list) Package: javax.vecmath Lớp Color* (Color3b. However. void set(Color color) <new in 1.vecmath http://tailieuhay. Dưới đây là một vài phương thức trong Color3* và Color4*.

com 275 .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. float angle(Vector3f v1) Trả về góc radians giữa vertor hiện tại với vertor tham số. giá trị này được rằng buộc trong khoảng [0.Lập trình đồ họa trên Java 2D và 3D Lớp Vector* thừa kế từ Tuple*. Vector3f v2) Lập một vertor trở thành vertor pháp tuyến của 2 vertor v1 và v2. với TexCoord3f thì có 3 tọa độ là (s. 2. 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. http://tailieuhay. 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ó. Ngoài ra nó còn có thêm những phương thức như dưới đây.PI].2. Mỗi instances của lớp Vector* đại diện cho một đỉnh vertor trong không gian 1. 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. r). Với TexCoord2f có một cặp tọa độ là (s. là TexCoord2f và TexCoord3f. 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. void cross(Vector3f v1. t.4 chiều. t).3.4.

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.5 Các lớp hình học Trong đồ họa 3D. Các lớp con của Geometry có những dạng sau: 1. Cây thừa kế được hiển thị dưới hình 2-10 http://tailieuhay. Text3D. và CompressedGeometry) Phần này chỉ nói về 2 dạng trên.Lập trình đồ họa trên Java 2D và 3D 2. 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. 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.com 276 . cho nên một đối tượng tham chiếu là một instance của lớp con của Geometry. Chính xác hơn Geometry là lớp trừu tượng. 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.

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

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. Chú ý lớp Axis trong AxisApp. 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. NORMALS: Chỉ ra mảng đỉnh chứa bề mặt thường. đăng kí dữ liệu cho mảng tương ứng với tạo định dạng của các đỉnh. Mỗi mảng này là số đỉnh (vertexCount) về kích cỡ.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. TEXTURE_COORDINATE_3: Chỉ ra mảng đỉnh chứa 3D texture coordinates.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. 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 .com 278 . Bit này buộc phải lập. 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. Những giá trị cờ để định dạng các đỉnh là: COORDINATES: Chỉ ra mảng các đỉnh chứa tọa độ.

QuadArray. TriangleArray. void setColor(int index. float colors[]) void setColors(int index. void setCoordinates(int index. double coordinate[]) void setCoordinate(int index. float normal[]) void setNormal(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. void setNormal(int index. LineArray. Vector* normals[]) http://tailieuhay. void setCoordinate(int index. float normals[]) void setNormals(int index.com 279 . float color[]) void setColor(int index. float coordinate[]) void setCoordinate(int index. double coordinates[]) void setCoordinates(int index. void setNormals(int index. Color* colors[]) Lập các màu tương ứng với các đỉnh . 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. và IndexedGeometryArray. void setColors(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. 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. 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. float coordinates[]) void setCoordinates(int index. GeometryStripArray. 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.

Cho phép một vài dữ liệu đỉnh có thể bỏ qua khi dựng hình. continued) void setTextureCoordinates(int texCoordSet. Đối tượng trục X chỉ gọi phương thức setCoordinate() để lưu trữ dữ liệu tọa độ. chọn lọc 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. int index. 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. <new in 1. float texCoord[]) void setTextureCoordinate(int texCoordSet. và các hoạt động khác. Cho phép một vài đỉnh có thể bỏ qua trong việc dựng hình.2> float texCoords[]) void setTextureCoordinates(int texCoordSet.2> Lạp các giá trị tính toán đỉnh đúng cho đối tượng GeometryArray. void setValidVertexCount(int validVertexCount) <new in 1.com 280 . void setTextureCoordinate(int texCoordSet. void setInitialVertexIndex(int initialVertexIndex) <new in 1. int index. http://tailieuhay. Đố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 độ.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.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. Đ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. GeometryArray Methods (partial list.2> Lập chỉ mục cho đỉnh ban đầu với đối tượng GeometryArray. int index.

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

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

setCoordinate(3. Point3f(0. axisZLines. axisZLines.setColors(1. Point3f(-0. axisZLines. 0.1f. colors[0] = new Color3f(0. z2). 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. z2). -0. 0.setCoordinate(9.9f)).1f.0f). 1. http://tailieuhay.setCoordinate(7. 1. v < 9.9f)). 0.setCoordinate(6. 0. -0. } // 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.1f.setCoordinate(5.1f. for (int v = 0.0f.9f)).0f.Lập trình đồ họa trên Java 2D và 3D axisZLines. axisZLines. 0. } axisZLines. v++) { colors[v] = red.1f.setCoordinate(8. Point3f(-0. Color3f colors[] = new Color3f[9].com 283 new new new new .setCoordinate(4. axisZLines. Point3f(0.1f. z2).1f. axisZLines. nếu cả COLOR_3 và COLOR_4 không được định nghĩa.1f.9f)). colors). 0.

com 284 . 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 đó. Đố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.5. (Shape3D là lớp con của Node. http://tailieuhay. chẳng hạn như LineArray. 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ó.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ậ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. 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.

com 285 . 3 đường. hoặc 2 tam giác. LineArray. TriangleArray. 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. int vertexFormat) LineArray(int vertexCount. 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. PointArray(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. int vertexFormat) TriangleArray(int vertexCount. và QuadArray (các lớp này không phải là lớp con của GeometryStripArray). int vertexFormat) http://tailieuhay. int vertexFormat) QuadArray(int vertexCount. Trong hình này.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. Hình thứ 4 chỉ ra 4 đỉnh định nghĩa một tứ giác.

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. 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. TriangleStripArray và TriangleFanArray.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. Lớp GeometryStripArray có hàm tạo khác với lớp GeometryArray. để cho kết quả dựng hình tốt hơn. GeometryStripArray có 2 phương thức thường sử dụng đến là getNumStrips() và getStripVertexCounts(). Nếu xảy ra. tuy nhiên có một vài trường hợp ta cần sử dụng lại các đỉnh. 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ế.5. 2. 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 lớp LineStripArray. 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. GeometryStripArray Subclass Constructors http://tailieuhay.com 286 . chúng không thể dựng đúng được. không cho phép sử dụng lại các đỉnh.2-6 sử dụng đối tượng LineArray.

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. Định dạng là một hay nhiều các bit cờ “OR” để mô tả cho mỗi dữ liệu đỉnh.com 287 . Triangulator Constructor Summary Triangulator() Tạo một đối tượng tam giác.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 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. int Triangulator Class Package: com. vtxCount.sun. 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.j3d. int vertexFormat. Triangulator Method Summary void triangulate(GeometryInfo ginfo) http://tailieuhay. Các đa giác phải là lồi. cùng nằm trên một mặt phẳng các cạnh không giao nhau. Định dạng các cờ là giống nhau như đã định nghĩa trong lớp GeometryArray. int vertexFormat.utils. int vtxCount.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. Nhiều mảnh cùng một lúc cũng được hỗ trợ.

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 . http://tailieuhay.com. Ví dụ về cách sử dụng: TRIANGLE_ARRAY Triangulator tr = new Triangulator().getGeometryArray()). tr. phương thức yoyoGeometry()tạo và trả về đối tượng TriangleFanArray mong muốn.GeometryInfo to be triangulated. Trong đoạn mã 2-7. // ginfo contains the Geometry shape.com 288 .utils. // shape is a Shape3D Yo-yo Code Demonstrates TriangleFanArray Đối tượng Yoyo trong chương trình YoyoApp.Geometry.triangulate(ginfo).setGeometry(ginfo.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.sun.j3d.

0f. coords[0*(N+1)+N-n] = new Point3f(x. 25.0f. 12. http://tailieuhay. int stripCounts[] = {N+1. Point3f coords[] = new Point3f[totalN]. 23. // set the central points for four triangle fan strips 15. 14. 0. N+1}. coords[3*(N+1)] = new Point3f(0. float w = 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. 24.0*Math. 22. w). 10. int n. coords[1*(N+1)+n+1] = new Point3f(x. 20. 4. 9. -w). coords[1*(N+1)] = new Point3f(0. x = (float) (r * Math.0f). n < N. Mỗi hình nón có 18 đỉnh được tính toán ở dòng 20-28. N+1. N+1.6f. y. 0.0f. coords[2*(N+1)] = new Point3f(0. 0. 17. 0. 16. for (a = 0.PI/(N-1) * ++n){ 21. y. 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.0f. 0. y = (float) (r * Math. 8. 6. 11.4f. 7. w). int totalN = 4*(N+1). a = 2.cos(a)). coords[0*(N+1)] = new Point3f(0. private Geometry yoyoGeometry() { 2. 3. 0. TriangleFanArray tfa.0f.0f).0f. 5.0f. int N = 17.sin(a)).com 289 .0f. w). float x. 13.n = 0. double a. 18. y. 19. float r = 0.

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

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

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

com 293 . 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ả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. Chúng ta có thể xen ví dụ dưới đây. 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à đủ. Với những mảng này cũng chứa tạo độ.Lập trình đồ họa trên Java 2D và 3D 2.5.4 Subclasses of IndexedGeometryArray Các phần trước mô tả các lớp con của GeometryArray. 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. màu sắc. cho thấy chỉ lớp GeometryStripArray có thêm quyền hạn sử dụng lại các đỉnh. Các lớp con của IndexedGeometryArray song song với các lớp con của lớp GeometryArray. từ đó cho phép sử dụng lại hiệu quả rõ ràng. 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.

int ic. int indexCount) vertexCount.Lập trình đồ họa trên Java 2D và 3D Hàm tạo cho IndexedGeometryArray. int ic. int stripVertexCounts[]) vc. int indexCount) IndexedLineArray(int vertexCount. IndexedGeometryArray(int indexCount) IndexedPointArray(int vertexCount. int vertexFormat. int vf. int vertexFormat. int indexCount) IndexedTriangleArray(int vertexCount. int vf. int http://tailieuhay. int indexCount) IndexedQuadArray(int vertexCount. 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 vertexFormat.com 294 . IndexedGeometryStripArray(int stripVertexCounts[]) IndexedLineStripArray(int vc. IndexedGeometryStripArray cùng các lớp con của chúng dưới đây. 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 vertexFormat. int vertexFormat.

int stripVertexCounts[]) Các phương thức của chúng cho đưới dây: IndexedGeometryArray Methods (partial list) void setCoordinateIndex(int index. void setNormalIndices(int index. 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. 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.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. <new in 1. int index. 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.Lập trình đồ họa trên Java 2D và 3D IndexedTriangleStripArray(int vc.com 295 . int ic. int vf. 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 setTextureCoordinateIndex(int texCoordSet. void setColorIndices(int index. http://tailieuhay. 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. void setNormalIndex(int index. 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 vf. int stripVertexCounts[]) IndexedTriangleFanArray(int vc.

Lập trình đồ họa trên Java 2D và 3D void setTextureCoordinateIndices(int texCoordSet. 2.5 Axis.com 296 . int index.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. 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 . Như vậy có 5 đường cho mỗi trục. 2.5. Trong trường hợp đó rất cần thiết đối tượng Apperance.6 Appearance and Attributes Đối tượng Shape3D có thể tham chiếu đến cả đối tượng Geometry và Apperance. 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 đó. 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.5. đố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. Thông tin mỗi đỉnh này có thể chỉ định ra màu của đối tượng. 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. Như đã thảo nói ở phía trên trong phần 2.

Ví dụ như tham chiếu đến đối tượng ColoringAttributes nó sử dụng phương thức Appearance. Trên đồ thị khung cảnh http://tailieuhay.com 297 . Để 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.setColoringAttributes().

hiệu quả càng cao.6. khả năng xuyên qua vô hiệu hóa. màu mặc định là màu trắng.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.com . Việc chia sẽ này giúp cho việc dựng hình nhanh hơn. Ví dụ trong hình 221 2 đối tượng Shape3D chia sẻ cùng thành phần LineAttributes.Lập trình đồ họa trên Java 2D và 3D 2.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. 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. 298 http://tailieuhay. Appearance() 2.6.

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.com 299 . Thường làm nếu pointSize >= 1 pixel. trừ phi bạn dùng setPointAntialiasingEnable(). http://tailieuhay. 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. 2.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.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. 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.6. Lúc đó điểm vuông được làm tròn đi.

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

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

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

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

setCullFace(PolygonAttributes. // polyAttrib. } } // end of class Twist // ////////////////////////////////////////// ///// // // create scene graph branch group // public BranchGroup createSceneGraph() { polyAttrib = new twistAppear = new http://tailieuhay.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.CULL_NON E). twistAppear. return twistAppear. PolygonAttributes PolygonAttributes().com 314 . Appearance createAppearance() { Appearance Appearance().

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

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

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

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

http://tailieuhay. Frame frame = new MainFrame(new wire frame is TwistStripApp(). 256.Lập trình đồ họa trên Java 2D và 3D System.com 319 . System.out.print("The visible only when components").println("one wireframe and one solid surface.").out. System."). 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. } // 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(" of the surface are culled.out. 256).

Một node có thể chỉ ra các đối http://tailieuhay. 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. Bounds được định nghĩa các đối tượng như BoundingSphere. Điều này thường liên quan đến “luật tay phải”. 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 . 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. BoundingBox. BoundingPolytope. Đặc biệt một Scope là một tập các đối tượng Group (chừng hạn BranchGroup).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ồ.7 Bounds and Scope Bound định nghĩa một không gian. 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.com 320 .9 mô tả mỗi đối tượng hành vi có một vùng riêng. 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. Để tiếp tục với ví dụ ánh sáng . Hình 2-24 chỉ ra một ví dụ sử dụng luật tay phải) 2. một vùng cho mỗi nút.

Trong khi đó một phạm vi độc lập với đối tượng quan sát trong môi trường ảo.Chúng được sử dụng trong nhiều ứng dụng.com 321 . được sử dụng trong rất nhiều tương tác và chọn lọc. Các vùng biên giới được định nghĩa băng một số lớp.7. 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. http://tailieuhay.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. 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. 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. 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. Nếu bạn có rất nhiều đối tượng Bound đang sử dụng.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. Bound là lớp trừu tượng là lớp cơ sở cho các lớp biên giới. 2. 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. BoundingPolytope. BoundingSphere là dễ nhất trong khi đó BoundingPolytope là khó nhất. âm thanh sẽ được nói phần sau của chương này. Đối tượng Bound định nghĩa các vùng lồi kín. đối với các nút AlternativeAppearance. và nên làm như vậy khi tạo các vùng biên giới. thêm vào đó ánh sáng và các hành vi được sử dụng. 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. 3 lớp mở rộng của nó là BoundingBox. như sương mù.

com 322 .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. 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. boolean intersect(Bounds boundsObject) Kiểm tra sự giao nhau giữa các đối tượng bao.lang. Kiểm tra khi nào các biên giới bao bị rỗng. void transform(Transform3D trans) Biến đổi đối tượng được bao dựa trên ma trận đưa ra. void combine(Bounds boundsObject) Kết nối đối tượng bị bao này với đối tượng bao. boolean equals(java. boolean isEmpty() Tests whether the Bounds is empty. BoundingPolytope.Object Bounds) Chỉ ra khi nào đối tượng bao này tương đương với đối tượng bao khác. 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. Ta có 2 phương thức sau. void set(Bounds boundsObject) Lập giá trị cho đối tượng bao. 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. 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.

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(Bounds boundsObject) Thiết lập một hình hộp bao từ một hình sẵn có. 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. 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() 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.com 323 .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.y. BoundingBox(Point3d lower. 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. z.

void setUpper(double xmax. 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 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 ymin. BoundingPolytope(Vector4d[] planes) Tạo một BoundingPolytope sử dụng các mặt cho trước. void setLower(Point3d p1) Lập góc dưới của hình hộp bao. Lập góc dưới của hình hộp bao. 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. BoundingPolytope(Bounds boundsObject) Tạo một BoundingPolytope ngoại tiếp một mặt bao cho trước. z <= 1. 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.Lập trình đồ họa trên Java 2D và 3D BoundingBox Method Summary (partial list) void setLower(double xmin. y. double zmin) Sets the lower corner of this bounding Box. BoundingPolytope(Bounds[] boundsObjects) http://tailieuhay. void setUpper(Point3d p1) Lập góc trên của hình hộp bao. double zmax) Lập góc trên của hình hộp bao. double ymax.com 324 .

Hình 2-25 chỉ ra một đồ thị khung cảnh với một nguồn sáng sử dụng BoundingLeafa. 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ó.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.com 325 . 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. Một cách giải quyết tốt hơn là sử dụng BoundingLeafa. Đ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. 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.7. Đây không phải là câu trả lời tốt nhất cho mọi trường hợp.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. void setPlanes(Vector4d[] planes) Lập các mặt phẳng cho bao này. http://tailieuhay. BoundingPolytope Method Summary (partial list) int getNumPlanes() Trả về số mặt phẳng của đối tượng BoundingPolytope. Đặ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.

Một trong những ứng dụng khá hay của đối tượng BoundingLeafa là đặt một BoundingLeafa trên viewPlatform. SchedulingBounds của Behaviors. và InfluencingBounds của Lights. Dòng 2. và PlatformGeometry.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.Ví dụ trong đoạn mã 2-11 sử dụng nguyên tắc đó.4 tạo đối tượng BoundingLeafa. Đối tượng PlatformGeometry được thêm vào nhánh hình thức của đồ thị khung cảnh ở dòng 6. đồng thời làm cho đối tượng BoundingLeafa trở thành con của PlatformGeometry. không gây cảm giác lặp lại thông tin trên cả vùng. http://tailieuhay. 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ù.3.com 326 .

Điều đó có nghĩa là http://tailieuhay. 2. 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.7. void setRegion(Bounds region) Sets this BoundingLeafa node's bounding 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. 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. or a scheduling region. BoundingLeafa Constructor Summary The BoundingLeafa node defines a bounding region object that can be referenced by other nodes to define a region of influence.com 327 . BoundingLeafa Method Summary Bounds getRegion() Nhật vùng BoundingLeafa.3 Scope Như đã giới thiệu ở phía trên. 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. 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. một vùng kích hoạt hoặc một vùng danh mục. đị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. an activation region. Lập vùng bao của nút BoundingLeafa.

Thực tế.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. 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. 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. Đị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. Hiện tượng này không thường xảy ra như ví dụ dưới đây. 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 nút không có phạm vị sẽ không ảnh hưởng được các đối tượng khác. Đồ 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. http://tailieuhay. Đố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. 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. Ngọn đèn có một bóng. 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. 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. 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. 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. Đồ 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. cũng có những trường hợp sử dụng được .com 328 . 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.

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.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.Lập trình đồ họa trên Java 2D và 3D 2.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.2 thêm rất nhiều phương thức tới lớp http://tailieuhay.2 .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. Việc sao chép dữ liệu làm mất thời gian và công sức.com 329 . 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.1 Multiple Geometries in a Single Shape3D Chương 1 giới thiệu về lớp Shape3D phần 2.8. Tính năng này cho phép dựng hình hiệu quả hơn.2. Phiên bản 1.

Trong AxisApp. LineStripArray} Polygon GeometryArray: [Indexed]{TriangleArray. 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.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. 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. QuadArray} http://tailieuhay. Tính năng mới này giảm thiểu số lượng đối tượng trong đồ thị khung cảnh.java giới thiệu trong phần 2.java có sử dụng 1 đối tượng Shape3D.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.5.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.com 330 . 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. TriangleStripArray. Tuy nhiên trong ví dụ AxisApp2. nó tham chiếu đến nhiều đối tượng thành phần hình học khác. TriangleFanArray. Sự cân bằng thể hiện đươi đây: Point GeometryArray: [Indexed]PointArray Line GeometryArray: [Indexed]{LineArray.

void insertGeometry(Geometry Geometry.2> Trả về số thành phần hình học trong danh sách. Shape3D Method Summary (partial list.Enumeration getAllGeometries() <new in 1. 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.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.com 331 .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. int numGeometries() <new in 1.util. int index) <new in 1. see Section 2.2> Trả về liệt kê danh sách các thành phần hình học.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. void removeGeometry(int index) <new in 1. 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.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. void setGeometry(Geometry Geometry.1) void addGeometry(Geometry Geometry) <new in 1.2.2> Lấy các thành phần hình học tại vị trí index trong danh sách. Geometry getGeometry(int index) <new in 1.

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. Những gợi ý và cảnh báo khi sử dụng BY_REFERENCE Nếu sử dụng BY_REFERENCE.Lập trình đồ họa trên Java 2D và 3D 2.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. Cách thay đổi hình chính là thay đối dữ liệu của nó.) . http://tailieuhay.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. 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. 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. 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. Vậy khi nào cần sử dụng BY_REFERENCE. rồi đăng kí giá trị cho nó để định nghĩa dữ liệu hình học (tạo độ. Với phiên bản 1... Ví dụ. 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. 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. màu . Nếu dữ liệu hình học là động 2.com 332 . sử dụng phương thức set*RefFloat là tốt hơn cả. có 2 lí do sử dụng nó là: 1. Người lập trình phải có trách nhiệm đảm bảo cho kiểu dữ liệu đúng đắns. 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ó.8. Và vì thế không có mảng bên trong đối tượng hình học. cách khác là phân chia mảng sử dụng bởi đối tượng hình học.

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. Trong trường hợp này đối tượng GeometryArray là một mảng TriangleStripArray. 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. 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. contentRoot = new http://tailieuhay. sử dụng tham chiếu đến dữ liệu hình học thay vì cách cũ. • Đ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. 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.com 333 . Trong đoạn ma 2-13 được lấy từ chương trình TwistByRefApp. // ////////////////////////////////////////// ///// // // create scene graph branch group // public BranchGroup createSceneGraph() { BranchGroup BranchGroup().java.

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

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

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

Point3f) array.2> Sets the byte color array reference to the specified array. void setCoordRef*(Point*[] coords) <new in 1.2> Sets the double coordinate array reference to the specified array.2> Sets the coordinate array reference to the specified Point* (Point3d. void setColorRef*(Color*[] colors) <new in 1. Color3f. void setTexCoordRef*(int texCoordSet. TexCoord*[] texCoords) <new in 1. void setCoordRefDouble(double[] coords) <new in 1.com 337 .2> Sets the color array reference to the specified Color* (Color3b. or Color4f) array.2> Sets the Vector3f normal array reference to the specified array. trong một số trường hợp chế độ dữ liệu có thể là INTERLEAVED. Color4b. void setNormalRef3f(Vector3f[] normals) <new in 1. TexCoord3f) array.2> Sets the float normal array reference to the specified array.2> Sets the interleaved vertices array reference to the specified array. trong một số trường hợp không được phép là INTERLEAVED.2> Sets the texture coordinate array reference for the specified texture coordinate set to the specified TexCoord* (TexCoord2f.2> Sets the float color array reference to the specified array.2> Sets the float coordinate array reference to the specified array. void setColorRefFloat(float[] colors) <new in 1. void setNormalRefFloat(float[] normals) <new in 1. void setInterleavedVertices(float[] vertexData) <new in 1. void setColorRefByte(byte[] colors) <new in 1. http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D chế độ dữ liệu không chọn là BY_REFERENCE. void setCoordRefFloat(float[] coords) <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.2> Sets the initial coordinate index for this GeometryArray object. void setInitialTexCoordIndex(int texCoordSet.2> int initialTexCoordIndex) Sets the initial texture coordinate index for the specified texture coordinate set for this GeometryArray object. 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.2> Sets the float texture coordinate array reference for the specified texture coordinate set to the specified array. <new in 1. This method is easily confused with the setInitialVetrexIndex method which is used when the Geometry is not BY_REFERENCE. http://tailieuhay. GeometryArray Methods for Setting Initial Location of Referenced Geometry Data (partial list) void setInitialColorIndex(int initialColorIndex) <new in 1. void setInitialNormalIndex(int initialNormalIndex) <new in 1. Dưới đây là các phương thức để thay đối giá trị dữ liệu hình học.com 338 .2> Sets the initial color index for this GeometryArray object.2> Sets the initial normal index for this GeometryArray object. float[] texCoords) <new in 1. void setInitialCoordIndex(int initialCoordIndex) <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.

and texture coordinate data for this GeometryArray are accessed via a single interleaved. http://tailieuhay. normal. This is only used in by-reference Geometry mode. floating-point array reference. This is only used in by-reference Geometry mode. normal.2> allow write access to the count or initial index information for this object ALLOW_REF_DATA_READ <new in 1. color. ALLOW_COUNT_READ | WRITE <new in 1. only used in by-reference Geometry mode ALLOW_REF_DATA_WRITE <new in 1.2> Specifies that the position.com 339 . 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. It also enables writing the referenced data itself.2> allow read access to the Geometry data reference information. and texture coordinate data for this object are accessed by reference INTERLEAVED <new in 1. 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ó.2> Specifies the position.2> allow write access to the Geometry data reference information for this object. color. via the GeometryUpdater interface.

Tạo một phạm vi quan sát cho AlternateAppearance AlternateAppearance theo vào ý đồ mình. 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. 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. Thứ 2 phải có một giới hạn quan sát trên ứng dụng của nó.8.4 AlternateAppearance <new in 1. 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. thị Đừng quên lập thêm cờ khung cảnh.6. Phần 2. appearanceOverrideEnable trên đối tượng Shape3D.Lập trình đồ họa trên Java 2D và 3D updateData method of GeometryArray public void updateData(GeometryUpdater updater) <new in 1. 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.1 đối tượng Shape3D có thể có một tham chiếu đến nút thành phành Appearance.2> Như đã thấy trong phần 2. http://tailieuhay.6. 2. Có 3 cách. Sau đso lập vùng ảnh hưởng thông qua đối tượng Bounds hoặc BoundingLeafa. Xem hình 2-20 và 2-37.com 340 . 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.2> Cập nhật mảng dữ liệu được truy cập thông qua tham chiếu. Thứ nhất đối tượng phải nằm trên trên vùng bao của AlternateAppearance.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.

1) ALLOW_APPEARANCE_OVERRIDE_READ | WRITE <new in 1. scope.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> cho phép truy cập đọc/ghi tới cờ appearanceOverrideEnable AlternativeAppearance Class <new in 1.Lập trình đồ họa trên Java 2D và 3D Shape3D setAppearanceOverrideEnable() Method void setAppearanceOverrideEnable(boolean flag) <new in 1.com 341 . http://tailieuhay.2> Tạo một nút AlternateAppearance với giao diện cho trước. AlternateAppearance Method Summary (partial list) void addScope(Group scope) <new in 1.2> Khởi tạo một nút AlternateAppearance với các tham số mặc định: Appearance. see Section 2. và influencingBoundingLeaf = null AlternateAppearance(Appearance Appearance) <new in 1. Shape3D Capabilities (partial list.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.2.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. influencingBounds. 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.

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> 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 vùng ảnh hưởng của AlternateAppearance tới vùng bao cho trước. void setAppearance(Appearance Appearance) <new in 1. void insertScope(Group scope.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.Lập trình đồ họa trên Java 2D và 3D java. Lập vùng ảnh hưởng của AlternateAppearance tới lá bao cho trước.Enumeration getAllScopes() <new in 1. void removeScope(int index) <new in 1.com 342 .2> Lập giao diện cho nút AlternateAppearance void setInfluencingBoundingLeaf(BoundingLeafa region) <new in 1.2> Sets the AlternateAppearance's influencing region to the specified bounding leaf. int index) <new in 1.2> Trả về bảng liệt kê danh sách nút AlternateAppearance của phạm vi quan sát. int numScopes() <new in 1. void setScope(Group scope.2> Trả về số nút trong danh sách. void setInfluencingBounds(Bounds region) <new in 1.util.2> Loại bỏ nút tại vị trí cho trước trong danh sách. int index) <new in 1.

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). 2.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. ngoài đối tượng có thể nằm ngoài vùng frustum (hình cụt). 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. 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. http://tailieuhay.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ó.com 343 . Lí do thì có rất nhiều.9. Hình 2-29 sẽ đưa ra cho bạn định nghĩa rõ hơn về vùng frustum. Đ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. Cắt xén là một chủ đề phức tạp. phần này đưa ra các vấn đề cơ bản nhất trong việc cắt hình . 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ị.

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. void setFrontClipDistance(double distance) Lập khoảng cách mặt cắt trước với mô hình quan sát. Nên để (back clip distance) / (front clip distance) < 3000. khoảng cách này phải lớn hơn với khoảng cách của mặt trước.com 344 .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.0 và nhỏ hơn khoảng cách sau. khoảng cách này phải lớn hơn 0. http://tailieuhay. 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. void setFieldOfView(double fieldOfView) Lập trường ngang mô hình quan sát dạng radians. void setBackClipDistance(double distance) Lập khoảng cách mặt cắt sau với mô hình quan sát. Tuy nhiên thực thế tỉ lệ này thường là từ 100 đến 1000 là hợp lí nhất. Dưới đây là một trong số đó.

void setApplicationBounds(Bounds region) Lập vùng ứng dụng cắt tới đối tượng bao.9. 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. 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á.com 345 . 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 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. Nút cắt là một đối tượng thực hiện điều này. mặt trước định nghĩa bởi đối tượng View không ảnh hưởng. Khi vùng bao này giao với khu vực quan sát .khoảng cách mặt sau của đối tượng Clip được sử dụng để dựng.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.Lập trình đồ họa trên Java 2D và 3D 2.

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. 2.com 346 . Nút ModelClip có thể cắt đối tượng quan sát ra theo nhiều cách. dù chúng ở trong hình chóp cụt nhìn thấy. http://tailieuhay. 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. • 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. Ả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. ALLOW_BACK_DISTANCE_READ | WRITE allow read (write) access to its back distance at runtime.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. 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.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.

boolean[] enables) <new in 1. ModelClip(Vector4d[] planes) <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 tham số mặc định.2> Tạo một nút ModelClip với mặt cho trước. void insertScope(Group scope. ModelClip Method Summary (partial list) void addScope(Group scope) <new in 1. Kết quả là mảng Vertor4d được sử dụng trong hàm tạo phải có kich thước 6.2> http://tailieuhay. ModelClip(Vector4d[] planes.2> Tạo một nút ModelClip với mặt cho trước và có thiết lập các cờ. ModelClip Constructor Summary ModelClip() <new in 1.2> Returns the number of nodes in this ModelClip node's list of scopes.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. int numScopes() <new in 1.2> Appends the specified Group node to this ModelClip node's list of scopes.com 347 . void removeScope(int index) <new in 1. int index) <new in 1.

2> Replaces the node at the specified index in this ModelClip node's list of scopes with the specified Group node. void setPlane(int planeNum. void setPlanes(Vector4d[] planes) <new in 1. void setScope(Group scope.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.2> Set the ModelClip node's influencing region to the specified bounding leaf.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.2> Sets the clipping planes of this ModelClip node to the specified planes. void setInfluencingBounds(Bounds region) <new in 1. boolean enable) <new in 1.com 348 . void setInfluencingBoundingLeaf(BoundingLeafa region) <new in 1.2> Sets the specified clipping plane of this ModelClip node.2> Set the ModelClip node's influencing region to the specified Bounds. void setEnables(boolean[] enables) <new in 1. 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. int index) <new in 1. Vector4d plane) <new in 1. void setEnable(int planeNum.

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 .

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. và tinh chỉnh các đa giác này.com 350 .2 sẽ giới thiệu lớp GeometryInfo. Lightwave.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.3 giới thiệu lớp Loader. 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. http://tailieuhay. Cụ thể lớp Loader có thể đọc các file VRML. Stripifier. 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. Các lớp này chuyển đổi đa giác thành tam giác. Lớp GeometryInfo cũng với các lớp Triangulator. 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.Lập trình đồ họa trên Java 2D và 3D CHƯƠNG 3 TẠO NỘI DUNG 3. 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. Bằng các phương pháp này công việc lập trình trơ nên buốn tẻ. Mục 3.

Để khởi tạo một đối tượng GeometryInfo. http://tailieuhay. chúng ta sẽ xác định một đa giác bất kỳ phù hợp với dối tượng đó. 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. 351 . Sử dụng lớp GeometryInfo công việc sẽ trở nen dễ dàng và thuận tiên hơn. Nếu chúng ta muốn tạo bóng cho đối tượng hình học.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. Khi bắt đầu vẽ một đối tượng hình học. 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. từ đó Java3D có thể render (tô_chát) . ta sử dụng NormalGenerator để tính toán các vector bề mặt của đối tượng hình học.com TRIANGLE_ARRAY.1 GeometryInfo Thông thường để vẽ một hình một đối tượng hình học bất kỳ. 3. 3. Để 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. QUAD_ARRAY. chúg ta cần chỉ rõ loại geometry cần dùng: POLYGON_ARRAY. Đa giác này có thể là đa giác lõm.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.1.2.

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

com 353 . chúng ta không cần quan tâm đến kiểu của GeometryInfo(POLYGON_ARRAY.geometry. 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. QUAD_ARRAY.2.sun. Khi sử dụng những lớp tiện ích này.util.Lập trình đồ họa trên Java 2D và 3D mục.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. 3. http://tailieuhay. STRIP_ARRAY… ). Tuy nhiên các thành phần khác của dối tượng GeometryInfo sẽ bị thay đổi. khi đó các dữ liệu này được chuyển đổi thành các tam giác chỉ mục.j3d.

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.sun.com 354 .3 chiều(đa http://tailieuhay.j3d. Khi chúng ta chuyển đối tượng hình học cần thể hiện cho đối tượng GeometryInfo. Hàm tạo GeometryInfo Gói: com..utils.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. các đa giác 2 chiều. 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. 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.lang.geometry Lớp cha: java.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.

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.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 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 độ. void setNormalIndices(int[] normalIndices) http://tailieuhay. mầu sắc. 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ạ độ. void setCoordinates(Point3d[] coordinates) Thiết lập mảng của hệ trục tọa độ. chỉ mục. 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.com 355 .

Trong đó lớp Triangulator chỉ làm việc với đối tượng hình học kiểu POLYGON_ARRAY.Lập trình đồ họa trên Java 2D và 3D Thiết lập mảng các chú dẫn. Đây cũng chính là thứ tự khi chúng ta làm việc với POLYGON_ARRAY. http://tailieuhay. 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. Stripifier và NormalGenerator. 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.com 356 .

Hàm tạo lớp Stripifier nhằm tạo ra một đối tượng stripification Stripifier Constructor Summary Gói: com.sun. Stripifier() Hàm tạo Pương thức của lớp Stripifier void stripify(GeometryInfo gi) http://tailieuhay.geometry Lớp cha: java. Để 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.utils.geometry Lớp cha: java.com 357 .utils.lang.j3d.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 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.sun.lang.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.j3d. Triangulator Constructor Summary Gói: com.

sun. NormalGenerator Constructor Summary Gói: com. Lớp NormalGenerator có hai hàm tạo.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. 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. 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.j3d. 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.76794 radians.geometry Lớp cha: java. Sau đó đối tượng 3D này có thể http://tailieuhay. Hàm tạo thứ hai cho phép thiết lập giá trị cho crease angle.com 358 .lang.Object NormalGenerator() Khởi tạo một NormalGenerator với góc gập mặc định (0. 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. or 44°).utils.

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. Để load vào nội dung một file.2/demo/java3d/ObjLoad. ma chỉ có phần giao diện dùng cho kỹ thuật loading được đưa vào.sun.com 359 . Class ObjectFile Gói: com.loaders Thực thi: Loader http://tailieuhay.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.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.j3d. 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.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. Một ví dụ đơn giản sử dụng leader. chúng ta không nhất thiết phải sử dụng một lớp tiện ích để load file đó.j3d. 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. Gói com.

2.. Chúng ta có thể thấy các bược 1.com 360 . 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. Ta có bảng danh sach cụ thể dưới đây. Các loader phổ biến Trong Java3D chúng ta có thể tìm thây rất nhiều lớp Loader.6 trong ví dụ trên đèu được hiện theo trình tự các bước ta phân tích. 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.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. Chúng ta xem xét một ví dụ được thực hiện theo các bước đã nói ở trên.obj.

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

URL url) Phương thức lấy ra nội dung của một file từ URL.j3d.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. Interface Loader Method Summary Gói: com. 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.sun.lang. 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.sun. Phần giao diện này cung cấp cho lớp Loader các định dạng file khác nhau.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.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.String fileName) Phương thức lấy ra nội dung của một file từ tên file. 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.j3d.io.Lập trình đồ họa trên Java 2D và 3D com.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. Scene load(java. và trả về một đối tượng scene có chứa khung cảnh Scene load(java.lang.com 362 . và trả về một đối tượng scene có chứa khung cảnh void setBasePath(java. Scene load(java.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.

com 363 .. Lớp Loader thực hiện phần thực thi 2 hàm tạo.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.loaders Thực thi: Loader Lớp Loader thực thi giao diện loader. LOAD_FOG_NODES Cờ cho phép load sương mù vào trong khung cảnh.sun. LOAD_LIGHT_NODES Cờ cho phép load đối tượng ánh sáng 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. LOAD_SOUND_NODES Cờ cho phép load đối tượng âm thanh vào trong khung cảnh.j3d. LOAD_VIEW_GROUPS Cờ cho phép load đối tượng view (camera) vào trong khung cảnh...Lập trình đồ họa trên Java 2D và 3D void setBaseUrl(java. LoaderBase Constructor Summary Gói: com. LoaderBase() Khởi tạo đối tượng Loader với cá giái trị mặc định http://tailieuhay.net. 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_BEHAVIOR_NODES Cờ cho phép load các hành vi vào trong khung cảnh.

j3d. chúng ta có thể thừa kế lại lớp loader cơ sở trong gói com. 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. 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*. SceneBase Constructor Summary Gói: com. 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.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. 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* . 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.com 364 . Khi thừa kế lớp loader cơ sở.lang. SceneBase() Khởi tạo một đối tượng SceneBasse SceneBase Method Summary (partial list: loader users' methods) Background[] getBackgroundNodes() Behavior[] getBehaviorNodes() java.j3d.sun.loaders Thực thi giao diện Scene Lớp SceneBase thực thi giao diện Scene.loaders và sử dụng lớp SceneBase trong cùng gói này.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.sun.

Phần tiếp theo ta sẽ đi vào chi tiết việc viết một loader. 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. 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ính toán bề mặt thông thường của các đa giác. 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. 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.com 365 . tạo ra một đối tuợng scene graph thể hiện cho nội dung của file được load. Tuy nhiên việc nghiên cứu cách viết. hiểu được việc thực thi của ObjectLoader.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. • 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. 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ạ.util. hiểu cách sử dụng GeometryInfo.

Số lượng các layer lại phụ thuộc nhiều vào format của file cần load. Đó là cách tiếp cận chuẩn cho việc xây dựng một loader. 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. có loại file đơn giản. Layer/leve l Tokenizer Chức năng Chuyển các ký tự thành các http://tailieuhay. có loại file phức tạp. việc xây dựng lớp loader trở nên dễ dàng hơn. chúng ta có thể dùng các lớp SceneBase và LoaderBase (đã trình bày ở các chương trước). Tuy nhiên để có thể tận dụng được sự hỗ trợ của Java3D. 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. 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. hoặc sử dụng LOD. 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. Có nhiều cách tiếp caạn trong việc xây dựng một loader.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. Sau đây chúng ta xem xét tập các layer đơn giản. Sử dụng khái niệm Layer. 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.com 366 . 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.

com 367 . Một vài đối tượng có thể là đối tượng đỉnh.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.Thông thường tầng scene trong Java3D đơn giản. Lấy ví dụ một token có thể là một số. 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ạ. 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. • File http://tailieuhay. hay một ký tự đơn. Ví dụ như file theo định dạng Open Inventor và OOGL List. 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. một từ. ánh sáng. kết cấu hay bất cứ đối tượng khung cảnh nào trong Java3D. 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. gọi là các token. Tần này có nhiệm vụ chia nhỏ nội dung cảu file thành phần nhỏ hơn. đa giác.

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

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

0. Color3f color.lang. java.0) kéo dài theo chiều dương trục x.geometry Lớp Text2D tạo ra một khung chữ nhật được ánh xạ đến phàn nội dung text.String http://tailieuhay.lang. trực y Text2D(java.com 381 . int fontSize. 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. hiẹn thị nội dung text được gửi bởi nguời dùng. 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 fontName. Text2D Constructor Summary Gói: com. 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.j3d.sun.utils.

com 382 .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.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. 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.String text) <new in 1. ta có thể chỉ định diểm tham chiếu tuỳ chọn • Tham chiếu đói tượng Shape3D.lang. 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. 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. kích thứoc và kích cỡ của font. 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. http://tailieuhay. 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. 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. Khởi tạo một đối tượng Text3D bao gồm nhiều công việc hơn trong đối Text2D.

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

Ta có thể “chiếu sáng” đối tượng Text3D theo nhiều hướng khác nhau. Để có thể chiếu nhiêug hướng khác nhau chúng ta sử dụng lớp Material.com 384 . Mỗi đối tượng Text3D có một điểm tham chiếu. http://tailieuhay. 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. Điểm tham chiếu là sự kết hợp của path và alignment của đố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. Trong bảng dưới đây cho ta minh họa về sự kết hợp này.

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

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). Point3f position.com 386 . int alignment. Những phương thức của lớp Text3D. String string. String string. 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. Text3D Method Summary void setAlignment(int alignment) Đặt canh lề cho đối tượng Text3D NodeComponent void setCharacterSpacing(float characterSpacing) http://tailieuhay. 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). Xem thêm ví dụ ở bảng trên. int path) ALIGN_CENTER Căn lề giữa. tọa độ của điểm tham chiếu. ALIGN_LAST alignment: ký tự cuối cùng của dòng chữ được đặt tại điểm tham chiếu. Point3f position) Tạo ra đối tượng Text3D với cá tham số đối tượng Font3D.. 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.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. ALIGN_FIRST alignment: ký tự đầu tiên của dòng chữ được đặt tịa điểm tham chiếu.

Copy xâu ký tự từ tham só đầu vào cho đối tượng Text3D node. ALLOW_POSITION_READ | WRITE Cho phép đọc ghi giá trị vị trí của xâu http://tailieuhay. Các chế độ của đối tượng Text3D.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ự.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_BOUNDING_BOX_READ ALLOW_CHARACTER_SPACING_READ | WRITE Cho phép đọc ghi các ký tự dấu cách.lang.com 387 . 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.

Object Một đối tượng Font3D bao gồm Java 2D Font và chiều sâu.lang. Dưới đây là các phương thức get*. 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.Font font. Đố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. FontExtrusion extrudePath) Font3D(java. Font3D Constructor Summary Lớp cha: java. Font3D Method Summary void getBoundingBox(int glyphCode. double tessellationTolerance.Font font.awt.awt. Một đối tượng Font3D có thể được dùng để tạo ra nhiều đối tượng Text3D khác nhau. Lớp Font3D không có những phương thức set* cụ thể.Font getFont() Returns the Java 2D Font used to create this Font3D object. ALLOW_STRING_READ | WRITE Cho phép đọc ghi đối tượng xau ký tự.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ự. 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.awt.com 388 . BoundingBox bounds) java. Trả về đối tượng Java2D Font được sử dụng để tạo ra đối tượng Font3D http://tailieuhay. FontExtrusion extrudePath) <new in 1.2> ALLOW_PATH_READ | WRITE Cho phép đọc ghi giá trị đường dẫn.. ALLOW_POSITION_READ | WRITE Cho phép đọc ghi giá trị vị trí. Font3D(java.

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

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

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.Shape getExtrusionShape() Gets the FontExtrusion's shape parameter. một hình ảnh hay thậm chí môt đối tượng hình học. • 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. 391 http://tailieuhay. 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. 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. ta có thể lựa chọn mầu sắc.com . ảnh. void setExtrusionShape(java. 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. double getTessellationTolerance() <new in 1. Một dói tuợng background có thể là một mầu cụ thể.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.

1. //black background backg.addChild(backg). Ví dụ background là mầu nền Background backg = new Background(1. ví dụ thứ hai ta thêm một đối tượng hinh học vào background.com 392 .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. Ta có thể xem một ví dụ hoàn chinh BackgroundApp. // backg. một thể hiện của lớp background là thành phần con thuộc đối tượng Group http://tailieuhay.0f.setApplicationBounds(BoundingSphere()). objRoot.setApplicationBounds(new Point3d().0f).setGeometry(createBackGraph()).addChild(backg).java trong thư mục examples/easyContent.0)). contentRoot. Phương thức createBackGraph() bao gồm việc tạo ra đối tượng hình học làm nền. 1. 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. // add BranchGroup of background backg. Ví dụ background là đối tượng hình học Background backg = new Background().0f. Phương thức này trả về đối tượng BranchGroup. 100.

Các phương thức trong lớp background http://tailieuhay. float b) Constructs a Background node with the specified color. float g. It also specifies an application region in which this background is active. Background(ImageComponent2D image) Constructs a Background node with the specified image. Background(Color3f color) Constructs a Background node with the specified color. Tham số trong hàm tọa cho biêt mầu sắc hoặc hình ảnh cho background. Background() Constructs a Background node with a default color (black). Background geometry must be pre-tessellated onto a unit sphere and is drawn at infinity. Background(float r. It optionally allows background geometry to be referenced. 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.com 393 .Lập trình đồ họa trên Java 2D và 3D Background có nhiều hàm tạo.

float b) Sets the background color to the specified color. Danh sách lớp con của lớp http://tailieuhay. void setColor(float r.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. float g. void setColor(Color3f color) Sets the background color to the specified color.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. void setImage(ImageComponent2D image) Sets the background image to the specified image. 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. void setGeometry(BranchGroup branch) Sets the background geometry to the specified BranchGroup node. void setApplicationBounds(Bounds region) Set the Background's application region to the specified bounds.com 394 .

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

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. 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. http://tailieuhay.com 396 . 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.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. cả tương tác và hoạt hình đều sử dụng 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. 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. Trong Java3D.

chúng ta gọi là ứng dụng cụ thể. 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. 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. hay phản ứng lại các kích thích. sắp lại lại các đối tượng … 4.Lập trình đồ họa trên Java 2D và 3D 4. 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. Đối tượng Behaviour trong một đồ thị khung cảnh có nhiệm vụ thây đổi đồ thị khung cảnh. 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. cung cấp các kỹ thuật để thay đổi đồ thị khung cảnh.com .1. 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. 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. âm thanh trong không gian ảo. 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ệ. liệt kê nhưng tác nhân từ cột bên trái xuống phỉa dưới. Lớp Behaviour là một lớp cơ sở trừu tượng.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. và những thay đổi nằm trên dòng đầu. di chuyển chuột.

Kỹ thuật này http://tailieuhay. Picking được thực thi sử dụng các hành vi nhưng không được liệ kê ở trên. trong đó chỉ có bè mặt cảu kết cấu đa diện được nhìn thấy. như một cái cây. Kỹ thuật trên (texture polygon) thương được gọi là billboard approach.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ưng sự vật ngoài tự nhiên. cành .com 398 . 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. 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. Lấy ví dụ biểu diễn một cái cây. Đ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.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. 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. 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á. Hành vi định hướnggọi là billboard behavior.

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. 4. của riêng mình và một ví sử dụng lớp http://tailieuhay. các đối tượng trực quan được biểu diễn ít chi tiết hơn. chi tiết hơn. 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. 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. Trong mục này chúng ta sẽ tìm hiểu lớp Behaviour.com 399 .2 Tổng quan lớp Behaviour Trong bảng 4-1. 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.1.2 Cơ bản về hành vi Như đã đề cập trong các phần trước.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. Hành vi LOD (level of detail) c ó nh ững ứng dụng liên quan. chỉ rõ sự chuyên môn hoá của Behaviour trong Java3D API và các gói tiện ích. 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. lớp Behaviour được sủ dụng nhiều trong các ứng dụng Java3D theo nhiều cách khác nhau. Cả billboard và LOD đều tương ứng với các lớp dẫn xuất từ lớp Behaviour 4. đưa ra cách thức để tạo ra một lớp Behaviour Behaviour. Với LOD.

Đối tượng Behaviour cần một tham chiếu đến đối tượng có sự thay đổi. 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ó.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. 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. 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. Nếu không.2. 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. để nó có khả năng tạo ra những hành vi thay đổi. http://tailieuhay. Trong hàm tạo. sẽ hành động trong một đồ thị khung cảnh nhằm tác động đến hành vi.Lập trình đồ họa trên Java 2D và 3D Sơ đồ các lớp con của lớp Behaviour 4. Các Behaviour thông qua các đối tượng đồ hoạ.com 400 .

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. 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. thường là sự thay đổi của các đối tượng. Phương thức processStimulus phản xạ lại các tác nhân. giải mã điều kiện xảy ra hành động của trigger. thiết lập lại các trigger. đượ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. 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). Chúng ta xem xét ví dụ dưới đây. reset lại trigger nếu cần thiết. Phương thức processStimulus được gọi khi các trigger được kích hoạt. 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.com 401 . nó bao gồm cả việc giải mã các sự kiện. Phương thức processStimulus có trach nhiệm bắt và xử lý các sự kiện xảy ra. chứa tham chiếu đến đối tượng trong sự thay đổi Viết đè hàm khởi tạo public void initialization(). hay là sự kết hợp của các WakeupCondition . Viết hàm tạo.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. Các triggger thực chất là các đối tượng WakeupCondition (các điệu kiến thức dậy). 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.chỉ định các tiêu chuẩn kích hoạt ban đầu (trigger) Viết đè hàm public void processStimulus().

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

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

Lấy ví dụ. this. http://tailieuhay. 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. các hàm này phải trả về để cho phép việc tô trát được tiếp tục. Chungs ta có thể phát triển thêm các chức năng phong phú hơn. 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. khi hành vi quay tròn được gọi.1. 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).wakeupOn(new WakeupOnAWTEvent(KeyEvent.rotY(angle).Lập trình đồ họa trên Java 2D và 3D public criteria) { // do what is necessary in response to stimulus angle += 0. 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. 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. Khi cả hai phương thức initilization và processStimulus được gọi bởi hệ thống Java3D.com 404 . 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.

Đọc và ghi các khả năng cho đối tượng đích http://tailieuhay.com 405 . Để nâng cấp làm việc hiệu quả hơn. Trong trường hợp đó. trong khi đó đồ thị khung cảnh đòi hỏi một Behaviour là ứng dụng và Behaviour phụ thuộc.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.Them Behaviour vào đồ thị khung cảnh. Rất nhiều Behaviour chỉ cần một đối tượng TransformGroup.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. 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 đồ thị khung cảnh phải có chứa đối tượng TransformGroup được chuẩn bị để quay. các tác nhân có thể bị một số Behaviour bỏ qua. thay đổi 3. 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.Bhv ch ỉ tr ở n ên active khi khung lịch của nó giao với sự hoạt động của ViewPlatform. để sử dụng được lớp SimpleBehaviourApp trong phần trên .Xác định một khung lịch (SchedulingBoundingLeaf) 4. Thiết lập sự hỗ trợ cảu một Behaviour.Chuẩn bị đồ thị khung cảnh 2. 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. một thể hiện của lớp Behaviour phải được thêm vào đồ thị khung cảnh. Java3D sử dụng khung lịch để thực hiện execution culling. Ví dụ. Các bước sử dụng một Behaviour 1. tham chiếu dến đối tượng cần chuyển động.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.Lập trình đồ họa trên Java 2D và 3D 4.2.

addChild(new ColorCube(0. objRoot. SimpleBehavior myRotationBehavior = new SimpleBehavior(objRotate).compile().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(). TransformGroup TransformGroup(). objRoot. objRotate. myRotationBehavior.com 406 . objRotate = new objRotate.ALLOW_TRAN SFORM_WRITE). } http://tailieuhay. // Let Java 3D perform optimizations on this scene graph. objRoot.addChild(objRotate).addChild(myRotationBehavior).setSchedulingBounds(new BoundingSphere()).4)).setCapability(TransformGroup. return objRoot.

Trong đồ thị khung cảnh tạo bởi SimpleBehaviourApp. 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. nhưng lớp Behaviour không chỉ giưoi hạn như vậy . http://tailieuhay. bảo trì code. Ví dụ của chúng ta nhằm thực hiện quay một ColorCube. 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 . chứ không có ý định thực hiện những khả năng có thể của Behaviour. 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 .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. ta có thẻ quay bất kỳ đối tượng nào là con của đối tượng TransformGroup. đối tượng SimpleBehaviour và đối tượng ColorCube khong nằm trong cùng một hệ tọa độ địa phương. Ví dụ trên chỉ có ý dịnh là điểm khởi đầu cho quá tnhf làm việc vói Behaviour. đối tượng TransformGroup.

Khi đối tượng bound nằm trong đồ thị khung cảnh cùng với đố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. Chúng ta có thể tương tác với đối tượng trực quan không nằm trong view. khi đó đối tượng Behaviour là không active. Điều này có thẻ thực hiện được trọn vẹn theo hình dưới đây. Chúng ta sẽ xem xét lớp BoundingLeaf này trong phần 3. Có hai giải pháp cho vấn đề này. người dùng có thể có khả năng tiếp tục biên dịch đối tượng đó. nều đối tượng TransformGroup được dùng để biêc dịch đối tượng ColorCube. Phương pháp thứ hai là sử dụng đối tượng BoundingLeaf cho khung lịch. Miễn là sự kích hoạt quả view vẫn giao với kung lịch của đối tượng Behaviour.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 .com 408 . khi dó đối tượng ColorCube có thể bị dịch chuyển ra ngoài của khung nhìn. lúc đó đối tượng Behaviour vẫn còn active. Dù sao.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. 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.7 http://tailieuhay.

‘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. Ví dụ như đoạn mã tỏng 4-1. Các phương thức của lớp Behaviour thuwòng gây ra vấn đề ‘memmory burn’.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ẽ ảnh huwòng đến quá trình garbage collection và quá trình ô trát sẽ bị dưng lại.2. http://tailieuhay. Một Behaviour không tốt sẽ làm giảm hiẹu năng của quá trình tô trát. Việc sử dụng bộ nhớ quá mức . thay bằng việc khởi tạo một đối tượng mới. 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. Tuy nhiên việc xác định và tránh xảy ra ‘memmory burn’ thường khá dễ dàng. 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. phương thức processStimulus sử dụng toán tử new trong qu á tr ình g ọi wakeupOn.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. 4. sẽ là không cần thiết nếu chúng ta gọi đến phương thức processStimulus. đối tượng này trở thành ‘rác’ mỗi lần Behaviour được kích hoạt.com 409 . chúng ta sẽ sử dụng lại đối tượng cũ. lớp Behaviour càn được thừa kế trước khi khởi tạo một đối tượng Behaviour. Ví dụ trong đoạn code 4-3.chức năng. Nếu như không có tác nhân gì kích hoạt Behaviour. 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.

http://tailieuhay. Mộ trong những điều kiện wakeup là WakeupOnBehaviorPost. Lớp WakeupCondition và các lớp liên quan sẽ được trình bày trong phần 4. 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à các lớp con của Leaf.Tham số đầu vào của phương thức này là đối tượng WakeupCondition . Chúng ta xem xem xét lớp akeupOnBehaviorPost chi tiết hơn trong mục 4-16.3. Đố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. Phương thức wakeOn được dùng trong hai phương thức initialization và processStimulus để thiết lập trigger cho Behaviour. 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.com 410 . 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. Các phương thức khác của lớp Behaviour đọc trình bày trong bảng dưới đây.

LOD. nếu chúng ta có nhiều View active. Chúng ta không có phương thức setView.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. void processStimulus(java. một Behaviour có thể được active bởi nhiều view.com 411 .util. Đố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. 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 đó. 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. Behavior Method Summary Behavior is an abstract class that contains the framework for all behavioral components in Java 3D. void postId(int postId) Post the specified Id.Tỏng một không gian ảo. 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. 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 .. chúng ta có thẻ có nhiều view.Enumeration criteria) http://tailieuhay. Vì vậy một hành vi Billboard pahỉ hướng tới view chính. void initialize() Initialize this behavior.) và đối với những Behaviour nói chung chung. trong trường hợp có nhiều view trong cùng một đồ thị khung cảnh. View getView() Returns the primary view associated with this behavior.

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

Phần tiếp theo chúng ta mô tả lớp WakeupCondition và các lớp con của nó.3. Phương thức còn lại.1 Điều kiện kích hoạt Lớp WakeupCondition cung cấp hai phương thức. It provides the following two methods. 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. allElements. triggeredElements. 4.Phương thức đầu tiên. trả về danh sách liệt kê các tác nhân wakeup của đối tượng WakeupCondition . WakeupCondition Method Summary The WakeupCondition abstract class is the base for all wakeup classes. Enumeration allElements() http://tailieuhay.com 413 .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.

3. http://tailieuhay. Enumeration triggeredElements() Returns an enumeration of all triggered WakeupCriterion objects in this Condition. WakeupCriterion Method Summary boolean hasTriggered() Returns true if this criterion triggered the wakeup.com 414 .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. 4. WakeupCondition chỉ cung cấp một phương thức duy nhất: hasTriggered. Chúng ta sẽ xem xét chi tiết các lớp này trong ngay sau đây. 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. 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. 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.Lập trình đồ họa trên Java 2D và 3D Returns an enumeration of all WakeupCriterion objects in this Condition. lớp WakeupOnActivation chỉ có một hàm tạo duy nhất. vì phương thức triggeredElements của lớp WakeupCondition thực hiện điều này hộ chúng ta. 4.3 Quy định lớp WakeupCriterion Trong bảng 4-2 đưa ra quy định 14 lớp WakeupCriterion.3.

Behaviour sẽ không trở nên active. thì WakeupCondition mới có thể kích hoạt lần tiếp theo. WakeupOnActivation() Constructs a new WakeupOnActivation criterion. WakeupOnActivation is paired with WakeupOnDeactivation which appears on page 4-21. Khi đó cả Acivation và Deactivation đều khong được kích hoạt. Đ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.com 415 . 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. WakeupCondition sẽ không kích hoạt thêm một nào nữa. trong những trường hợp như vậy. Ta có những lớp WakeupCriterion theo từn cặp (Entry/Exit hay Activation/ Deactivation). 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. Khi sự giao nhau này vần còn.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. Đề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. 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. 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. WakeupOnAWTEvent http://tailieuhay.

MOUSE_PRESSED. 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_RELEASED. MouseEvent.và AWT EVENT_MASK với các giá trị: : KEY_EVENT_MASK.MOUSE_CLICKED. 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.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. MouseEvent.KEY_TYPED. MouseEvent. trong đó AWTId là một trong các hằng số KeyEvent. KeyEvent.com 416 . or one of many other event values. WakeupOnAWTEvent Method Summary AWTEvent[] getAWTEvent() http://tailieuhay.KEY_RELEASED. MouseEvent.MOUSE_DRAGGED. KeyEvent. MouseEvent.KEY_PRESSED.MOUSE_MOVED. WakeupOnAWTEvent(long eventMask) Khởi tạo một đối tượng WakeupOnAWTEvent sử dụng ORed EVENT_MASK. Ví dụ WakeupOnAWTEvent có 2 hàm tạo và một phương thức. MOUSE_MOTION_EVENT_MASK. MOUSE_EVENT_MASK.

http://tailieuhay. kết hợp Behaviour với post ID. sử dụng ID của một Behaviour xác định.Một đối tượng Behavior có thể post đưa ra một giá tri ID (kiểu số nguyên). bao gồm nhiều hơn 1 WakeupOnBehaviorPost. và một Behaviour khác đóng cửa. 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.com 417 . những sự kiện kích hoạt lớp WakeupOnAWTEvent . int postId) Khởi tạo một đối tượng WakeupOnBehaviorPost Do WakeupCondition có thể chứa nhiều đối tượng WakeupCriterion. 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. Điều này cho phép chúng ta có thể tạo ra một Behaviour mở cửa ra vào.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ó. phương thức để xác định rõ các triggering post caàn thiết cho sự kiện trigger. 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.

hoàn toàn giốnh hệt OpenBehaviour. private pairPostCondition.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. đ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. Trong lớp CloseBehaviour. private AWTEventCondition. 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. Ví dụ mở và đóng cửa ra vào. http://tailieuhay. private WakeupCriterion wakeupNextFrame. Đối tượng thứ hai là thể hiện của CloseBehaviour.com 418 WakeupCriterion WakeupCriterion . và đaọn code tạo ra hai đối tượng Behaviour.

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

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

println("door open").wakeupOn(wakeupNextFrame).out. } } } } // 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. rotMat.sin(doorAngle). } else { // finished opening is door. postId(1). this.setTransform(t3D).m20 = -rotMat. targetTG.m02 Math.Đố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.setRotation(rotMat).Đối tượng open behavior mở cửa để trả lời lại tác nhân phím bấm. t3D. this.Lập trình đồ họa trên Java 2D và 3D rotMat.m02. signal other behavior System.Đố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.com 421 .wakeupOn(pairPostCondition).

Dù sao tron tài liệu này chúng ta không đi sâu vào collision detection. 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. • WakeupOnCollisionExit. CollisionEntry và CollisionExit đều không đựoc kích hoạt. Đối tượng close đóng cửa để trả lời sự kiện bấm phím. Đố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ó. Tiếp đó phím bấm tiếp theo cũng được thực hiện tương tự. 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. Một WakeupOnCollisionEntry sẽ đựoc kích hoạt khi một đối tượng lần đầu va chạm. 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. Java3D cung cấp 3 lớp WakeupCondition để xử lý sự va chạm của các đối tượng: • WakeupOnCollisionEntry. WakeupOnCollisionEntry(Bounds armingBounds) http://tailieuhay.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.com 422 . có thể tham kahỏ thêm trong Java3D API specification. Một cách hợp lý. • WakeupOnCollisionMovement. Quá trình nhạn biết va chạm Collision detectiontrong thực tế diễn ra rất phức tạp. 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.

com 423 . 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) 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.Lập trình đồ họa trên Java 2D và 3D Tạo một đối tượng WakeupOnCollisionEntry mới. 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. WakeupOnCollisionEntry(Node armingNode) Tạo một đối tượng WakeupOnCollisionEntry mới.speedHine WakeupOnCollisionExit(SceneGraphPath armingPath) Hàm tạo với tham sốarmingPath http://tailieuhay. int speedHint) Hàm tạo với tham số armingNode. WakeupOnCollisionEntry(Node armingNode.

int speedHint) Hàm tạo WakeupOnCollisionMovement trong đó speedHint nhận giá trị: http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D WakeupOnCollisionExit(SceneGraphPath speedHint) Hàm tạo với tham số armingPath. 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 .

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. 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.com 425 . trong đó speedHint nhận một trong hai giá trị: USE_BOUNDS hoặc USE_GEOMETRY armingPath.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. int WakeupOnCollisionMovement Method Summary Bounds getArmingBounds() Trả về đối tượng bounds đựợc sử dụng trong collision condition. SceneGraphPath getArmingPath() Trả về đương dẫn đựoc sủ dụng trong collision condition.

WakeupOnElapsedFrames(int frameCount. 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.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.2> Hàm tạo WakeupOnElapsedFrames với tham số frameCount và tham số passive passive .com 426 . WakeupOnElapsedFrames Method Summary int getElapsedFrameCount() Trả về số lương các frameCount boolean isPassive() <new in 1. giá trị n cho biết sao n frame Behaviour sẽ đuợc kích hoạt.2> Trả về trạng thái của cờ bị động.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. http://tailieuhay. giá trị 0 cho biết Behaviour sẽ đựoc kích hoạt ngay sau frame hiện thời. boolean passive) <new in 1. 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. frameCount .

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. 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.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. 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. 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 .

WakeupOnTransformChange http://tailieuhay. Sensor getTriggeringSensor() <new in 1.2> Trả về đối tượng sensor gây ra wakeup. WakeupOnSensorExit Method Summary Bounds getBounds() Trả về bound của đối tượng xác định.Lập trình đồ họa trên Java 2D và 3D Hàm tạo đối tượng WakeupOnEntry. WakeupOnSensorEntry Method Summary Bounds getBounds() Trả về bound của đối tượng xác định. Sensor getTriggeringSensor() <new in 1.2> Trả về đối tượng Sensor gây ra wakeup.com 428 . WakeupOnSensorExit(Bounds region) Hàm tạo đối tượng WakeupOnExit . 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.

http://tailieuhay. WakeupOnTransformChange(TransformGroup node) Hàm tạo đối tượng WakeupOnTransformChange. 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. Lớp này sử dụng phương thức postId để tạo ra các Behaviour hợp tác. 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.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. Đ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 đó.com 429 . 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. WakeupOnViewPlatformEntry(Bounds region) Hàm tạo đối tượng WakeupOnEntry.

Lớp thứ ba và lớp thư tư cho phép kết http://tailieuhay.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.com 430 .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. 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ý.3.

com 431 .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.. WakeupOrOfAnds Constructor Summary http://tailieuhay. WakeupAnd Constructor Summary extends: WakeupCondition Class specifying any number of wakeup criterion logically ANDed together. WakeupOr Constructor Summary extends: WakeupCondition Class specifying any number of wakeup criterion logically ORed together. WakeupAnd(WakeupCriterion[] conditions) Constructs a new WakeupOr condition. WakeupAnd(WakeupCriterion[] conditions) Constructs a new WakeupAnd condition. WakeupAndOfOrs(WakeupOr[] conditions) Constructs a new WakeupAndOfOrs condition. WakeupAndOfOrs Constructor Summary extends: WakeupCondition Class specifying any number of WakeupOr condition logically ANDed together.

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. 4. hướng của viewer. WakeupOrsOfAnds(WakeupAnd[] conditions) Constructs a new WakeupOrOfAnds condition. Nếu như transform thay đổi. http://tailieuhay.com 432 . ảnh huwỏng tới dịch chuyển hoặc định hướng lại hoặc của viewer. Trong hình dưới đây chúng ta có thể thấy nền transform.Lập trình đồ họa trên Java 2D và 3D extends: WakeupCondition Class specifying any number of WakeupAnd condition logically ORed together. Đây chính cách mà là lớp tiện ích Java3D làm việc. Thay đổi viewer là một khả năng quan trọng trong rất nhiều ứng dụng 3D.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. Java3D cung cấp khả năng thay đổi vị trí. 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.

Thêm đối tượng KeyNavigatorBehavior vào đồ thị khung cảnh 3. objRoot.4. 1. BranchGroup objRoot = new BranchGroup().thiết lập transform http://tailieuhay. Từ đó chúng ta có thể di chuyển SimpleUniverse.getViewPlatformTransform ().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. Tạo ra đối tượng KeyNavigatorBehaviour group 2.com 433 . Đặcbiệt đaọn cod dưới đây nhận được ViewPlatformTransform từ một đối tượng SimpleUniverse TransformGroup vpt = su.getViewingPlatform(). // create other scene graph content BranchGroup (hoặc BoundingLeaf) cho đối tượng .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.addChild(createLand()). 4. Cung cấp một gới hạn KeyNavigatorBehavior public createSceneGraph(SimpleUniverse su) { // Create the root of the branch graph TransformGroup vpTrans = null.

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

com 435 .addBranchGraph(scene). BranchGroup createSceneGraph(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. simpleU. // Utility class SimpleUniverse SimpleUniverse(canvas3D). KeyNavigatorBehaviour chỉ active khi khung lịch của nó giao nhau với giai đoạn active của một ViewPlatform. scene = simpleU = new SimpleUniverse is a Convenience 4. Đầ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. // The following allows this to be run as an application // as well as an applet public KeyNavigatorApp() { setLayout(new BorderLayout()).4.2 Lớp KeyNavigatorBehaviour và KeyNavigator http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D ban đầu của thế giới ảo. Canvas3D canvas3D = new Canvas3D(null). canvas3D). add("Center".

sun.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. Lớp thứ hai không cần thiết phải trình bày trong tài liẹu này. Lớp KeyNavigator thực thi sự vận động nhanh chóng.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. Đố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.com 436 . đối tượng thứ hai là KeyNavigator.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. Trong thời gian chạy chương trình có hai đối tượng.util. 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.utils.Enumeration criteria) Hàm đè phương thức processStimulus của lớp Behavior để quản lý sự kiện http://tailieuhay.behaviors. KeyNavigatorBehavior Constructor Summary Gói: com. Đối tượng đầu tiên là đối tượng KeyNavigatorBehavior.j3d.

5 Lớp tiện ích tương tác với chuột Gói tiện ích Behaviour (com. 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. Cung cấp một giứoi hạn (or BoundingLeaf) cho đối tượng MouseBehavior 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. 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.Cung cấp khả năng đọc và ghi cho đối tượng đích transform group 2. Bao gồm các lớp để chuyển dịch.utils. 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 đủ. Các bước khi sử dụng lớp mouse Behaviour 1. Khởi toạ một đối tượng MouseBehavior 3. 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.sun.com 437 . ví dụ dưới đây giới http://tailieuhay.j3d. Bước 2 và bước 3 có thể cung thực hiện trong một hàm tạo.mouse) chứa những lớp Behaviour tỏng đó quản lý việc tương tác với chuột. 4.behaviors. Trong gói còn có chứa lớp cơ sở trừu tượng MouseBehavior class và giao diện MouseCallback .Lập trình đồ họa trên Java 2D và 3D 4. Thiết lập đối tượng đích đến transform group 4.5.

ALLOW_TRAN SFORM_WRITE). Đồ thị khung cảnh chứa đối tượng ColorCube.Lập trình đồ họa trên Java 2D và 3D thiệu phương thức createSceneGraph từ ví dụ MouseRotateApp.com 438 .addChild(objRotate). TransformGroup TransformGroup(). interactively rotatable cube. objRotate. objRoot. objRotate. http://tailieuhay. objRoot.ALLOW_TRAN SFORM_READ). objRotate = new objRotate.addChild(new ColorCube(0.setCapability(TransformGroup. 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.4)).addChild(new Axis()). public class MouseRotateApp extends Applet { public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().setCapability(TransformGroup.

compile().addChild(myMouseRotate).com 439 . Canvas3D canvas3D = new Canvas3D(null). myMouseRotate. BranchGroup scene = createSceneGraph().setTransformGroup(objRotate). // 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()).Lập trình đồ họa trên Java 2D và 3D MouseRotate MouseRotate(). objRoot.setSchedulingBounds(new BoundingSphere()). canvas3D). myMouseRotate. return objRoot. // Let Java 3D perform optimizations on this scene graph. add("Center". objRoot.

"). } // 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.out .out . simpleU. System. System.setNominalViewingTra nsform().println("utility behavior class to provide interaction in a Java 3D scene. simpleU = new simpleU. \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.").java a demonstration of using the MouseRotate ").addBranchGraph(scene).Lập trình đồ họa trên Java 2D và 3D SimpleUniverse SimpleUniverse(canvas3D).com 440 .getViewingPlatform().print("MouseRotateApp.

Frame frame = new MainFrame(new MouseRotateApp().Lập trình đồ họa trên Java 2D và 3D System. System.println("The Java 3D Tutorial is available on the web at:"). System.").out . 256.sun.com/pr oducts/java-media/3D/collateral"). } // 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.println("This is a simple example progam from The Java 3D API Tutorial.com 441 .println("http://java. 256).out.out .

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. Ví dụ MouseRotate2App tạo ra một đồ thị khung cảnh với hai đối tượng ColorCube nằm gần nhau.5. 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. lúc đo người dùng click và di chuyển chuột.2 Mouse Behaviour Foundation Các phương thức mouse Behaviour xác định (MouseRotate.Mỗi đối tượng ColorCubes gắn liền với một đối tượng MouseRotate. cả hai đối tượng ColorCubes cùng quay. 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 . 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. MouseTranslate. Khi cả hai đối tượng mouse behavior cùng active.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. 4. Ký thuật picking được xem xét trong phần 4. Lớp cơ sở trừu tượng Mouse Behavior http://tailieuhay.6 • Trong phần 4. 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.

sun. 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.util. 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.j3d.com 443 . 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. cả 3 lớp mouse Behaviour đều phải thực thi giao diện này.behaviors.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. Transform3D transform) void setTransformGroup(TransformGroup http://tailieuhay. void processMouseEvent(java.utils.event.mouse void transformChanged(int type. void processStimulus(java. MouseCallback Interface Một lớp thực thi giao diện này cung cấp phương thức transformChanged.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.MouseEvent evt) kiểm soat các sự kiện chuột.awt.

giái trị của cờ: MouseBehavior. MouseRotate() Hàm tạo một mouse rotate behavior mặc định.utils.INVERT_INPUT Cho phép đảo ngược đầu vào. 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.5.com 444 . Để sử dụng lớp này.j3d.sun. và MouseBehaviorApp. hoặc MouseCallback. http://tailieuhay. MouseRotate2App. 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ờ.ROTATE.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. người dùng có thẻ quay bất cứ đối tượng con nào của nhóm TransformGroup. Chúng ta sẽ xem chi tiết trong các ví dụ MouseRotateApp.ZOOM.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. MouseCallback. 4. Giá trị của type: MouseCallback. Hàm tạo MouseRotate Constructor Gói: com.TRANSLATE.behaviors.

com 445 . 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. Xem ví dụ MouseBehaviorApp.Lập trình đồ họa trên Java 2D và 3D MouseBehavior.utils.behaviors.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. MouseTranslate Constructor Summary Gói : com.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.sun.j3d. 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.

j3d. MouseZoom() Tạo ra đối tượng mouse zoom behavior mặc định.sun. 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 .com 446 .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ờ.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.behaviors.utils.Xem them ví dụ MouseBehaviorApp. MouseBehavior. Hàm tạo MouseZoom Gói: com. 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. Cờ nhận một trong các giá trị: MouseBehavior.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.INVERT_INPUT Cho phép đảo ngược đầu vào. http://tailieuhay.

5. Đoạn code trong 4-8 trình bày phương thức createSceneGraph. Cờ nhận một trong các giá trị: MouseBehavior.com 447 . MouseZoom(int flags) Khởi tạo một zoom Behaviour với tham số cờ.Xem ví dụ MouseNavigatorApp. Nhờ vậy ta các lớp mouse Behaviour có thể dùng để điều khiển chuyển hướng. Đối tượng TransformGroup đích của mỗi đối tượng the mouse behavior objects là ViewPlatform transform.Khi cờ có giá trị MouseBehavior. MouseBehavior.INVERT_INPUT Cho phép đảo ngược đầu vào.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. Đối tượng SimpleUniverse là tham số truyền http://tailieuhay. khi đó hàm mới sẽ được gọi mỗi khi Behaviour cập nhật transform 4.INVERT_INPUTS đối tượng mouse Behaviour đảo ngược lại thứ tự của input.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.4 Mouse Navigation Trong số các hàm tạo của ba lớp mouse Behaviour đều có tham số flag.

MouseRotate myMouseRotate = new = su.0).setTransformGroup(vpTrans).addChild(myMouseRotate). vpTrans ). objRoot.setSchedulingBounds(mouseBo unds). mouseBounds = new BoundingSphere(new Point3d().addChild(new Axis()). objRoot.getViewPlatformTransform( MouseRotate(MouseBehavior. http://tailieuhay.addChild(new ColorCube(0. objRoot.4)). TransformGroup vpTrans = null. myMouseRotate. myMouseRotate. 1000.com 448 . 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.INVERT_INPUT).getViewingPlatform(). public createSceneGraph(SimpleUniverse su) { BranchGroup // Create the root of the branch graph BranchGroup objRoot = new BranchGroup().

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

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. Sự giao nhau của ray với đối tượng trong không gian ảo được tính toán .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 . cả hai đối tượng ColorCube đều quay khi gặp tác động của guời dùng.com 450 .Lập trình đồ họa trên Java 2D và 3D 4. http://tailieuhay. Đố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. Trong ví dụ đó cả hai đối tượng đều chưa có thể quay một cách đọc lập.6 Picking Object Trong ví dụ MouseRotate2App. dưới sự kích hoạt của sự kiện click chuột. Đối tượng behavior được kích hoạt bởi sự kiện click chuột và thực hiện picking. Để picking một đối tượng. người dùng di chuyển chuột vào đối tượng trực quan và click chuột.

com 451 . 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. 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 . Lấy ví dụ để picking một đối tượng ColorCube object để điều khiển quay . Nếu chúng ta cần quay một đối tượng hìn lập phương 6 mặt .khi đó đối tượng trực quan phải được tác động một cách trực tiếp. đố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. 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. là con của đối tượng BranchGroup trong đồ thị khung cảnh . 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. mà làm việc với đối tượng chuyển hướng đồ thị khung cảnh đến đố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ể. 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.

com 452 . 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.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”. Vì vậy. 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. 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. 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. những node không được xem xét đến khi tính toán giao cắt. Một node. 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. đặc điểm khác của lớp Node là khả năng ENABLE_PICK_REPORTING. 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.Nó cung cấp một khung thông dụng trong việc xây dựng một http://tailieuhay.

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

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

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

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. 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. 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.lang. trả về null nếu không có transform. Node newNode) void setNodes(Node[] nodes) void setObject(Node object) http://tailieuhay.xác định void setNode(int index.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.Đ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. SceneGraphPath Method Summary (partial list) boolean equals(java. Một đối tượng SceneGraphPath thể hiện một đường đi trong đồ thị khung cảnh.com 466 . int nodeCount() Trả về số node của đừong đi.

PickMouseBehavior Method Summary http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D void setTransform(Transform3D trans) java.com 467 .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.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.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ó. PickMouseBehavior Class Lớp cơ sở cung cấp các phương thức picking behavior.6. 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. PickObject. 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.lang.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 .và PickCallback. Các lớp : PickMouseBehavior.

Lập trình đồ họa trên Java 2D và 3D Gói : com.behaviors.j3d.Object PickObject(Canvas3D c. void processStimulus(java.lang.utils.continued) http://tailieuhay.Enumeration criteria) void updateScene(int xpos.util. BranchGroup root) Hàm tạo PickObject. PickShape generatePickRay(int xpos.behaviors.j3d.com 468 . 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.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. PickObject Constructor Summary Gói: com.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.. 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.sun.sun. PickObject Method Summary (partial list .

TRANSFORM_GROUP. Node pickNode(SceneGraphPath sgPath. int node_types. PickObject.LINK.SHAPE3D. 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.BRANCH_GROUP.GROUP. int ypos) Node pickNode(SceneGraphPath sgPath. PickObject. xác định giá trị của kiểu node: PickObject. PickObject. 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ự. Interface PickingCallback Method Summary http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D SceneGraphPath[] pickAll(int xpos.MORPH.com 469 . 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. PickObject.PRIMITIVE. int occurrence) PickObject. SceneGraphPath pickAny(int xpos.SWITCH. 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. 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.

int index. Lien đuợc xác định bởi tham số đầu vào. int index.Object Intersect() Hàm tạo Intersect. Intersect Method Summary (partial list) boolean pointAndLine(PickPoint point.picking void transformChanged(int type. Point3d[] coordinates.utils. double[] dist) boolean rayAndPoint(PickRay ray. Point3d[] coordinates.sun.j3d.lang. Point3d pnt.behaviors.sun. Point3d[] coordinates. boolean rayAndLine(PickRay ray.Lập trình đồ họa trên Java 2D và 3D Gói: com. Point3d[] coordinates. 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.j3d. double[] dist) boolean rayAndTriangle(PickRay ray. http://tailieuhay. Point3d pnt) Tra về true néu đối tượng PickPoint và đối tượng Point3d giao cắt nhau. Intersect Constructor Summary Gói: com. double[] dist) boolean rayAndQuad(PickRay ray.behaviors. int index.com 470 . int index) Trả về true nếu như đối tượng PickPoint và đối tượng Line giao nhau.utils. boolean pointAndPoint(PickPoint point.picking Thừa kế : java.

Canvas3D canvas. PickRotateBehavior Constructor Summary Gói: com. Bounds bounds) http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D double[] dist) boolean segmentAndLine(PickSegment segment.sun.picking Thừa kế : PickMouseBehavior Thực this: PickingCallback PickRotateBehavior(BranchGroup root.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. Point3d[] coordinates. double[] dist) Intersect Method Summary (partial list .utils.j3d.utils.j3d.behaviors. double[] dist) boolean segmentAndTriangle(PickSegment segment. Point3d pnt. Point3d[] coordinates.behaviors. int index. double[] dist) segment. int index. int index.sun. Point3d[] coordinates.4 Các lớp Picking Behavior Gói com.continued) boolean boolean segmentAndPoint(PickSegment segmentAndQuad(PickSegment segment.6. double[] dist) 4.com 471 .

j3d. 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.sun. PickTranslateBehavior Constructor Summary Gói : com.behaviors. Canvas3D canvas. 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. all geometry objects in the scene graph intended to be available for picking must have their ALLOW_INTERSECT bit set. Note: If pickMode is set to PickObject.picking Thừa kế : PickMouseBehavior http://tailieuhay.com 472 . void setupCallback(PickingCallback callback) void transformChanged(int type.USE_BOUNDS hay PickObject. Bounds bounds. Transform3D transform) void updateScene(int xpos.Lập trình đồ họa trên Java 2D và 3D PickRotateBehavior(BranchGroup root.USE_GEOMETRY.USE_GEOMETRY.USE_BOUNDS hay PickObject. int pickMode) Giáptrị PickMode : PickObject.USE_GEOMETRY. PickRotateBehavior Method Summary void setPickMode(int pickMode) Thiết lập giá trị pickMode: nhạn một trong các giá trị PickObject.utils.

utils.picking Thừa kế : PickMouseBehavior Thực thi: PickingCallback http://tailieuhay. 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. PickZoomBehavior Constructor Summary Gói: com. Transform3D transform) void updateScene(int xpos.j3d. 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. root.com 473 .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. int pickMode) root. Canvas3D canvas.sun. void transformChanged(int type. Canvas3D canvas.behaviors. 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.

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

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. http://tailieuhay. nó có thể hoạt động mà không cần tương tác của người dùng. Trong thế giới ảo.Lập trình đồ họa trên Java 2D và 3D Trong chương này. Chiếc đồng hồ chính là một ví dụ về hoạt ảnh. Ví như một chiếc đồng hồ ảo chẳng hạn. 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. 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). Ngược lại. 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.com 475 .

Đố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 . Hai lớp hành vi sẽ được xét kĩ hơn trong các mục 5. lớp hoạt ảnh được đưa vào Java 3D API từ phiên bản v1. Đối tượng Alpha cung cấp cơ chế định thời gian. 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 . 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.3 và 5. Chi tiết về hai lớp đối tượng này sẽ được bàn đến trong mục 5. Mục 5.Hoạt hình: Tương tự như phần tương tác. http://tailieuhay. Tập các lớp này (bao gồm: lớp OrientedShape3D. lớp hoạt ảnh được sử dụng cả trong các ứng dụng hoạt ảnh và nội suy. Mục 5. 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.4 sẽ trình bày về OrientedShape3D.2. hoạt ảnh trong Java 3D cũng được cài đặt nhờ sử dụng đối tượng Behavior (hành vi).5 Một vài lớp hoạt ảnh không kế thừa từ lớp Behavior như: OrientedShape3D và Morph . Các lớp này đều kế thừa lớp Behavior. Tuy nhiên.Lập trình đồ họa trên Java 2D và 3D Animation .2 như một sự thay thế cho hành vi Billboard trong các phiên bản trước đó. 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. 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 ).

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

Số chu kì của sóng xác định bởi tham số loopCount. Kết quả là. 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. Vì thế tuy các đối tượng Alpha được tạo ra ở các thời điểm khác nhau. Hình 5-2 biểu diễn bốn đoạn của dạng sóng Alpha. Nếu dạng sóng Alpha quay vòng hơn 1 chu kì. loopCount bằng –1 xác định vòng lặp không dừng. Thời gian của một chu kì được xác định bằng một số nguyên. 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. 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ễ). loopCount dương qui định số chu kì. ngoại trừ giai đoạn trễ. 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. Các tham số này được thể hiện trong hình 52. http://tailieuhay. 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. Dạng sóng của đối tượng Alpha có thể quay vòng một chu kì. đơn vị tính là mili giây. 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.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. nhưng chúng đều có chung một thời điểm khởi động. tất cả các giai đoạn trên đều được lặp lại. chu kì của dạng sóng đầu tiên bắt đầu. 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.com 478 .

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

khi kiểu là INCREASING_INABLE. 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. 3. 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. Đ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.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. Khung cảnh là mặt một chiếc đồng hồ. 5. Hình 5-4. tuy nhiên. 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. Ví dụ. thì các tham số DecreasingAlphaDuration.java là một ví dụ sử dụng lớp RotationInterpolator. DecreasingAlphaRampDuration và AlphaAtZeroDuration sẽ bị bỏ qua. việc đặc tả chính xác kiểu sẽ làm tăng hiệu quả của đối tượng Alpha. Chiếc đồng hồ này được điều khiển quay http://tailieuhay. 2. 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. Công thức sử dụng các đối tượng Interpolator và Alpha có thể tóm tắt như sau: 1.com 480 .

Trục quay mặc định là trục y.java. Các đối tượng Interpolator khác nhau sẽ hoạt động trên các đối tượng đích khác nhau. Đố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. 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. Đối tượng Interpolator định nghĩa điểm kết thúc của hoạt ảnh. đối tượng này xác định góc quay bắt đầu và kết thúc. Yêu cầu đối tượng này phải được thiết lập khả năng ALLOW_TRANSFORM_WRITE. Ví dụ. Trong chương trình này. public BranchGroup createSceneGraph() { http://tailieuhay. Đố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ữ. Trong trường hợp của RotationInterpolator. đối tượng đích là một đối tượng TransformGroup. Ứ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).000 mili giây).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. ở đây chúng tôi chỉ trích rút một phần để tập trung vào vấn đề chính. Đ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. 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. Chu trình này được tiếp diễn và lặp lại ngay lập tức. đích của đối tượng ColorInterpolator là một đối tượng Material. Đoạn mã sau định nghĩa phương thức createSceneGraph trong chương trình ClockApp. Chương trình đầy đủ xin xem phần phụ lục.com 481 . Đố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.

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

Mặt đồng hồ trông bị nghiêng đi là do cả mặt đấy quay theo trục thẳng đứng. 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.Lập trình đồ họa trên Java 2D và 3D // Let Java 3D perform optimizations on this scene graph. 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.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. 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. 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.compile(). Trong đoạn thoải này. objRoot. // end of CreateSceneGraph method of http://tailieuhay. return objRoot. } 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. Trong trường hợp lập trình cho vật thể chuyển động. giá trị Alpha thay đổi dần dần.

còn chiếc ở http://tailieuhay. 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). 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ập trình đồ họa trên Java 2D và 3D Hình 5-5.com 484 . Chiếc xe trên cùng không có đoạn giá trị Alpha thoải. 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.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. Làm trơn dạng sóng Alpha AlphaApp. 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.

4s Time ~ 0.2s Time ~ 1.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). 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. 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. Time ~ 0. Quan sát chương trình.8s Time ~ 1.6s Hình 5-7.com 485 . Mỗi xe cần 2 giây để chuyển động qua khung nhìn.

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

long triggerTime.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. Lớp Alpha cung cấp rất nhiều các phương thức hữu ích. 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. int mode. long alphaAtZeroDuration) Khởi tạo đối tượng Alpha theo các tham số định nghĩa của người dùng. Chúng tôi liệt kê ở đây một vài phương thức phổ dụng nhất. 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. long decreasingAlphaDuration. cho phép người dùng tuỳ biến các đặc tính của đối tượng Alpha. long phaseDelayDuration. void setDecreasingAlphaRampDuration(long decreasingAlphaRampDuration) Thiết lập giá trị xác định cho thuộc tính 487 http://tailieuhay. 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.com . long increasingAlphaDuration. 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. long alphaAtOneDuration. long increasingAlphaRampDuration. 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.

Giá trị mặc định của startTime là thời điểm khởi động hệ thống.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.Lập trình đồ họa trên Java 2D và 3D decreasingAlphaRampDuration của đối Alpha tượng 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ố. 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. mode có thể là INCREASING_ENABLE hoặc DECREASING_ENABLE. 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. 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. startTime quy định mốc cho mọi tính toán thời gian tương đối.com 488 . INCREASING_ENABLE . hay là hoặc của hai giá trị. 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ố.chỉ định sử dụng giai đoạn 3 và 4 DECREASING_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.

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. 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). float value(long atTime) Trả về một giá trị nằm trong đoạn [0. 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ó. 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.com 489 . 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).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. Có khoảng hơn 10 lớp con Interpolator cơ bản. Trong phương thức processStimulus. 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. Các lớp hành vi Interpolator : Interpolator là một lớp trừu tượng. Hình 5-8. 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.

đối tượng Interpolator sẽ nội suy tuyến tính giữa hai giá trị. 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ẻ.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 . chúng ta lần lượt sẽ đi sâu hơn về 7 lớp này. thì giá trị kia sẽ được sử dụng. Bảng sau so sánh các đặc điểm khác nhau của 7 lớp Interpolator cơ bản. nên trong lớp này.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 . Trong các phần sau. chúng cũng mang một vài chi tiết khác nhau dễ nhận ra. Ví dụ. 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. Với mỗi khung ảnh. dựa trên giá trị Alpha rồi sử dụng kết quả để điều chỉnh đối tượng đích. không hề có quá trình nội suy. Nếu giá trị Alpha nằm trong khoảng từ 0 đến 1. đố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 nội suy RotationInterpolator lưu trữ hai góc là giới hạn quay do nó điều khiể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. Tuy rằng các lớp Interpolator rất giống nhau. Đối tượng SwitchValueInterpolator lựa chọn một nút con trong nhóm các nút đích Switch. Nếu giá trị Alpha là 0 thì một trong hai giá trị sẽ được sử dụng. nếu giá trị Alpha là 1. 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.

độ lớn.com 491 . và SwitchValueInterpolator tương ứng. Tóm tắt các lớp Interpolator cơ bản Chú ý: PathInterpolator là một lớp trừu tượng. mỗi đối tượng Interpolator được điều khiển bởi một đối tượng Alpha đơn. ColorInterpolator. và đối tượng trực quan được tạo ra bởi các đối tượng PositionInterpolator. độ trong suốt.java (chi tiết ở phần phụ lục). Để hiểu thêm hiệu ứng của các Interpolator này. hãy xem ví dụ InterpolatorApp. http://tailieuhay. TransparencyInterpolator. RotationInterpolator. nên không có đối tượng đích. Tuy nhiên. Các thay đổi về vị trí. 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. quay. màu sắc.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. ScaleInterpolator. Trong chương trình này.

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

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

setCoordinate(11.0f)).35f.setCoordinate(14. 0.Lập trình đồ họa trên Java 2D và 3D carGeom.00f.0f)).45f. Point3f(xScale*-0. yScale*0.0f)). 8. yScale*0. 0. yScale*0. Point3f(xScale*-0. 0. 4.28f. yScale*0.00f. yScale*0. Point3f(xScale*-0. 0. 0.0f)).setCoordinate( carGeom. Point3f(xScale*-0. yScale*0.00f.setCoordinate(13. yScale*0.setCoordinate( carGeom.setCoordinate( carGeom.0f)).26f. 0.0f)). yScale*0.0f)).20f.23f.setCoordinate( 3. 0.setCoordinate( carGeom. 0. Point3f(xScale* 0. carGeom.00f.48f. 0.setCoordinate(15. 9.com 494 .0f)).setCoordinate( carGeom.12f.50f. Point3f(xScale* 0.setCoordinate( carGeom. carGeom. 0. yScale*0. http://tailieuhay. carGeom.12f.35f. 0.50f.20f.0f)). Point3f(xScale*-0.0f)). 7.33f. yScale*0. Point3f(xScale* 0.16f.10f. 0.25f. 5. carGeom.0f)). Point3f(xScale*-0. yScale*0. 6. Point3f(xScale* 0.12f. Point3f(xScale* 0. new new new new new new new new new new new new new Point3f(xScale*-0.0f)). 0.10f.18f.0f)). Point3f(xScale* 0. if (createNormals){ int i.20f. yScale*0.setCoordinate(12. carGeom.12f. carGeom.setCoordinate(10. yScale*0.

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

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

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

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

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

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

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

TransparencyAttributes target. void setMinimumTransparency(float transparency) Thiết lập giá trị minimumTransparency cho đối tượng Interpolator hiện thời. 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. 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. TransparencyAttributes target) Khởi tạo đối tượng nội suy độ trong suốt với đối tượng đích cho trước. 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. độ trong suốt tối thiểu là 0.com 512 . void setTarget(TransparencyAttributes target) Thiết lập đối tượng đích TransparencyAttributes cho đối tượng Interpolator hiện thời. 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. TransparencyInterpolator(Alpha Alpha. Các phương thức khởi tạo: TransparencyInterpolator(Alpha Alpha. Nhiều hơn một đối tượng trực quan có thể chia sẻ một đối tượng TransparencyAttributes. http://tailieuhay.0f và tối đa là 1.0f.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.

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

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. và mảng của các giá trị thiết lập 5. Hình 5-11. và các giá trị điểm mút (mảng giá trị thực). đối tượng đích. 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.Lập trình đồ họa trên Java 2D và 3D nhau của ví dụ này. http://tailieuhay. Công thức sử dụng đối tượng nội suy đường Chương trình RotPosPathApp. 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. tạo đối tượng nội suy đường tham chiếu đến đối tượng Alpha. 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. tạo các mảng điểm mút và các giá trị khác 4. Đối tượng RotPosPathInterpolator chứa tập các giá trị quay (mảng Quat4f). vị trí (mảng Point3f). 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.com 514 . tạo đối tượng Alpha 3. Chi tiết của ví dụ này xin xem thêm phần phụ lục.

0.0f.8f. 0. 1.6f. 0.0f.0f.0f. axis = new axisOfRotPos = new target = new http://tailieuhay. 0. 1. 0. quats[0] = new Quat4f(0.0f). 0.4f.0f.0f).0f.0f.0f. Transform3D Transform3D(). 10000).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().3f.0f.0. Point3f[] positions = new Point3f[9].0f). target. Alpha alpha = new Alpha(-1. 0.0f. AxisAngle4f AxisAngle4f(1.1f.0f}.setCapability(TransformGroup. 0. 1.9f. 0.com 515 .2f. float[] knots = {0.ALLOW _TRANSFORM_WRITE). 1.0. 0.0f.0.0f. 0. axisOfRotPos. quats[1] = new Quat4f(1. 0.0f.0f).set(axis). quats[2] = new Quat4f(0. Quat4f[] quats = new Quat4f[9]. 0. TransformGroup TransformGroup().

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

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

addChild(points). objRoot. true). objRoot. Shape3D points = new Shape3D(point_geom. return objRoot. Hình 5-13 là một cảnh trong chương trình RotPosPathApp.0f.Lập trình đồ họa trên Java 2D và 3D points_appear. points_appear.compile(). chúng ta chỉ thấy có 8 điểm.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. nên trong hình. http://tailieuhay. } // 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.com 518 .setColoringAttributes(point s_coloring). PointAttributes points_points = new PointAttributes(4. với các điểm màu đỏ biểu diễn vị trí của 9 điểm mút. 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. points_appear). Điểm đầu tiên được dùng 2 lần.setPointAttributes(points_p oints).

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.com 519 . Như đã nói bên trên. Lớp TCBPathSplineInterpolator là một lớp tương tự với lớp PathInterpolator. 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. chuyển động của tất cả các vật đều có tính ì nhất định.Lập trình đồ họa trên Java 2D và 3D Hình 5-13. còn có một cặp các lớp liên quan trong gói tiện ích. Ngoài các lớp con trong hạt nhân của Java 3D. Giống như tất cả các đối tượng nội suy khác. http://tailieuhay. lớp PathInterpolator có rất nhiều các lớp con khác nhau. 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). Di chuyển như vậy không tự nhiên do trong thế giới thực. đồng thời tự quay để đến được các điểm mút khác nhau. 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. Khi khối hộp ColorCube di chuyển đến mỗi vị trí điểm mút xác định. thì ngay lập tức chuyển động của nó thay đổi để đến được điểm mút tiếp theo. Một cảnh trong chương trình RotPosPathApp Khi chương trình RotPosPathApp được thực hiện. Trong chương trình RotPosPathApp.

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). Điểm mút đầu tiên phải có giá trị là 0.java.0 và điểm mút cuối cùng phải có giá trị là 1. 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ó. SplineAnim. bạn đọc có thể tìm trong đĩa chương trình kèm theo. http://tailieuhay. đố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. 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). Trong chuyển động này. 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.com 520 . Chương trình ví dụ. Đ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.0. 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. 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. 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.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. Đường cong này bắt chước chuyển động của đối tượng trong thế giới thực.

TransformGroup target. 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. 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. Trong phương thức khởi tạo. Transform3D axisOfRotPos.com 521 . 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. tất cả các giá trị và đối tượng liên quan đều phải được xác định. 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. void setPosition(int index. sử dụng giá trị sinh bởi đối tượng Alpha xác định. 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. Mảng quats phải đủ lớn để chứa dữ liệu. float[] knots. 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. 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. Mảng positions phải đủ lớn để chứa dữ liệu.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. Point3f position) http://tailieuhay. RotPosPathInterpolator(Alpha Alpha. Quat4f[] quats. 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.

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. 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. 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. 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. Quat4f quat) Thiết lập quantenion tại chỉ mục xác định cho đối tượng Interpolator hiện thời. nếu cái cây chỉ giữ một hướng cố định thì khi góc nhìn thay đổi.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. vì vậy.com 522 . Hành vi Billboard thông thường được dùng cho mục đích này. 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. Trong Java 3D. đằng sau hay từ bất cứ góc nhìn http://tailieuhay. người ta vẫn hay dùng thuật ngữ “hành vi Billboard ” để chỉ công nghệ này. người quan sát sẽ phát hiện ra hình dạng 2 chiều của cây. ngoài ra. Tất nhiên. nó còn được dùng cho các mục đích khác. 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. 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. công nghệ Billboard được cài đặt bởi một lớp con của lớp hành vi Behavior. void setQuat(int index. void setTarget(TransformGroup target) Thiết lập đối tượng đích TransformGroup cho đối tượng Interpolator hiện thời.

Biểu đồ đồ thị khung cảnh sử dụng đối tượng Billboard http://tailieuhay.Lập trình đồ họa trên Java 2D và 3D nà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 . 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ụ. 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. 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. ngoại trừ rằng không cần dùng đối tượng Alpha để điều khiển hoạt ảnh. tháp nước. 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 . hay bất kì đối tượng hình trụ nào. 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 . Hình 5-14. Chi tiết việc lập trình sẽ được trình bày trong phần dưới đây. Hình 5-15 biểu diễn các bước sử dụng Billboard . Thông thường hai nút TransformGroup được sử dụng. Đố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.com 523 .

Lập trình đồ họa trên Java 2D và 3D 1. 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. nhưng cũng có hai lỗi lập trình thường gặp sau. 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.com 524 . Đố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. 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. đối tượng TransformGroup này không thể sử dụng để định vị đối tượng trực quan.2 giới thiệu lớp OrientedShape3D để vượt qua giới hạn này. thêm danh giới làm việc cho đối tượng Billboard 4. 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. 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. tạo đối tượng Billboard tham chiếu đến đối tượng đích TransformGroup 3. Nếu dùng đối tượng đích để định vị. tuy nhiên. Với một vài ứng dụng thì khả năng cung cấp của Billboard là đảm bảo. còn với các ứng dụng khác. 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. tạo đối tượng đích với khả năng ALLOW_TRANSFORM_WRITE 2. lắp ghép đồ thị Hình 5-15. Java3D API phiên bản 1. hiệu ứng Billboard vẫn hoạt động. trong lần cập nhật quay đầu tiên. 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. đặc điểm này là một giới hạn lớn. 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.

nếu một trục quay của đối tượng được xác định là (0. Đối tượng TransformGroup thứ hai. TGT. 0. đơn giản chỉ dịch các cây thành tọa độ vị trí trong ứng dụng. BranchGroup http://tailieuhay. Trong trường hợp sử dụng khác. đố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. 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. BranchGroup objRoot = new BranchGroup(). TGR là đối tượng đích của Billboard . TGR. Hai đối tượng TransformGroup được sử dụng cho mỗi cây trong ví dụ này. Một đối tượng TransformGroup. z) thì đơn giản Billboard không làm gì cả.com 525 .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. Giá trị của TGT không bị thay đổi trong thời gian thực thi của ứng dụng. điều khiển hoạt động quay của cây. Vector3f translate = new Vector3f(). Vì lý do này. Billboard quay quanh một trục hoặc một điểm. 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. 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 . public createSceneGraph(SimpleUniverse su) { // Create the root of the branch graph TransformGroup vpTrans = null.

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

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

setApplicationBounds(new BoundingSphere()).Lập trình đồ họa trên Java 2D và 3D background. Hình 5-16.compile(). return objRoot. objRoot.com 528 . } // 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. Biểu đồ đồ thị sử dụng đối tượng Billboard BillboardApp.java trong Hình 5-17 hiển thị một cảnh sinh bởi chương trình ví dụ BillboardApp.addChild(background). http://tailieuhay. objRoot. // Let Java 3D perform optimizations on this scene graph.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.

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. 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. http://tailieuhay. Giao diện lập trình ứng dụng của Billboard (Billboard API) Trong ví dụ BillboardApp phía trên. Xin xem lại phần 4. 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.Lập trình đồ họa trên Java 2D và 3D Hình 5-17. Trong chế độ này. đố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 chế độ thay thế là quay đối tượng trực quan quanh một điểm. do đó. đố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. hình ảnh 2 chiều được điều khiển quay quanh 1 điểm.com 529 . 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. Nên.2 của chương 4 để biết thêm chi tiết về lớp đối tượng này.4.

void setAlignmentAxis(float x.com 530 () với tham số mặc định: mode = ROTATE_ABOUT_AXIS.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. 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. hoạt động trên đối tượng đích TransformGroup xác định. float z) Thiết lập tâm quay http://tailieuhay. . float y. float z) Thiết lập trục canh chỉnh. Billboard (TransformGroup tg. 0).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. 1. int mode. int mode. void setAlignmentMode(int mode) Thiết lập chế độ canh chỉnh. axis = (0.Chỉ định quay xung quanh một . 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. trong đó mode có thể là ROTATE_ABOUT_AXIS trục xác định ROTATE_ABOUT_POINT . Billboard (TransformGroup tg. Point3f point) Khởi tạo đối tượng Billboard với tâm quay và chế độ xác định. float y.

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 . OrientedShape3D không phải là một đối tượng hành vi do đó. cũng như khả năng chia sẻ sử dụng chỉ có ở OrientedShape3D. trục quay không được định nghĩa là (0. Nếu một trục song song với z được chỉ định. Đối tượng OrientedShape3D quay xung quanh một trục hoặc một tâm. Do OrientedShape3D hướng trục z+ của các vật thể về phía người quan sát. có nghĩa là.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.com 531 . 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. 0. Trong cả hai trường hợp. 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. OrientedShape3D không hiệu chỉnh đối tượng đích TransformGroup. đố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. người lập trình cũng không cần quan tâm đến giới hạn hoạt động. Đ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. nên không có ý nghĩa gì nếu quay vật thể quanh trục z. mà để mở khả năng này cho mã chương trình thực hiện. OrientedShape3D đơn giản sẽ không http://tailieuhay. z) với bất cứ giá trị nào của z. Đối tượng OrientedShape3D cũng yêu cầu sử dụng ít mã hơn. Vì lí do này nên trục quay không được song song với trục z.

Lập trình đồ họa trên Java 2D và 3D làm gì cả. thành phần xuất hiện. Trong trường hợp này. Không có giới hạn cho giá trị được sử dụng để làm tâm quay. 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. Ví dụ như không có phương thức khởi tạo với chỉ một tham số Geometry. ngoài ra. 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. Lúc đó coi như là đối tượng TransformGroup được thiết lập ma trận đồng nhất. các phương thức khởi tạo không kế thừa lớp cơ sở. Billboard lại kế thừa từ Behavior. http://tailieuhay. OrientedShape3D(Geometry geometry. Appearance appearance. OrientedShape3D kế thừa từ lớp Shape3D. 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. Appearance appearance. chế độ và trục quay xác định. 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. int mode. thành phần xuất hiện.com 532 . Point3f point) Khởi tạo đối tượng OrientedShape3D với thành phần hình học. 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. trong khi đó. 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 . Vector3f axis) Khởi tạo đối tượng OrientedShape3D với thành phần hình học. int mode. chế độ và tâm quay xác định. cũng có vài điểm khác biệt.

com . 1. float y. Mỗi cây là một con của một đối tượng OrientedShape3D. 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. ALLOW_MODE_READ | WRITE Cho phép đọc (ghi) thông tin chế độ canh chỉnh. // Create the root of the branch graph 3. 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 . Xem chi tiết ở phần “Giao diện lập trình ứng dụng của Billboard ”. 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. BranchGroup objRoot = new BranchGroup(). đối tượng này tạo hiệu ứng Billboard cho cây. ALLOW_POINT_READ | WRITE Cho phép đọc (ghi) thông tin tâm quay. Xét chương trình ví dụ OrientedShape3DApp. 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.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. public BranchGroup createSceneGraph(SimpleUniverse su) { 2.java. float y. 533 http://tailieuhay.

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

được tính bằng số khung hình / giây) để giữ tỉ lệ khung hình là thấp nhất. dựa trên một tập các ngưỡng khoảng cách. 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. tốc độ của vật thể. 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ị. 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ị. Khi khoảng cách của đối tượng DistanceLOD đối với http://tailieuhay. Do vậy.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. 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ể. 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. 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. Đối tượng Switch là một nhóm đặc biệt bao gồm không.com 535 . 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ị. Trong trường hợp sử dụng DistanceLOD. Ứ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. khi đó. 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. 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. con đầu tiên của đối tượng đích sẽ được sử dụng. 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ị. 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.

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. con thứ hai của đối tượng switch sẽ được sử dụng. các đối tượng đích Switch sẽ được sử dụng song song. 1. tạo các đối tượng Switch đích với khả năng ALLOW_SWITCH_WRITE 2. Do đó.com 536 . số lượng con của đối tượng đích là nhiều hơn số ngưỡng khoảng cách. tạo danh sách mảng các ngưỡng khoảng cách cho đối tượng DistanceLOD 3. Theo cách làm này. việc sử dụng đối tượng DistanceLOD giống với việc sử dụng đối tượng Billboard . Hình 5-18 biểu diễn các bước để sử dụng DistanceLOD. đố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. tạo đối tượng DistanceLOD sử dụng mảng các ngưỡng khoảng cách 4. 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 . thiết lập đối tượng Switch đích cho đối tượng DistanceLOD http://tailieuhay. 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. 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. 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. 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 .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ó 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. theo cách này.

“lắp ghép” đồ thị khung cảnh. xin xem http://tailieuhay. 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. 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 đó. bao gồm cả việc thêm các con cho các đối tượng Switch Hình 5-18. Chi tiết về chương trình này. 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. Tương tự như các đối tượng hành vi khác. 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. 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. 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. 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. thiết lập giới hạn hoạt động cho đối tượng DistanceLOD 6. 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.com 537 . 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. Nếu chương trình có nhiều hơn một quan sát. Còn nữa. nếu giới hạn hoạt động không được thiết lập.Lập trình đồ họa trên Java 2D và 3D 5. 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. nhưng cũng có hai lỗi lập trình thường gặp sau.

Transform3D axisT3D = new Transform3D().0.1. 0. // create target TransformGroup with Capabilities TransformGroup TransformGroup(). // create Alpha Alpha alpha = new Alpha (-1. 1000. 0. Đ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.set(axisOfTra). // specify the axis of translation AxisAngle4f axisOfTra = new AxisAngle4f(0.(float)Math.0f.setCapability(TransformGroup.com . // create position interpolator 538 bounds = new objMove = new http://tailieuhay. axisT3D. 1000).0f. 1000.PI/-2.0f.ALLO W_TRANSFORM_WRITE).0f). 5000.DECREASING_ENABLE. public BranchGroup createSceneGraph() { BranchGroup objRoot = new BranchGroup(). Alpha.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.INCREASING_ENABLE + Alpha. 1000. BoundingSphere BoundingSphere(). 5000. objMove.

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

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

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

0f. http://tailieuhay.0f). background. background.setApplicationBounds(new BoundingSphere()). return objRoot. objRoot. đố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.setColor(1.0f.compile(). } // 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. 1.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(). Chú ý rằng. // Let Java 3D perform optimizations on this scene graph. 1.com 542 .addChild(background). objRoot. Cả hai quan hệ này đều cần được xác lập.

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. Trong chương trình này. 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. Nếu không sử dụng các khối http://tailieuhay. 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. Khi đối tượng DistanceLOD dịch chuyển ra xa người quan sát. 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.Lập trình đồ họa trên Java 2D và 3D Hình 5-19. Hai khối cầu này được hiển thị để làm mốc so sánh. khối cầu bên trái nhất đã bị che khuất). đố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. 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ộ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 . nó sẽ chuyển đối tượng trực quan để hiển thị.

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 giá trị khoảng cách [0. đượ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.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. Một mảng n giá trị khoảng cách đơn điệu tăng. i 2. 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-1] lựa chọn n+1 mức chi tiết [0. 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. Hình 5-20. n]. Dựa vào khoảng cách thực từ người quan sát đến nút DistanceLOD. Hai cảnh được sinh ra từ DistanceLODApp. n nếu distances[i-1] < d <= distances[i] nếu d > distances[n-1] http://tailieuhay.com 544 .

thậm chí. lớp Morph giống với các lớp nội suy. 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. 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. 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. nó còn không kế thừa lớp hành vi Behavior. 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. void setPosition(Point3f position) Thiết lập vị trí của nút LOD . 0). Lớp Morph mở rộng từ lớp Node. DistanceLOD(float[] distances. Morph không phải là lớp nội suy. Theo đặc điểm này. Tuy nhiên. double distance) Thiết lập ngưỡng khoảng cách LOD xác định.com 545 .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. 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. void setDistance(int whichDistance. 0. Khả năng này do lớp Morph cung cấp. 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. Tuy nhiên. http://tailieuhay. Đố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.

java cũng có thể tìm thấy trong đĩa chương trình kèm theo. các ứng dụng Morph phải tự xây dựng lớp hành vi riêng. trong đĩa chương trình kèm theo. biến một kìm tự tháp thành hình hộp.com 546 . Chương trình ví dụ tạo hoạt ảnh cho bàn tay. Hạn chế về số lượng đỉnh không phải là hạn chế lớn của Morph . Morphing. cần phải biết các thức đối tượng Morph làm việc. với cùng số lượng các đỉnh. Các đối tượng GeometryArray có thể được coi như là các http://tailieuhay. Sử dụng đối tượng Morph Để hiểu được cách sử dụng đối tượng Morph .Lập trình đồ họa trên Java 2D và 3D Trong chương 4. Do không có lớp hành vi chuyên biệt sử dụng với đối tượng Morph . bạn đọc có thể thấy chương trình Pyramid2Cube. Chương trình ví dụ thứ 3. hay làm cho bàn tay có thể cầm nắm được vật dụng…).java. Morph không quá phức tạp. 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. mèo thành chó. 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 . Đối tượng Morph có thể được sử dụng để biến kim tự tháp thành hình khối hộ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. Đố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. trước hết. 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. Đố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.

đố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 độ. Tất nhiên. 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ập trình đồ họa trên Java 2D và 3D khung ảnh chính trong hoạt ảnh. Morph hoàn toàn có thể sử dụng mà không cần đối tượng hành vi. tạo một đối tượng Morph với khả năng ALLOW_WEIGHTS_WRITE 3. Thay đổi các trọng số sẽ làm thay đổi hình dạng hình học. tạo một mảng các đối tượng GeometryArray 2. đây chính là các biến số trong phương trình. 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. …cung cấp bởi đối tượng GeometryArray. Ngoài mảng các đối tượng GeometryArray. các bước này đúng cho cả hoạt ảnh và tương tác. Cách viết lớp hành vi đã được trình bày trong phần 4. lắp ghép đồ thị khung cả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. tuy nhiên. hay chính xác hơn.1. nên ở đây không nói chi tiết. 1.2. 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. Công thức sử dụng đối tượng Morph Như đã trình bày. Do đó. 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ố. http://tailieuhay. nhưng nó sẽ không thể tạo ra được hoạt ảnh. sử dụng đối tượng Morph thường có nghĩa là viết một lớp hành vi.com 547 . Sử dụng các đối tượng GeometryArray cùng với các trọng số. sử dụng đối tượng Morph không khó.

0. private Alpha alpha. phương thức processStimlus thay đổi trọng số của đối tượng Morph .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 . Alpha alpha){ this. 0}.com 548 . Đ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. } http://tailieuhay. this.wakeupOn(trigger). 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. // the following two members are here for effciency (no memory burn) private double[] weights = {0. // create MorphBehavior MorphBehavior(Morph targetMorph.targetMorph = targetMorph. public class MorphBehavior extends Behavior{ private Morph targetMorph.alpha = alpha. } public void initialize(){ // set initial wakeup condition this. 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. private WakeupCondition trigger = new WakeupOnElapsedFrames(0). 0.

setWeights(weights).0 - http://tailieuhay.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. int alphaIndex = (int) alphaValue.0 weights[alphaIndex].(double)alphaIndex.value() . weights[3] = 0. } } // end of class MorphBehavior = 1.00001f.0. else weights[0] weights[alphaIndex].com 549 . weights[1] = 0. weights[alphaIndex] = (double) alphaValue . targetMorph. if(alphaIndex < 3) weights[alphaIndex + 1] = 1. // set next wakeup condition this.wakeupOn(trigger). float alphaValue = 4f * alpha. weights[2] = 0.

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. có thể sử dụng các gói 3D. chúng là bốn khung hình chính riêng biệt. 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. Trong phương thức này. một đối tượng MorphBehavior. Các hình có màu đen trông giống như là hai khung hình chính. nhưng thực tế. Muốn xây dựng các khung ảnh đẹp hơn. 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ụ. mỗi cái được lặp lại một lần. Toàn bộ chương trình có thể tìm thấy trong đĩa chương trình kèm theo.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. Đoạn mã sau được trích từ phương thức createSceneGraph của chương trình MorphApp. 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. 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. Sự khác nhau là ở thứ tự các đỉnh được xác định. mọi việc còn lại chỉ là tạo khung ảnh chính sử dụng cho hoạt ảnh.com 550 . một đối tượng Alpha và một đối tượng Morph được tạo ra. rồi được gộp vào đồ thị khung cảnh. Với lớp hành vi tùy chỉnh vừa viết.

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

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

com 553 . 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. http://tailieuhay. void setGeometryArrays(GeometryArray[] geometryArrays) Thiết lập thành phần geometryArrays cho nút Morph . Morph (GeometryArray[] geometryArrays. 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 . 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 .Lập trình đồ họa trên Java 2D và 3D Hình 5-23. 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.

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. sinh bóng mờ tự động hay các hiệu ứng đặc biệt như chớp… Do GeometryUpdater cho http://tailieuhay. kể cả các hoạt ảnh sử dụng kĩ thuật Billboard . Ngoại trừ Morph tạo ra hình nội suy từ các hình cho trước. 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. 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.com 554 . Giao diện GeometryUpdater có tính mềm dẻo cao.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. 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. chứ không thay đổi hay tạo ra hình mới. level of detail và Morph . Giao diện GeometryUpdater Trong các phần trên. 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ó. các hệ phân tử. Java 3D API giới thiệu giao diện GeometryUpdater. 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ó. 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ó. Với giao diện GeometryUpdater. 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.

Đối tượng hành vi lập lịch gọi đối tượng GeometryUpdater trong ứng dụng. void updateData(GeometryUpdater updater) http://tailieuhay. phương thức này sẽ gọi phương thức được cài đặt trong lớp GeometryUpdater. tạo một lớp GeometryUpdater và lấy ra một đối tượng thuộc lớp đó. 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. Hai phương thức này có cùng tên là updateData(). 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 đó. Sử dụng GeometryUpdater Để sử dụng được đối tượng GeometryUpdater cho các ứng dụng hình học động. 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. 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.com 555 . Công việc này không quá phức tạp như nhìn nhận ban đầu. 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.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. 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. Phương thức updateData() thứ hai là phương thức của GeometryArray. Đối tượng GeometryUpdater có nhiệm vụ hiệu chỉnh đối tượng hình học khi được gọi. 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.

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. Các phân tử thông thường được biểu diễn dưới dạng điểm hoặc đường. các dạng hình học khác cũng có thể được sử dụng. Trong ảnh này. Thông thường. Ảnh ở giữa là khi cột “nước” được khởi tạo trong đài phun. pháo hoa và các hiện tượng giống dạng lỏng khác. 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. Trong hình này có khoảng 500 phần tử nước hoạt động. Ả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. 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. vị trí và hướng của nó sẽ được cập nhật ra sao. Hình 5-24 là một chuỗi các ảnh thu được từ chương trình ví dụ ParticleApp. Mỗi đoạn thẳng được xác định bởi 2 điểm. khói. tuy nhiên.com 556 . Trong một hệ thống phân tử. 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. 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). có tất cả khoảng 300 phần tử hoạt động. có hai tham số thiết kế cơ bản: các phân tử sẽ có dạng như thế nào. Trong chương trình ví dụ.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. http://tailieuhay.

java. Đoạn mã đầu tiên đưa ra định nghĩa cho 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. 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. Chuỗi hình ảnh thu từ chương trình ParticleApp Trong chương trình ParticleApp.Lập trình đồ họa trên Java 2D và 3D Hình 5-24. Lớp hành vi tuỳ biến Behavior và lớp GeometryUpdater là các lớp trong của lớp Fountain. Ba đoạn mã này là thành phần chính tạo nên hoạt ảnh trong ParticleApp. Ba trường (hay 3 thuộc tính) được định nghĩa gần thẻ . do cả hai lớp Behavior và Geometry đều chỉ được sử dụng cho riêng ứng dụng này. hành vi và geometryUpdater cho ứng dụng ParticleApp. Cụ thể. Tuy nhiên. 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.com 557 . 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. đối tượng hình học của phần tử nước. baseElevation là giá trị toạ độ y của http://tailieuhay. Có thể dùng một vài cách khác để thiết kế hoạt ảnh như trên. Các đoạn mã sau tương ứng định nghĩa các đối tượng hình học. Hơn nữa. 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.

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. thông tin này chỉ có thể đọc được nếu khả năng thích hợp được thiết lập. đối tượng LineArray được tạo ra trên dòng mã gán nhãn . 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. Phương thức này có định nghĩa một biến nguyên N . 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. http://tailieuhay. khả năng đọc cũng cần phải được thiết lập.Lập trình đồ họa trên Java 2D và 3D chân đài phun. Trong hầu hết các ứng dụng sử dụng GeometryUpdater. 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. Phụ thuộc ứng dụng và cách đối tượng GeometryUpdater được thiết kế. 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.com 558 thứ 2 chịu trách nhiệm thiết lập khả năng đọc số lượng . Chú ý rằng định dạng đỉnh bao gồm cả BY_REFERENCE. Phương thức thứ nhất của lớp Fountain là createWaterGeometry(). Ứng dụng này đòi hỏi như vậy. Dòng mã tiếp sau hai dòng mã gán nhãn đỉnh. Trong phương thức createWaterGeometry(). Gần như bất cứ giá trị nào cũng có thể gán cho N. Ví dụ. 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. 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. Số lượng các đỉnh là N*2. 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ớ. 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. Tất nhiên. 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. 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.

waterLines.45f. protected GeometryUpdater geometryUpdater = new WaterUpdater(). Mỗi đỉnh được khởi tạo toạ độ (0.setCapability(GeometryArray. không có phần tử nào được nhìn thấy. do đó ban đầu.ALLOW_REF_ DATA_READ). baseElevation. = new LineArray(N * 2.BY_REFERENCE).setCapability(GeometryArray.ALLOW_REF_ DATA_WRITE). waterLines.com 559 . 0). http://tailieuhay. protected float baseElevation = -0. Geometry createWaterGeometry() { int N = 1400. // number of 'drops' waterLines LineArray.COORDINATES | LineArray.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. public class Fountain extends BranchGroup { protected LineArray waterLines = null.

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

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

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

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

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

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. } // end processStimulus } // end class UpdateWaterBehavior Đoạn mã sau định nghĩa lớp GeometryUpdater. public UpdateWaterBehavior() { w = new WakeupOnElapsedFrames(0). Trong hàm khởi tạo. nhãn phương thức updateData().com 565 . 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. } public void initialize() { wakeupOn(w). 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. .updateData(geometryUpdater).Lập trình đồ họa trên Java 2D và 3D abstract Behavior { WakeupOnElapsedFrames w = null. void processStimulus(Enumeration class UpdateWaterBehavior extends http://tailieuhay. wakeupOn(w). } public critiria) { waterLines.

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

i < N. int i.getCoordRefFloat(). Trong ví dụ này. được ngẫu nhiên khởi tạo bởi điều kiện trên dòng khởi tạo. public class WaterUpdater implements .com .getValidVertexCount(). } public void updateData(Geometry geometry) { GeometryArray (GeometryArray) geometry. for (i = 0. phần else của điều kiện trên dòng . 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. i += 2) { // for each particle if (coords[i * 3 + 1] > baseElevation) { // update active 567 geometryArray = http://tailieuhay.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. geometryArray. public WaterUpdater() { random = new Random(). float[] int coords N = = geometryArray.

com 568 . // x1 coords[i baseElevation.coords[i * 3 + 4] . // y1 coords[i 0. // * 3 + 4] = (coords[i * 3 + 1] + coords[i * 3 + 4] + 0.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] . // x1 coords[i * 3 + 1] .0f. // baseElevation) { // if particle // below base coords[i 0. // y1 coords[i coords[i x2 coords[i 2.01f) / * * 3 3 + + 2] 3] += = coords[i * 3 + 2] .// y2 coords[i z2 if (coords[i * 3 + 1] < * 3 + 5] = (coords[i * 3 + 2] + coords[i * 3 + 5]) / 2.0.coords[i * 3 + 5].01f.0f. // z1 (coords[i * 3 + 0] + coords[i * 3 + 3]) / 2.coords[i * 3 + 3]. // z1 * 3 + 2] = * 3 + 1] = * 3 + 0] = http://tailieuhay.

// x2 coords[i baseElevation. // x1 * 3 + 2] = 0.0.nextFloat() .nextFloat() coords[i coords[i 0. http://tailieuhay. 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.nextFloat() . việc làm này có thể phải trả giá bởi tốc độ xử lý hoạt ảnh. Tuy nhiên. // 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.03f * (random.8) { // randomly start a drop * * 3 3 + + 0] 1] 0.0f.03f * (random.14f * random.0. // z1 .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.com 569 * * * 3 3 3 + + + 3] 4] 5] = = = > = = 0.5f).5f). lưu ý rằng. // y2 coords[i 0.

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

The Java 2D Sample Programs.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.sun. 2nd Volume. 2.com 571 .html 3.com/products/java-media/2D/index. The 2D Text Tutorial. Slide bài giảng Kĩ thuật đồ họa và hiện thực ảo của ThS.sun. The Java 3D document at: http://java.com/developer/onlineTraining/Graphics/2 DText/ 3.sun.sun.com/products/java-media/2D/samples/index. The Java Tutorial. The Java 2D Demo.sun. Available online at: http://java.com/docs/books/tutorial/2d/index. Available from the Java 2D website: http://java.com/developer/onlineTraining/java3d/ http://tailieuhay. Available online at: http://java. Available online from the Java Developer Connection: http://developer.java.html 5.html 4.Lê Tấn Hùng.

Sign up to vote on this title
UsefulNot useful