Compare commits
17 Commits
78a360ae89
...
462c90e8c8
| Author | SHA1 | Date | |
|---|---|---|---|
| 462c90e8c8 | |||
| ac3a18a864 | |||
| 656f1c3a94 | |||
| 762cd45f63 | |||
| d6ad12e344 | |||
| f5d79908f6 | |||
| a69e404817 | |||
| 43d95041af | |||
| c97bc25323 | |||
| dda29eb836 | |||
| fa5971faa4 | |||
| 4d649c735b | |||
| 3d2d763a3b | |||
| ea6114b9ae | |||
| ec0331b88b | |||
| 72b15e5516 | |||
| 3cf580f607 |
537
rtchallenge/Cargo.lock
generated
537
rtchallenge/Cargo.lock
generated
@ -12,6 +12,17 @@ version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
@ -24,18 +35,56 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
@ -45,6 +94,108 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"itertools 0.10.1",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.8.6"
|
||||
@ -55,6 +206,12 @@ dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.8.0"
|
||||
@ -64,6 +221,90 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.3.7"
|
||||
@ -82,6 +323,50 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"plotters-svg",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.8"
|
||||
@ -112,16 +397,137 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rtchallenge"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"criterion",
|
||||
"float-cmp",
|
||||
"png",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f3aac57ee7f3272d8395c6e4f502f434f0e289fcd62876f70daa008c20dcabe"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
|
||||
dependencies = [
|
||||
"half",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
@ -133,6 +539,15 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.25"
|
||||
@ -153,8 +568,130 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
@ -8,6 +8,12 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.41"
|
||||
criterion = "0.3.4"
|
||||
float-cmp = "0.8.0"
|
||||
png = "0.16.8"
|
||||
thiserror = "1.0.25"
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "matrices"
|
||||
harness = false
|
||||
13
rtchallenge/benches/matrices.rs
Normal file
13
rtchallenge/benches/matrices.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
use rtchallenge::matrices::Matrix4x4;
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
let mut i = Matrix4x4::identity();
|
||||
c.bench_function("inverse_new", |b| b.iter(|| i = i.inverse()));
|
||||
let mut i = Matrix4x4::identity();
|
||||
c.bench_function("inverse_old", |b| b.iter(|| i = i.inverse_old()));
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
criterion_main!(benches);
|
||||
@ -1,4 +1,4 @@
|
||||
use rtchallenge::tuples::{point, vector, Tuple};
|
||||
use rtchallenge::tuples::Tuple;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Environment {
|
||||
@ -18,12 +18,12 @@ fn tick(env: &Environment, proj: &Projectile) -> Projectile {
|
||||
}
|
||||
fn main() {
|
||||
let mut p = Projectile {
|
||||
position: point(0., 1., 0.),
|
||||
velocity: 4. * vector(1., 1., 0.).normalize(),
|
||||
position: Tuple::point(0., 1., 0.),
|
||||
velocity: 4. * Tuple::vector(1., 1., 0.).normalize(),
|
||||
};
|
||||
let e = Environment {
|
||||
gravity: vector(0., -0.1, 0.).normalize(),
|
||||
wind: vector(-0.01, 0., 0.),
|
||||
gravity: Tuple::vector(0., -0.1, 0.).normalize(),
|
||||
wind: Tuple::vector(-0.01, 0., 0.),
|
||||
};
|
||||
|
||||
let mut i = 0;
|
||||
|
||||
@ -72,13 +72,13 @@ impl Canvas {
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::canvas;
|
||||
use super::Canvas;
|
||||
|
||||
use crate::tuples::Color;
|
||||
|
||||
#[test]
|
||||
fn create_canvas() {
|
||||
let c = canvas(10, 20);
|
||||
let c = Canvas::new(10, 20);
|
||||
assert_eq!(c.width, 10);
|
||||
assert_eq!(c.height, 20);
|
||||
let black = Color::new(0., 0., 0.);
|
||||
@ -89,7 +89,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn write_to_canvas() {
|
||||
let mut c = canvas(10, 20);
|
||||
let mut c = Canvas::new(10, 20);
|
||||
let red = Color::new(1., 0., 0.);
|
||||
c.set(2, 3, red);
|
||||
assert_eq!(c.get(2, 3), red);
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod canvas;
|
||||
pub mod matrices;
|
||||
pub mod tuples;
|
||||
|
||||
761
rtchallenge/src/matrices.rs
Normal file
761
rtchallenge/src/matrices.rs
Normal file
@ -0,0 +1,761 @@
|
||||
use std::fmt;
|
||||
use std::ops::{Index, IndexMut, Mul};
|
||||
|
||||
use float_cmp::{ApproxEq, F32Margin};
|
||||
|
||||
use crate::tuples::Tuple;
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
/// Matrix4x4 represents a 4x4 matrix in row-major form. So, element `m[i][j]` corresponds to m<sub>i,j</sub>
|
||||
/// where `i` is the row number and `j` is the column number.
|
||||
pub struct Matrix4x4 {
|
||||
m: [[f32; 4]; 4],
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Matrix2x2 {
|
||||
m: [[f32; 2]; 2],
|
||||
}
|
||||
impl Matrix2x2 {
|
||||
/// Create a `Matrix2x2` with each of the given rows.
|
||||
pub fn new(r0: [f32; 2], r1: [f32; 2]) -> Matrix2x2 {
|
||||
Matrix2x2 { m: [r0, r1] }
|
||||
}
|
||||
|
||||
/// Calculate the determinant of a 2x2.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix2x2;
|
||||
///
|
||||
/// let a = Matrix2x2::new([1., 5.], [-3., 2.]);
|
||||
///
|
||||
/// assert_eq!(a.determinant(), 17.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
let m = self;
|
||||
m[(0, 0)] * m[(1, 1)] - m[(0, 1)] * m[(1, 0)]
|
||||
}
|
||||
}
|
||||
impl Index<(usize, usize)> for Matrix2x2 {
|
||||
type Output = f32;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Matrix3x3 {
|
||||
m: [[f32; 3]; 3],
|
||||
}
|
||||
impl Matrix3x3 {
|
||||
/// Create a `Matrix3x2` with each of the given rows.
|
||||
pub fn new(r0: [f32; 3], r1: [f32; 3], r2: [f32; 3]) -> Matrix3x3 {
|
||||
Matrix3x3 { m: [r0, r1, r2] }
|
||||
}
|
||||
/// submatrix extracts a 2x2 matrix ignoring the 0-based `row` and `col` given.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::{Matrix2x2, Matrix3x3};
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// Matrix3x3::new([1., 5., 0.], [-3., 2., 7.], [0., 6., -3.],).submatrix(0, 2),
|
||||
/// Matrix2x2::new([-3., 2.], [0., 6.])
|
||||
/// );
|
||||
/// ```
|
||||
pub fn submatrix(&self, row: usize, col: usize) -> Matrix2x2 {
|
||||
assert!(row < 3);
|
||||
assert!(col < 3);
|
||||
let mut rows = vec![];
|
||||
for r in 0..3 {
|
||||
if r != row {
|
||||
let mut v = vec![];
|
||||
for c in 0..3 {
|
||||
if c != col {
|
||||
v.push(self[(r, c)]);
|
||||
}
|
||||
}
|
||||
rows.push(v);
|
||||
}
|
||||
}
|
||||
let m = [[rows[0][0], rows[0][1]], [rows[1][0], rows[1][1]]];
|
||||
Matrix2x2 { m }
|
||||
}
|
||||
|
||||
/// Compute minor of a 3x3 matrix.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix3x3;
|
||||
///
|
||||
/// let a = Matrix3x3::new([3., 5., 0.], [2., -1., -7.], [6., -1., 5.]);
|
||||
/// let b = a.submatrix(1, 0);
|
||||
/// assert_eq!(b.determinant(), 25.0);
|
||||
/// assert_eq!(b.determinant(), a.minor(1, 0));
|
||||
/// ```
|
||||
pub fn minor(&self, row: usize, col: usize) -> f32 {
|
||||
self.submatrix(row, col).determinant()
|
||||
}
|
||||
|
||||
/// Compute cofactor of a 3x3 matrix.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix3x3;
|
||||
///
|
||||
/// let a = Matrix3x3::new([3., 5., 0.], [2., -1., -7.], [6., -1., 5.]);
|
||||
/// assert_eq!(a.minor(0, 0), -12.);
|
||||
/// assert_eq!(a.cofactor(0, 0), -12.);
|
||||
/// assert_eq!(a.minor(1, 0), 25.);
|
||||
/// assert_eq!(a.cofactor(1, 0), -25.);
|
||||
/// ```
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> f32 {
|
||||
let negate = if (row + col) % 2 == 0 { 1. } else { -1. };
|
||||
self.submatrix(row, col).determinant() * negate
|
||||
}
|
||||
|
||||
/// Compute determinant of a 3x3 matrix.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix3x3;
|
||||
///
|
||||
/// let a = Matrix3x3::new([1., 2., 6.], [-5., 8., -4.], [2., 6., 4.]);
|
||||
/// assert_eq!(a.cofactor(0, 0), 56.);
|
||||
/// assert_eq!(a.cofactor(0, 1), 12.);
|
||||
/// assert_eq!(a.cofactor(0, 2), -46.);
|
||||
/// assert_eq!(a.determinant(), -196.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
(0..3).map(|i| self.cofactor(0, i) * self[(0, i)]).sum()
|
||||
}
|
||||
}
|
||||
impl Index<(usize, usize)> for Matrix3x3 {
|
||||
type Output = f32;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
}
|
||||
|
||||
impl From<[f32; 16]> for Matrix4x4 {
|
||||
fn from(t: [f32; 16]) -> Self {
|
||||
Matrix4x4 {
|
||||
m: [
|
||||
[t[0], t[1], t[2], t[3]],
|
||||
[t[4], t[5], t[6], t[7]],
|
||||
[t[8], t[9], t[10], t[11]],
|
||||
[t[12], t[13], t[14], t[15]],
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ApproxEq for &'a Matrix4x4 {
|
||||
type Margin = F32Margin;
|
||||
|
||||
/// Implement float_cmp::ApproxEq for Matrix4x4
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use float_cmp::approx_eq;
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// assert!(!approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &Matrix4x4::default(),
|
||||
/// &Matrix4x4::identity(),
|
||||
/// ulps = 1
|
||||
/// ));
|
||||
///
|
||||
/// assert!(approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &Matrix4x4::identity(),
|
||||
/// &Matrix4x4::identity(),
|
||||
/// ulps = 1
|
||||
/// ));
|
||||
/// ```
|
||||
fn approx_eq<T: Into<Self::Margin>>(self, m2: Self, margin: T) -> bool {
|
||||
let m = self;
|
||||
let margin = margin.into();
|
||||
for row in 0..4 {
|
||||
for col in 0..4 {
|
||||
if !m[(row, col)].approx_eq(m2[(row, col)], margin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Matrix4x4 {
|
||||
/// Create a `Matrix4x4` containing the identity, all zeros with ones along the diagonal.
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [0., 1., 2., 3.],
|
||||
/// [1., 2., 4., 8.],
|
||||
/// [2., 4., 8., 16.],
|
||||
/// [4., 8., 16., 32.],
|
||||
/// );
|
||||
/// let i = Matrix4x4::identity();
|
||||
///
|
||||
/// assert_eq!(a * i, a);
|
||||
/// ```
|
||||
pub fn identity() -> Matrix4x4 {
|
||||
Matrix4x4::new(
|
||||
[1., 0., 0., 0.],
|
||||
[0., 1., 0., 0.],
|
||||
[0., 0., 1., 0.],
|
||||
[0., 0., 0., 1.],
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a `Matrix4x4` with each of the given rows.
|
||||
pub fn new(r0: [f32; 4], r1: [f32; 4], r2: [f32; 4], r3: [f32; 4]) -> Matrix4x4 {
|
||||
Matrix4x4 {
|
||||
m: [r0, r1, r2, r3],
|
||||
}
|
||||
}
|
||||
|
||||
/// Transpose self, returning a new matrix that has been reflected across the diagonal.
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let m = Matrix4x4::new(
|
||||
/// [2., 0., 0., 0.],
|
||||
/// [3., 1., 0., 0.],
|
||||
/// [4., 0., 1., 0.],
|
||||
/// [5., 6., 7., 1.],
|
||||
/// );
|
||||
/// let m_t = Matrix4x4::new(
|
||||
/// [2., 3., 4., 5.],
|
||||
/// [0., 1., 0., 6.],
|
||||
/// [0., 0., 1., 7.],
|
||||
/// [0., 0., 0., 1.],
|
||||
/// );
|
||||
/// assert_eq!(m.transpose(), m_t);
|
||||
///
|
||||
/// assert_eq!(Matrix4x4::identity(), Matrix4x4::identity().transpose());
|
||||
pub fn transpose(&self) -> Matrix4x4 {
|
||||
let m = self.m;
|
||||
Matrix4x4 {
|
||||
m: [
|
||||
[m[0][0], m[1][0], m[2][0], m[3][0]],
|
||||
[m[0][1], m[1][1], m[2][1], m[3][1]],
|
||||
[m[0][2], m[1][2], m[2][2], m[3][2]],
|
||||
[m[0][3], m[1][3], m[2][3], m[3][3]],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new matrix that is the inverse of self. If self is A, inverse returns A<sup>-1</sup>, where
|
||||
/// AA<sup>-1</sup> = I.
|
||||
/// This implementation uses a numerically stable Gauss–Jordan elimination routine to compute the inverse.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let i = Matrix4x4::identity();
|
||||
/// assert_eq!(i.inverse_old() * i, i);
|
||||
///
|
||||
/// let m = Matrix4x4::new(
|
||||
/// [2., 0., 0., 0.],
|
||||
/// [0., 3., 0., 0.],
|
||||
/// [0., 0., 4., 0.],
|
||||
/// [0., 0., 0., 1.],
|
||||
/// );
|
||||
/// assert_eq!(m.inverse_old() * m, i);
|
||||
/// assert_eq!(m * m.inverse_old(), i);
|
||||
/// ```
|
||||
pub fn inverse_old(&self) -> Matrix4x4 {
|
||||
// TODO(wathiede): how come the C++ version doesn't need to deal with non-invertable
|
||||
// matrix.
|
||||
let mut indxc: [usize; 4] = Default::default();
|
||||
let mut indxr: [usize; 4] = Default::default();
|
||||
let mut ipiv: [usize; 4] = Default::default();
|
||||
let mut minv = self.m;
|
||||
|
||||
for i in 0..4 {
|
||||
let mut irow: usize = 0;
|
||||
let mut icol: usize = 0;
|
||||
let mut big: f32 = 0.;
|
||||
// Choose pivot
|
||||
for j in 0..4 {
|
||||
if ipiv[j] != 1 {
|
||||
for (k, ipivk) in ipiv.iter().enumerate() {
|
||||
if *ipivk == 0 {
|
||||
if minv[j][k].abs() >= big {
|
||||
big = minv[j][k].abs();
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
} else if *ipivk > 1 {
|
||||
eprintln!("Singular matrix in MatrixInvert");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ipiv[icol] += 1;
|
||||
// Swap rows _irow_ and _icol_ for pivot
|
||||
if irow != icol {
|
||||
// Can't figure out how to make swap work here.
|
||||
#[allow(clippy::manual_swap)]
|
||||
for k in 0..4 {
|
||||
let tmp = minv[irow][k];
|
||||
minv[irow][k] = minv[icol][k];
|
||||
minv[icol][k] = tmp;
|
||||
}
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if minv[icol][icol] == 0. {
|
||||
eprintln!("Singular matrix in MatrixInvert");
|
||||
}
|
||||
|
||||
// Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
|
||||
let pivinv: f32 = minv[icol][icol].recip();
|
||||
minv[icol][icol] = 1.;
|
||||
for j in 0..4 {
|
||||
minv[icol][j] *= pivinv;
|
||||
}
|
||||
|
||||
// Subtract this row from others to zero out their columns
|
||||
for j in 0..4 {
|
||||
if j != icol {
|
||||
let save = minv[j][icol];
|
||||
minv[j][icol] = 0.;
|
||||
for k in 0..4 {
|
||||
minv[j][k] -= minv[icol][k] * save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Swap columns to reflect permutation
|
||||
for j in (0..4).rev() {
|
||||
if indxr[j] != indxc[j] {
|
||||
for mi in &mut minv {
|
||||
mi.swap(indxr[j], indxc[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
Matrix4x4 { m: minv }
|
||||
}
|
||||
/// submatrix extracts a 3x3 matrix ignoring the 0-based `row` and `col` given.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::{Matrix3x3, Matrix4x4};
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// Matrix4x4::new(
|
||||
/// [-6., 1., 1., 6.],
|
||||
/// [-8., 5., 8., 6.],
|
||||
/// [-1., 0., 8., 2.],
|
||||
/// [-7., 1., -1., 1.],
|
||||
/// )
|
||||
/// .submatrix(2, 1),
|
||||
/// Matrix3x3::new([-6., 1., 6.], [-8., 8., 6.], [-7., -1., 1.],)
|
||||
/// );
|
||||
/// ```
|
||||
pub fn submatrix(&self, row: usize, col: usize) -> Matrix3x3 {
|
||||
assert!(row < 4);
|
||||
assert!(col < 4);
|
||||
let mut rows = vec![];
|
||||
for r in 0..4 {
|
||||
if r != row {
|
||||
let mut v = vec![];
|
||||
for c in 0..4 {
|
||||
if c != col {
|
||||
v.push(self[(r, c)]);
|
||||
}
|
||||
}
|
||||
rows.push(v);
|
||||
}
|
||||
}
|
||||
let m = [
|
||||
[rows[0][0], rows[0][1], rows[0][2]],
|
||||
[rows[1][0], rows[1][1], rows[1][2]],
|
||||
[rows[2][0], rows[2][1], rows[2][2]],
|
||||
];
|
||||
Matrix3x3 { m }
|
||||
}
|
||||
|
||||
/// Compute minor of a 4x4 matrix.
|
||||
pub fn minor(&self, row: usize, col: usize) -> f32 {
|
||||
self.submatrix(row, col).determinant()
|
||||
}
|
||||
/// Compute cofactor of a 4x4 matrix.
|
||||
pub fn cofactor(&self, row: usize, col: usize) -> f32 {
|
||||
let negate = if (row + col) % 2 == 0 { 1. } else { -1. };
|
||||
self.submatrix(row, col).determinant() * negate
|
||||
}
|
||||
/// Compute determinant of a 4x4 matrix.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [-2., -8., 3., 5.],
|
||||
/// [-3., 1., 7., 3.],
|
||||
/// [1., 2., -9., 6.],
|
||||
/// [-6., 7., 7., -9.],
|
||||
/// );
|
||||
/// assert_eq!(a.cofactor(0, 0), 690.);
|
||||
/// assert_eq!(a.cofactor(0, 1), 447.);
|
||||
/// assert_eq!(a.cofactor(0, 2), 210.);
|
||||
/// assert_eq!(a.cofactor(0, 3), 51.);
|
||||
/// assert_eq!(a.determinant(), -4071.);
|
||||
/// ```
|
||||
pub fn determinant(&self) -> f32 {
|
||||
(0..4).map(|i| self.cofactor(0, i) * self[(0, i)]).sum()
|
||||
}
|
||||
|
||||
/// Compute invertibility of matrix (i.e. non-zero determinant.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [6., 4., 4., 4.],
|
||||
/// [5., 5., 7., 6.],
|
||||
/// [4., -9., 3., -7.],
|
||||
/// [9., 1., 7., -6.],
|
||||
/// );
|
||||
/// assert_eq!(a.determinant(), -2120.);
|
||||
/// assert_eq!(a.invertable(), true);
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [-4., 2., -2., -3.],
|
||||
/// [9., 6., 2., 6.],
|
||||
/// [0., -5., 1., -5.],
|
||||
/// [0., 0., 0., 0.],
|
||||
/// );
|
||||
/// assert_eq!(a.determinant(), 0.);
|
||||
/// assert_eq!(a.invertable(), false);
|
||||
/// ```
|
||||
pub fn invertable(&self) -> bool {
|
||||
self.determinant() != 0.
|
||||
}
|
||||
|
||||
/// Compute the inverse of a 4x4 matrix.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use float_cmp::approx_eq;
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [-5., 2., 6., -8.],
|
||||
/// [1., -5., 1., 8.],
|
||||
/// [7., 7., -6., -7.],
|
||||
/// [1., -3., 7., 4.],
|
||||
/// );
|
||||
/// let b = a.inverse();
|
||||
///
|
||||
/// assert_eq!(a.determinant(), 532.);
|
||||
/// assert_eq!(a.cofactor(2, 3), -160.);
|
||||
/// assert_eq!(b[(3, 2)], -160. / 532.);
|
||||
/// assert_eq!(a.cofactor(3, 2), 105.);
|
||||
/// assert_eq!(b[(2, 3)], 105. / 532.);
|
||||
/// assert!(approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &b,
|
||||
/// &Matrix4x4::new(
|
||||
/// [0.21805, 0.45113, 0.24060, -0.04511],
|
||||
/// [-0.80827, -1.45677, -0.44361, 0.52068],
|
||||
/// [-0.07895, -0.22368, -0.05263, 0.19737],
|
||||
/// [-0.52256, -0.81391, -0.30075, 0.30639],
|
||||
/// ),
|
||||
/// epsilon = 0.0001
|
||||
/// ));
|
||||
///
|
||||
/// // Second test case
|
||||
/// assert!(approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &Matrix4x4::new(
|
||||
/// [8., -5., 9., 2.],
|
||||
/// [7., 5., 6., 1.],
|
||||
/// [-6., 0., 9., 6.],
|
||||
/// [-3., 0., -9., -4.],
|
||||
/// )
|
||||
/// .inverse(),
|
||||
/// &Matrix4x4::new(
|
||||
/// [-0.15385, -0.15385, -0.28205, -0.53846],
|
||||
/// [-0.07692, 0.12308, 0.02564, 0.03077],
|
||||
/// [0.35897, 0.35897, 0.43590, 0.92308],
|
||||
/// [-0.69231, -0.69241, -0.76923, -1.92308],
|
||||
/// ),
|
||||
/// epsilon = 0.0005
|
||||
/// ));
|
||||
///
|
||||
/// // Third test case
|
||||
/// assert!(approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &Matrix4x4::new(
|
||||
/// [9., 3., 0., 9.],
|
||||
/// [-5., -2., -6., -3.],
|
||||
/// [-4., 9., 6., 4.],
|
||||
/// [-7., 6., 6., 2.],
|
||||
/// )
|
||||
/// .inverse(),
|
||||
/// &Matrix4x4::new(
|
||||
/// [-0.04074, -0.07778, 0.14444, -0.22222],
|
||||
/// [-0.07778, 0.03333, 0.36667, -0.33333],
|
||||
/// [-0.02901, -0.14630, -0.10926, 0.12963],
|
||||
/// [0.17778, 0.06667, -0.26667, 0.33333],
|
||||
/// ),
|
||||
/// epsilon = 0.0001
|
||||
/// ));
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [3., -9., 7., 3.],
|
||||
/// [3., -8., 2., -9.],
|
||||
/// [-4., 4., 4., 1.],
|
||||
/// [-6., 5., -1., 1.],
|
||||
/// );
|
||||
/// let b = Matrix4x4::new(
|
||||
/// [8., 2., 2., 2.],
|
||||
/// [3., -1., 7., 0.],
|
||||
/// [7., 0., 5., 4.],
|
||||
/// [6., -2., 0., 5.],
|
||||
/// );
|
||||
/// let c = a * b;
|
||||
/// assert!(approx_eq!(
|
||||
/// &Matrix4x4,
|
||||
/// &(c * b.inverse()),
|
||||
/// &a,
|
||||
/// epsilon = 0.0001
|
||||
/// ));
|
||||
/// ```
|
||||
pub fn inverse(&self) -> Matrix4x4 {
|
||||
let m = self;
|
||||
if !m.invertable() {
|
||||
panic!("Matrix4x4::inverse called on matrix with determinant() == 0");
|
||||
}
|
||||
let mut m2 = Matrix4x4::identity();
|
||||
let det = m.determinant();
|
||||
for row in 0..4 {
|
||||
for col in 0..4 {
|
||||
let c = m.cofactor(row, col);
|
||||
m2[(col, row)] = c / det;
|
||||
}
|
||||
}
|
||||
m2
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Matrix4x4 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
write!(
|
||||
f,
|
||||
"{:?}\n {:?}\n {:?}\n {:?}",
|
||||
self.m[0], self.m[1], self.m[2], self.m[3]
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"[{:?} {:?} {:?} {:?}]",
|
||||
self.m[0], self.m[1], self.m[2], self.m[3]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Matrix4x4> for Matrix4x4 {
|
||||
type Output = Matrix4x4;
|
||||
|
||||
/// Implement matrix multiplication for `Matrix4x4`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
///
|
||||
/// let i = Matrix4x4::identity();
|
||||
/// let m1 = Matrix4x4::identity();
|
||||
/// let m2 = Matrix4x4::identity();
|
||||
///
|
||||
/// assert_eq!(m1 * m2, i);
|
||||
/// ```
|
||||
fn mul(self, m2: Matrix4x4) -> Matrix4x4 {
|
||||
let m1 = self;
|
||||
let mut r: Matrix4x4 = Default::default();
|
||||
for i in 0..4 {
|
||||
for j in 0..4 {
|
||||
r.m[i][j] = m1.m[i][0] * m2.m[0][j]
|
||||
+ m1.m[i][1] * m2.m[1][j]
|
||||
+ m1.m[i][2] * m2.m[2][j]
|
||||
+ m1.m[i][3] * m2.m[3][j];
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Tuple> for Matrix4x4 {
|
||||
type Output = Tuple;
|
||||
|
||||
/// Implement matrix multiplication for `Matrix4x4` * `Tuple`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use rtchallenge::matrices::Matrix4x4;
|
||||
/// use rtchallenge::tuples::Tuple;
|
||||
///
|
||||
/// let a = Matrix4x4::new(
|
||||
/// [1., 2., 3., 4.],
|
||||
/// [2., 4., 4., 2.],
|
||||
/// [8., 6., 4., 1.],
|
||||
/// [0., 0., 0., 1.],
|
||||
/// );
|
||||
/// let b = Tuple::new(1., 2., 3., 1.);
|
||||
///
|
||||
/// assert_eq!(a * b, Tuple::new(18., 24., 33., 1.));
|
||||
/// ```
|
||||
fn mul(self, t: Tuple) -> Tuple {
|
||||
let m = self;
|
||||
Tuple {
|
||||
x: m.m[0][0] * t.x + m.m[0][1] * t.y + m.m[0][2] * t.z + m.m[0][3] * t.w,
|
||||
y: m.m[1][0] * t.x + m.m[1][1] * t.y + m.m[1][2] * t.z + m.m[1][3] * t.w,
|
||||
z: m.m[2][0] * t.x + m.m[2][1] * t.y + m.m[2][2] * t.z + m.m[2][3] * t.w,
|
||||
w: m.m[3][0] * t.x + m.m[3][1] * t.y + m.m[3][2] * t.z + m.m[3][3] * t.w,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Matrix4x4 {
|
||||
fn eq(&self, rhs: &Matrix4x4) -> bool {
|
||||
let l = self.m;
|
||||
let r = rhs.m;
|
||||
for i in 0..4 {
|
||||
for j in 0..4 {
|
||||
let d = (l[i][j] - r[i][j]).abs();
|
||||
if d > f32::EPSILON {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<(usize, usize)> for Matrix4x4 {
|
||||
type Output = f32;
|
||||
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
|
||||
&self.m[row][col]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<(usize, usize)> for Matrix4x4 {
|
||||
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output {
|
||||
&mut self.m[row][col]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn construct2x2() {
|
||||
let m = Matrix2x2::new([-3., 5.], [1., -2.]);
|
||||
|
||||
assert_eq!(m[(0, 0)], -3.);
|
||||
assert_eq!(m[(0, 1)], 5.);
|
||||
assert_eq!(m[(1, 0)], 1.);
|
||||
assert_eq!(m[(1, 1)], -2.);
|
||||
}
|
||||
#[test]
|
||||
fn construct3x3() {
|
||||
let m = Matrix3x3::new([-3., 5., 0.], [1., -2., -7.], [0., 1., 1.]);
|
||||
|
||||
assert_eq!(m[(0, 0)], -3.);
|
||||
assert_eq!(m[(1, 1)], -2.);
|
||||
assert_eq!(m[(2, 2)], 1.);
|
||||
}
|
||||
#[test]
|
||||
fn construct4x4() {
|
||||
let m = Matrix4x4::new(
|
||||
[1., 2., 3., 4.],
|
||||
[5.5, 6.5, 7.5, 8.5],
|
||||
[9., 10., 11., 12.],
|
||||
[13.5, 14.5, 15.5, 16.5],
|
||||
);
|
||||
|
||||
assert_eq!(m[(0, 0)], 1.);
|
||||
assert_eq!(m[(0, 3)], 4.);
|
||||
assert_eq!(m[(1, 0)], 5.5);
|
||||
assert_eq!(m[(1, 2)], 7.5);
|
||||
assert_eq!(m[(2, 2)], 11.);
|
||||
assert_eq!(m[(3, 0)], 13.5);
|
||||
assert_eq!(m[(3, 2)], 15.5);
|
||||
}
|
||||
#[test]
|
||||
fn equality4x4() {
|
||||
let a = Matrix4x4::new(
|
||||
[1., 2., 3., 4.],
|
||||
[5., 6., 7., 8.],
|
||||
[9., 8., 7., 6.],
|
||||
[5., 4., 3., 2.],
|
||||
);
|
||||
let b = Matrix4x4::new(
|
||||
[1., 2., 3., 4.],
|
||||
[5., 6., 7., 8.],
|
||||
[9., 8., 7., 6.],
|
||||
[5., 4., 3., 2.],
|
||||
);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
#[test]
|
||||
fn inequality4x4() {
|
||||
let a = Matrix4x4::new(
|
||||
[1., 2., 3., 4.],
|
||||
[5., 6., 7., 8.],
|
||||
[9., 8., 7., 6.],
|
||||
[5., 4., 3., 2.],
|
||||
);
|
||||
let b = Matrix4x4::new(
|
||||
[2., 3., 4., 5.],
|
||||
[6., 7., 8., 9.],
|
||||
[8., 7., 6., 5.],
|
||||
[4., 3., 2., 1.],
|
||||
);
|
||||
assert_ne!(a, b);
|
||||
}
|
||||
#[test]
|
||||
fn mul4x4() {
|
||||
let a = Matrix4x4::new(
|
||||
[1., 2., 3., 4.],
|
||||
[5., 6., 7., 8.],
|
||||
[9., 8., 7., 6.],
|
||||
[5., 4., 3., 2.],
|
||||
);
|
||||
let b = Matrix4x4::new(
|
||||
[-2., 1., 2., 3.],
|
||||
[3., 2., 1., -1.],
|
||||
[4., 3., 6., 5.],
|
||||
[1., 2., 7., 8.],
|
||||
);
|
||||
assert_eq!(
|
||||
a * b,
|
||||
Matrix4x4::new(
|
||||
[20., 22., 50., 48.],
|
||||
[44., 54., 114., 108.],
|
||||
[40., 58., 110., 102.],
|
||||
[16., 26., 46., 42.],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub struct Tuple {
|
||||
pub x: f32,
|
||||
@ -214,11 +215,11 @@ impl Sub for Color {
|
||||
mod tests {
|
||||
use float_cmp::approx_eq;
|
||||
|
||||
use super::{color, cross, dot, point, tuple, vector};
|
||||
use super::{cross, dot, Color, Tuple};
|
||||
#[test]
|
||||
fn is_point() {
|
||||
// A tuple with w = 1 is a point
|
||||
let a = tuple(4.3, -4.2, 3.1, 1.0);
|
||||
let a = Tuple::new(4.3, -4.2, 3.1, 1.0);
|
||||
assert_eq!(a.x, 4.3);
|
||||
assert_eq!(a.y, -4.2);
|
||||
assert_eq!(a.z, 3.1);
|
||||
@ -229,7 +230,7 @@ mod tests {
|
||||
#[test]
|
||||
fn is_vector() {
|
||||
// A tuple with w = 0 is a point
|
||||
let a = tuple(4.3, -4.2, 3.1, 0.0);
|
||||
let a = Tuple::new(4.3, -4.2, 3.1, 0.0);
|
||||
assert_eq!(a.x, 4.3);
|
||||
assert_eq!(a.y, -4.2);
|
||||
assert_eq!(a.z, 3.1);
|
||||
@ -239,78 +240,81 @@ mod tests {
|
||||
}
|
||||
#[test]
|
||||
fn point_tuple() {
|
||||
assert_eq!(point(4., -4., 3.), tuple(4., -4., 3., 1.))
|
||||
assert_eq!(Tuple::point(4., -4., 3.), Tuple::new(4., -4., 3., 1.))
|
||||
}
|
||||
#[test]
|
||||
fn vector_tuple() {
|
||||
assert_eq!(vector(4., -4., 3.), tuple(4., -4., 3., 0.))
|
||||
assert_eq!(Tuple::vector(4., -4., 3.), Tuple::new(4., -4., 3., 0.))
|
||||
}
|
||||
#[test]
|
||||
fn add_two_tuples() {
|
||||
let a1 = tuple(3., -2., 5., 1.);
|
||||
let a2 = tuple(-2., 3., 1., 0.);
|
||||
assert_eq!(a1 + a2, tuple(1., 1., 6., 1.));
|
||||
let a1 = Tuple::new(3., -2., 5., 1.);
|
||||
let a2 = Tuple::new(-2., 3., 1., 0.);
|
||||
assert_eq!(a1 + a2, Tuple::new(1., 1., 6., 1.));
|
||||
}
|
||||
#[test]
|
||||
fn sub_two_points() {
|
||||
let p1 = point(3., 2., 1.);
|
||||
let p2 = point(5., 6., 7.);
|
||||
assert_eq!(p1 - p2, vector(-2., -4., -6.));
|
||||
let p1 = Tuple::point(3., 2., 1.);
|
||||
let p2 = Tuple::point(5., 6., 7.);
|
||||
assert_eq!(p1 - p2, Tuple::vector(-2., -4., -6.));
|
||||
}
|
||||
#[test]
|
||||
fn sub_vector_point() {
|
||||
let p = point(3., 2., 1.);
|
||||
let v = vector(5., 6., 7.);
|
||||
assert_eq!(p - v, point(-2., -4., -6.));
|
||||
let p = Tuple::point(3., 2., 1.);
|
||||
let v = Tuple::vector(5., 6., 7.);
|
||||
assert_eq!(p - v, Tuple::point(-2., -4., -6.));
|
||||
}
|
||||
#[test]
|
||||
fn sub_two_vectors() {
|
||||
let v1 = vector(3., 2., 1.);
|
||||
let v2 = vector(5., 6., 7.);
|
||||
assert_eq!(v1 - v2, vector(-2., -4., -6.));
|
||||
let v1 = Tuple::vector(3., 2., 1.);
|
||||
let v2 = Tuple::vector(5., 6., 7.);
|
||||
assert_eq!(v1 - v2, Tuple::vector(-2., -4., -6.));
|
||||
}
|
||||
#[test]
|
||||
fn sub_zero_vector() {
|
||||
let zero = vector(0., 0., 0.);
|
||||
let v = vector(1., -2., 3.);
|
||||
assert_eq!(zero - v, vector(-1., 2., -3.));
|
||||
let zero = Tuple::vector(0., 0., 0.);
|
||||
let v = Tuple::vector(1., -2., 3.);
|
||||
assert_eq!(zero - v, Tuple::vector(-1., 2., -3.));
|
||||
}
|
||||
#[test]
|
||||
fn negate_tuple() {
|
||||
let a = tuple(1., -2., 3., -4.);
|
||||
assert_eq!(-a, tuple(-1., 2., -3., 4.));
|
||||
let a = Tuple::new(1., -2., 3., -4.);
|
||||
assert_eq!(-a, Tuple::new(-1., 2., -3., 4.));
|
||||
}
|
||||
#[test]
|
||||
fn mul_tuple_scalar() {
|
||||
let a = tuple(1., -2., 3., -4.);
|
||||
assert_eq!(a * 3.5, tuple(3.5, -7., 10.5, -14.));
|
||||
assert_eq!(3.5 * a, tuple(3.5, -7., 10.5, -14.));
|
||||
let a = Tuple::new(1., -2., 3., -4.);
|
||||
assert_eq!(a * 3.5, Tuple::new(3.5, -7., 10.5, -14.));
|
||||
assert_eq!(3.5 * a, Tuple::new(3.5, -7., 10.5, -14.));
|
||||
}
|
||||
#[test]
|
||||
fn mul_tuple_fraction() {
|
||||
let a = tuple(1., -2., 3., -4.);
|
||||
assert_eq!(a * 0.5, tuple(0.5, -1., 1.5, -2.));
|
||||
assert_eq!(0.5 * a, tuple(0.5, -1., 1.5, -2.));
|
||||
let a = Tuple::new(1., -2., 3., -4.);
|
||||
assert_eq!(a * 0.5, Tuple::new(0.5, -1., 1.5, -2.));
|
||||
assert_eq!(0.5 * a, Tuple::new(0.5, -1., 1.5, -2.));
|
||||
}
|
||||
#[test]
|
||||
fn div_tuple_scalar() {
|
||||
let a = tuple(1., -2., 3., -4.);
|
||||
assert_eq!(a / 2., tuple(0.5, -1., 1.5, -2.));
|
||||
let a = Tuple::new(1., -2., 3., -4.);
|
||||
assert_eq!(a / 2., Tuple::new(0.5, -1., 1.5, -2.));
|
||||
}
|
||||
#[test]
|
||||
fn vector_magnitude() {
|
||||
assert_eq!(1., vector(1., 0., 0.).magnitude());
|
||||
assert_eq!(1., vector(0., 1., 0.).magnitude());
|
||||
assert_eq!(1., vector(0., 0., 1.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), vector(1., 2., 3.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), vector(-1., -2., -3.).magnitude());
|
||||
assert_eq!(1., Tuple::vector(1., 0., 0.).magnitude());
|
||||
assert_eq!(1., Tuple::vector(0., 1., 0.).magnitude());
|
||||
assert_eq!(1., Tuple::vector(0., 0., 1.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), Tuple::vector(1., 2., 3.).magnitude());
|
||||
assert_eq!(14_f32.sqrt(), Tuple::vector(-1., -2., -3.).magnitude());
|
||||
}
|
||||
#[test]
|
||||
fn vector_normalize() {
|
||||
assert_eq!(vector(1., 0., 0.), vector(4., 0., 0.).normalize());
|
||||
assert_eq!(
|
||||
vector(1. / 14_f32.sqrt(), 2. / 14_f32.sqrt(), 3. / 14_f32.sqrt()),
|
||||
vector(1., 2., 3.).normalize()
|
||||
Tuple::vector(1., 0., 0.),
|
||||
Tuple::vector(4., 0., 0.).normalize()
|
||||
);
|
||||
assert_eq!(
|
||||
Tuple::vector(1. / 14_f32.sqrt(), 2. / 14_f32.sqrt(), 3. / 14_f32.sqrt()),
|
||||
Tuple::vector(1., 2., 3.).normalize()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
@ -318,53 +322,53 @@ mod tests {
|
||||
assert!(approx_eq!(
|
||||
f32,
|
||||
1.,
|
||||
vector(1., 2., 3.).normalize().magnitude(),
|
||||
Tuple::vector(1., 2., 3.).normalize().magnitude(),
|
||||
ulps = 1
|
||||
));
|
||||
}
|
||||
#[test]
|
||||
fn dot_two_tuples() {
|
||||
let a = vector(1., 2., 3.);
|
||||
let b = vector(2., 3., 4.);
|
||||
let a = Tuple::vector(1., 2., 3.);
|
||||
let b = Tuple::vector(2., 3., 4.);
|
||||
assert_eq!(20., dot(a, b));
|
||||
}
|
||||
#[test]
|
||||
fn cross_two_tuples() {
|
||||
let a = vector(1., 2., 3.);
|
||||
let b = vector(2., 3., 4.);
|
||||
assert_eq!(vector(-1., 2., -1.), cross(a, b));
|
||||
assert_eq!(vector(1., -2., 1.), cross(b, a));
|
||||
let a = Tuple::vector(1., 2., 3.);
|
||||
let b = Tuple::vector(2., 3., 4.);
|
||||
assert_eq!(Tuple::vector(-1., 2., -1.), cross(a, b));
|
||||
assert_eq!(Tuple::vector(1., -2., 1.), cross(b, a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn color_rgb() {
|
||||
let c = color(-0.5, 0.4, 1.7);
|
||||
let c = Color::new(-0.5, 0.4, 1.7);
|
||||
assert_eq!(c.red, -0.5);
|
||||
assert_eq!(c.green, 0.4);
|
||||
assert_eq!(c.blue, 1.7);
|
||||
}
|
||||
#[test]
|
||||
fn add_color() {
|
||||
let c1 = color(0.9, 0.6, 0.75);
|
||||
let c2 = color(0.7, 0.1, 0.25);
|
||||
assert_eq!(c1 + c2, color(0.9 + 0.7, 0.6 + 0.1, 0.75 + 0.25));
|
||||
let c1 = Color::new(0.9, 0.6, 0.75);
|
||||
let c2 = Color::new(0.7, 0.1, 0.25);
|
||||
assert_eq!(c1 + c2, Color::new(0.9 + 0.7, 0.6 + 0.1, 0.75 + 0.25));
|
||||
}
|
||||
#[test]
|
||||
fn sub_color() {
|
||||
let c1 = color(0.9, 0.6, 0.75);
|
||||
let c2 = color(0.7, 0.1, 0.25);
|
||||
assert_eq!(c1 - c2, color(0.9 - 0.7, 0.6 - 0.1, 0.75 - 0.25));
|
||||
let c1 = Color::new(0.9, 0.6, 0.75);
|
||||
let c2 = Color::new(0.7, 0.1, 0.25);
|
||||
assert_eq!(c1 - c2, Color::new(0.9 - 0.7, 0.6 - 0.1, 0.75 - 0.25));
|
||||
}
|
||||
#[test]
|
||||
fn mul_color_scalar() {
|
||||
let c = color(0.2, 0.3, 0.4);
|
||||
assert_eq!(c * 2., color(0.2 * 2., 0.3 * 2., 0.4 * 2.));
|
||||
assert_eq!(2. * c, color(0.2 * 2., 0.3 * 2., 0.4 * 2.));
|
||||
let c = Color::new(0.2, 0.3, 0.4);
|
||||
assert_eq!(c * 2., Color::new(0.2 * 2., 0.3 * 2., 0.4 * 2.));
|
||||
assert_eq!(2. * c, Color::new(0.2 * 2., 0.3 * 2., 0.4 * 2.));
|
||||
}
|
||||
#[test]
|
||||
fn mul_colors() {
|
||||
let c1 = color(1., 0.2, 0.4);
|
||||
let c2 = color(0.9, 1., 0.1);
|
||||
assert_eq!(c1 * c2, color(1.0 * 0.9, 0.2 * 1., 0.4 * 0.1));
|
||||
let c1 = Color::new(1., 0.2, 0.4);
|
||||
let c2 = Color::new(0.9, 1., 0.1);
|
||||
assert_eq!(c1 * c2, Color::new(1.0 * 0.9, 0.2 * 1., 0.4 * 0.1));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user