تصف فئة AffineTransform دالة تحويل تقاربية ثنائية الأبعاد، وهي عبارة عن تحويل خطي من إحداثيات ثنائية الأبعاد إلى إحداثيات ثنائية الأبعاد، مما يحافظ على "استقامة" الرسومات ثنائية الأبعاد (الترجمة: الاستقامة، أي الخط المستقيم بعد التحويل) لا يزال خطًا مستقيمًا بدون انحناء، وقوسًا ساكنًا القوس) و"التوازي" (تعليق توضيحي: التوازي، يشير في الواقع إلى الحفاظ على العلاقة الموضعية النسبية بين الأشكال ثنائية الأبعاد دون تغيير، والخطوط المتوازية تظل خطوطًا متوازية، وزوايا تقاطع الخطوط المستقيمة المتقاطعة تظل دون تغيير. المتغيرات المعقدة التي تم تعلمها في السنة الثانية ، " تذكر "التحويل المطابقة/التحويل المطابقة"، الرياضيات هي الملك!). يمكن تحقيق التحول الأفيني من خلال مجموعة من سلسلة من التحولات الذرية، بما في ذلك: الترجمة، والقياس، والقلب، والدوران، والقص.
يمكن تمثيل هذا النوع من التحويل بمصفوفة 3×3، صفها الأخير هو (0، 0، 1). تقوم مصفوفة التحويل هذه بتحويل الإحداثيات الأصلية (x، y) إلى إحداثيات جديدة (x'، y'). هنا، تعتبر الإحداثيات الأصلية والإحداثيات الجديدة بمثابة متجه عمود ثلاثي الأبعاد للصف الأخير (1). يتم تحويل متجه العمود الأصلي عن طريق الضرب الأيسر، وتحصل المصفوفة على متجهات أعمدة جديدة:
[x'] [m00 m01 m02] [x] [m00*x+m01*y+m02] [y'] = [m10 m11 m12] [y] = [m10*x+m11*y+m12] [1 ] [ 0 0 1 ] [1] [ 1 ]
العديد من التحولات التقاربية النموذجية:
AffineTransform العام الثابت getTranslateInstance (double tx، double ty)
تحويل الترجمة، انقل كل نقطة إلى (x+tx, y+ty)، مصفوفة التحويل هي:
[ 1 0 تكساس ] [ 0 1 تاي ] [ 0 0 1 ]
(ملاحظة: تحويل الترجمة هو نوع من "تحويل الجسم الصلب". أي شخص درس الفيزياء في المدرسة الإعدادية يعرف ما هو "الجسم الصلب". إنه كائن مثالي لن يتغير. بالطبع، لن تتغير الترجمة (الرسومات ثنائية الأبعاد، وبنفس الطريقة، فإن "التحويل الدوراني" أدناه هو أيضًا تحويل جامد للجسم، وسيؤدي "القياس" و"القطع المتقاطع" إلى تغيير شكل الرسم.)
AffineTransform getScaleInstance العام الثابت (double sx، double sy)
يؤدي تحجيم التحويل إلى تكبير (تقليل) الإحداثي لكل نقطة إلى مرات sx، وتوسيع (تقليل) الإحداثيات إلى أوقات sy.
[ سكس 0 0 ] [ 0 سي 0 ] [ 0 0 1 ]
AffineTransform العام الثابت getShearInstance (shx مزدوج، خجول مزدوج)
تحويل القص، مصفوفة التحويل هي:
[ 1 شx 0 ] [ خجول 1 0 ] [ 0 0 1 ]
أي ما يعادل مزيج من القص العرضي والقص الطولي
[ 1 0 0 ] [ 1 shx 0 ] [ خجول 1 0 ] [ 0 1 0 ] [ 0 0 1 ] [ 0 0 1 ]
(ملاحظة الترجمة: "التحويل القصي" يُسمى أيضًا "التحويل الخاطئ"، والذي يشير إلى خصائص مشابهة لعدم الاستقرار الرباعي. هل سبق لك أن رأيت الأبواب الحديدية المنزلقة في المتاجر الصغيرة في الشارع؟ تخيل القضبان الحديدية أعلاه. عملية المعين السحب هو عملية "القطع الخاطئ").
ثابت عام AffineTransform getRotateInstance (ثيتا مزدوجة)
تحويل التناوب، الرسم المستهدف يدور ثيتا راديان في اتجاه عقارب الساعة حول الأصل، مصفوفة التحويل هي:
[ كوس (ثيتا) -الخطيئة (ثيتا) 0 ] [ الخطيئة (ثيتا) كوس (ثيتا) 0 ] [ 0 0 1 ]
AffineTransform العام الثابت getRotateInstance (ثيتا مزدوج، مزدوج x، مزدوج y)
يتم تدوير الرسم المستهدف في اتجاه عقارب الساعة بواسطة راديان ثيتا مع (x، y) كمحور.
[ cos(ثيتا) -sin(ثيتا) xx*cos+y*sin] [ sin(theta) cos(theta) yx*sin-y*cos ] [ 0 0 1 ]
إنه يعادل مركب تحويلين للترجمة وتحويل دوران الأصل:
[1 0 -x][cos(theta) -sin(theta) 0][1 0 x] [0 1 -y][sin(theta) cos(theta) 0][0 1 y] [0 0 1 ] [0 0 1][0 0 1]
في الهندسة، يتبع التحول الخطي لمساحة متجهة ترجمة.
يمكن التعبير عنها ببساطة على النحو التالي: y = Ax + b، حيث يمثل الحرف المنخفض متجهًا ويمثل الحرف الغامق A مصفوفة.
لا يهم إذا كنت لا تستطيع فهمها في الوقت الحالي (أنا لا أفهمها أيضًا ^_^#)، لا يهم، نحن نستخدم فقط بعض الحالات الخاصة منها هنا: الترجمة والتدوير تحويل.
كالعادة، دعونا ننشر الكود بأكمله أدناه:
import java.applet.Applet;import java.awt.BorderLayout;import java.awt.Checkbox;import java.awt.CheckboxGroup;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Panel;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.geom.AffineTransform;import java.awt.geom.Rectangle2D;import java.util.Random;public class AffineTest Extends Appletlets ItemListener{ Private Rectangle2D rect; خانة الاختيار TranslateFirst public void init() { setLayout(new BorderLayout()); CheckboxGroup cbg = new CheckboxGroup(); Panel p = new Panel(); RotateFirst = new Checkbox("rotate, Translator", cbg, true); ("ترجمة، تدوير"، cbg، false)؛ BorderLayout.SOUTH); rect = new Rectangle2D.Float(-0.5f, -0.5f, 1.0f, 1.0f); } public void Paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; ()؛ oneRadian = Math.toRadians(1.0); for(double radians = 0.0; radians < 2.0*Math.PI ; radians += oneRadian) { g2d.setTransform(identify); ; g2d.rotate(راديان) } else { g2d.rotate(راديان); g2d.translate(100, 100); } g2d.scale(100, 100); arg0) { // إعادة رسم الطريقة التي تم إنشاؤها تلقائيًا لـ TODO() }}import java.applet.Applet;import java.awt.BorderLayout;import java.awt.Checkbox;import java.awt.CheckboxGroup;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;استيراد java .awt.Panel;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.awt.geom.AffineTransform;import java.awt.geom.Rectangle2D;import java.util.Random;public class AffineTest Extends Appletlets ItemListener{ Private Rectangle2D rect; مربع الاختيار ترجمة الأول public void init() { setLayout(new BorderLayout()); CheckboxGroup cbg = new CheckboxGroup(); Panel p = new Panel(); RotateFirst = new Checkbox("rotate, Translator", cbg, true); ("ترجمة، تدوير"، cbg، false)؛ BorderLayout.SOUTH); rect = new Rectangle2D.Float(-0.5f, -0.5f, 1.0f, 1.0f); } public void Paint(Graphics g) { Graphics2D g2d = (Graphics2D)g; ()؛ oneRadian = Math.toRadians(1.0); for(double radians = 0.0; radians < 2.0*Math.PI ; radians += oneRadian) { g2d.setTransform(identify); ; g2d.rotate(راديان) } else { g2d.rotate(راديان); g2d.translate(100, 100); } g2d.scale(100, 100); arg0) { // إعادة رسم كعب الطريقة التي تم إنشاؤها تلقائيًا () TODO }}
من المقارنة، يمكن أن نرى أن ترتيب التحول التقاربي لا يمكن تبادله بشكل عرضي.