Difference between revisions of "Focal length equivalents between formats"

From Aram's Wiki
Jump to: navigation, search
(Code)
(Focal lens equivalents)
Line 15: Line 15:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 25: Line 26:
 
|14
 
|14
 
|17
 
|17
 +
|21
 
|48
 
|48
 
|36
 
|36
Line 35: Line 37:
 
|20
 
|20
 
|24
 
|24
 +
|30
 
|67
 
|67
 
|50
 
|50
Line 45: Line 48:
 
|23
 
|23
 
|28
 
|28
 +
|34
 
|77
 
|77
 
|57
 
|57
Line 55: Line 59:
 
|26
 
|26
 
|31
 
|31
 +
|39
 
|87
 
|87
 
|65
 
|65
Line 65: Line 70:
 
|50
 
|50
 
|61
 
|61
 +
|75
 
|169
 
|169
 
|126
 
|126
Line 75: Line 81:
 
|72
 
|72
 
|87
 
|87
 +
|107
 
|241
 
|241
 
|180
 
|180
Line 85: Line 92:
 
|79
 
|79
 
|96
 
|96
 +
|118
 
|265
 
|265
 
|198
 
|198
Line 95: Line 103:
 
|80
 
|80
 
|98
 
|98
 +
|120
 
|270
 
|270
 
|201
 
|201
Line 105: Line 114:
 
|86
 
|86
 
|105
 
|105
 +
|128
 
|289
 
|289
 
|216
 
|216
Line 115: Line 125:
 
|115
 
|115
 
|140
 
|140
 +
|171
 
|386
 
|386
 
|287
 
|287
Line 125: Line 136:
 
|129
 
|129
 
|157
 
|157
 +
|193
 
|434
 
|434
 
|323
 
|323
Line 135: Line 147:
 
|287
 
|287
 
|349
 
|349
 +
|428
 
|964
 
|964
 
|719
 
|719
Line 149: Line 162:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 159: Line 173:
 
|14
 
|14
 
|17
 
|17
 +
|21
 
|47
 
|47
 
|35
 
|35
Line 169: Line 184:
 
|16
 
|16
 
|19
 
|19
 +
|24
 
|54
 
|54
 
|40
 
|40
Line 179: Line 195:
 
|17
 
|17
 
|21
 
|21
 +
|25
 
|57
 
|57
 
|42
 
|42
Line 189: Line 206:
 
|19
 
|19
 
|23
 
|23
 +
|28
 
|64
 
|64
 
|48
 
|48
Line 199: Line 217:
 
|20
 
|20
 
|24
 
|24
 +
|30
 
|67
 
|67
 
|50
 
|50
Line 209: Line 228:
 
|24
 
|24
 
|29
 
|29
 +
|36
 
|81
 
|81
 
|60
 
|60
Line 219: Line 239:
 
|28
 
|28
 
|34
 
|34
 +
|42
 
|94
 
|94
 
|70
 
|70
Line 229: Line 250:
 
|35
 
|35
 
|43
 
|43
 +
|52
 
|118
 
|118
 
|88
 
|88
Line 239: Line 261:
 
|45
 
|45
 
|55
 
|55
 +
|67
 
|151
 
|151
 
|112
 
|112
Line 249: Line 272:
 
|50
 
|50
 
|61
 
|61
 +
|75
 
|168
 
|168
 
|125
 
|125
Line 259: Line 283:
 
|85
 
|85
 
|103
 
|103
 +
|127
 
|286
 
|286
 
|212
 
|212
Line 269: Line 294:
 
|105
 
|105
 
|128
 
|128
 +
|157
 
|353
 
|353
 
|262
 
|262
Line 279: Line 305:
 
|120
 
|120
 
|146
 
|146
 +
|179
 
|403
 
|403
 
|300
 
|300
Line 289: Line 316:
 
|200
 
|200
 
|243
 
|243
 +
|298
 
|672
 
|672
 
|500
 
|500
Line 303: Line 331:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 313: Line 342:
 
|17
 
|17
 
|23
 
|23
 +
|28
 
|64
 
|64
 
|42
 
|42
Line 323: Line 353:
 
|23
 
|23
 
|32
 
|32
 +
|39
 
|88
 
|88
 
|59
 
|59
Line 333: Line 364:
 
|33
 
|33
 
|45
 
|45
 +
|55
 
|124
 
|124
 
