Skip to content
Snippets Groups Projects
Commit 4ed96bda authored by orestis.malaspin's avatar orestis.malaspin
Browse files

Merge branch 'tp_galaxy' into 'master'

Ajout tp système planétaire

See merge request orestis.malaspin/isc_physics!19
parents f5bb2bb8 73cf8569
Branches
No related tags found
No related merge requests found
Showing
with 850 additions and 1 deletion
......@@ -9,3 +9,5 @@
.vscode
practical_work/tp_vec2/main
practical_work/tp_vec2/tests
practical_work/planets/skeleton/main
practical_work/planets/skeleton/tests
\ No newline at end of file
......@@ -36,7 +36,7 @@ $$
En ce qui concerne sa direction, si $Q>0$ alors le vecteur va chercher à s'éloigner de la particule, et si $Q<0$ alors le vecteur est dirigé vers la particule.
![Champs de vecteurs représentant de champs électrique d'une charge positive. Source: Wikipédia, <https://bit.ly/3bTIJDx>.](https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/E_FieldOnePointCharge.svg/langfr-1024px-E_FieldOnePointCharge.svg.png){#fig:champ_e width=50%}
![Champs de vecteurs représentant de champs électrique d'une charge positive. Source: Wikipédia, <https://bit.ly/3kUEcGu>.](https://upload.wikimedia.org/wikipedia/commons/f/f0/E_FieldOnePointCharge.svg){#fig:champ_e width=50%}
En réalité, on rencontre souvent (très souvent) plus d'une particule chargée, dans ce cas, on se sert du principe de superposition des champs électriques. Le vecteur en un point représente alors la résultante des actions induites par chacune de nos particules chargées.
......
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="989" height="775"><defs><clipPath id="ZNxznfRplkyb"><path fill="none" stroke="none" d=" M 0 0 L 989 0 L 989 775 L 0 775 L 0 0 Z"/></clipPath></defs><g transform="scale(1,1)" clip-path="url(#ZNxznfRplkyb)"><g><rect fill="rgb(255,255,255)" stroke="none" x="0" y="0" width="989" height="775" fill-opacity="1"/><path fill="rgb(21,101,192)" stroke="none" paint-order="stroke fill markers" d=" M 425.74752862300124 584.4329932425899 C 425.74752862300124 674.531164865674 352.70852933798386 747.5701641506912 262.6103577148996 747.5701641506912 C 172.5121860918153 747.5701641506912 99.47318680679794 674.531164865674 99.47318680679794 584.4329932425899 C 99.47318680679794 494.33482161950565 172.5121860918153 421.29582233448843 262.6103577148996 421.29582233448843 C 352.70852933798386 421.29582233448843 425.74752862300124 494.33482161950565 425.74752862300124 584.4329932425899 Z" fill-opacity="1"/><path fill="none" stroke="rgb(21,101,192)" paint-order="fill stroke markers" d=" M 425.74752862300124 584.4329932425899 C 425.74752862300124 674.531164865674 352.70852933798386 747.5701641506912 262.6103577148996 747.5701641506912 C 172.5121860918153 747.5701641506912 99.47318680679794 674.531164865674 99.47318680679794 584.4329932425899 C 99.47318680679794 494.33482161950565 172.5121860918153 421.29582233448843 262.6103577148996 421.29582233448843 C 352.70852933798386 421.29582233448843 425.74752862300124 494.33482161950565 425.74752862300124 584.4329932425899 Z" stroke-opacity="0.6980392156862745" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="0.5"/><path fill="rgb(255,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 895.8370009494233 173.192886789024 C 895.8370009494233 220.10214870531163 857.8095306263009 258.12961902843404 810.9002687100132 258.12961902843404 C 763.9910067937254 258.12961902843404 725.963536470603 220.10214870531163 725.963536470603 173.192886789024 C 725.963536470603 126.28362487273633 763.9910067937254 88.25615454961394 810.9002687100132 88.25615454961394 C 857.8095306263009 88.25615454961394 895.8370009494233 126.28362487273633 895.8370009494233 173.192886789024 Z" fill-opacity="1"/><path fill="none" stroke="rgb(255,0,0)" paint-order="fill stroke markers" d=" M 895.8370009494233 173.192886789024 C 895.8370009494233 220.10214870531163 857.8095306263009 258.12961902843404 810.9002687100132 258.12961902843404 C 763.9910067937254 258.12961902843404 725.963536470603 220.10214870531163 725.963536470603 173.192886789024 C 725.963536470603 126.28362487273633 763.9910067937254 88.25615454961394 810.9002687100132 88.25615454961394 C 857.8095306263009 88.25615454961394 895.8370009494233 126.28362487273633 895.8370009494233 173.192886789024 Z" stroke-opacity="0.6980392156862745" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2.5"/><path fill="none" stroke="rgb(255,0,0)" paint-order="fill stroke markers" d=" M 262.6103577148996 584.4329932425899 L 505.55593250745994 402.21376571971524" stroke-opacity="1" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="6.5"/><path fill="rgb(255,0,0)" stroke="none" paint-order="stroke fill markers" fill-rule="evenodd" d=" M 536.7553132124564 378.81294001580693 L 511.40613893343703 410.01361089596435 L 499.70572608148285 394.41392054346613 Z" fill-opacity="1"/><path fill="none" stroke="rgb(0,0,255)" paint-order="fill stroke markers" d=" M 810.9002687100132 173.192886789024 L 567.9546939174528 355.4121143118986" stroke-opacity="1" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="6.5"/><path fill="rgb(0,0,255)" stroke="none" paint-order="stroke fill markers" fill-rule="evenodd" d=" M 536.7553132124564 378.81294001580693 L 562.1044874914758 347.6122691356495 L 573.8049003434298 363.2119594881477 Z" fill-opacity="1"/><path fill="none" stroke="rgb(51,0,0)" paint-order="fill stroke markers" d=" M 257.6103577148996 579.4329932425899 L 267.6103577148996 589.4329932425899" stroke-opacity="1" stroke-linecap="square" stroke-miterlimit="10" stroke-width="2.5"/><path fill="none" stroke="rgb(51,0,0)" paint-order="fill stroke markers" d=" M 257.6103577148996 589.4329932425899 L 267.6103577148996 579.4329932425899" stroke-opacity="1" stroke-linecap="square" stroke-miterlimit="10" stroke-width="2.5"/><path fill="none" stroke="rgb(0,0,0)" paint-order="fill stroke markers" d=" M 805.9002687100132 168.192886789024 L 815.9002687100132 178.192886789024" stroke-opacity="1" stroke-linecap="square" stroke-miterlimit="10" stroke-width="2.5"/><path fill="none" stroke="rgb(0,0,0)" paint-order="fill stroke markers" d=" M 805.9002687100132 178.192886789024 L 815.9002687100132 168.192886789024" stroke-opacity="1" stroke-linecap="square" stroke-miterlimit="10" stroke-width="2.5"/><text fill="rgb(0,0,0)" stroke="none" font-family="geogebra-sans-serif, sans-serif" font-size="64px" font-style="normal" font-weight="normal" text-decoration="normal" x="149" y="402" text-anchor="start" dominant-baseline="alphabetic" fill-opacity="1">A</text><text fill="rgb(0,0,0)" stroke="none" font-family="geogebra-sans-serif, sans-serif" font-size="64px" font-style="normal" font-weight="normal" text-decoration="normal" x="762" y="71" text-anchor="start" dominant-baseline="alphabetic" fill-opacity="1">B</text><g transform="scale(35,35)"><g transform="translate(10.661285714285714,11.656857142857143)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.537 -0.595 L 0.217 -0.595 Q 0.186 -0.595 0.183 -0.609 Q 0.182 -0.612 0.182 -0.615 Q 0.188 -0.635 0.217 -0.635 L 0.554 -0.635 Q 0.534 -0.661 0.53 -0.6930000000000001 Q 0.53 -0.709 0.544 -0.713 Q 0.547 -0.714 0.55 -0.714 Q 0.5650000000000001 -0.714 0.5700000000000001 -0.6920000000000001 Q 0.583 -0.654 0.611 -0.635 Q 0.625 -0.625 0.625 -0.615 Q 0.625 -0.604 0.608 -0.594 Q 0.5630000000000001 -0.5720000000000001 0.529 -0.529 Q 0.518 -0.516 0.51 -0.516 Q 0.496 -0.516 0.491 -0.53 Q 0.49 -0.533 0.49 -0.536 Q 0.49 -0.552 0.537 -0.595 Z"/></g><g transform="translate(10.514285714285714,11.908857142857144)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.303 -0.325 L 0.241 -0.076 Q 0.23700000000000002 -0.061 0.23700000000000002 -0.053 Q 0.23700000000000002 -0.039 0.25 -0.036000000000000004 Q 0.257 -0.034 0.269 -0.033 Q 0.294 -0.031 0.321 -0.031 Q 0.34600000000000003 -0.031 0.34900000000000003 -0.03 L 0.354 -0.023 Q 0.355 -0.021 0.355 -0.019 Q 0.355 0 0.334 0 L 0.186 -0.003 L 0.185 -0.003 L 0.054 0 L 0.053 0 Q 0.038 0 0.038 -0.012 Q 0.038 -0.029 0.054 -0.031 L 0.066 -0.031 Q 0.131 -0.031 0.14400000000000002 -0.045 Q 0.15 -0.052000000000000005 0.156 -0.073 Q 0.156 -0.074 0.157 -0.078 L 0.289 -0.607 Q 0.294 -0.625 0.294 -0.631 Q 0.294 -0.648 0.248 -0.649 L 0.247 -0.649 L 0.229 -0.649 Q 0.203 -0.649 0.201 -0.66 Q 0.201 -0.678 0.217 -0.68 L 0.231 -0.68 L 0.721 -0.68 Q 0.745 -0.68 0.747 -0.673 L 0.748 -0.673 Q 0.75 -0.667 0.748 -0.653 L 0.728 -0.48 Q 0.721 -0.457 0.714 -0.455 Q 0.7020000000000001 -0.455 0.7020000000000001 -0.467 Q 0.7020000000000001 -0.47200000000000003 0.704 -0.485 Q 0.707 -0.512 0.707 -0.539 Q 0.707 -0.606 0.673 -0.628 L 0.672 -0.629 Q 0.64 -0.649 0.561 -0.649 L 0.429 -0.649 Q 0.392 -0.649 0.385 -0.638 L 0.384 -0.638 L 0.384 -0.637 Q 0.381 -0.633 0.379 -0.625 L 0.379 -0.624 L 0.378 -0.623 Q 0.377 -0.619 0.375 -0.61 L 0.311 -0.356 L 0.402 -0.356 Q 0.47500000000000003 -0.356 0.5 -0.383 L 0.501 -0.384 Q 0.518 -0.403 0.531 -0.452 Q 0.536 -0.47100000000000003 0.546 -0.47300000000000003 Q 0.557 -0.47300000000000003 0.558 -0.462 Q 0.558 -0.457 0.555 -0.446 L 0.5 -0.229 Q 0.49 -0.209 0.485 -0.20800000000000002 Q 0.47300000000000003 -0.20800000000000002 0.47300000000000003 -0.22 Q 0.47300000000000003 -0.224 0.47600000000000003 -0.231 Q 0.483 -0.261 0.483 -0.28 Q 0.483 -0.309 0.461 -0.318 L 0.461 -0.318 Q 0.442 -0.325 0.4 -0.325 L 0.303 -0.325 Z"/></g><g transform="translate(11.157285714285715,12.058857142857143) scale(0.7,0.7)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.16 -0.078 L 0.294 -0.615 Q 0.298 -0.631 0.298 -0.634 Q 0.298 -0.646 0.28200000000000003 -0.649 L 0.281 -0.649 L 0.28 -0.649 Q 0.277 -0.649 0.271 -0.65 Q 0.254 -0.652 0.233 -0.652 Q 0.20700000000000002 -0.652 0.20500000000000002 -0.663 Q 0.20500000000000002 -0.681 0.22 -0.683 L 0.221 -0.683 L 0.222 -0.683 L 0.234 -0.683 L 0.5700000000000001 -0.683 Q 0.685 -0.683 0.734 -0.615 Q 0.756 -0.583 0.756 -0.545 Q 0.756 -0.464 0.666 -0.404 Q 0.665 -0.404 0.664 -0.403 Q 0.611 -0.369 0.547 -0.357 Q 0.649 -0.34500000000000003 0.687 -0.277 Q 0.7020000000000001 -0.249 0.7020000000000001 -0.216 Q 0.7020000000000001 -0.14300000000000002 0.632 -0.079 L 0.631 -0.078 Q 0.545 0 0.426 0 L 0.069 0 Q 0.044 0 0.042 -0.011 Q 0.042 -0.029 0.057 -0.031 L 0.069 -0.031 Q 0.134 -0.031 0.147 -0.045 Q 0.153 -0.052000000000000005 0.159 -0.073 Q 0.159 -0.074 0.16 -0.078 M 0.311 -0.366 L 0.457 -0.366 Q 0.556 -0.366 0.62 -0.438 Q 0.665 -0.489 0.665 -0.549 Q 0.665 -0.622 0.605 -0.644 Q 0.584 -0.652 0.556 -0.652 L 0.427 -0.652 Q 0.391 -0.652 0.383 -0.642 L 0.383 -0.642 L 0.383 -0.641 L 0.382 -0.641 L 0.382 -0.64 Q 0.378 -0.634 0.373 -0.614 L 0.311 -0.366 M 0.266 -0.031 L 0.402 -0.031 Q 0.498 -0.031 0.561 -0.10300000000000001 Q 0.609 -0.159 0.609 -0.227 Q 0.609 -0.3 0.557 -0.33 Q 0.531 -0.34400000000000003 0.494 -0.34400000000000003 L 0.305 -0.34400000000000003 L 0.23600000000000002 -0.065 Q 0.231 -0.047 0.231 -0.042 Q 0.231 -0.034 0.24 -0.032 L 0.24 -0.032 L 0.24 -0.032 L 0.244 -0.032 Q 0.25 -0.031 0.266 -0.031 Z"/></g><g transform="translate(11.723585714285715,12.058857142857143) scale(0.7,0.7)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.179 -0.115 L 0.527 -0.6990000000000001 Q 0.537 -0.715 0.553 -0.716 Q 0.5680000000000001 -0.716 0.5700000000000001 -0.706 Q 0.5710000000000001 -0.7030000000000001 0.5720000000000001 -0.6920000000000001 L 0.633 -0.067 Q 0.636 -0.042 0.645 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.036000000000000004 Q 0.658 -0.031 0.6980000000000001 -0.031 Q 0.72 -0.031 0.721 -0.02 Q 0.721 0 0.7030000000000001 0 L 0.591 -0.003 L 0.59 -0.003 L 0.466 0 L 0.465 0 Q 0.451 0 0.451 -0.011 Q 0.459 -0.03 0.47500000000000003 -0.031 Q 0.547 -0.031 0.547 -0.064 Q 0.547 -0.063 0.531 -0.231 L 0.28 -0.231 L 0.20400000000000001 -0.10300000000000001 Q 0.19 -0.078 0.19 -0.066 Q 0.19 -0.035 0.23700000000000002 -0.031 Q 0.253 -0.031 0.253 -0.019 Q 0.253 0 0.234 0 L 0.138 -0.003 L 0.134 -0.003 L 0.05 0 L 0.048 0 Q 0.035 0 0.035 -0.011 Q 0.035 -0.029 0.05 -0.03 L 0.05 -0.031 L 0.056 -0.031 Q 0.11900000000000001 -0.035 0.159 -0.085 Q 0.169 -0.098 0.179 -0.115 M 0.299 -0.262 L 0.528 -0.262 L 0.496 -0.592 L 0.299 -0.262 Z"/></g></g><g transform="scale(35,35)"><g transform="translate(20.061285714285713,8.399714285714285)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.537 -0.595 L 0.217 -0.595 Q 0.186 -0.595 0.183 -0.609 Q 0.182 -0.612 0.182 -0.615 Q 0.188 -0.635 0.217 -0.635 L 0.554 -0.635 Q 0.534 -0.661 0.53 -0.6930000000000001 Q 0.53 -0.709 0.544 -0.713 Q 0.547 -0.714 0.55 -0.714 Q 0.5650000000000001 -0.714 0.5700000000000001 -0.6920000000000001 Q 0.583 -0.654 0.611 -0.635 Q 0.625 -0.625 0.625 -0.615 Q 0.625 -0.604 0.608 -0.594 Q 0.5630000000000001 -0.5720000000000001 0.529 -0.529 Q 0.518 -0.516 0.51 -0.516 Q 0.496 -0.516 0.491 -0.53 Q 0.49 -0.533 0.49 -0.536 Q 0.49 -0.552 0.537 -0.595 Z"/></g><g transform="translate(19.914285714285715,8.651714285714286)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.303 -0.325 L 0.241 -0.076 Q 0.23700000000000002 -0.061 0.23700000000000002 -0.053 Q 0.23700000000000002 -0.039 0.25 -0.036000000000000004 Q 0.257 -0.034 0.269 -0.033 Q 0.294 -0.031 0.321 -0.031 Q 0.34600000000000003 -0.031 0.34900000000000003 -0.03 L 0.354 -0.023 Q 0.355 -0.021 0.355 -0.019 Q 0.355 0 0.334 0 L 0.186 -0.003 L 0.185 -0.003 L 0.054 0 L 0.053 0 Q 0.038 0 0.038 -0.012 Q 0.038 -0.029 0.054 -0.031 L 0.066 -0.031 Q 0.131 -0.031 0.14400000000000002 -0.045 Q 0.15 -0.052000000000000005 0.156 -0.073 Q 0.156 -0.074 0.157 -0.078 L 0.289 -0.607 Q 0.294 -0.625 0.294 -0.631 Q 0.294 -0.648 0.248 -0.649 L 0.247 -0.649 L 0.229 -0.649 Q 0.203 -0.649 0.201 -0.66 Q 0.201 -0.678 0.217 -0.68 L 0.231 -0.68 L 0.721 -0.68 Q 0.745 -0.68 0.747 -0.673 L 0.748 -0.673 Q 0.75 -0.667 0.748 -0.653 L 0.728 -0.48 Q 0.721 -0.457 0.714 -0.455 Q 0.7020000000000001 -0.455 0.7020000000000001 -0.467 Q 0.7020000000000001 -0.47200000000000003 0.704 -0.485 Q 0.707 -0.512 0.707 -0.539 Q 0.707 -0.606 0.673 -0.628 L 0.672 -0.629 Q 0.64 -0.649 0.561 -0.649 L 0.429 -0.649 Q 0.392 -0.649 0.385 -0.638 L 0.384 -0.638 L 0.384 -0.637 Q 0.381 -0.633 0.379 -0.625 L 0.379 -0.624 L 0.378 -0.623 Q 0.377 -0.619 0.375 -0.61 L 0.311 -0.356 L 0.402 -0.356 Q 0.47500000000000003 -0.356 0.5 -0.383 L 0.501 -0.384 Q 0.518 -0.403 0.531 -0.452 Q 0.536 -0.47100000000000003 0.546 -0.47300000000000003 Q 0.557 -0.47300000000000003 0.558 -0.462 Q 0.558 -0.457 0.555 -0.446 L 0.5 -0.229 Q 0.49 -0.209 0.485 -0.20800000000000002 Q 0.47300000000000003 -0.20800000000000002 0.47300000000000003 -0.22 Q 0.47300000000000003 -0.224 0.47600000000000003 -0.231 Q 0.483 -0.261 0.483 -0.28 Q 0.483 -0.309 0.461 -0.318 L 0.461 -0.318 Q 0.442 -0.325 0.4 -0.325 L 0.303 -0.325 Z"/></g><g transform="translate(20.557285714285715,8.801714285714286) scale(0.7,0.7)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.179 -0.115 L 0.527 -0.6990000000000001 Q 0.537 -0.715 0.553 -0.716 Q 0.5680000000000001 -0.716 0.5700000000000001 -0.706 Q 0.5710000000000001 -0.7030000000000001 0.5720000000000001 -0.6920000000000001 L 0.633 -0.067 Q 0.636 -0.042 0.645 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.037 L 0.646 -0.036000000000000004 Q 0.658 -0.031 0.6980000000000001 -0.031 Q 0.72 -0.031 0.721 -0.02 Q 0.721 0 0.7030000000000001 0 L 0.591 -0.003 L 0.59 -0.003 L 0.466 0 L 0.465 0 Q 0.451 0 0.451 -0.011 Q 0.459 -0.03 0.47500000000000003 -0.031 Q 0.547 -0.031 0.547 -0.064 Q 0.547 -0.063 0.531 -0.231 L 0.28 -0.231 L 0.20400000000000001 -0.10300000000000001 Q 0.19 -0.078 0.19 -0.066 Q 0.19 -0.035 0.23700000000000002 -0.031 Q 0.253 -0.031 0.253 -0.019 Q 0.253 0 0.234 0 L 0.138 -0.003 L 0.134 -0.003 L 0.05 0 L 0.048 0 Q 0.035 0 0.035 -0.011 Q 0.035 -0.029 0.05 -0.03 L 0.05 -0.031 L 0.056 -0.031 Q 0.11900000000000001 -0.035 0.159 -0.085 Q 0.169 -0.098 0.179 -0.115 M 0.299 -0.262 L 0.528 -0.262 L 0.496 -0.592 L 0.299 -0.262 Z"/></g><g transform="translate(21.082285714285714,8.801714285714286) scale(0.7,0.7)"><path fill="rgb(0,0,0)" stroke="none" paint-order="stroke fill markers" d=" M 0.16 -0.078 L 0.294 -0.615 Q 0.298 -0.631 0.298 -0.634 Q 0.298 -0.646 0.28200000000000003 -0.649 L 0.281 -0.649 L 0.28 -0.649 Q 0.277 -0.649 0.271 -0.65 Q 0.254 -0.652 0.233 -0.652 Q 0.20700000000000002 -0.652 0.20500000000000002 -0.663 Q 0.20500000000000002 -0.681 0.22 -0.683 L 0.221 -0.683 L 0.222 -0.683 L 0.234 -0.683 L 0.5700000000000001 -0.683 Q 0.685 -0.683 0.734 -0.615 Q 0.756 -0.583 0.756 -0.545 Q 0.756 -0.464 0.666 -0.404 Q 0.665 -0.404 0.664 -0.403 Q 0.611 -0.369 0.547 -0.357 Q 0.649 -0.34500000000000003 0.687 -0.277 Q 0.7020000000000001 -0.249 0.7020000000000001 -0.216 Q 0.7020000000000001 -0.14300000000000002 0.632 -0.079 L 0.631 -0.078 Q 0.545 0 0.426 0 L 0.069 0 Q 0.044 0 0.042 -0.011 Q 0.042 -0.029 0.057 -0.031 L 0.069 -0.031 Q 0.134 -0.031 0.147 -0.045 Q 0.153 -0.052000000000000005 0.159 -0.073 Q 0.159 -0.074 0.16 -0.078 M 0.311 -0.366 L 0.457 -0.366 Q 0.556 -0.366 0.62 -0.438 Q 0.665 -0.489 0.665 -0.549 Q 0.665 -0.622 0.605 -0.644 Q 0.584 -0.652 0.556 -0.652 L 0.427 -0.652 Q 0.391 -0.652 0.383 -0.642 L 0.383 -0.642 L 0.383 -0.641 L 0.382 -0.641 L 0.382 -0.64 Q 0.378 -0.634 0.373 -0.614 L 0.311 -0.366 M 0.266 -0.031 L 0.402 -0.031 Q 0.498 -0.031 0.561 -0.10300000000000001 Q 0.609 -0.159 0.609 -0.227 Q 0.609 -0.3 0.557 -0.33 Q 0.531 -0.34400000000000003 0.494 -0.34400000000000003 L 0.305 -0.34400000000000003 L 0.23600000000000002 -0.065 Q 0.231 -0.047 0.231 -0.042 Q 0.231 -0.034 0.24 -0.032 L 0.24 -0.032 L 0.24 -0.032 L 0.244 -0.032 Q 0.25 -0.031 0.266 -0.031 Z"/></g></g></g></g></svg>
\ No newline at end of file
OPTIONS = --filter=pandoc-numbering
OPTIONS += --filter=pandoc-crossref
PDFOPTIONS = --highlight-style kate
PDFOPTIONS += --pdf-engine pdflatex
PDFOPTIONS += --number-sections
PDFOPTIONS += --template=./default.latex
HTMLOPTIONS += -t html5
HTMLOPTIONS += -c ../../css/tufte-css/tufte.css
HTMLOPTIONS += --self-contained
HTMLOPTIONS += --mathjax=MathJax.js
MD=$(wildcard *.md)
HTML=$(MD:%.md=%.html)
PDF=$(MD:%.md=%.pdf)
all: $(HTML) $(PDF)
%.pdf: %.md Makefile
pandoc -s $(OPTIONS) $(PDFOPTIONS) -o $@ $<
%.html: %.md Makefile
pandoc -s $(OPTIONS) $(HTMLOPTIONS) -o $@ $<
clean:
rm -rf *.html *.pdf
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
document.getElementsByTagName("head")[0].appendChild(fileref)
---
# author:
# - El Kharroubi Michaël
title: Travail pratique
subtitle: Simulation d'un système planétaire sur un plan à l'aide des lois de Newton
autoSectionLabels: true
autoEqnLabels: true
eqnPrefix:
- "éq."
- "éqs."
chapters: true
numberSections: false
chaptersDepth: 1
sectionsDepth: 3
lang: fr
documentclass: article
papersize: A4
cref: false
pandoc-numbering:
- category: TP
urlcolor: blue
---
\newcommand{\vectwo}[2]{\begin{pmatrix}#1 \\ #2 \end{pmatrix}}
# But
- Simuler un phénomène physique vu en cours à l'aide du langage C
- Visualiser les interactions gravitationnelles au sein d'un système planétaire.
# Théorie
## Rappel théorique
Dans notre univers, tous les corps sont soumis à des forces. Une force est une grandeur permettant de quantifier pour un corps : la direction, le sens et l'intensité de l'interaction, avec les autres corps, subie. Dans le cadre de ce travail pratique, nous nous intéresserons à l'une des quatre forces fondamentales, la force de gravitation. Pour rappel, les forces suivent les trois lois de Newton.
1. Si un corps est immobile, alors la somme des forces qu'il subit, appelée force résultante, est nulle. ($\vec{F} = \vec{0}$)
2. La force résultante subit par un corps est égale à la masse de ce dernier multipliée par son accélération. ($\vec{F} = m\vec{a}_p$)
3. Si un corps *A* subit une force de la part d'un corps *B*, alors le corps *B* subit une force de réaction de sens opposé et de même intensité. ($\vec{F}_{BA} = -\vec{F}_{AB}$)
![Exemple d'interaction gravitationnelle](./Exemple_force.svg){#fig:gravity width=50%}
La force de gravitation est une force qui apparaît entre tous les objets ayant une masse (un corps). Elle régit le mouvements des objets massifs (planètes, étoiles, trou noir, galaxies...). La force de gravité causée par un corps *B* et subie par un corps *A* s'obtient avec la formule suivante :
$$
\vec{F}_{BA} = G\displaystyle\frac{m_Am_B}{\| \vec{r}_{AB} \|^3}\vec{r}_{AB}
$$
Avec $G$ en [$\frac{\text{m}^3}{\text{kg}\cdot \text{s}^2}$], $m_a$,$m_b$ en [kg] et $\| \vec{r}_{AB} \|$ en [m].
\pagebreak
L'orbite d'une planète n'est pas un cercle parfait, il s'agit en réalité d'une ellipsoïde. Cette orbite ellipsoïdale est définie par trois paramètres :
1. Le demi-grand axe ($a$ en mètres, **!!! à ne pas confondre avec l'accélération $\vec{a}$**)
2. Le demi-petit axe ($b$ en mètres)
3. L'excentricité ($e$ sans unité)
![Exemple (volontairement exagéré) de l'orbite de la terre autour du soleil. Source: Alexis Durgnat (Bureau A403).](./perihelie.svg){#fig:orbite width=50%}
Sur la figure \ref{fig:e}, vous observer différentes orbites pour différentes valeurs de $e$.
![Différentes orbites en fonction de l'excentricité. Source: Wikipédia, <https://bit.ly/3x53F4A>.](https://upload.wikimedia.org/wikipedia/commons/8/89/OrbitalEccentricityDemo.svg){#fig:e width=30%}
\pagebreak
## Simulation d'un système planétaire
### Idée générale
Dans notre simulation, nous représentrons un système planétaire sur un plan, basé sur notre système solaire. Au centre nous aurons une étoile (fixe) et un certain nombre de planètes qui orbitent autour de cette dernière.
Pour simuler un système planétaire, on peut effectuer les étapes suivantes :
1. Créer une étoile au centre de notre domaine.
2. On ajoute autant de planètes que l'on désire autour de l'étoile.
3. On définit nos conditions initiales.
4. On affiche puis on simule l'évolution :
1. [On affiche notre système.]{#here4}
2. On calcule la force résultante sur chacune des planètes.
3. On calcule la prochaine position de chacune des planètes ($\vec{x}_p(t + \Delta t)$).
4. On met à jour la position des planètes de notre système.
5. On revient à l'étape [4.1](#here4).
# Évolution
Concentrons nous tout d'abord sur l'évolution de la simulation, nous verrons les conditions initiales dans un second temps. Pour déterminer les informations néccéssaires, on commence par calculer la force résultante :
$$
\vec{F}_p = \sum_{\{q \in \mathcal{C}\ |\ q \neq p\}}\vec{F}_{qp}
$$
Où $\mathcal{C}$ est l'ensemble des corps célèstes (les planètes et l'étoile) de votre simulation.
Ensuite, on calcule la nouvelle position à partir de l'ancienne. En reprenant les équations du mouvement uniformément accéléré on a :
$$
\label{eq:verlet}
\begin{aligned}
\vec{x}_p(t+\Delta t) &= \vec{x}_p(t) + \Delta t\vec{v}_p(t) + \frac{(\Delta t)^2}{2}\vec{a}_p(t)\\
\vec{x}_p(t-\Delta t) &= \vec{x}_p(t) - \Delta t\vec{v}_p(t) + \frac{(\Delta t)^2}{2}\vec{a}_p(t)
\end{aligned}
$$
Avec $t$ et $\Delta t$ en [s], $\| \vec{x}_p(t) \|$ en [m], $\| \vec{v}_p(t) \|$ en [$\frac{m}{s}$] et $\| \vec{a}_p(t) \|$ en [$\frac{m}{s^2}$].
En additionnant les deux équations de \eqref{eq:verlet}, on obtient :
$$
\label{eq:mouvement}
\begin{aligned}
\vec{x}_p(t+\Delta t) + \vec{x}_p(t-\Delta t) &= 2\vec{x}_p(t) + (\Delta t)^2\vec{a}_p(t)\\
\vec{x}_p(t+\Delta t) &= 2\vec{x}_p(t) - \vec{x}_p(t-\Delta t) + (\Delta t)^2\vec{a}_p(t)\\
\end{aligned}
$$
On remarque donc qu'il n'est pas nécessaire de retenir l'évolution de $\vec{v}_p$ pour calculer le prochain état de notre simulation. Nous n'avons besoin que des deux dernières positions ($\vec{x}_p(t), \vec{x}_p(t-\Delta t)$) et de l'accélération ($\vec{a}_p(t)$). Nous calculerons donc les $\vec{x}_p$ itérativement et je vous laisse le soin de déduire comment nous pouvons obtenir $\vec{a}_p(t)$ à partir des formules données.
### Conditions initiales
Si l'on regarde \eqref{eq:mouvement}, on remarque que pour calculer $\vec{x}_p(t + \Delta t)$ en $t=0$ ($\vec{x}_p(\Delta t)$), il nous faudrait la position $\vec{x}_p(t-\Delta t)$. Comme nous ne considirons pas de temps négatif dans notre simulation, nous allons fixer la valeur en $t=0$ avec la formule \eqref{eq:mouvement}. Ce qui nous donne :
$$
\vec{x}_p(\Delta t) = \vec{x}_p(0) + \Delta t\vec{v}_p(0) + \frac{(\Delta t)^2}{2}\vec{a}_p(0)
$$
Commencons par $\vec{v}_p(0)$. Pour rappel, l'orbite d'une planète est éllipsoïdale. Sans rentrer dans des détails qui dépassent le cadre de ce tp, nous pouvons connaître la vitesse à la périhélie (voir \ref{fig:orbite}) de l'orbite d'une planète autour de notre étoile. La périhélie est la distance la plus courte dans l'orbite d'une planète (autour du soleil, -hélie=soleil). Nous avons donc :
$$
\vec{v}_p(0) = \displaystyle\sqrt{\frac{GM_{\odot}(1+e_p)}{a_p(1-e_p)}}\cdot\frac{\vec{r}_{p\bot}}{\| \vec{r}_{p\bot} \|}
$$
Où $M_{\odot}$ est la masse de l'étoile en [kg], $a_p$ est le demi-grand axe, de l'orbite de la planète $p$, en [m], $e$ l'exentricité, de l'orbite de la planète $p$, sans unité et $\vec{r}_{\bot}$ est le vecteur perdiculaire ($\vec{r}_{p\bot} = \vectwo{-{r_p}_y}{{r_p}_x}$) au vecteur allant de la planète $p$ à son étoile.
Par conséquent, puisque que nous connaissons la vitesse à la périhélie, nous placerons intelligement $\vec{x}_p(0)$ à la périhélie. Pour $\vec{a}_p(0)$, on peut le calculer de la même manière qu'avec n'importe quelle autre valeur de $t$.
Dans votre simulation vous utiliserez des données en mètres, vous aurez donc vraisemblablement (vu l'échelle cosmique) des valeurs en millions de kilomètres. Lors d'un précédent travail pratique, vous avez implementé une fonction permettant de convertir un vecteur en deux dimensions $\vec{r}\in\{[-1;1]\}^2$ en coordonnées d'écran $\vec{c}\in\{[0;lignes[\}\times\{[0;colonnes[\}$. Pour obtenir un vecteur $\vec{r}$, vous devrez définir le rayon de votre écran en mètres $R_S$ (p.ex : 110% du demi-grand axe de l'orbite de la planète la plus éloignée de l'étoile). Puis à partir de votre vecteur position en mètres $\vec{x}_p$, vous obtiendrez la nouvelle position $\vec{r} = \frac{\vec{x}_p}{R_S}$. Vous pourrez ensuite convertir cette position en coordonnées d'écran $\vec{c}$ grâce à votre fonction.
# Énoncé
Dans le cadre de ce travail pratique, vous allez devoir implementer une simulation de système planétaire semblable à notre système solaire. Pour cela vous avez à votre disposition un squelette de code nommé `skeleton.zip`. Ce squelette est uniquement là dans le but de vous aider. Vous pouvez donc vous en passer (ce que je vous déconseille). En revanche, vous devez impérativement utiliser la méthode et les équations présentées dans la partie théorique de cet énoncé.
Si toutefois vous décidiez de prendre ce squelette (excellente décision, je vous en félicite), une fois téléchargé et décompressé, vous devrez effectuer les actions suivantes :
1. Remplacer le fichier `skeleton/vec2/vec2.c` par celui que vous avez réalisé durant un précédent travail pratique.
2. Prendre connaisance des fichiers `skeleton/planet/planet.h` et `skeleton/main.c`. Ces fichiers contiennent des commentaires pour vous guider.
3. Réaliser le travail pratique.
Ce travail est séparé en deux parties, qui valent respectivement 4.5 et 1.5 points (Pour un total de 6 (c'est dingue !!!)).
La première partie, consiste à simuler un système planétaire avec les quatres premières planètes (par ordre de distance) du système solaire (Mercure, Vénus, Terre (souriez, vous êtes simulé), Mars).
Dans un second temps vous devrez ajouter quelques planètes fictives ($\geq 2$), et essayez de faire varier les différents paramètres. C'est à dire :
* La masse
* La distance à l'étoile
* La forme de l'orbite en changeant la vitesse initiale via le demi-grand axe et l'excentricité.
Pour dessiner vos planètes et votre étoile, vous pouvez utiliser la fonction `draw_full_circle` qui a été ajoutée à cette occasion dans la librairie `skeleton/gfx`. Elle prend en paramètre un contexte SDL, un centre, un rayon et une couleur.
Pour que votre simulation marche, vous serez amené, à un moment ou à un autre, à devoir mettre des données (position de vos planètes, choix du $\Delta t$, masse, etc...). Vous devez dans le cadre de ce travail aller chercher ces données, et ce dans les bonnes unités (p.ex : distance en mètre et non en années lumière). Vous devrez indiquer dans votre rapport les données choisies (dans les bonnes unités) et leur source.
# Travail à rendre par groupe de deux (strictement égal à deux)
- Un rapport succint (moins de 6 pages) présentant le travail réalisé, avec des images de ce dernier.
- Le repos git contenant le code réalisé.
- (Bonus) Une vidéo du résultat, si vous réussissez à créer un système cool.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 500 250" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"><g id="Calque1"><ellipse cx="246.823" cy="115.152" rx="211.245" ry="87.675" style="fill:#ebebeb;fill-opacity:0;stroke:#000;stroke-opacity:0.73;stroke-width:0.83px;"/><path d="M35.578,115.152l422.491,0l-306.871,0" style="fill:none;stroke:#000;stroke-width:1px;"/><path d="M35.578,115.152l115.62,0" style="fill:none;stroke:#07ff00;stroke-opacity:0.73;stroke-width:1.67px;"/><path d="M246.506,115.152l211.563,0" style="fill:none;stroke:#f00;stroke-width:1.67px;"/><ellipse cx="148.983" cy="114.47" rx="6.671" ry="6.036" style="fill:#ffeb00;"/><ellipse cx="33.99" cy="114.376" rx="6.671" ry="6.036" style="fill:#001aff;"/><path d="M246.823,27.478l0,175.349" style="fill:none;stroke:#000;stroke-width:1px;"/><path d="M246.823,27.478l0,88.31" style="fill:none;stroke:#0600ff;stroke-opacity:0.73;stroke-width:1.67px;"/><text x="333.545px" y="133.577px" style="font-family:'LucidaCalligraphy-Italic', 'Lucida Calligraphy', cursive;font-style:italic;font-size:17.739px;fill:#f00;">a</text><text x="254.765px" y="73.221px" style="font-family:'LucidaSans-TypewriterOblique', 'Lucida Sans Typewriter', monospace;font-style:italic;font-stretch:semi-condensed;font-size:17.739px;fill:#01f;">b</text><text x="56.544px" y="106.893px" style="font-family:'LucidaSans-TypewriterOblique', 'Lucida Sans Typewriter', monospace;font-style:italic;font-stretch:semi-condensed;font-size:12.5px;fill:#16ba00;">périhélie</text><text x="138.501px" y="134.848px" style="font-family:'LucidaSans-TypewriterOblique', 'Lucida Sans Typewriter', monospace;font-style:italic;font-stretch:semi-condensed;font-size:12.5px;">Soleil</text><g transform="matrix(0.579483,-0.814984,0.814984,0.579483,-341.887,-216.219)"><text x="-46.92px" y="481.765px" style="font-family:'LucidaSans-TypewriterOblique', 'Lucida Sans Typewriter', monospace;font-style:italic;font-stretch:semi-condensed;font-size:12.5px;">Terre</text></g></g></svg>
\ No newline at end of file
#The compiler
CC:=gcc
#The flags passed to the compiler
CFLAGS:=-g -Ofast -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11
#The flags passed to the linker
LDFLAGS:=-lm -lSDL2
#Path to the lib Vec2
VPATH:=vec2 gfx planet
main: main.o vec2.o gfx.o planet.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
run_tests: tests
./$<
tests: vec_tests.o vec2.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
planet.o: planet.h
vec2.o: vec2.h
gfx.o: gfx.h
clean:
rm -f *.o main tests
/// @file gfx.c
/// @author Florent Gluck
/// @date November 6, 2016
/// Helper routines to render pixels in fullscreen graphic mode.
/// Uses the SDL2 library.
/// Update : Add full circle
/// @author Michaël El Kharroubi
/// @date 19 November 2021
#include "gfx.h"
#include <assert.h>
/// Create a fullscreen graphic window.
/// @param title Title of the window.
/// @param width Width of the window in pixels.
/// @param height Height of the window in pixels.
/// @return a pointer to the graphic context or NULL if it failed.
struct gfx_context_t *gfx_create(char *title, uint32_t width, uint32_t height)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
goto error;
SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, width, height);
uint32_t *pixels = malloc(width * height * sizeof(uint32_t));
struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
if (!window || !renderer || !texture || !pixels || !ctxt)
goto error;
ctxt->renderer = renderer;
ctxt->texture = texture;
ctxt->window = window;
ctxt->width = width;
ctxt->height = height;
ctxt->pixels = pixels;
SDL_ShowCursor(SDL_DISABLE);
gfx_clear(ctxt, COLOR_BLACK);
return ctxt;
error:
return NULL;
}
/// Draw a pixel in the specified graphic context.
/// @param ctxt Graphic context where the pixel is to be drawn.
/// @param column X coordinate of the pixel.
/// @param row Y coordinate of the pixel.
/// @param color Color of the pixel.
void gfx_putpixel(struct gfx_context_t *ctxt, uint32_t column, uint32_t row, uint32_t color)
{
if (column < ctxt->width && row < ctxt->height)
ctxt->pixels[ctxt->width * row + column] = color;
}
/// Clear the specified graphic context.
/// @param ctxt Graphic context to clear.
/// @param color Color to use.
void gfx_clear(struct gfx_context_t *ctxt, uint32_t color)
{
int n = ctxt->width * ctxt->height;
while (n)
ctxt->pixels[--n] = color;
}
/// Display the graphic context.
/// @param ctxt Graphic context to clear.
void gfx_present(struct gfx_context_t *ctxt)
{
SDL_UpdateTexture(
ctxt->texture, NULL, ctxt->pixels, ctxt->width * sizeof(uint32_t));
SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
SDL_RenderPresent(ctxt->renderer);
}
/// Destroy a graphic window.
/// @param ctxt Graphic context of the window to close.
void gfx_destroy(struct gfx_context_t *ctxt)
{
SDL_ShowCursor(SDL_ENABLE);
SDL_DestroyTexture(ctxt->texture);
SDL_DestroyRenderer(ctxt->renderer);
SDL_DestroyWindow(ctxt->window);
free(ctxt->pixels);
ctxt->texture = NULL;
ctxt->renderer = NULL;
ctxt->window = NULL;
ctxt->pixels = NULL;
SDL_Quit();
free(ctxt);
}
/// If a key was pressed, returns its key code (non blocking call).
/// List of key codes: https://wiki.libsdl.org/SDL_Keycode
/// @return the key that was pressed or 0 if none was pressed.
SDL_Keycode gfx_keypressed()
{
SDL_Event event;
if (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
return event.key.keysym.sym;
}
return 0;
}
/// Draw a full circle using Andres's discrete circle algorithm.
/// @param ctxt Graphic context to clear.
/// @param c_column X coordinate of the circle center.
/// @param c_row Y coordinate of the circle center.
/// @param r The radius of circle (in pixels).
/// @param color Color to use.
void draw_full_circle(struct gfx_context_t *ctxt, uint32_t c_column, uint32_t c_row, uint32_t r, uint32_t color)
{
int32_t x = 0, y = r, d = r - 1;
while (y >= x)
{
gfx_putpixel(ctxt, c_column + x, c_row + y, color);
gfx_putpixel(ctxt, c_column + y, c_row + x, color);
gfx_putpixel(ctxt, c_column - x, c_row + y, color);
gfx_putpixel(ctxt, c_column - y, c_row + x, color);
gfx_putpixel(ctxt, c_column + x, c_row - y, color);
gfx_putpixel(ctxt, c_column + y, c_row - x, color);
gfx_putpixel(ctxt, c_column - x, c_row - y, color);
gfx_putpixel(ctxt, c_column - y, c_row - x, color);
if ((2 * x) <= d)
{
d -= 2 * x + 1;
x += 1;
}
else if (d < (2 * (((int32_t)r) - y)))
{
d += 2 * y - 1;
y -= 1;
}
else
{
d -= 2 * (x - y + 1);
y -= 1;
x += 1;
}
}
if (r > 0)
draw_full_circle(ctxt, c_column, c_row, r - 1, color);
}
\ No newline at end of file
#ifndef _GFX_H_
#define _GFX_H_
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <stdint.h>
#define MAKE_COLOR(r, g, b) \
((uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16))
#define COLOR_GET_B(color) (color & 0xff)
#define COLOR_GET_G(color) ((color >> 8) & 0xff)
#define COLOR_GET_R(color) ((color >> 16) & 0xff)
#define COLOR_BLACK 0x00000000
#define COLOR_RED 0x00FF0000
#define COLOR_GREEN 0x0000FF00
#define COLOR_BLUE 0x000000FF
#define COLOR_WHITE 0x00FFFFFF
#define COLOR_YELLOW 0x00FFFF00
struct gfx_context_t
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
uint32_t *pixels;
uint32_t width;
uint32_t height;
};
extern void gfx_putpixel(
struct gfx_context_t *ctxt, uint32_t column, uint32_t row, uint32_t color);
extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color);
extern struct gfx_context_t *gfx_create(char *text, uint32_t width, uint32_t height);
extern void gfx_destroy(struct gfx_context_t *ctxt);
extern void gfx_present(struct gfx_context_t *ctxt);
extern SDL_Keycode gfx_keypressed();
extern void draw_full_circle(struct gfx_context_t *ctxt, uint32_t c_column, uint32_t c_row, uint32_t r, uint32_t color);
#endif
#include "gfx/gfx.h"
#include "vec2/vec2.h"
#include "planet/planet.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 1000
int main()
{
srand(time(NULL));
struct gfx_context_t *ctxt =
gfx_create("Planetary system", SCREEN_WIDTH, SCREEN_HEIGHT);
if (!ctxt)
{
fprintf(stderr, "Graphics initialization failed!\n");
return EXIT_FAILURE;
}
// TODO : create your system
while (true)
{
gfx_present(ctxt);
// TODO : draw the current state of your system
// TODO : update your system
gfx_clear(ctxt, COLOR_BLACK);
if (gfx_keypressed() == SDLK_ESCAPE)
{
break;
}
}
// TODO : Free your system
gfx_destroy(ctxt);
return EXIT_SUCCESS;
}
#include "planet.h"
#include <stdlib.h>
#define G 6.67e-11
#define M_SOLEIL 1.989e30
// TODO : magic
\ No newline at end of file
#ifndef _PLANET_H_
#define _PLANET_H_
#include "../vec2/vec2.h"
#include "../gfx/gfx.h"
typedef struct _planet
{
double mass;
vec2 pos; // x(t)
vec2 prec_pos; // x(t - dt)
} planet_t;
typedef struct _system
{
planet_t star; // ex. The sun
uint32_t nb_planets; // The number of orbiting planets
planet_t *planets; // An array of orbiting planets
} system_t;
// Those function are not mandatory to implement,
// it's rather a hint of what you should have.
planet_t create_planet(double mass, vec2 pos);
system_t create_system(double delta_t);
void show_system(struct gfx_context_t *ctxt, system_t *system);
void update_system(system_t *system, double delta_t);
void free_system(system_t *system);
#endif
\ No newline at end of file
// TODO : Replace this file by your vec2.c from last tp.
#ifndef _VEC2_H_
#define _VEC2_H_
#include <stdbool.h>
#include <stdint.h>
typedef struct _vec2
{
double x, y;
} vec2;
typedef struct _coordinates
{
uint32_t row, column;
} coordinates;
vec2 vec2_create(double x_, double y_);
vec2 vec2_create_zero();
vec2 vec2_add(vec2 lhs, vec2 rhs);
vec2 vec2_sub(vec2 lhs, vec2 rhs);
vec2 vec2_mul(double scalar, vec2 rhs);
double vec2_dot(vec2 lhs, vec2 rhs);
double vec2_norm_sqr(vec2 v);
double vec2_norm(vec2 v);
vec2 vec2_normalize(vec2 v);
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps);
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height);
void vec2_print(vec2 v);
#endif
#include "vec2.h"
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
typedef struct _test_result
{
bool passed;
const char *name;
} test_result;
typedef test_result (*unit_test_t)(void);
void print_in_color(char *color, char *text)
{
printf("\033%s", color);
printf("%s", text);
printf("\033[0m");
}
void print_in_red(char *text)
{
print_in_color("[0;31m", text);
}
void print_in_green(char *text)
{
print_in_color("[0;32m", text);
}
bool dbl_eq(double a, double b)
{
return fabs(a - b) < 1e-6;
}
/*
*
* Write your tests here
*
*/
/* TODO
vec2 vec2_create(double x_, double y_); -- Ok
vec2 vec2_create_zero(); -- Ok
vec2 vec2_add(vec2 lhs, vec2 rhs); -- Ok
vec2 vec2_sub(vec2 lhs, vec2 rhs); -- Ok
vec2 vec2_mul(double scalar, vec2 lhs); -- Ok
double vec2_dot(vec2 lhs, vec2 rhs); -- Ok
double vec2_norm_sqr(vec2 v); -- Ok
double vec2_norm(vec2 v); -- Ok
vec2 vec2_normalize(vec2 v); -- Ok
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps);
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height);
*/
const double u_x[] = {1.25, 3.53, 2.64, 8.8};
const double u_y[] = {3.42, 7.22, 5.32, 2.44};
const double v_x[] = {4.32, 6.21, 7.42, 9.32};
const double v_y[] = {5.22, 3.56, 8.65, 6.44};
const uint32_t nb_tests = sizeof(u_x) / sizeof(double);
test_result t_vec2_create_0()
{
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 v = vec2_create(u_x[i], u_y[i]);
if (u_x[i] != v.x || u_y[i] != v.y)
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_create 0"};
}
test_result t_vec2_create_zero_0()
{
vec2 v = vec2_create_zero();
return (test_result){.passed = v.x == 0.0 && v.y == 0.0,
.name = "Test vec2_create_zero 0"};
}
test_result t_vec2_add_0()
{
double r_x[] = {5.57, 9.74, 10.06, 18.12};
double r_y[] = {8.64, 10.78, 13.97, 8.88};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
vec2 r = vec2_add(u, v);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_add 0"};
}
test_result t_vec2_sub_0()
{
double r_x[] = {-3.07, -2.68, -4.78, -0.52};
double r_y[] = {-1.80, 3.66, -3.33, -4.00};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
vec2 r = vec2_sub(u, v);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_sub 0"};
}
test_result t_vec2_mul_0()
{
double r_x[] = {5.40, 21.9213, 19.5888, 82.016};
double r_y[] = {14.7744, 44.8362, 39.4744, 22.740800};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
double alpha = v_x[i];
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 r = vec2_mul(alpha, u);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_mul 0"};
}
test_result t_vec2_dot_0()
{
double r[] = {23.2524, 47.6245, 65.6068, 97.7296};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
double res = vec2_dot(u, v);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_dot 0"};
}
test_result t_vec2_norm_sqr_0()
{
double r[] = {13.2589, 64.5893, 35.272, 83.3936};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
double res = vec2_norm_sqr(u);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_norm_sqr 0"};
}
test_result t_vec2_norm_0()
{
double r[] = {3.641277, 8.036747, 5.939023, 9.132010};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
double res = vec2_norm(u);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_norm 0"};
}
test_result t_vec2_normalize_0()
{
double r_x[] = {0.343286, 0.439232, 0.444518, 0.963643};
double r_y[] = {0.939231, 0.898373, 0.895770, 0.267192};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 r = vec2_normalize(u);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_normalize 0"};
}
test_result t_vec2_is_approx_equal_0()
{
bool r[] = {true, true, false, false};
double t_x[] = {u_x[0], u_x[1] + 1e-4, u_x[2] + 15.0, u_x[3] + 1e-2};
double t_y[] = {u_y[0], u_y[1] - 1e-4, u_y[2] + 15.0, u_y[3] + 1e-2};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 t = vec2_create(t_x[i], t_y[i]);
if (vec2_is_approx_equal(u, t, 1e-3) != r[i])
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_is_approx_equal 0"};
}
test_result t_vec2_to_coordinates_0()
{
uint32_t height = 300;
uint32_t width = 100;
double t_x[] = {0.25, 0.5, 0.75, 1};
double t_y[] = {0, 1.0 / 3.0, 2.0 / 3.0, 1};
uint32_t r_col[] = {62, 74, 87, 99};
uint32_t r_row[] = {150, 199, 249, 299};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
vec2 t = vec2_create(t_x[i], t_y[i]);
coordinates r = vec2_to_coordinates(t, width, height);
if (r.row != r_row[i] || r.column != r_col[i])
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_to_coordinates 0"};
}
//Add or remove your test function name here
const unit_test_t tests[] = {
t_vec2_create_0,
t_vec2_create_zero_0,
t_vec2_add_0,
t_vec2_sub_0,
t_vec2_mul_0,
t_vec2_dot_0,
t_vec2_norm_sqr_0,
t_vec2_norm_0,
t_vec2_normalize_0,
t_vec2_is_approx_equal_0,
t_vec2_to_coordinates_0};
int main()
{
uint32_t nb_tests = sizeof(tests) / sizeof(unit_test_t);
char message[256];
bool all_passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
printf("Running test n°%d: ...\n", i);
test_result r = tests[i]();
if (r.passed)
{
sprintf(message, "\t- %s : OK", r.name);
print_in_green(message);
}
else
{
all_passed = false;
sprintf(message, "\t- %s : FAILED", r.name);
print_in_red(message);
}
printf("\n");
}
if (all_passed)
print_in_green("\nTests suite result : OK\n");
else
print_in_red("\nTests suite result : FAILED\n");
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment