Lab 14-2: Simple Complex Number Geometry Transformation (Binary File ver.) (25%)

  • 輸入:
    1. 從檔案中讀取多個幾何形狀或幾何變換的複數資料。
      1. 請使用 int main(int argc, char *argv[]) 來開啟指定檔案 (Ref: One and the only: main function
      2. 開啟檔案名稱會放在 argv[1] 中。
    2. 幾何圖形
    3. char 格式讀取幾何圖形形狀,包含三角形 (t)、四邊形 (q)、多邊形 (p)、圓形 (c),sizeof(char) byte 讀取一個幾何圖形
    4. unsinged int 格式讀取幾何圖形的頂點數, sizeof(unsigned) byte 讀取一個正整數
      1. 三角形:3
      2. 四邊形:4
      3. 多邊形:大於 3 的正整數
      4. 圓形:2
    5. double 格式讀取組合幾何圖形的複數的實數及虛數部分,sizeof(double) byte 讀取一個實數或虛數部分
    6. 讀取幾何圖形形狀及頂點數後依據 2. 的頂點數接著讀取相對應的複數
      1. 三角形:連續讀取三個複數
      2. 四邊形:連續讀取四個複數
      3. 多邊形:連續讀取多個複數
      4. 圓形:連續讀取兩個複數
    7. 幾何變換
    8. char 格式讀取幾何變換字元,包含以 0 點旋轉 (r)、以 0 點縮放 (z)、平移 (m),sizeof(char) byte 讀取一個幾何變換
    9. double 格式讀取幾何變換的複數的實數及虛數部分,sizeof(double) byte 讀取一個實數或虛數部分
      1. 0 點旋轉:\(z * (cos(\theta) + sin(\theta)i), norm = 1\)
      2. 0 點縮放:\(z * (r + 0i)\)
      3. 平移:\(z + (x + yi)\)
    10. 讀取幾何變換後須將所有的幾何圖形複數變換
  • 輸出:
    1. 將結果的幾何形狀及幾何變換的複數資料輸出至指令列及檔案中。
      1. 請使用 int main(int argc, char *argv[]) 來開啟指定檔案 (Ref: One and the only: main function
      2. 開啟檔案名稱會放在 argv[2] 中。
    2. 幾何圖形
      1. 顯示紀錄幾何圖形的形狀、頂點個數及其複數
        1. 格式請參考 Format 中的說明
        2. 頂點順序與讀取順序相同
      2. 複數的格式為 <real part in binary><imaginary part in binary>
    3. 幾何變換
      1. 輸出變換後的所有幾何圖形複數
  • 檔名:lab14-2_<學號>.cpp (e.g. lab14-2_106062802.cpp)

注意事項:

  • 程式不會輸出任何使用者提示,只會輸出程式結果
  • 使用者不需要處理錯誤輸入
  • 請基於 pseudo code 提供的 mainprint_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;
}