|82
 
|82
Line 343: Line 375:
 
|37
 
|37
 
|50
 
|50
 +
|61
 
|138
 
|138
 
|91
 
|91
Line 353: Line 386:
 
|46
 
|46
 
|63
 
|63
 +
|77
 
|174
 
|174
 
|115
 
|115
Line 363: Line 397:
 
|73
 
|73
 
|100
 
|100
 +
|123
 
|276
 
|276
 
|183
 
|183
Line 373: Line 408:
 
|80
 
|80
 
|110
 
|110
 +
|135
 
|304
 
|304
 
|201
 
|201
Line 383: Line 419:
 
|146
 
|146
 
|200
 
|200
 +
|245
 
|553
 
|553
 
|366
 
|366
Line 393: Line 430:
 
|183
 
|183
 
|250
 
|250
 +
|306
 
|691
 
|691
 
|457
 
|457
Line 403: Line 441:
 
|18
 
|18
 
|24
 
|24
 +
|29
 
|66
 
|66
 
|44
 
|44
Line 413: Line 452:
 
|20
 
|20
 
|28
 
|28
 +
|34
 
|77
 
|77
 
|51
 
|51
Line 423: Line 463:
 
|26
 
|26
 
|35
 
|35
 +
|43
 
|97
 
|97
 
|64
 
|64
Line 433: Line 474:
 
|37
 
|37
 
|50
 
|50
 +
|61
 
|138
 
|138
 
|91
 
|91
Line 443: Line 485:
 
|59
 
|59
 
|80
 
|80
 +
|98
 
|221
 
|221
 
|146
 
|146
Line 453: Line 496:
 
|66
 
|66
 
|90
 
|90
 +
|110
 
|249
 
|249
 
|165
 
|165
Line 463: Line 507:
 
|80
 
|80
 
|110
 
|110
 +
|135
 
|304
 
|304
 
|201
 
|201
Line 473: Line 518:
 
|110
 
|110
 
|150
 
|150
 +
|184
 
|414
 
|414
 
|274
 
|274
Line 483: Line 529:
 
|154
 
|154
 
|210
 
|210
 +
|257
 
|580
 
|580
 
|384
 
|384
Line 493: Line 540:
 
|220
 
|220
 
|300
 
|300
 +
|368
 
|829
 
|829
 
|549
 
|549
Line 503: Line 551:
 
|26
 
|26
 
|36
 
|36
 +
|44
 
|99
 
|99
 
|66
 
|66
Line 513: Line 562:
 
|31
 
|31
 
|42
 
|42
 +
|51
 
|116
 
|116
 
|77
 
|77
Line 523: Line 573:
 
|38
 
|38
 
|52
 
|52
 +
|64
 
|145
 
|145
 
|96
 
|96
Line 533: Line 584:
 
|55
 
|55
 
|75
 
|75
 +
|92
 
|207
 
|207
 
|137
 
|137
Line 543: Line 595:
 
|88
 
|88
 
|120
 
|120
 +
|147
 
|332
 
|332
 
|220
 
|220
Line 553: Line 606:
 
|99
 
|99
 
|135
 
|135
 +
|165
 
|373
 
|373
 
|247
 
|247
Line 563: Line 617:
 
|121
 
|121
 
|165
 
|165
 +
|202
 
|456
 
|456
 
|302
 
|302
Line 573: Line 628:
 
|165
 
|165
 
|225
 
|225
 +
|276
 
|622
 
|622
 
|412
 
|412
Line 583: Line 639:
 
|230
 
|230
 
|315
 
|315
 +
|386
 
|870
 
|870
 
|576
 
|576
Line 593: Line 650:
 
|329
 
|329
 
|450
 
|450
 +
|552
 
|1243
 
|1243
 
|823
 
|823
Line 607: Line 665:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 617: Line 676:
 
|18
 
|18
 
|25
 
|25
 +
|31
 
|69
 
|69
 
|46
 
|46
Line 627: Line 687:
 
|20
 
|20
 
|28
 
|28
 +
|34
 
|77
 
|77
 
|51
 
|51
Line 637: Line 698:
 
|24
 
|24
 
|33
 
|33
 +
|40
 
|91
 
|91
 
|60
 
|60
Line 647: Line 709:
 
|33
 
|33
 
|45
 
|45
 +
|55
 
|124
 
|124
 
|82
 
