less copy protection, more size visualization
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

739 line
22 KiB

  1. function makeObject(name, viewInfo) {
  2. views = {};
  3. Object.entries(viewInfo).forEach(([key, value]) => {
  4. views[key] = {
  5. attributes: {
  6. height: {
  7. name: "Height",
  8. power: 1,
  9. type: "length",
  10. base: value.height
  11. }
  12. },
  13. image: value.image,
  14. name: value.name,
  15. rename: value.rename
  16. }
  17. if (value.mass) {
  18. views[key].attributes.mass = {
  19. name: "Mass",
  20. power: 3,
  21. type: "mass",
  22. base: value.mass
  23. };
  24. }
  25. if (value.volume) {
  26. views[key].attributes.capacity = {
  27. name: "Volume",
  28. power: 3,
  29. type: "volume",
  30. base: value.volume
  31. }
  32. }
  33. if (value.energy) {
  34. views[key].attributes.capacity = {
  35. name: "Energy",
  36. power: 3,
  37. type: "energy",
  38. base: value.energy
  39. }
  40. }
  41. });
  42. return makeEntity({ name: name }, views);
  43. }
  44. SHOE_REFERENCE = 60
  45. function addShoeView(object, name, points) {
  46. object[name] = {
  47. height: math.unit(points / SHOE_REFERENCE, "inches"),
  48. image: { source: "./media/objects/shoes/shoe_" + name + ".svg" },
  49. name: name.replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  50. rename: true
  51. }
  52. }
  53. function makeHeight(info, category, prefix = "", type = "objects") {
  54. const views = {};
  55. info.forEach(object => {
  56. let src;
  57. // this lets us provide our own source if needed
  58. // useful for reusing existing art
  59. if (object[3]) {
  60. src = object[3];
  61. } else {
  62. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  63. }
  64. views[object[0]] = {
  65. height: math.unit(object[1], object[2]),
  66. image: { source: src },
  67. name: object[0].replace(/-/g, " ").replace(/\b(?<!')\w/g, x => x.toUpperCase()),
  68. rename: true
  69. }
  70. });
  71. return {
  72. name: category,
  73. constructor: () => makeObject(
  74. category,
  75. views
  76. )
  77. }
  78. }
  79. function makeHeightWeight(info, category, prefix = "", type = "objects") {
  80. const views = {};
  81. info.forEach(object => {
  82. let src;
  83. // this lets us provide our own source if needed
  84. // useful for reusing existing art
  85. if (object[5]) {
  86. src = object[5];
  87. } else {
  88. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  89. }
  90. views[object[0]] = {
  91. height: math.unit(object[1], object[2]),
  92. mass: math.unit(object[3], object[4]),
  93. image: { source: src },
  94. name: object[0].replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  95. rename: true
  96. }
  97. });
  98. return {
  99. name: category,
  100. constructor: () => makeObject(
  101. category,
  102. views
  103. )
  104. }
  105. }
  106. function makeHeightWeightSphere(info, category, prefix = "", type = "objects") {
  107. const views = {};
  108. info.forEach(object => {
  109. let src;
  110. // this lets us provide our own source if needed
  111. // useful for reusing existing art
  112. if (object[5]) {
  113. src = object[5];
  114. } else {
  115. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  116. }
  117. views[object[0]] = {
  118. height: math.unit(object[1], object[2]),
  119. mass: math.unit(object[3], object[4]),
  120. volume: math.unit(Math.PI * 4 / 3 * Math.pow((object[1]/2), 3), object[2] + "^3"),
  121. image: { source: src },
  122. name: object[0].replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  123. rename: true
  124. }
  125. });
  126. return {
  127. name: category,
  128. constructor: () => makeObject(
  129. category,
  130. views
  131. )
  132. }
  133. }
  134. function makeShoes() {
  135. const views = {};
  136. [
  137. ["flip-flops", 154.239],
  138. ["knee-boots", 841.827],
  139. ["trainers", 260.607],
  140. ["stilettos", 418.839]
  141. ].forEach(shoe => {
  142. addShoeView(views, shoe[0], shoe[1])
  143. });
  144. return {
  145. name: "Shoes",
  146. constructor: () => makeObject(
  147. "Shoes",
  148. views
  149. )
  150. }
  151. }
  152. function makeObjects() {
  153. const results = [];
  154. results.push({
  155. name: "Soda Can",
  156. constructor: () => makeObject(
  157. "Soda Can",
  158. {
  159. front: {
  160. height: math.unit(4.83, "inches"),
  161. mass: math.unit(15, "grams"),
  162. image: { source: "./media/objects/soda-can.svg" },
  163. name: "Side"
  164. }
  165. }
  166. )
  167. });
  168. results.push({
  169. name: "Sewing Pin",
  170. constructor: () => makeObject(
  171. "Sewing Pin",
  172. {
  173. side: {
  174. height: math.unit(1.5, "inches"),
  175. image: { source: "./media/objects/sewing-pin.svg" },
  176. name: "Side"
  177. },
  178. top: {
  179. height: math.unit(2, "millimeters"),
  180. image: { source: "./media/objects/pin-head.svg" },
  181. name: "Head"
  182. }
  183. }
  184. )
  185. });
  186. results.push({
  187. name: "Lamp",
  188. constructor: () => makeObject(
  189. "Lamp",
  190. {
  191. lamp: {
  192. height: math.unit(30, "inches"),
  193. mass: math.unit(10, "lbs"),
  194. image: { source: "./media/objects/lamp.svg" },
  195. name: "Lamp"
  196. }
  197. }
  198. )
  199. });
  200. results.push({
  201. name: "Nail Polish",
  202. constructor: () => makeObject(
  203. "Nail Polish",
  204. {
  205. bottle: {
  206. height: math.unit(3.25, "inches"),
  207. mass: math.unit(66, "g"),
  208. image: { source: "./media/objects/nail-polish.svg" },
  209. name: "Bottle"
  210. }
  211. }
  212. )
  213. });
  214. results.push({
  215. name: "Shot Glass",
  216. constructor: () => makeObject(
  217. "Shot Glass",
  218. {
  219. glass: {
  220. height: math.unit(2 + 3 / 8, "inches"),
  221. mass: math.unit(75, "g"),
  222. image: { source: "./media/objects/shot-glass.svg" },
  223. name: "Bottle"
  224. }
  225. }
  226. )
  227. });
  228. results.push({
  229. name: "Beer Bottle",
  230. constructor: () => makeObject(
  231. "Beer Bottle",
  232. {
  233. longneck: {
  234. height: math.unit(9, "inches"),
  235. mass: math.unit(200, "g"),
  236. image: { source: "./media/objects/beer-bottle.svg" },
  237. name: "Longneck Bottle"
  238. }
  239. }
  240. )
  241. });
  242. results.push({
  243. name: "Coin",
  244. constructor: () => makeObject(
  245. "Coin",
  246. {
  247. penny: {
  248. height: math.unit(0.75, "inches"),
  249. mass: math.unit(2.5, "g"),
  250. image: { source: "./media/objects/circle.svg" },
  251. name: "Penny",
  252. rename: true
  253. },
  254. nickel: {
  255. height: math.unit(0.835, "inches"),
  256. mass: math.unit(5, "g"),
  257. image: { source: "./media/objects/circle.svg" },
  258. name: "Nickel",
  259. rename: true
  260. },
  261. dime: {
  262. height: math.unit(0.705, "inches"),
  263. mass: math.unit(2.268, "g"),
  264. image: { source: "./media/objects/circle.svg" },
  265. name: "Dime",
  266. rename: true
  267. },
  268. quarter: {
  269. height: math.unit(0.955, "inches"),
  270. mass: math.unit(5.67, "g"),
  271. image: { source: "./media/objects/circle.svg" },
  272. name: "Quarter",
  273. rename: true
  274. },
  275. dollar: {
  276. height: math.unit(1.043, "inches"),
  277. mass: math.unit(8.1, "g"),
  278. image: { source: "./media/objects/circle.svg" },
  279. name: "Dollar Coin",
  280. rename: true
  281. },
  282. }
  283. )
  284. });
  285. results.push({
  286. name: "Pencil",
  287. constructor: () => makeObject(
  288. "Pencil",
  289. {
  290. pencil: {
  291. height: math.unit(7.5, "inches"),
  292. mass: math.unit(7, "g"),
  293. image: { source: "./media/objects/pencil.svg" },
  294. name: "Pencil"
  295. }
  296. }
  297. )
  298. });
  299. results.push({
  300. name: "Balls",
  301. constructor: () => makeObject(
  302. "Balls",
  303. {
  304. golf: {
  305. height: math.unit(1.62, "inches"),
  306. mass: math.unit(45, "g"),
  307. image: { source: "./media/objects/circle.svg" },
  308. name: "Golfball",
  309. rename: true
  310. },
  311. tennis: {
  312. height: math.unit(2.6, "inches"),
  313. mass: math.unit(57, "g"),
  314. image: { source: "./media/objects/circle.svg" },
  315. name: "Tennisball",
  316. rename: true
  317. },
  318. baseball: {
  319. height: math.unit(2.9, "inches"),
  320. mass: math.unit(145, "g"),
  321. image: { source: "./media/objects/circle.svg" },
  322. name: "Baseball",
  323. rename: true
  324. },
  325. volleyball: {
  326. height: math.unit(8, "inches"),
  327. mass: math.unit(270, "g"),
  328. image: { source: "./media/objects/circle.svg" },
  329. name: "Volleyball",
  330. rename: true
  331. }
  332. }
  333. )
  334. });
  335. results.push({
  336. name: "Paperclip",
  337. constructor: () => makeObject(
  338. "Paperclip",
  339. {
  340. paperclip: {
  341. height: math.unit(1.834, "inches"),
  342. mass: math.unit(1, "g"),
  343. image: { source: "./media/objects/paperclip.svg" },
  344. name: "Paperclip"
  345. }
  346. }
  347. )
  348. });
  349. results.push({
  350. name: "Pebbles",
  351. constructor: () => makeObject(
  352. "Pebbles",
  353. {
  354. gravelGrain: {
  355. height: math.unit(20, "mm"),
  356. image: { source: "./media/objects/pebble.svg" },
  357. name: "Grain of gravel",
  358. rename: true
  359. },
  360. sandGrain: {
  361. height: math.unit(0.5, "mm"),
  362. image: { source: "./media/objects/pebble.svg" },
  363. name: "Grain of sand",
  364. rename: true
  365. },
  366. siltGrain: {
  367. height: math.unit(0.03, "mm"),
  368. image: { source: "./media/objects/pebble.svg" },
  369. name: "Grain of silt",
  370. rename: true
  371. },
  372. }
  373. )
  374. });
  375. results.push({
  376. name: "Credit Card",
  377. constructor: () => makeObject(
  378. "Credit Card",
  379. {
  380. creditCard: {
  381. height: math.unit(53.98, "mm"),
  382. image: { source: "./media/objects/credit-card.svg" },
  383. name: "Credit card",
  384. },
  385. creditCardVertical: {
  386. height: math.unit(85.60, "mm"),
  387. image: { source: "./media/objects/credit-card-vertical.svg" },
  388. name: "Credit card (vertical)",
  389. },
  390. }
  391. )
  392. });
  393. results.push({
  394. name: "Molecular",
  395. constructor: () => makeObject(
  396. "Molecular",
  397. {
  398. hydrogen: {
  399. height: math.unit(1.06e-10, "m"),
  400. mass: math.unit(1, "dalton"),
  401. image: { source: "./media/objects/circle.svg" },
  402. name: "Hydrogen atom",
  403. rename: true
  404. },
  405. proton: {
  406. height: math.unit(0.877e-15, "m"),
  407. mass: math.unit(1, "dalton"),
  408. image: { source: "./media/objects/circle.svg" },
  409. name: "Proton",
  410. rename: true
  411. },
  412. }
  413. )
  414. });
  415. results.push(makeShoes());
  416. results.push({
  417. name: "Flagpole",
  418. constructor: () => makeObject(
  419. "Flagpole",
  420. {
  421. residential: {
  422. height: math.unit(20, "feet"),
  423. image: { source: "./media/objects/flagpole.svg" },
  424. name: "Residential"
  425. },
  426. medium: {
  427. height: math.unit(50, "feet"),
  428. image: { source: "./media/objects/flagpole.svg" },
  429. name: "Medium"
  430. },
  431. large: {
  432. height: math.unit(100, "feet"),
  433. image: { source: "./media/objects/flagpole.svg" },
  434. name: "Large"
  435. },
  436. }
  437. )
  438. });
  439. results.push({
  440. name: "Vending Machine",
  441. constructor: () => makeObject(
  442. "Vending Machine",
  443. {
  444. object: {
  445. height: math.unit(183, "cm"),
  446. mass: math.unit(347, "kg"),
  447. image: { source: "./media/objects/vending-machine.svg" },
  448. name: "Vending Machine"
  449. }
  450. }
  451. )
  452. })
  453. results.push({
  454. name: "International Space Station",
  455. constructor: () => makeObject(
  456. "International Space Station",
  457. {
  458. object: {
  459. height: math.unit(209, "feet"),
  460. mass: math.unit(925300, "lbs"),
  461. image: { source: "./media/objects/international-space-station.svg" },
  462. name: "International Space Station"
  463. }
  464. }
  465. )
  466. })
  467. results.push(makeHeight(
  468. [
  469. ["king", 4, "inches"],
  470. ["queen", 351 / 407 * 4, "inches"],
  471. ["bishop", 340 / 407 * 4, "inches"],
  472. ["knight", 309 / 407 * 4, "inches"],
  473. ["rook", 271 / 407 * 4, "inches"],
  474. ["pawn", 197 / 407 * 4, "inches"],
  475. ],
  476. "Chess Pieces",
  477. "chess_"
  478. ));
  479. results.push({
  480. name: "Strand",
  481. constructor: () => {
  482. views = {};
  483. viewInfo = {
  484. opticalFibre: {
  485. name: "Optical Fibre",
  486. thickness: math.unit(0.375, "mm")
  487. },
  488. hair: {
  489. name: "Hair",
  490. thickness: math.unit(0.07, "mm")
  491. },
  492. spiderSilk: {
  493. name: "Spider Silk",
  494. thickness: math.unit(0.003, "mm")
  495. },
  496. suspensionCables: {
  497. name: "Suspension Bridge Cables",
  498. thickness: math.unit(3, "feet")
  499. },
  500. capillary: {
  501. name: "Capillary",
  502. thickness: math.unit(7.5, "micrometers")
  503. },
  504. vein: {
  505. name: "Vein",
  506. thickness: math.unit(10, "mm")
  507. },
  508. thread: {
  509. name: "Thread",
  510. thickness: math.unit(0.4, "mm")
  511. },
  512. powerCord: {
  513. name: "Power Cord",
  514. thickness: math.unit(0.25, "inches")
  515. },
  516. pianoWireBass: {
  517. name: "Piano Wire (Bass)",
  518. thickness: math.unit(8.5, "mm")
  519. },
  520. pianoWireTreble: {
  521. name: "Piano Wire (Treble)",
  522. thickness: math.unit(0.85, "mm")
  523. },
  524. guitarString: {
  525. name: "Guitar String",
  526. thickness: math.unit(0.03, "inches")
  527. },
  528. powerLineThin: {
  529. name: "Power Line (Thin)",
  530. thickness: math.unit(0.325, "inches")
  531. },
  532. powerLineThick: {
  533. name: "Power Line (Thick)",
  534. thickness: math.unit(0.720, "inches")
  535. },
  536. carbonNanotube: {
  537. name: "Carbon Nanotube",
  538. thickness: math.unit(4, "nm")
  539. }
  540. }
  541. Object.entries(viewInfo).forEach(([key, value]) => {
  542. views[key] = {
  543. attributes: {
  544. height: {
  545. name: "Height",
  546. power: 1,
  547. type: "length",
  548. base: math.multiply(value.thickness, 253.4385 / 5)
  549. },
  550. thickness: {
  551. name: "Thickness",
  552. power: 1,
  553. type: "length",
  554. base: value.thickness
  555. },
  556. },
  557. image: {
  558. source: "./media/objects/strand.svg"
  559. },
  560. name: value.name,
  561. rename: true
  562. }
  563. if (value.mass) {
  564. views[key].attributes.mass = {
  565. name: "Mass",
  566. power: 3,
  567. type: "mass",
  568. base: value.mass
  569. };
  570. }
  571. });
  572. return makeEntity({ name: "Strand" }, views);
  573. }
  574. })
  575. results.push(makeHeight(
  576. [
  577. ["animal-cell", 25, "micrometers"],
  578. ["plant-cell", 75, "micrometers"],
  579. ["mitochondria", 0.5, "micrometer"],
  580. ["bacteria", 0.3, "micrometer"],
  581. ["red-blood-cell", 6.5, "micrometer"],
  582. ["white-blood-cell", 13, "micrometer"],
  583. ["amoeba-proteus", 500, "micrometers"],
  584. ["chaos-carolinensis", 1500, "micrometers"]
  585. ],
  586. "Cells",
  587. "cell_"
  588. ))
  589. results.push(makeHeight(
  590. [
  591. ["stop-sign", 36, "inches"],
  592. ["yield-sign", 36, "inches"],
  593. ["pedestrian-crossing", 30, "inches"],
  594. ["highway-exit", 150, "inches"]
  595. ],
  596. "Signs",
  597. ""
  598. ))
  599. results.push({
  600. name: "Game Consoles",
  601. constructor: () => makeVehicleGroup([
  602. {
  603. name: "Switch",
  604. mass: math.unit(10.48, "ounces"),
  605. sides: {
  606. "Front": { height: math.unit(4.01, "inches") },
  607. "Top": { height: math.unit(1.13, "inches") },
  608. "Side": { height: math.unit(4.01, "inches") },
  609. }
  610. }
  611. ],
  612. "Game Consoles",
  613. "",
  614. "objects")
  615. })
  616. results.push({
  617. name: "Electromagnetic Waves",
  618. constructor: () => {
  619. views = {};
  620. viewInfo = [
  621. ["Gamma rays", math.unit(1, "pm")],
  622. ["Hard X-rays", math.unit(20, "pm")],
  623. ["Soft X-rays", math.unit(1, "nm")],
  624. ["Extreme-ultraviolet", math.unit(50, "nm")],
  625. ["UVC", math.unit(200, "nm")],
  626. ["UVB", math.unit(295, "nm")],
  627. ["UVA", math.unit(350, "nm")],
  628. ["Violet", math.unit(415, "nm")],
  629. ["Blue", math.unit(470, "nm")],
  630. ["Cyan", math.unit(490, "nm")],
  631. ["Green", math.unit(530, "nm")],
  632. ["Yellow", math.unit(580, "nm")],
  633. ["Orange", math.unit(610, "nm")],
  634. ["Red", math.unit(690, "nm")],
  635. ["Near-infrared", math.unit(1.2, "um")],
  636. ["Short-wavelength infrared", math.unit(2.2, "um")],
  637. ["Mid-wavelength infrared", math.unit(6.5, "um")],
  638. ["Long-wavelength infrared", math.unit(12, "um")],
  639. ["Far infrared", math.unit(500, "um")],
  640. ["D-band microwaves (mm-wave)", math.unit(2, "mm")],
  641. ["S-band microwaves (ovens, wifi)", math.unit(11, "cm")],
  642. ["L-band microwaves (GPS)", math.unit(22, "cm")],
  643. ["UHF", math.unit(50, "cm")],
  644. ["FM radio", math.unit(3.5, "m")],
  645. ["VHF", math.unit(5, "m")],
  646. ["HF", math.unit(50, "m")],
  647. ["AM radio", math.unit(250, "m")],
  648. ["MF", math.unit(500, "m")],
  649. ["LF", math.unit(5, "km")],
  650. ["VLF", math.unit(50, "km")],
  651. ["ULF", math.unit(500, "km")],
  652. ["SLF", math.unit(5000, "km")],
  653. ["ELF", math.unit(50000, "km")],
  654. ]
  655. viewInfo.forEach(([name, length]) => {
  656. views[name] = {
  657. attributes: {
  658. height: {
  659. name: "Height",
  660. power: 1,
  661. type: "length",
  662. base: math.multiply(length, 2)
  663. }
  664. },
  665. image: {
  666. source: "./media/objects/sine-wave.svg"
  667. },
  668. name: name,
  669. rename: true,
  670. default: name === "Green"
  671. }
  672. });
  673. return makeEntity({ name: "Electromagnetic Waves" }, views);
  674. }
  675. })
  676. results.sort((b1, b2) => {
  677. e1 = b1.constructor();
  678. e2 = b2.constructor();
  679. return -math.subtract(e1.views[e1.defaultView].height, e2.views[e2.defaultView].height).value;
  680. });
  681. return results;
  682. }