Lab 14-2: Simple Complex Number Geometry Transformation (Binary File ver.) (25%)
- 輸入:
- 從檔案中讀取多個幾何形狀或幾何變換的複數資料。
- 請使用
int main(int argc, char *argv[])
來開啟指定檔案 (Ref: One and the only: main function。 - 開啟檔案名稱會放在
argv[1]
中。
- 請使用
- 幾何圖形
- 以
char
格式讀取幾何圖形形狀,包含三角形 (t
)、四邊形 (q
)、多邊形 (p
)、圓形 (c
),sizeof(char)
byte 讀取一個幾何圖形 - 以
unsinged int
格式讀取幾何圖形的頂點數,sizeof(unsigned)
byte 讀取一個正整數- 三角形:3
- 四邊形:4
- 多邊形:大於 3 的正整數
- 圓形:2
- 以
double
格式讀取組合幾何圖形的複數的實數及虛數部分,sizeof(double)
byte 讀取一個實數或虛數部分 - 讀取幾何圖形形狀及頂點數後依據 2. 的頂點數接著讀取相對應的複數
- 三角形:連續讀取三個複數
- 四邊形:連續讀取四個複數
- 多邊形:連續讀取多個複數
- 圓形:連續讀取兩個複數
- 幾何變換
- 以
char
格式讀取幾何變換字元,包含以0
點旋轉 (r
)、以0
點縮放 (z
)、平移 (m
),sizeof(char)
byte 讀取一個幾何變換 - 以
double
格式讀取幾何變換的複數的實數及虛數部分,sizeof(double)
byte 讀取一個實數或虛數部分- 以
0
點旋轉:\(z * (cos(\theta) + sin(\theta)i), norm = 1\) - 以
0
點縮放:\(z * (r + 0i)\) - 平移:\(z + (x + yi)\)
- 以
- 讀取幾何變換後須將所有的幾何圖形複數變換
- 從檔案中讀取多個幾何形狀或幾何變換的複數資料。
- 輸出:
- 將結果的幾何形狀及幾何變換的複數資料輸出至指令列及檔案中。
- 請使用
int main(int argc, char *argv[])
來開啟指定檔案 (Ref: One and the only: main function。 - 開啟檔案名稱會放在
argv[2]
中。
- 請使用
- 幾何圖形
- 顯示紀錄幾何圖形的形狀、頂點個數及其複數
- 格式請參考 Format 中的說明
- 頂點順序與讀取順序相同
- 複數的格式為
<real part in binary><imaginary part in binary>
- 顯示紀錄幾何圖形的形狀、頂點個數及其複數
- 幾何變換
- 輸出變換後的所有幾何圖形複數
- 將結果的幾何形狀及幾何變換的複數資料輸出至指令列及檔案中。
- 檔名:
lab14-2_<學號>.cpp
(e.g.lab14-2_106062802.cpp
)
注意事項:
- 程式不會輸出任何使用者提示,只會輸出程式結果
- 使用者不需要處理錯誤輸入
- 請基於 pseudo code 提供的
main
及print_output_file
進行修改來處理輸入與輸出 - 程式需要於 10 秒內完成,所有的測資皆會保證於 10 秒內完成
Input Format
Geometry Objects
<geometry type><n><real 1><imag 1><real 2><imag 2>...<real n> <imag n><EOF>
Transformation
<geometry type 1><n><real 1> <imag 1><real 2> <imag 2>...<real n> <imag n><geometry type 2><n><real 1> <imag 1><real 2> <imag 2>...<real n><imag n><geometry transformation type><real trans> <imag trans><EOF>
Output Format
Geometry Objects
<geometry type1><n><real 1><imag 1><real 2><imag 2>...<real n> <imag n><EOF>
Transformation
<geometry type1><n><real 1><imag 1><real 2><imag 2>...<real n> <imag n><geometry type1><n><real 1><imag 1><real 2><imag 2>...<real n><imag n><EOF>
Example
Note: 有 #
前置的行為註解,僅方便顯示,不會在 .bin
檔案內。
Geometry Objects
Triangle
Input File: input_triangle.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00
Output File: output_triangle.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00
Terminal:
$ ./a.out input_triangle.bin output_triangle.bin
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00
$
Quadrilateral
Input File: input_quadrilateral.bin
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# Hex dump
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40
Output File: output_quadrilateral.bin
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# Hex dump
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40
Terminal:
$ ./a.out input_quadrilateral.bin output_quadrilateral.bin
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40
$
Circle
Input File: input_circle.bin
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# Hex dump
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40
Output File: output_circle.bin
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# Hex dump
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40
Terminal:
$ ./a.out input_circle.bin output_circle.bin
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40
$
Polygon
Input File: input_polygon.bin
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# Hex dump
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40
Output File: output_polygon.bin
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# Hex dump
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40
Terminal:
$ ./a.out input_polygon.bin output_polygon.bin
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40
$
Multiple Objects
Input File: input_multiple_objects.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40
Output File: output_multiple_objects.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40
Terminal:
$ ./a.out input_multiple.bin output_multiple.bin
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40
$
Transformation
Scaling
Input File: input_scaling.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# z
# 2.000000000000000 0.000000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 7a 00 00 00 00 00 00 00 40 00 00
00 00 00 00 00 00
Output File: output_scaling.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# t
# 3
# 2.000000000000000 4.000000000000000
# 6.000000000000000 8.000000000000000
# 10.000000000000000 0.000000000000000
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 74 03 00 00 00 00 00 00 00 00 00
00 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
18 40 00 00 00 00 00 00 20 40 00 00 00 00 00 00
24 40 00 00 00 00 00 00 00 00
Terminal:
$ ./a.out input_scaling.bin output_scaling.bin
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 74 03 00 00 00 00 00 00 00 00 00
00 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
18 40 00 00 00 00 00 00 20 40 00 00 00 00 00 00
24 40 00 00 00 00 00 00 00 00
$
Translation
Input File: input_translation.bin
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# m
# 3.000000000000000 -1.000000000000000
# Hex dump
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40 6d 00 00 00 00 00 00 08 40 00 00
00 00 00 00 f0 bf
Output File: output_translation.bin
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# q
# 4
# 4.000000000000000 1.000000000000000
# 6.000000000000000 1.000000000000000
# 6.000000000000000 3.000000000000000
# 4.000000000000000 3.000000000000000
# Hex dump
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40 71 04 00 00 00 00 00 00 00 00 00
10 40 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00
18 40 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00
18 40 00 00 00 00 00 00 08 40 00 00 00 00 00 00
10 40 00 00 00 00 00 00 08 40
Terminal:
$ ./a.out input_translation.bin output_translation.bin
71 04 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 10 40 71 04 00 00 00 00 00 00 00 00 00
10 40 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00
18 40 00 00 00 00 00 00 f0 3f 00 00 00 00 00 00
18 40 00 00 00 00 00 00 08 40 00 00 00 00 00 00
10 40 00 00 00 00 00 00 08 40
$
Rotation
Input File: input_rotation.bin
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# r
# 0.999906049801550 0.013707354604752
# Hex dump
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 72 ea 0b df f8 3a ff ef 3f 2e ca
ef fd 99 12 8c 3f
Output File: output_rotation.bin
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# c
# 2
# 0.972491340592046 2.013519454207852
# 2.944888730985642 4.040746263020456
# Hex dump
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 63 02 00 00 00 99 8d ef 28 a6 1e
ef 3f bf 75 6d 16 b0 1b 00 40 c7 89 af d2 21 8f
07 40 a4 6d 6c 63 b9 29 10 40
Terminal:
$ ./a.out input_rotation.bin output_rotation.bin
63 02 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 63 02 00 00 00 99 8d ef 28 a6 1e
ef 3f bf 75 6d 16 b0 1b 00 40 c7 89 af d2 21 8f
07 40 a4 6d 6c 63 b9 29 10 40
$
Multiple Transformations
Input File: input_multiple_transformations.bin
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# z
# 2.000000000000000 0.000000000000000
# m
# 3.000000000000000 -1.000000000000000
# r
# 0.999906049801550 0.013707354604752
# Hex dump
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40 7a 00 00 00 00 00 00 00 40 00 00
00 00 00 00 00 00 6d 00 00 00 00 00 00 08 40 00
00 00 00 00 00 f0 bf 72 ea 0b df f8 3a ff ef 3f
2e ca ef fd 99 12 8c 3f
Output File: output_multiple_transformations.bin
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# p
# 5
# 2.000000000000000 0.000000000000000
# 4.000000000000000 2.200000000000000
# -6.000000000000000 -4.400000000000000
# 8.600000000000000 4.200000000000000
# -2.400000000000000 6.800000000000000
# p
# 5
# 5.000000000000000 -1.000000000000000
# 7.000000000000000 1.200000000000000
# -3.000000000000000 -5.400000000000000
# 11.600000000000000 3.200000000000000
# 0.600000000000000 5.800000000000000
# p
# 5
# 5.013237603612501 -0.931369276777790
# 6.982893523085147 1.295838741995124
# -2.925698434538989 -5.440614732742626
# 11.555046642962772 3.358704672780083
# 0.520440973173368 5.807679501611840
# Hex dump
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40 70 05 00 00 00 00 00 00 00 00 00
00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 40 9a 99 99 99 99 99 01 40 00 00 00 00 00 00
18 c0 9a 99 99 99 99 99 11 c0 33 33 33 33 33 33
21 40 cd cc cc cc cc cc 10 40 33 33 33 33 33 33
03 c0 33 33 33 33 33 33 1b 40 70 05 00 00 00 00
00 00 00 00 00 14 40 00 00 00 00 00 00 f0 bf 00
00 00 00 00 00 1c 40 34 33 33 33 33 33 f3 3f 00
00 00 00 00 00 08 c0 9a 99 99 99 99 99 15 c0 33
33 33 33 33 33 27 40 9a 99 99 99 99 99 09 40 34
33 33 33 33 33 e3 3f 33 33 33 33 33 33 17 40 70
05 00 00 00 57 5f 8a 28 8e 0d 14 40 1e 50 08 f1
c6 cd ed bf 5a 67 c4 a3 7b ee 1b 40 36 24 9c 67
c1 bb f4 3f 46 6d b2 94 d4 67 07 c0 ba 0f 2d 82
30 c3 15 c0 34 8f d6 12 2f 1c 27 40 4b 1a 34 8e
a0 de 0a 40 a1 e5 e8 d3 73 a7 e0 3f 2c 4a d4 55
10 3b 17 40
Terminal:
$ ./a.out input_multiple_transformations.bin output_multiple_transformations.bin
70 05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99
99 99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99
99 99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc
cc cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33
33 33 33 0b 40 70 05 00 00 00 00 00 00 00 00 00
00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00
10 40 9a 99 99 99 99 99 01 40 00 00 00 00 00 00
18 c0 9a 99 99 99 99 99 11 c0 33 33 33 33 33 33
21 40 cd cc cc cc cc cc 10 40 33 33 33 33 33 33
03 c0 33 33 33 33 33 33 1b 40 70 05 00 00 00 00
00 00 00 00 00 14 40 00 00 00 00 00 00 f0 bf 00
00 00 00 00 00 1c 40 34 33 33 33 33 33 f3 3f 00
00 00 00 00 00 08 c0 9a 99 99 99 99 99 15 c0 33
33 33 33 33 33 27 40 9a 99 99 99 99 99 09 40 34
33 33 33 33 33 e3 3f 33 33 33 33 33 33 17 40 70
05 00 00 00 57 5f 8a 28 8e 0d 14 40 1e 50 08 f1
c6 cd ed bf 5a 67 c4 a3 7b ee 1b 40 36 24 9c 67
c1 bb f4 3f 46 6d b2 94 d4 67 07 c0 ba 0f 2d 82
30 c3 15 c0 34 8f d6 12 2f 1c 27 40 4b 1a 34 8e
a0 de 0a 40 a1 e5 e8 d3 73 a7 e0 3f 2c 4a d4 55
10 3b 17 40
$
Multiple Transformations on Multiple Objects
Input File: input_mix.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# z
# 2.000000000000000 0.000000000000000
# m
# 3.000000000000000 -1.000000000000000
# r
# 0.999906049801550 0.013707354604752
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40 7a 00 00 00 00 00 00 00 40 00 00 00
00 00 00 00 00 6d 00 00 00 00 00 00 08 40 00 00
00 00 00 00 f0 bf 72 ea 0b df f8 3a ff ef 3f 2e
ca ef fd 99 12 8c 3f
Output File: output_mix.bin
# t
# 3
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 5.000000000000000 0.000000000000000
# q
# 4
# 1.000000000000000 2.000000000000000
# 3.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# 1.000000000000000 4.000000000000000
# c
# 2
# 1.000000000000000 2.000000000000000
# 3.000000000000000 4.000000000000000
# p
# 5
# 1.000000000000000 0.000000000000000
# 2.000000000000000 1.100000000000000
# -3.000000000000000 -2.200000000000000
# 4.300000000000000 2.100000000000000
# -1.200000000000000 3.400000000000000
# t
# 3
# 2.000000000000000 4.000000000000000
# 6.000000000000000 8.000000000000000
# 10.000000000000000 0.000000000000000
# q
# 4
# 2.000000000000000 4.000000000000000
# 6.000000000000000 4.000000000000000
# 6.000000000000000 8.000000000000000
# 2.000000000000000 8.000000000000000
# c
# 2
# 2.000000000000000 4.000000000000000
# 6.000000000000000 8.000000000000000
# p
# 5
# 2.000000000000000 0.000000000000000
# 4.000000000000000 2.200000000000000
# -6.000000000000000 -4.400000000000000
# 8.600000000000000 4.200000000000000
# -2.400000000000000 6.800000000000000
# t
# 3
# 5.000000000000000 3.000000000000000
# 9.000000000000000 7.000000000000000
# 13.000000000000000 -1.000000000000000
# q
# 4
# 5.000000000000000 3.000000000000000
# 9.000000000000000 3.000000000000000
# 9.000000000000000 7.000000000000000
# 5.000000000000000 7.000000000000000
# c
# 2
# 5.000000000000000 3.000000000000000
# 9.000000000000000 7.000000000000000
# p
# 5
# 5.000000000000000 -1.000000000000000
# 7.000000000000000 1.200000000000000
# -3.000000000000000 -5.400000000000000
# 11.600000000000000 3.200000000000000
# 0.600000000000000 5.800000000000000
# t
# 3
# 4.958408185193494 3.068254922428410
# 8.903202965980686 7.122708540053618
# 13.012486002024902 -0.821710439939774
# q
# 4
# 4.958408185193494 3.068254922428410
# 8.958032384399694 3.123084340847418
# 8.903202965980686 7.122708540053618
# 4.903578766774485 7.067879121634610
# c
# 2
# 4.958408185193494 3.068254922428410
# 8.903202965980686 7.122708540053618
# p
# 5
# 5.013237603612501 -0.931369276777790
# 6.982893523085147 1.295838741995124
# -2.925698434538989 -5.440614732742626
# 11.555046642962772 3.358704672780083
# 0.520440973173368 5.807679501611840
# Hex dump
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40 74 03 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 18
40 00 00 00 00 00 00 20 40 00 00 00 00 00 00 24
40 00 00 00 00 00 00 00 00 71 04 00 00 00 00 00
00 00 00 00 00 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 18 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 18 40 00 00 00 00 00 00 20 40 00 00
00 00 00 00 00 40 00 00 00 00 00 00 20 40 63 02
00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00
00 10 40 00 00 00 00 00 00 18 40 00 00 00 00 00
00 20 40 70 05 00 00 00 00 00 00 00 00 00 00 40
00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 40
9a 99 99 99 99 99 01 40 00 00 00 00 00 00 18 c0
9a 99 99 99 99 99 11 c0 33 33 33 33 33 33 21 40
cd cc cc cc cc cc 10 40 33 33 33 33 33 33 03 c0
33 33 33 33 33 33 1b 40 74 03 00 00 00 00 00 00
00 00 00 14 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 22 40 00 00 00 00 00 00 1c 40 00 00 00
00 00 00 2a 40 00 00 00 00 00 00 f0 bf 71 04 00
00 00 00 00 00 00 00 00 14 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 22 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 22 40 00 00 00 00 00 00
1c 40 00 00 00 00 00 00 14 40 00 00 00 00 00 00
1c 40 63 02 00 00 00 00 00 00 00 00 00 14 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 22 40 00
00 00 00 00 00 1c 40 70 05 00 00 00 00 00 00 00
00 00 14 40 00 00 00 00 00 00 f0 bf 00 00 00 00
00 00 1c 40 34 33 33 33 33 33 f3 3f 00 00 00 00
00 00 08 c0 9a 99 99 99 99 99 15 c0 33 33 33 33
33 33 27 40 9a 99 99 99 99 99 09 40 34 33 33 33
33 33 e3 3f 33 33 33 33 33 33 17 40 74 03 00 00
00 c3 7f 8e f4 68 d5 13 40 e3 f7 9c 3c c9 8b 08
40 12 13 81 9e 70 ce 21 40 7b e1 b9 4e a7 7d 1c
40 a1 b5 b4 90 64 06 2a 40 d9 56 4a b1 73 4b ea
bf 71 04 00 00 00 c3 7f 8e f4 68 d5 13 40 e3 f7
9c 3c c9 8b 08 40 dc 02 7f 38 83 ea 21 40 0c b7
94 a4 13 fc 08 40 12 13 81 9e 70 ce 21 40 7b e1
b9 4e a7 7d 1c 40 2e a0 92 c0 43 9d 13 40 e6 01
be 1a 82 45 1c 40 63 02 00 00 00 c3 7f 8e f4 68
d5 13 40 e3 f7 9c 3c c9 8b 08 40 12 13 81 9e 70
ce 21 40 7b e1 b9 4e a7 7d 1c 40 70 05 00 00 00
57 5f 8a 28 8e 0d 14 40 1e 50 08 f1 c6 cd ed bf
5a 67 c4 a3 7b ee 1b 40 36 24 9c 67 c1 bb f4 3f
46 6d b2 94 d4 67 07 c0 ba 0f 2d 82 30 c3 15 c0
34 8f d6 12 2f 1c 27 40 4b 1a 34 8e a0 de 0a 40
a1 e5 e8 d3 73 a7 e0 3f 2c 4a d4 55 10 3b 17 40
Terminal:
$ ./a.out input_mix.bin output_mix.bin
74 03 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00
00 00 00 00 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 10 40 00 00 00 00 00 00 14 40 00 00 00
00 00 00 00 00 71 04 00 00 00 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 10 40 00 00 00 00 00 00
f0 3f 00 00 00 00 00 00 10 40 63 02 00 00 00 00
00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 10 40 70
05 00 00 00 00 00 00 00 00 00 f0 3f 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 40 9a 99 99 99
99 99 f1 3f 00 00 00 00 00 00 08 c0 9a 99 99 99
99 99 01 c0 33 33 33 33 33 33 11 40 cd cc cc cc
cc cc 00 40 33 33 33 33 33 33 f3 bf 33 33 33 33
33 33 0b 40 74 03 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 10 40 00 00 00 00 00 00 18
40 00 00 00 00 00 00 20 40 00 00 00 00 00 00 24
40 00 00 00 00 00 00 00 00 71 04 00 00 00 00 00
00 00 00 00 00 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 18 40 00 00 00 00 00 00 10 40 00 00
00 00 00 00 18 40 00 00 00 00 00 00 20 40 00 00
00 00 00 00 00 40 00 00 00 00 00 00 20 40 63 02
00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00
00 10 40 00 00 00 00 00 00 18 40 00 00 00 00 00
00 20 40 70 05 00 00 00 00 00 00 00 00 00 00 40
00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 40
9a 99 99 99 99 99 01 40 00 00 00 00 00 00 18 c0
9a 99 99 99 99 99 11 c0 33 33 33 33 33 33 21 40
cd cc cc cc cc cc 10 40 33 33 33 33 33 33 03 c0
33 33 33 33 33 33 1b 40 74 03 00 00 00 00 00 00
00 00 00 14 40 00 00 00 00 00 00 08 40 00 00 00
00 00 00 22 40 00 00 00 00 00 00 1c 40 00 00 00
00 00 00 2a 40 00 00 00 00 00 00 f0 bf 71 04 00
00 00 00 00 00 00 00 00 14 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 22 40 00 00 00 00 00 00
08 40 00 00 00 00 00 00 22 40 00 00 00 00 00 00
1c 40 00 00 00 00 00 00 14 40 00 00 00 00 00 00
1c 40 63 02 00 00 00 00 00 00 00 00 00 14 40 00
00 00 00 00 00 08 40 00 00 00 00 00 00 22 40 00
00 00 00 00 00 1c 40 70 05 00 00 00 00 00 00 00
00 00 14 40 00 00 00 00 00 00 f0 bf 00 00 00 00
00 00 1c 40 34 33 33 33 33 33 f3 3f 00 00 00 00
00 00 08 c0 9a 99 99 99 99 99 15 c0 33 33 33 33
33 33 27 40 9a 99 99 99 99 99 09 40 34 33 33 33
33 33 e3 3f 33 33 33 33 33 33 17 40 74 03 00 00
00 c3 7f 8e f4 68 d5 13 40 e3 f7 9c 3c c9 8b 08
40 12 13 81 9e 70 ce 21 40 7b e1 b9 4e a7 7d 1c
40 a1 b5 b4 90 64 06 2a 40 d9 56 4a b1 73 4b ea
bf 71 04 00 00 00 c3 7f 8e f4 68 d5 13 40 e3 f7
9c 3c c9 8b 08 40 dc 02 7f 38 83 ea 21 40 0c b7
94 a4 13 fc 08 40 12 13 81 9e 70 ce 21 40 7b e1
b9 4e a7 7d 1c 40 2e a0 92 c0 43 9d 13 40 e6 01
be 1a 82 45 1c 40 63 02 00 00 00 c3 7f 8e f4 68
d5 13 40 e3 f7 9c 3c c9 8b 08 40 12 13 81 9e 70
ce 21 40 7b e1 b9 4e a7 7d 1c 40 70 05 00 00 00
57 5f 8a 28 8e 0d 14 40 1e 50 08 f1 c6 cd ed bf
5a 67 c4 a3 7b ee 1b 40 36 24 9c 67 c1 bb f4 3f
46 6d b2 94 d4 67 07 c0 ba 0f 2d 82 30 c3 15 c0
34 8f d6 12 2f 1c 27 40 4b 1a 34 8e a0 de 0a 40
a1 e5 e8 d3 73 a7 e0 3f 2c 4a d4 55 10 3b 17 40
$
Pseudo Code
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
using namespace std;
class Geometry_Comp;
class Complex
{
private:
// data members
// save the real and imaginary parts of the complex number
// with `double` precision
double m_real;
double m_imag;
public:
// Constructor, initializes real and imaginary parts
Complex(const double &arg_real = 0.0, const double &arg_imag = 0.0);
// Copy constructor
Complex(const Complex &arg_c);
// assignment operator
Complex &operator=(const Complex &arg_c);
// add assignment operator
Complex &operator+=(const Complex &arg_c);
// multiply assignment operator
Complex &operator*=(const Complex &arg_c);
// length of the complex number
double length() const;
// angle of the complex number in radians
// use `atan2` to compute the angle by the formula `atan(imag/real)`
// and use `NAN` for 0/0 case
// `atan2` ref: https://en.cppreference.com/w/cpp/numeric/math/atan2
// `NAN` ref: https://en.cppreference.com/w/cpp/numeric/math/NAN
double angle() const;
// write data members in binary format
// note: be careful about the type used in `.write()` function
void write_binary_record(ostream &arg_os);
// read data members in binary format
// note: use `.read()` to get the double in binary format,
// use `istream::fail()` to check the conversion is successful
// and use `istream::eof()` to check the is parse to the end of line
void read_binary_record(istream &arg_is);
// friend class
friend class Geometry_Comp;
};
class Geometry_Comp
{
protected:
// data members
vector<Complex> m_comp_array;
// utility function to check if the transformation is valid
// hint: use `isnan` to check the angle is valid or not
// ref: https://en.cppreference.com/w/cpp/numeric/math/isnan
bool _check_transform(const Complex &arg_trans_c, const char &arg_op);
public:
// Constructor, initializes the array
Geometry_Comp(const unsigned int &arg_num_of_vertex = 0);
// Copy constructor
Geometry_Comp(const Geometry_Comp &arg_gc);
// assignment operator
Geometry_Comp &operator=(const Geometry_Comp &arg_gc);
// print the geometry
virtual void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
virtual void parse_geometry(ifstream &arg_ifs);
// apply transformation to the geometry
void transform_geometry(const Complex &arg_trans_c, const char &arg_op);
// set the geometry
void set_geometry(const vector<Complex> &arg_comp_array);
// get the geometry array
vector<Complex> get_geometry_array();
};
class Triangle_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Triangle_Comp();
// Copy constructor
Triangle_Comp(const Triangle_Comp &arg_tc);
// assignment operator
Triangle_Comp &operator=(const Triangle_Comp &arg_tc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned triangle_num_of_vertex = 3;
class Quadrilateral_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Quadrilateral_Comp();
// Copy constructor
Quadrilateral_Comp(const Quadrilateral_Comp &arg_qc);
// assignment operator
Quadrilateral_Comp &operator=(const Quadrilateral_Comp &arg_qc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned quadrilateral_num_of_vertex = 4;
class Polygon_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Polygon_Comp();
// Copy constructor
Polygon_Comp(const Polygon_Comp &arg_pc);
// assignment operator
Polygon_Comp &operator=(const Polygon_Comp &arg_pc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
class Circle_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Circle_Comp();
// Copy constructor
Circle_Comp(const Circle_Comp &arg_cc);
// assignment operator
Circle_Comp &operator=(const Circle_Comp &arg_cc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned circle_num_of_vertex = 2;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
// Ref: https://stackoverflow.com/q/9621893
void print_output_file(int argc, char *argv[])
{
ifstream ans_ifs(argv[2], ios::in | ios::binary);
if (!ans_ifs)
{
cout << "Error: Cannot open output file" << endl;
exit(1);
}
char ans_block = 0;
unsigned offset_count = 0;
ans_ifs.read(&ans_block, 1);
while (!ans_ifs.eof())
{
int z = ans_block & 0xff;
cout << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
cout << endl;
}
ans_ifs.read(&ans_block, 1);
}
cout << endl;
ans_ifs.close();
}
int main(int argc, char *argv[])
{
char input;
vector<Geometry_Comp *> geo_ptr_array;
Geometry_Comp *geo_ptr;
Complex trans_c;
char trans_op;
string input_file_path(argv[1]);
string output_file_path(argv[2]);
// open & check input file
// open & check output file
while (infile.get(input))
{
// check the geometry type
switch (input)
{
case 't':
geo_ptr = new Triangle_Comp();
break;
case 'q':
geo_ptr = new Quadrilateral_Comp();
break;
case 'p':
geo_ptr = new Polygon_Comp();
break;
case 'c':
geo_ptr = new Circle_Comp();
break;
case 'r':
case 'z':
case 'm':
break;
default:
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
error_and_exit();
}
if (input == 't' || input == 'q' || input == 'p' || input == 'c')
{
// parse the cin to the geometry
geo_ptr->parse_geometry(infile);
// print the geometry
geo_ptr->print_geometry(outfile);
// push the pointer to the array
geo_ptr_array.push_back(geo_ptr);
}
else if (input == 'r' || input == 'z' || input == 'm')
{
trans_c.read_binary_record(infile);
// transform the geometry using operator and complex
for (int i = 0; i < geo_ptr_array.size(); i++)
{
geo_ptr_array[i]->transform_geometry(trans_c, input);
// print transformed geometry
geo_ptr_array[i]->print_geometry(outfile);
}
}
else
{
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
error_and_exit();
}
}
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
// close input and output file
print_output_file(argc, argv);
return 0;
}
Reference Code:
TA
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <vector>
using namespace std;
class Geometry_Comp;
class Complex
{
private:
// data members
// save the real and imaginary parts of the complex number
// with `double` precision
double m_real;
double m_imag;
public:
// Constructor, initializes real and imaginary parts
Complex(const double &arg_real = 0.0, const double &arg_imag = 0.0);
// Copy constructor
Complex(const Complex &arg_c);
// assignment operator
Complex &operator=(const Complex &arg_c);
// add assignment operator
Complex &operator+=(const Complex &arg_c);
// multiply assignment operator
Complex &operator*=(const Complex &arg_c);
// length of the complex number
double length() const;
// angle of the complex number in radians
// use `atan2` to compute the angle by the formula `atan(imag/real)`
// and use `NAN` for 0/0 case
// `atan2` ref: https://en.cppreference.com/w/cpp/numeric/math/atan2
// `NAN` ref: https://en.cppreference.com/w/cpp/numeric/math/NAN
double angle() const;
// write data members in binary format
// note: be careful about the type used in `.write()` function
void write_binary_record(ostream &arg_os);
// read data members in binary format
// note: use `.read()` to get the double in binary format,
// use `istream::fail()` to check the conversion is successful
// and use `istream::eof()` to check the is parse to the end of line
void read_binary_record(istream &arg_is);
// friend class
friend class Geometry_Comp;
};
class Geometry_Comp
{
protected:
// data members
vector<Complex> m_comp_array;
// utility function to check if the transformation is valid
// hint: use `isnan` to check the angle is valid or not
// ref: https://en.cppreference.com/w/cpp/numeric/math/isnan
bool _check_transform(const Complex &arg_trans_c, const char &arg_op);
public:
// Constructor, initializes the array
Geometry_Comp(const unsigned int &arg_num_of_vertex = 0);
// Copy constructor
Geometry_Comp(const Geometry_Comp &arg_gc);
// assignment operator
Geometry_Comp &operator=(const Geometry_Comp &arg_gc);
// print the geometry
virtual void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
virtual void parse_geometry(ifstream &arg_ifs);
// apply transformation to the geometry
void transform_geometry(const Complex &arg_trans_c, const char &arg_op);
// set the geometry
void set_geometry(const vector<Complex> &arg_comp_array);
// get the geometry array
vector<Complex> get_geometry_array();
};
class Triangle_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Triangle_Comp();
// Copy constructor
Triangle_Comp(const Triangle_Comp &arg_tc);
// assignment operator
Triangle_Comp &operator=(const Triangle_Comp &arg_tc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned triangle_num_of_vertex = 3;
class Quadrilateral_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Quadrilateral_Comp();
// Copy constructor
Quadrilateral_Comp(const Quadrilateral_Comp &arg_qc);
// assignment operator
Quadrilateral_Comp &operator=(const Quadrilateral_Comp &arg_qc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned quadrilateral_num_of_vertex = 4;
class Polygon_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Polygon_Comp();
// Copy constructor
Polygon_Comp(const Polygon_Comp &arg_pc);
// assignment operator
Polygon_Comp &operator=(const Polygon_Comp &arg_pc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
class Circle_Comp : public Geometry_Comp
{
public:
// Constructor, initializes the array
Circle_Comp();
// Copy constructor
Circle_Comp(const Circle_Comp &arg_cc);
// assignment operator
Circle_Comp &operator=(const Circle_Comp &arg_cc);
// print the geometry
void print_geometry(ofstream &arg_ofs);
// parse the cin to the geometry
void parse_geometry(ifstream &arg_ifs);
};
const unsigned circle_num_of_vertex = 2;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
// Ref: https://stackoverflow.com/q/9621893
void print_output_file(int argc, char *argv[])
{
ifstream ans_ifs(argv[2], ios::in | ios::binary);
if (!ans_ifs)
{
cout << "Error: Cannot open output file" << endl;
exit(1);
}
char ans_block = 0;
unsigned offset_count = 0;
ans_ifs.read(&ans_block, 1);
while (!ans_ifs.eof())
{
int z = ans_block & 0xff;
cout << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
cout << endl;
}
ans_ifs.read(&ans_block, 1);
}
cout << endl;
ans_ifs.close();
}
// Complex class implementation
// Constructor, initializes real and imaginary parts
// hint: as like as `modify` function in examples
// but use default constructor to implement
Complex::Complex(const double &arg_real, const double &arg_imag)
: m_real(arg_real), m_imag(arg_imag)
{
}
// Copy constructor
Complex::Complex(const Complex &arg_c)
: m_real(arg_c.m_real), m_imag(arg_c.m_imag)
{
}
// assignment operator
Complex &Complex::operator=(const Complex &arg_c)
{
if (this == &arg_c) // self-assignment
return *this;
m_real = arg_c.m_real;
m_imag = arg_c.m_imag;
return *this;
}
// add assignment operator
Complex &Complex::operator+=(const Complex &arg_c)
{
m_real += arg_c.m_real;
m_imag += arg_c.m_imag;
return *this;
}
// multiply assignment operator
Complex &Complex::operator*=(const Complex &arg_c)
{
double real = m_real * arg_c.m_real - m_imag * arg_c.m_imag;
double imag = m_real * arg_c.m_imag + m_imag * arg_c.m_real;
m_real = real;
m_imag = imag;
return *this;
}
// length of the complex number
double Complex::length() const
{
return sqrt(m_real * m_real + m_imag * m_imag);
}
// angle of the complex number in radians
double Complex::angle() const
{
if (m_real == 0 && m_imag == 0)
{
return NAN;
}
return atan2(m_imag, m_real);
}
// write data members in binary format
// note: be careful about the type used in `.write()` function
void Complex::write_binary_record(ostream &arg_os)
{
arg_os.write((char *)&m_real, sizeof(double));
arg_os.write((char *)&m_imag, sizeof(double));
}
// read data members in binary format
// note: use `.read()` to get the double in binary format,
// use `istream::fail()` to check the conversion is successful
// and use `istream::eof()` to check the is parse to the end of line
void Complex::read_binary_record(istream &arg_is)
{
double input_real, input_imag;
arg_is.read((char *)&input_real, sizeof(double));
if (arg_is.fail())
{
error_and_exit();
}
arg_is.read((char *)&input_imag, sizeof(double));
if (arg_is.fail())
{
error_and_exit();
}
m_real = input_real;
m_imag = input_imag;
}
// Geometry_Comp class implementation
// check if the transformation is valid
bool Geometry_Comp::_check_transform(const Complex &arg_c, const char &arg_op)
{
// check if the operation is valid
if (arg_op == 'r' && (arg_c.length() != 1 || isnan(arg_c.angle())))
{
return false;
}
else if (arg_op == 'z' && (arg_c.m_real == 0 || arg_c.m_imag != 0))
{
return false;
}
else
{
return true;
}
}
// Constructor, initializes the array
Geometry_Comp::Geometry_Comp(const unsigned int &arg_num_of_vertex)
: m_comp_array(arg_num_of_vertex)
{
}
// Copy constructor
Geometry_Comp::Geometry_Comp(const Geometry_Comp &arg_gc)
: m_comp_array(arg_gc.m_comp_array)
{
}
// assignment operator
Geometry_Comp &Geometry_Comp::operator=(const Geometry_Comp &arg_gc)
{
if (this == &arg_gc) // self-assignment
return *this;
m_comp_array = arg_gc.m_comp_array;
return *this;
}
// print the geometry
void Geometry_Comp::print_geometry(ofstream &arg_ofs)
{
cout << "not implemented" << endl;
}
// parse the cin to the geometry
void Geometry_Comp::parse_geometry(ifstream &arg_ifs)
{
cout << "not implemented" << endl;
}
// apply transformation to the geometry
void Geometry_Comp::transform_geometry(const Complex &arg_c, const char &arg_op)
{
if (!(_check_transform(arg_c, arg_op)))
{
error_and_exit();
}
if (arg_op == 'm')
{
for (unsigned int i = 0; i < m_comp_array.size(); i++)
{
m_comp_array[i] += arg_c;
}
}
else if (arg_op == 'r' || arg_op == 'z')
{
for (unsigned int i = 0; i < m_comp_array.size(); i++)
{
m_comp_array[i] *= arg_c;
}
}
}
// set the geometry
void Geometry_Comp::set_geometry(const vector<Complex> &arg_comp_array)
{
m_comp_array = arg_comp_array;
}
// get the geometry array
vector<Complex> Geometry_Comp::get_geometry_array()
{
return m_comp_array;
}
// Triangle_Comp class implementation
// Constructor, initializes the array
Triangle_Comp::Triangle_Comp()
: Geometry_Comp(triangle_num_of_vertex)
{
}
// Copy constructor
Triangle_Comp::Triangle_Comp(const Triangle_Comp &arg_tc)
: Geometry_Comp(arg_tc)
{
}
// assignment operator
Triangle_Comp &Triangle_Comp::operator=(const Triangle_Comp &arg_tc)
{
if (this == &arg_tc) // self-assignment
return *this;
Geometry_Comp::operator=(arg_tc);
return *this;
}
// print the geometry
void Triangle_Comp::print_geometry(ofstream &arg_ofs)
{
unsigned int num_of_vertex = m_comp_array.size();
arg_ofs.write("t", 1);
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (unsigned int i = 0; i < num_of_vertex; i++)
{
m_comp_array[i].write_binary_record(arg_ofs);
}
}
// parse the cin to the geometry
void Triangle_Comp::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num != triangle_num_of_vertex)
{
error_and_exit();
}
for (int i = 0; i < vertex_num; i++)
{
Complex c;
c.read_binary_record(arg_ifs);
if (arg_ifs.fail())
{
error_and_exit();
}
m_comp_array[i] = c;
}
}
// Quadrilateral_Comp class implementation
// Constructor, initializes the array
Quadrilateral_Comp::Quadrilateral_Comp()
: Geometry_Comp(quadrilateral_num_of_vertex)
{
}
// Copy constructor
Quadrilateral_Comp::Quadrilateral_Comp(const Quadrilateral_Comp &arg_qc)
: Geometry_Comp(arg_qc)
{
}
// assignment operator
Quadrilateral_Comp &Quadrilateral_Comp::operator=(const Quadrilateral_Comp &arg_qc)
{
if (this == &arg_qc) // self-assignment
return *this;
Geometry_Comp::operator=(arg_qc);
return *this;
}
// print the geometry
void Quadrilateral_Comp::print_geometry(ofstream &arg_ofs)
{
arg_ofs.write("q", 1);
unsigned int num_of_vertex = m_comp_array.size();
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < quadrilateral_num_of_vertex; i++)
{
m_comp_array[i].write_binary_record(arg_ofs);
}
}
// parse the cin to the geometry
void Quadrilateral_Comp::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num != quadrilateral_num_of_vertex)
{
error_and_exit();
}
for (int i = 0; i < vertex_num; i++)
{
Complex c;
c.read_binary_record(arg_ifs);
if (arg_ifs.fail())
{
error_and_exit();
}
m_comp_array[i] = c;
}
}
// Polygon_Comp class implementation
// Constructor, initializes the array
Polygon_Comp::Polygon_Comp()
: Geometry_Comp()
{
}
// Copy constructor
Polygon_Comp::Polygon_Comp(const Polygon_Comp &arg_pc)
: Geometry_Comp(arg_pc)
{
}
// assignment operator
Polygon_Comp &Polygon_Comp::operator=(const Polygon_Comp &arg_pc)
{
if (this == &arg_pc) // self-assignment
return *this;
Geometry_Comp::operator=(arg_pc);
return *this;
}
// print the geometry
void Polygon_Comp::print_geometry(ofstream &arg_ofs)
{
arg_ofs.write("p", 1);
unsigned int num_of_vertex = m_comp_array.size();
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < m_comp_array.size(); i++)
{
m_comp_array[i].write_binary_record(arg_ofs);
}
}
// parse the cin to the geometry
void Polygon_Comp::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num < triangle_num_of_vertex)
{
error_and_exit();
}
m_comp_array.resize(vertex_num);
for (int i = 0; i < vertex_num; i++)
{
Complex c;
c.read_binary_record(arg_ifs);
if (arg_ifs.fail())
{
error_and_exit();
}
m_comp_array[i] = c;
}
}
// Circle_Comp class implementation
// Constructor, initializes the array
Circle_Comp::Circle_Comp()
: Geometry_Comp(circle_num_of_vertex)
{
}
// Copy constructor
Circle_Comp::Circle_Comp(const Circle_Comp &arg_cc)
: Geometry_Comp(arg_cc)
{
}
// assignment operator
Circle_Comp &Circle_Comp::operator=(const Circle_Comp &arg_cc)
{
if (this == &arg_cc) // self-assignment
return *this;
Geometry_Comp::operator=(arg_cc);
return *this;
}
// print the geometry
void Circle_Comp::print_geometry(ofstream &arg_ofs)
{
arg_ofs.write("c", 1);
unsigned int num_of_vertex = m_comp_array.size();
arg_ofs.write((char *)&num_of_vertex, sizeof(unsigned int));
for (int i = 0; i < circle_num_of_vertex; i++)
{
m_comp_array[i].write_binary_record(arg_ofs);
}
}
// parse the cin to the geometry
void Circle_Comp::parse_geometry(ifstream &arg_ifs)
{
unsigned int vertex_num;
arg_ifs.read((char *)&vertex_num, sizeof(unsigned int));
if (vertex_num != circle_num_of_vertex)
{
error_and_exit();
}
for (int i = 0; i < vertex_num; i++)
{
Complex c;
c.read_binary_record(arg_ifs);
if (arg_ifs.fail())
{
error_and_exit();
}
m_comp_array[i] = c;
}
}
int main(int argc, char *argv[])
{
char input;
vector<Geometry_Comp *> geo_ptr_array;
Geometry_Comp *geo_ptr;
Complex trans_c;
char trans_op;
string input_file_path(argv[1]);
string output_file_path(argv[2]);
ifstream infile(input_file_path, ios::in | ios::binary);
if (!infile)
{
cout << "Input file cannot open." << endl;
return -1;
}
ofstream outfile(output_file_path, ios::out | ios::trunc | ios::binary);
if (!outfile)
{
cout << "Output file cannot open." << endl;
return -1;
}
while (infile.get(input))
{
// check the geometry type
switch (input)
{
case 't':
geo_ptr = new Triangle_Comp();
break;
case 'q':
geo_ptr = new Quadrilateral_Comp();
break;
case 'p':
geo_ptr = new Polygon_Comp();
break;
case 'c':
geo_ptr = new Circle_Comp();
break;
case 'r':
case 'z':
case 'm':
break;
default:
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
error_and_exit();
}
if (input == 't' || input == 'q' || input == 'p' || input == 'c')
{
// parse the cin to the geometry
geo_ptr->parse_geometry(infile);
// print the geometry
geo_ptr->print_geometry(outfile);
// push the pointer to the array
geo_ptr_array.push_back(geo_ptr);
}
else if (input == 'r' || input == 'z' || input == 'm')
{
trans_c.read_binary_record(infile);
// transform the geometry using operator and complex
for (int i = 0; i < geo_ptr_array.size(); i++)
{
geo_ptr_array[i]->transform_geometry(trans_c, input);
// print transformed geometry
geo_ptr_array[i]->print_geometry(outfile);
}
}
else
{
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
error_and_exit();
}
}
for (int i = 0; i < geo_ptr_array.size(); i++)
{
delete geo_ptr_array[i];
}
infile.close();
outfile.close();
print_output_file(argc, argv);
return 0;
}
Convert Text Version Input to Binary Version Input
/*** convert text version input to binary version input ***/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "Usage: txt_to_bin <input_file> <output_file>" << endl;
return 1;
}
ifstream input_file(argv[1]);
ofstream output_file(argv[2], ios::binary | ios::trunc);
if (!input_file.is_open())
{
cout << "Could not open input file" << endl;
return 1;
}
if (!output_file.is_open())
{
cout << "Could not open output file" << endl;
return 1;
}
string line, temp;
unsigned num_of_vertices = 1;
while (getline(input_file, line))
{
// check the geometry type
switch (line[0])
{
case 't':
case 'q':
case 'p':
case 'c':
// get the number of vertices from the next line
getline(input_file, temp);
num_of_vertices = stoul(temp);
break;
case 'r':
case 'z':
case 'm':
num_of_vertices = 1;
break;
default:
error_and_exit();
}
// write the geometry type
char geometry_type = line[0];
output_file.write(&geometry_type, 1);
// write the number of vertices
if (line[0] == 't' || line[0] == 'q' || line[0] == 'p' || line[0] == 'c')
{
output_file.write((char *)&num_of_vertices, sizeof(unsigned));
}
// convert the lines to binary
for (int i = 0; i < num_of_vertices; i++)
{
getline(input_file, line);
stringstream ss(line);
double real, imag;
ss >> real >> imag;
output_file.write((char *)&real, sizeof(double));
output_file.write((char *)&imag, sizeof(double));
}
}
input_file.close();
output_file.close();
return 0;
}
Convert Binary Version Input/Output to Human-readable Input/Output & Dump HEX File
/*** convert binary version input/output to
* human-readable input/output & dump hex file ***/
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
// error and exit
void error_and_exit()
{
cout << "Error: Invalid input" << endl;
exit(1);
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
cout << "Usage: bin_to_txt <input_file> <output_file>" << endl;
return 1;
}
ifstream input_file(argv[1], ios::binary);
ofstream output_file(argv[2], ios::trunc);
if (!input_file.is_open())
{
cout << "Could not open input file" << endl;
return 1;
}
if (!output_file.is_open())
{
cout << "Could not open output file" << endl;
return 1;
}
char input;
unsigned num_of_vertices = 1;
while (input_file.get(input))
{
// check the geometry type
switch (input)
{
case 't':
case 'q':
case 'p':
case 'c':
// get the number of vertices from the next line
input_file.read((char *)&num_of_vertices, sizeof(unsigned));
break;
case 'r':
case 'z':
case 'm':
num_of_vertices = 1;
break;
default:
error_and_exit();
}
// write the geometry type
char geometry_type = input;
output_file << "# " << geometry_type << endl;
// write the number of vertices
if (geometry_type == 't' || geometry_type == 'q'
|| geometry_type == 'p' || geometry_type == 'c')
{
output_file << "# " << num_of_vertices << endl;
}
// convert the lines to binary
for (int i = 0; i < num_of_vertices; i++)
{
double real, imag;
input_file.read((char *)&real, sizeof(double));
input_file.read((char *)&imag, sizeof(double));
output_file << "# " << setprecision(15) << fixed
<< real << " " << imag << endl;
}
}
input_file.close();
input_file.open(argv[1], ios::binary);
output_file << "# Hex dump" << endl;
char file_block = 0;
unsigned offset_count = 0;
input_file.read(&file_block, 1);
while (!input_file.eof())
{
int z = file_block & 0xff;
output_file << std::hex
<< std::setfill('0')
<< std::setw(2)
<< z
<< " ";
offset_count++;
if (offset_count % 16 == 0)
{
output_file << endl;
}
input_file.read(&file_block, 1);
}
output_file << endl;
output_file.close();
return 0;
}