|82
Line 657: Line 720:
 
|40
 
|40
 
|55
 
|55
 +
|67
 
|152
 
|152
 
|101
 
|101
Line 667: Line 731:
 
|59
 
|59
 
|80
 
|80
 +
|98
 
|221
 
|221
 
|146
 
|146
Line 677: Line 742:
 
|62
 
|62
 
|85
 
|85
 +
|104
 
|235
 
|235
 
|155
 
|155
Line 687: Line 753:
 
|80
 
|80
 
|110
 
|110
 +
|135
 
|304
 
|304
 
|201
 
|201
Line 697: Line 764:
 
|110
 
|110
 
|150
 
|150
 +
|184
 
|414
 
|414
 
|274
 
|274
Line 707: Line 775:
 
|117
 
|117
 
|160
 
|160
 +
|196
 
|442
 
|442
 
|293
 
|293
Line 717: Line 786:
 
|220
 
|220
 
|300
 
|300
 +
|368
 
|829
 
|829
 
|549
 
|549
Line 731: Line 801:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 741: Line 812:
 
|14
 
|14
 
|20
 
|20
 +
|24
 
|54
 
|54
 
|36
 
|36
Line 751: Line 823:
 
|17
 
|17
 
|23
 
|23
 +
|28
 
|63
 
|63
 
|42
 
|42
Line 761: Line 834:
 
|21
 
|21
 
|29
 
|29
 +
|35
 
|79
 
|79
 
|52
 
|52
Line 771: Line 845:
 
|30
 
|30
 
|41
 
|41
 +
|50
 
|113
 
|113
 
|75
 
|75
Line 781: Line 856:
 
|48
 
|48
 
|65
 
|65
 +
|80
 
|180
 
|180
 
|119
 
|119
Line 791: Line 867:
 
|54
 
|54
 
|73
 
|73
 +
|90
 
|203
 
|203
 
|134
 
|134
Line 801: Line 878:
 
|66
 
|66
 
|90
 
|90
 +
|110
 
|248
 
|248
 
|164
 
|164
Line 811: Line 889:
 
|90
 
|90
 
|122
 
|122
 +
|150
 
|338
 
|338
 
|224
 
|224
Line 821: Line 900:
 
|125
 
|125
 
|171
 
|171
 +
|210
 
|473
 
|473
 
|313
 
|313
Line 831: Line 911:
 
|179
 
|179
 
|245
 
|245
 +
|300
 
|676
 
|676
 
|448
 
|448
Line 841: Line 922:
 
|21
 
|21
 
|29
 
|29
 +
|36
 
|81
 
|81
 
|54
 
|54
Line 851: Line 933:
 
|25
 
|25
 
|34
 
|34
 +
|42
 
|95
 
|95
 
|63
 
|63
Line 861: Line 944:
 
|31
 
|31
 
|43
 
|43
 +
|52
 
|118
 
|118
 
|78
 
|78
Line 871: Line 955:
 
|45
 
|45
 
|61
 
|61
 +
|75
 
|169
 
|169
 
|112
 
|112
Line 881: Line 966:
 
|72
 
|72
 
|98
 
|98
 +
|120
 
|270
 
|270
 
|179
 
|179
Line 891: Line 977:
 
|81
 
|81
 
|110
 
|110
 +
|135
 
|304
 
|304
 
|201
 
|201
Line 901: Line 988:
 
|99
 
|99
 
|135
 
|135
 +
|165
 
|372
 
|372
 
|246
 
|246
Line 911: Line 999:
 
|134
 
|134
 
|184
 
|184
 +
|225
 
|507
 
|507
 
|336
 
|336
Line 921: Line 1,010:
 
|188
 
|188
 
|257
 
|257
 +
|315
 
|710
 
|710
 
|470
 
|470
Line 931: Line 1,021:
 
|269
 
|269
 
|367
 
|367
 +
|450
 
|1014
 
|1014
 
|672
 
|672
Line 945: Line 1,036:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 955: Line 1,047:
 
|18
 
|18
 
|24
 
|24
 +
|30
 
|72
 
|72
 
|45
 
|45
Line 965: Line 1,058:
 
|22
 
|22
 
|30
 
|30
 +
|37
 
|90
 
|90
 
|56
 
|56
Line 975: Line 1,069:
 
|37
 
|37
 
|51
 
|51
 +
|62
 
|150
 
