Example 13 — Rotate a Text Picture with a Rotation Matrix ตัวอย่างที่ 13 — หมุนภาพตัวอักษรด้วย rotation matrix
Turn a picture by an angle you enter, with a rotation matrix made of cos and sin. หมุนภาพด้วยมุมที่ป้อนเอง โดยใช้ rotation matrix ที่มี cos และ sin
This page solves the problem of Example 12 again, and this time the picture can turn by other angles. Read card 2 for the basics of turning with a matrix and card 3 for a worked example, then follow the flowchart and press Run.
หน้านี้แก้โจทย์เดียวกับตัวอย่างที่ 12 แต่หมุนได้หลายมุม อ่านการ์ดที่ 2 เพื่อปูพื้นฐานการหมุนด้วย matrix และการ์ดที่ 3 เพื่อดูตัวอย่างการคำนวณ แล้วค่อยไล่ตาม flowchart และกด Run
Use a picture like the one in Example 12. Read an angle in degrees with input(), then show the picture turned around its center by that angle. A positive angle turns clockwise. The result has the same size as the picture, and any cell with no data shows -.
ใช้ picture แบบตัวอย่างที่ 12 รับมุมเป็นองศาจาก input() แล้วแสดงภาพที่หมุนรอบจุดกึ่งกลางด้วยมุมนั้น มุมบวกหมุนตามเข็มนาฬิกา ภาพผลมีขนาดเท่าเดิม ช่องที่ไม่มีข้อมูลให้แสดง -
- Example: the angle 90 gives the same result as Example 12
- ตัวอย่าง: มุม 90 ได้ผลเหมือนตัวอย่างที่ 12
- math.radians(angle) changes degrees to radians, because math.cos and math.sin take radians.
- round(v) rounds v to the nearest whole number. A value exactly halfway goes to the even neighbour, so round(2.5) is 2 and round(3.5) is 4.
- and is True when every condition is true. It checks that a position is inside the picture.
- math.radians(angle) แปลงองศาเป็นเรเดียน เพราะ math.cos และ math.sin รับค่าเป็นเรเดียน
- round(v) ปัด v เป็นจำนวนเต็มที่ใกล้ที่สุด ค่าที่อยู่กึ่งกลางพอดีจะปัดไปหาเลขคู่ round(2.5) จึงได้ 2 และ round(3.5) ได้ 4
- and เป็น True เมื่อทุกเงื่อนไขเป็นจริง ใช้ตรวจว่าตำแหน่งอยู่ในภาพ
Step 1: positions become coordinates. The character at row r and column c is one point. The picture turns around its center, so the coordinates are measured from the center.
ขั้นที่ 1 เปลี่ยนตำแหน่งเป็นพิกัด ตัวอักษรแถว r คอลัมน์ c เป็นจุด 1 จุด เนื่องจากต้องการหมุนรอบกึ่งกลางภาพ จึงวัดพิกัดจากจุดกึ่งกลาง
A 9×9 picture has center = 4, so the @ at r = 2, c = 3 has the coordinates \(x = -1,\ y = -2\).
ภาพ 9×9 มี center = 4 ตัว @ ที่ r = 2, c = 3 จึงมีพิกัด \(x = -1,\ y = -2\)
Step 2: turn the point with a rotation matrix.
ขั้นที่ 2 หมุนจุดด้วย rotation matrix
The y axis of a text picture points down, because the row number grows from top to bottom. So this formula turns the point clockwise when \(\theta\) is positive. For \(\theta = 90^\circ\), \(\cos\theta = 0\) and \(\sin\theta = 1\):
แกน y ของภาพตัวอักษรชี้ลง เพราะเลขแถวเพิ่มจากบนลงล่าง สูตรนี้จึงหมุนตามเข็มนาฬิกาเมื่อ \(\theta\) เป็นบวก ตัวอย่างที่ \(\theta = 90^\circ\) ซึ่ง \(\cos\theta = 0\) และ \(\sin\theta = 1\)
Adding center back gives c = 6, r = 3, which is where @ is in the result of Example 12. The code below does the same calculation. In a computer math.cos(theta) is not exactly 0 but about \(6 \times 10^{-17}\), so the code rounds the result to 6 decimal places.
บวก center กลับ ได้ c = 6, r = 3 ตรงกับตำแหน่งของ @ ในผลของตัวอย่างที่ 12 โค้ดด้านล่างคำนวณแบบเดียวกัน ในคอมพิวเตอร์ math.cos(theta) ไม่ได้เป็น 0 พอดี แต่ประมาณ \(6 \times 10^{-17}\) โค้ดจึงปัดผลเหลือทศนิยม 6 ตำแหน่ง
2.0 -1.0
Step 3: the trouble with other angles. Other angles give coordinates with decimals. If each character turns from the picture to the result and is then rounded, several characters land on the same cell and some cells get nothing. In this 9×9 picture turned by 45°, a . marks a cell where no character landed. These cells are at the corners and also inside the picture, such as r = 2, c = 4.
ขั้นที่ 3 ปัญหาของมุมที่ไม่ใช่มุมฉาก มุมอื่นให้พิกัดเป็นทศนิยม ถ้าหมุนจากภาพเดิมไปภาพผลแล้วปัดเศษ หลายตัวจะตกช่องเดียวกัน และบางช่องไม่มีตัวอักษรเลย ในภาพ 9×9 ที่หมุน 45° นี้ ช่อง . คือช่องที่ไม่มีตัวอักษรตกลงมา มีทั้งมุมภาพและรูโหว่กลางภาพ เช่น แถว r = 2 คอลัมน์ c = 4
..*-*-*.. .*.---.*. *.--.@-.* ------@-- *-.+--.-* *---++--* *.--.--.* .*.---.*. ..*****..
Step 4: reverse mapping. Turn the thinking around. Go through the cells of the result one at a time, and turn each cell back by \(-\theta\) to find where it came from in the picture. Putting \(-\theta\) into the matrix gives:
ขั้นที่ 4 แก้ด้วย reverse mapping กลับทิศการคิด ไล่ทีละช่องของภาพผล แล้วหมุนกลับด้วยมุม \(-\theta\) เพื่อหาว่าช่องนี้มาจากตำแหน่งใดของภาพเดิม แทน \(-\theta\) ลงใน matrix ได้
Rounding the result picks the nearest cell. A character can be off by up to 1 cell, but every cell always gets a value. If the position falls outside the picture, the cell gets -.
ปัดผลเป็นจำนวนเต็มเพื่อเลือกช่องที่ใกล้ที่สุด ตัวอักษรอาจคลาดไม่เกิน 1 ช่อง แต่ทุกช่องจะมีค่าเสมอ ถ้าตำแหน่งที่ได้อยู่นอกภาพ ให้เติม -
Take the 3×3 picture of numbers from Example 12 and the angle 90, and work out every cell of the result by hand. The picture and the result are:
ลองใช้ภาพตัวเลขขนาด 3×3 จากตัวอย่างที่ 12 กับมุม 90 แล้วคำนวณทุกช่องของภาพผลด้วยมือ ภาพเดิมและภาพผลเป็นดังนี้
| c = 0 | c = 1 | c = 2 | |
|---|---|---|---|
| r = 0 | 1 | 2 | 3 |
| r = 1 | 4 | 5 | 6 |
| r = 2 | 7 | 8 | 9 |
| c′ = 0 | c′ = 1 | c′ = 2 | |
|---|---|---|---|
| r′ = 0 | 7 | 4 | 1 |
| r′ = 1 | 8 | 5 | 2 |
| r′ = 2 | 9 | 6 | 3 |
r′ and c′ are the row and the column of the result, and r and c are the row and the column of the picture the character comes from. The picture has size = 3, so center = (3 - 1) / 2 = 1, and the angle 90° gives \(\cos\theta = 0\) and \(\sin\theta = 1\). Each cell of the result is worked out in three steps:
ให้ r′ และ c′ เป็นแถวและคอลัมน์ของภาพผล ส่วน r และ c เป็นแถวและคอลัมน์ของภาพเดิมที่ตัวอักษรนั้นมาจาก ภาพนี้มี size = 3 จึงได้ center = (3 - 1) / 2 = 1 และมุม 90° ให้ \(\cos\theta = 0\) กับ \(\sin\theta = 1\) การคิดแต่ละช่องของภาพผลมี 3 ขั้น
| New data — the resultข้อมูลใหม่ — ภาพผล | Coordinatesพิกัดจากกึ่งกลาง | Turned backหมุนกลับ | Old dataข้อมูลเดิม | |||||
|---|---|---|---|---|---|---|---|---|
| Valueค่า | r′ | c′ | x | y | x_src | y_src | r | c |
| 7 | 0 | 0 | −1 | −1 | −1 | 1 | 2 | 0 |
| 4 | 0 | 1 | 0 | −1 | −1 | 0 | 1 | 0 |
| 1 | 0 | 2 | 1 | −1 | −1 | −1 | 0 | 0 |
| 8 | 1 | 0 | −1 | 0 | 0 | 1 | 2 | 1 |
| 5 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
| 2 | 1 | 2 | 1 | 0 | 0 | −1 | 0 | 1 |
| 9 | 2 | 0 | −1 | 1 | 1 | 1 | 2 | 2 |
| 6 | 2 | 1 | 0 | 1 | 1 | 0 | 1 | 2 |
| 3 | 2 | 2 | 1 | 1 | 1 | −1 | 0 | 2 |
Every r and c in the table is a whole number between 0 and 2, so no cell falls outside the picture and no cell gets -. Reading the values down the table gives 741, 852, 963, the same result as Example 12. In the code the loop counters r and c run over the result, so they are r′ and c′ of this table, and the two columns on the right are src_r and src_c.
ค่า r และ c ในตารางเป็นจำนวนเต็มตั้งแต่ 0 ถึง 2 ทุกช่อง จึงไม่มีช่องใดตกนอกภาพและไม่มีช่องใดได้ - อ่านค่าไล่ลงมาตามตารางได้ 741, 852, 963 ซึ่งเป็นผลเดียวกับตัวอย่างที่ 12 ส่วนในโค้ด ตัวนับของ loop คือ r และ c ซึ่งไล่ไปตามภาพผล จึงเป็น r′ และ c′ ของตารางนี้ และสองคอลัมน์ขวาสุดคือ src_r กับ src_c
The program starts by setting the picture in picture, keeps its size in size, and reads the angle with input into angle. Next it changes the angle to radians in theta and works out center. Then it sets r = 0 and c = 0 as the row and column counters of the result, and changes the position to the coordinates x and y. It turns them back with the reverse mapping formula, adds center and rounds with round to get src_c and src_r. It checks whether this position is inside the picture: if so, it adds the character from picture to the end of text; if not, it adds -. It repeats this until every column is done, shows the row with print and moves on to the next row. When every row is done, the program ends.
เริ่มต้นด้วยกำหนดภาพไว้ใน picture หาขนาดภาพเก็บใน size แล้วรับมุมจาก input เก็บใน angle ถัดไปแปลงมุมเป็นเรเดียนเก็บใน theta และคำนวณ center จากนั้นกำหนด r = 0 และ c = 0 เป็นตัวนับแถวและคอลัมน์ของภาพผล แล้วเปลี่ยนตำแหน่งเป็นพิกัด x และ y หมุนกลับด้วยสูตร reverse mapping บวก center และปัดเศษด้วย round ได้ src_c และ src_r ตรวจสอบเงื่อนไขว่าตำแหน่งนี้อยู่ในภาพหรือไม่ ถ้าใช่ให้หยิบตัวอักษรจาก picture ต่อท้าย text ถ้าไม่ใช่ให้ต่อด้วย - ทำแบบนี้จนครบทุกคอลัมน์จึงแสดงแถวด้วย print แล้วไปแถวถัดไป เมื่อครบทุกแถวแล้วจบการทำงานของโปรแกรม
Angle (degrees): 45 --*****-- -**---**- **---@-** *-----@-* *-++----* *--++---* **--+--** -**---**- --*****--
Try it yourself — enter an angle in degrees and press Submit. Each value starts a new run.
ลองป้อนค่าเอง — ป้อนมุมเป็นองศาแล้วกดส่ง ทุกค่าที่ส่งจะเริ่มรันใหม่
Enter each angle in the form of card 4 to check this table. Characters on a screen are taller than they are wide, so a picture at a slanted angle looks a little squeezed.
ป้อนแต่ละมุมในฟอร์มของการ์ดที่ 4 เพื่อตรวจตารางนี้ ตัวอักษรบนจอสูงกว่ากว้าง ภาพที่มุมเอียงจึงดูบีบเล็กน้อย
| Angleมุม | Resultผล |
|---|---|
| 0, 360 | The same as the pictureเหมือนภาพเดิม |
| 90 | The same as Example 12เหมือนตัวอย่างที่ 12 |
| 180 | The picture upside downภาพกลับหัว |
| 270, -90 | The same result: a 90° counterclockwise turnผลเท่ากัน หมุนทวนเข็มนาฬิกา 90° |
| 45 | A slanted picture, shown in card 4ภาพเอียง ดูผลได้ในการ์ดที่ 4 |
| 30 | A slanted picture, and some cells of the outline are lost to roundingภาพเอียง ขอบบางช่องหายเพราะการปัดเศษ |
| Example 12ตัวอย่างที่ 12 | Example 13ตัวอย่างที่ 13 | |
|---|---|---|
| Finding the positionการหาตำแหน่ง | Whole-number indexindex จำนวนเต็ม | cos and sin, then roundingคำนวณด้วย cos และ sin แล้วปัดเศษ |
| Anglesมุมที่หมุนได้ | 90° only90° เท่านั้น | Any angleมุมใดก็ได้ |
| Result at 90°ผลที่ 90° | Exactตรงทุกตัว | Exactตรงทุกตัว |
| Result at other anglesผลที่มุมอื่น | Not possibleทำไม่ได้ | A character can be off by up to 1 cell, and some outline cells can be lostตัวอักษรคลาดได้ไม่เกิน 1 ช่อง ขอบบางช่องอาจหาย |
| Lines that work out one cellจำนวนบรรทัดที่คำนวณ 1 ช่อง | 1 | 8 |
If you need only 90°, Example 12 is simpler and exact. If you need many angles, use the matrix.
ถ้าต้องการแค่ 90° ตัวอย่างที่ 12 ง่ายและแม่นกว่า ถ้าต้องการหลายมุมให้ใช้ matrix
Think further: the smiley face is round, so all its characters stay in the picture at 45°. But a picture with characters in its corners, such as a * frame around it, loses its corners in the result. What would you do to see the whole picture?
ชวนคิดต่อ: หน้ายิ้มเป็นรูปกลม หมุน 45° แล้วตัวอักษรจึงอยู่ในภาพครบ แต่ถ้าภาพมีตัวอักษรที่มุม เช่น กรอบ * รอบภาพ มุมจะหลุดออกนอกภาพผล จะทำอย่างไรให้เห็นครบ
Show the answer ดูคำตอบ
Make the result bigger. Its side must be at least \(\sqrt{2}\) times the side of the picture, so a 9×9 picture needs 13×13, because \(9\sqrt{2} \approx 12.7\).
ขยายภาพผลให้ด้านยาวอย่างน้อย \(\sqrt{2}\) เท่าของเดิม ภาพ 9×9 จึงต้องใช้ 13×13 เพราะ \(9\sqrt{2} \approx 12.7\)
The Run buttons on this page simulate Python with JavaScript, the same as the other lessons. To run the real Python, paste the code into Google Colab.
ปุ่ม Run ในหน้านี้จำลองโค้ด Python ด้วย JavaScript เหมือนบทเรียนอื่นๆ หากต้องการรัน Python จริง ให้นำโค้ดไปวางใน Google Colab
References References / แหล่งอ้างอิง
-
Python docs — math: Trigonometric functions
(
math.cos,math.sin) (math.cos,math.sin) -
Python docs — math: Angular conversion
(
math.radians) (math.radians) - Python docs — round (rounding to a whole number) (การปัดเป็นจำนวนเต็ม)
- The 90° version of this problem: Example 12 — Rotate a Text Picture 90° โจทย์นี้แบบ 90°: ตัวอย่างที่ 12 — หมุนภาพตัวอักษร 90°