|150
 
|93
 
|93
Line 985: Line 1,080:
 
|59
 
|59
 
|81
 
|81
 +
|99
 
|240
 
|240
 
|148
 
|148
Line 995: Line 1,091:
 
|74
 
|74
 
|101
 
|101
 +
|124
 
|300
 
|300
 
|186
 
|186
Line 1,009: Line 1,106:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 1,019: Line 1,117:
 
|15
 
|15
 
|19
 
|19
 +
|23
 
|51
 
|51
 
|72
 
|72
Line 1,029: Line 1,128:
 
|19
 
|19
 
|23
 
|23
 +
|28
 
|64
 
|64
 
|90
 
|90
Line 1,039: Line 1,139:
 
|32
 
|32
 
|39
 
|39
 +
|47
 
|107
 
|107
 
|150
 
|150
Line 1,049: Line 1,150:
 
|51
 
|51
 
|62
 
|62
 +
|76
 
|171
 
|171
 
|240
 
|240
Line 1,059: Line 1,161:
 
|64
 
|64
 
|77
 
|77
 +
|95
 
|214
 
|214
 
|300
 
|300
Line 1,073: Line 1,176:
 
|35mm
 
|35mm
 
|GFX
 
|GFX
 +
|H5D
 
|4x5
 
|4x5
 
|6x17
 
|6x17
Line 1,083: Line 1,187:
 
|18
 
|18
 
|24
 
|24
 +
|30
 
|71
 
|71
 
|44
 
|44
Line 1,093: Line 1,198:
 
|28
 
|28
 
|39
 
|39
 +
|48
 
|114
 
|114
 
|71
 
|71
Line 1,103: Line 1,209:
 
|35
 
|35
 
|48
 
|48
 +
|59
 
|143
 
|143
 
|89
 
|89
Line 1,113: Line 1,220:
 
|53
 
|53
 
|73
 
|73
 +
|89
 
|214
 
|214
 
|133
 
|133
Line 1,123: Line 1,231:
 
|71
 
|71
 
|97
 
|97
 +
|119
 
|286
 
|286
 
|177
 
|177

Revision as of 21:07, 4 November 2018

Introduction

The table below lists the focal length equivalents between formats, keeping track of aspect ratios, such that every format can fit into any target format. In other words the equivalent format is strictly wider.

Focal lens equivalents

APS-C

APS-C
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
10mm 102.9 79.7 10 14 17 21 48 36 101
14mm 83.7 61.6 14 20 24 30 67 50 142
16mm 76.2 55.1 16 23 28 34 77 57 162
18mm 69.8 49.8 18 26 31 39 87 65 182
35mm 39.5 26.8 35 50 61 75 169 126 354
50mm 28.2 19.0 50 72 87 107 241 180 506
55mm 25.7 17.3 55 79 96 118 265 198 557
56mm 25.3 17.0 56 80 98 120 270 201 567
60mm 23.6 15.8 60 86 105 128 289 216 607
80mm 17.8 11.9 80 115 140 171 386 287 810
90mm 15.9 10.6 90 129 157 193 434 323 911
200mm 7.2 4.8 200 287 349 428 964 719 2024

35mm full frame

35mm full frame
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
14mm 104.3 81.2 10 14 17 21 47 35 99
16mm 96.7 73.7 11 16 19 24 54 40 113
17mm 93.3 70.4 12 17 21 25 57 42 120
19mm 86.9 64.6 13 19 23 28 64 48 134
20mm 84.0 61.9 14 20 24 30 67 50 141
24mm 73.7 53.1 17 24 29 36 81 60 169
28mm 65.5 46.4 19 28 34 42 94 70 198
35mm 54.4 37.8 24 35 43 52 118 88 247
45mm 43.6 29.9 31 45 55 67 151 112 318
50mm 39.6 27.0 35 50 61 75 168 125 353
85mm 23.9 16.1 59 85 103 127 286 212 600
105mm 19.5 13.0 73 105 128 157 353 262 741
120mm 17.1 11.4 84 120 146 179 403 300 847
200mm 10.3 6.9 139 200 243 298 672 500 1411

Fuji GFX

Fuji GFX
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
23mm 87.2 71.0 12 17 23 28 64 42 133
32mm 68.8 54.3 16 23 32 39 88 59 186
45mm 51.9 40.0 23 33 45 55 124 82 261
50mm 47.3 36.3 25 37 50 61 138 91 290
63mm 38.3 29.2 32 46 63 77 174 115 365
100mm 24.7 18.6 51 73 100 123 276 183 580
110mm 22.5 17.0 56 80 110 135 304 201 638
200mm 12.5 9.4 102 146 200 245 553 366 1160
250mm 10.0 7.5 127 183 250 306 691 457 1450
Hasselblad 24mm 84.8 68.7 12 18 24 29 66 44 139
Hasselblad 28mm 76.1 60.7 14 20 28 34 77 51 162
Hasselblad 35mm 64.1 50.2 18 26 35 43 97 64 203
Hasselblad 50mm 47.3 36.3 25 37 50 61 138 91 290
Hasselblad 80mm 30.6 23.2 41 59 80 98 221 146 464
Hasselblad 90mm 27.4 20.7 46 66 90 110 249 165 522
Hasselblad 110mm 22.5 17.0 56 80 110 135 304 201 638
Hasselblad 150mm 16.6 12.5 76 110 150 184 414 274 870
Hasselblad 210mm 11.9 8.9 107 154 210 257 580 384 1218
Hasselblad 300mm 8.4 6.3 153 220 300 368 829 549 1740
Hasselblad 24mm (1.5) 62.6 49.0 18 26 36 44 99 66 209
Hasselblad 28mm (1.5) 55.1 42.7 21 31 42 51 116 77 244
Hasselblad 35mm (1.5) 45.3 34.7 27 38 52 64 145 96 304
Hasselblad 50mm (1.5) 32.6 24.7 38 55 75 92 207 137 435
Hasselblad 80mm (1.5) 20.7 15.6 61 88 120 147 332 220 696
Hasselblad 90mm (1.5) 18.4 13.9 69 99 135 165 373 247 783
Hasselblad 110mm (1.5) 15.1 11.4 84 121 165 202 456 302 957
Hasselblad 150mm (1.5) 11.1 8.3 115 165 225 276 622 412 1305
Hasselblad 210mm (1.5) 8.0 6.0 160 230 315 386 870 576 1827
Hasselblad 300mm (1.5) 5.6 4.2 229 329 450 552 1243 823 2610

Pentax 645

Pentax 645
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
25mm 82.4 66.5 13 18 25 31 69 46 145
28mm 76.1 60.7 14 20 28 34 77 51 162
33mm 67.1 52.9 17 24 33 40 91 60 191
45mm 51.9 40.0 23 33 45 55 124 82 261
55mm 43.4 33.2 28 40 55 67 152 101 319
80mm 30.6 23.2 41 59 80 98 221 146 464
85mm 28.9 21.8 43 62 85 104 235 155 493
110mm 22.5 17.0 56 80 110 135 304 201 638
150mm 16.6 12.5 76 110 150 184 414 274 870
160mm 15.6 11.7 81 117 160 196 442 293 928
300mm 8.4 6.3 153 220 300 368 829 549 1740

Hasselblad H5D-60

Hasselblad H5D-60
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
24mm 96.4 79.9 10 14 20 24 54 36 114
28mm 87.6 71.3 12 17 23 28 63 42 132
35mm 75.0 59.7 15 21 29 35 79 52 166
50mm 56.5 43.8 21 30 41 50 113 75 236
80mm 37.1 28.2 33 48 65 80 180 119 378
90mm 33.2 25.2 37 54 73 90 203 134 426
110mm 27.4 20.7 46 66 90 110 248 164 520
150mm 20.3 15.3 62 90 122 150 338 224 709
210mm 14.6 10.9 87 125 171 210 473 313 993
300mm 10.2 7.7 125 179 245 300 676 448 1419
24mm (1.5) 73.4 58.4 15 21 29 36 81 54 170
28mm (1.5) 65.2 51.1 17 25 34 42 95 63 199
35mm (1.5) 54.2 41.9 22 31 43 52 118 78 248
50mm (1.5) 39.4 30.0 31 45 61 75 169 112 355
80mm (1.5) 25.2 19.0 50 72 98 120 270 179 568
90mm (1.5) 22.5 16.9 56 81 110 135 304 201 639
110mm (1.5) 18.5 13.9 69 99 135 165 372 246 780
150mm (1.5) 13.6 10.2 93 134 184 225 507 336 1064
210mm (1.5) 9.7 7.3 131 188 257 315 710 470 1490
300mm (1.5) 6.8 5.1 187 269 367 450 1014 672 2128

LF (4x5)

LF (4x5)
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
72mm 80.1 67.9 12 18 24 30 72 45 151
90mm 67.8 56.6 15 22 30 37 90 56 188
150mm 43.9 35.8 26 37 51 62 150 93 314
240mm 28.3 22.8 41 59 81 99 240 148 502
300mm 22.8 18.4 52 74 101 124 300 186 628

LF (6x17)

LF (6x17)
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
72mm 99.5 45.2 11 15 19 23 51 72 108
90mm 86.7 36.9 13 19 23 28 64 90 134
150mm 59.1 22.6 22 32 39 47 107 150 224
240mm 39.0 14.3 35 51 62 76 171 240 359
300mm 31.6 11.4 44 64 77 95 214 300 448

LF (8x10)

LF (8x10)
Focal length Horizontal FOV Vertical FOV APS-C 35mm GFX H5D 4x5 6x17 8x10
150mm 80.5 68.2 12 18 24 30 71 44 150
240mm 55.8 45.8 20 28 39 48 114 71 240
300mm 45.9 37.4 25 35 48 59 143 89 300
450mm 31.5 25.4 37 53 73 89 214 133 450
600mm 23.9 19.2 49 71 97 119 286 177 600

Code

The table above was generated by the program below.

package main

import (
	"fmt"
	"math"
)

type Medium struct {
	h, v float64
	name string
}

func (m Medium) AspectRatio() float64 {
	return m.h/m.v
}

var (
	MediumAPSC  = Medium{25.1, 16.7, "APS-C"}
	MediumFF    = Medium{36, 24, "35mm"}
	MediumMFF   = Medium{43.8, 32.8, "GFX"}
	MediumMFH   = Medium{53.7, 40.2, "H5D"}
	MediumLF45  = Medium{121, 97, "4x5"}
	MediumLF617 = Medium{170, 60, "6x17"}
	MediumLF810 = Medium{254, 203, "8x10"}
)

var Mediums = []Medium {
	MediumAPSC,
	MediumFF,
	MediumMFF,
	MediumLF45,
	MediumLF617,
	MediumLF810,
}

type Lens struct {
	focal float64
	tc float64
	mfg string
}

func (l Lens) String() string {
	var s string
	if l.mfg != "" {
		s = l.mfg + " "
	}
	s += fmt.Sprintf("%.0fmm", l.focal)
	if l.tc == 1.0 {
		return s
	}
	return s + fmt.Sprintf(" (%.1f)", l.tc)
}

func (l Lens) Focal() float64 {
	return l.focal * l.tc
}

var LensesAPSC = []Lens {
	{10, 1.0, ""},
	{14, 1.0, ""},
	{16, 1.0, ""},
	{18, 1.0, ""},
	{35, 1.0, ""},
	{50, 1.0, ""},
	{55, 1.0, ""},
	{56, 1.0, ""},
	{60, 1.0, ""},
	{80, 1.0, ""},
	{90, 1.0, ""},
	{200, 1.0, ""},
}

var LensesFF = []Lens{
	{14, 1.0, ""},
	{16, 1.0, ""},
	{17, 1.0, ""},
	{19, 1.0, ""},
	{20, 1.0, ""},
	{24, 1.0, ""},
	{28, 1.0, ""},
	{35, 1.0, ""},
	{45, 1.0, ""},
	{50, 1.0, ""},
	{85, 1.0, ""},
	{105, 1.0, ""},
	{120, 1.0, ""},
	{200, 1.0, ""},
}

var LensesGFX = []Lens{
	{23, 1.0, ""},
	{32, 1.0, ""},
	{45, 1.0, ""},
	{50, 1.0, ""},
	{63, 1.0, ""},
	{100, 1.0, ""},
	{110, 1.0, ""},
	{200, 1.0, ""},
	{250, 1.0, ""},
}

var LensesPentax = []Lens {
	{25, 1.0, ""},
	{28, 1.0, ""},
	{33, 1.0, ""},
	{45, 1.0, ""},
	{55, 1.0, ""},
	{80, 1.0, ""},
	{85, 1.0, ""},
	{110, 1.0, ""},
	{150, 1.0, ""},
	{160, 1.0, ""},
	{300, 1.0, ""},
}

var LensesHasselblad = []Lens {
	{24, 1.0, ""},
	{28, 1.0, ""},
	{35, 1.0, ""},
	{50, 1.0, ""},
	{80, 1.0, ""},
	{90, 1.0, ""},
	{110, 1.0, ""},
	{150, 1.0, ""},
	{210, 1.0, ""},
	{300, 1.0, ""},
}

func init() {
	for _, v := range LensesHasselblad {
		v1 := v
		v1.tc = 1.5
		LensesHasselblad = append(LensesHasselblad, v1)
	}
}

func init() {
	for _, v := range LensesHasselblad {
		v1 := v
		v1.mfg = "Hasselblad"
		LensesGFX = append(LensesGFX, v1)
	}
}

var LensesLF = []Lens {
	{72, 1.0, ""},
	{90, 1.0, ""},
	{150, 1.0, ""},
	{240, 1.0, ""},
	{300, 1.0, ""},
}

var LensesLF810 = []Lens {
	{150, 1.0, ""},
	{240, 1.0, ""},
	{300, 1.0, ""},
	{450, 1.0, ""},
	{600, 1.0, ""},
}

type System struct {
	Medium
	Lenses *[]Lens
	Name string
}

var (
	SystemAPSC = System{MediumAPSC, &LensesAPSC, "APS-C"}
	SystemFF = System{MediumFF, &LensesFF, "35mm full frame"}
	SystemGFX = System{MediumMFF, &LensesGFX, "Fuji GFX"}
	SystemPentax = System{MediumMFF, &LensesPentax, "Pentax 645"}
	SystemHasselblad = System{MediumMFH, &LensesHasselblad, "Hasselblad H5D-60"}
	SystemLF45 = System{MediumLF45, &LensesLF, "LF (4x5)"}
	SystemLF617 = System{MediumLF617, &LensesLF, "LF (6x17)"}
	SystemLF810 = System{MediumLF810, &LensesLF810, "LF (8x10)"}
)

var Systems = []System {
	SystemAPSC,
	SystemFF,
	SystemGFX,
	SystemPentax,
	SystemHasselblad,
	SystemLF45,
	SystemLF617,
	SystemLF810,
}

func fov(ssize, focal float64) float64 {
	return 2 * math.Atan(ssize/(2*focal)) * 180 / math.Pi
}

type LensAll struct {
	Lens
	HFoV float64
	VFoV float64
	Eq map[Medium]float64
}

func (la LensAll) String() string {
	var s string
	s = fmt.Sprintf("|%v\n|%.1f\n|%.1f", la.Lens, la.HFoV, la.VFoV)
	for _, m := range Mediums {
		s += fmt.Sprintf("\n|%.0f", la.Eq[m])
	}
	return s
}

func Equivalent(l Lens, m Medium, mtarg Medium) float64 {
	if m.AspectRatio() <= mtarg.AspectRatio() {
		return l.Focal() * mtarg.v/m.v
	}
	return l.Focal() * mtarg.h/m.h
}

type SystemEquiv struct {
	System
	Lenses []LensAll
}

func (se SystemEquiv) String() string {
	s := fmt.Sprintf("=== %s ===\n", se.Name)

	s += `{| class="wikitable"` + "\n"
 	s += "|+"+se.Name + "\n"

	s += fmt.Sprintf("|-\n")
	s += fmt.Sprintf("|Focal length\n")
	s += fmt.Sprintf("|Horizontal FOV\n")
	s += fmt.Sprintf("|Vertical FOV\n")
 	for _, m := range Mediums {
 		s += fmt.Sprintf("|%s\n", m.name)
 	}
 	for _, l := range se.Lenses {
 		s += fmt.Sprintf("|-\n%s\n", l)
 	}
 
 	s += "|}"
 
	return s
}

func main() {
	for _, system := range Systems {
		se := SystemEquiv{system, nil}
		lenses := []LensAll{}
		for _, lens := range *system.Lenses {
			la := LensAll{Lens: lens}
			la.HFoV = fov(system.Medium.h, lens.Focal())
			la.VFoV = fov(system.Medium.v, lens.Focal())

			la.Eq = make(map [Medium]float64)
			for _, m := range Mediums {
				la.Eq[m] = Equivalent(lens, system.Medium, m)
			}

			lenses = append(lenses, la)
		}
		se.Lenses = lenses
		fmt.Println(se)
	}
}