From 528cd9ff7a8cb8a624500e0db835049ec7b324cf Mon Sep 17 00:00:00 2001 From: BrSh31 Date: Tue, 11 Nov 2025 16:08:47 +0100 Subject: [PATCH] Add project_ortho() function and tests --- matrixmania/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 261 bytes matrixmania/__pycache__/compute.cpython-312.pyc | Bin 0 -> 6390 bytes matrixmania/compute.py | 14 +++++++++++++- .../test_matmul.cpython-312-pytest-8.4.2.pyc | Bin 0 -> 2293 bytes .../test_projection.cpython-312-pytest-8.4.2.pyc | Bin 0 -> 2092 bytes .../test_rot.cpython-312-pytest-8.4.2.pyc | Bin 0 -> 3719 bytes .../test_rot3D.cpython-312-pytest-8.4.2.pyc | Bin 0 -> 2386 bytes .../test_transpose.cpython-312-pytest-8.4.2.pyc | Bin 0 -> 2046 bytes tests/test_projection.py | 14 ++++++++++++++ 9 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 matrixmania/__pycache__/__init__.cpython-312.pyc create mode 100644 matrixmania/__pycache__/compute.cpython-312.pyc create mode 100644 tests/__pycache__/test_matmul.cpython-312-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_projection.cpython-312-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_rot.cpython-312-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_rot3D.cpython-312-pytest-8.4.2.pyc create mode 100644 tests/__pycache__/test_transpose.cpython-312-pytest-8.4.2.pyc create mode 100644 tests/test_projection.py diff --git a/matrixmania/__pycache__/__init__.cpython-312.pyc b/matrixmania/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c22d1e9a23193764d56a400f7d0cdbbd9791b7b1 GIT binary patch literal 261 zcmX@j%ge<81c!sTGR=VWV-N=hn4pZ$GC;<3h7^Vr#vF!R#wf;IrYNRd<|yV|mM9iR zhDs()=9i2>C7LX^*m4s~a!Ye=ah4P%<`oy@7pLB0E6Oj4H*$f{#x8!Ethd;c^K%PI zOHzxNfx3!VKm;p@U;`2>89oC^hF?z3RxzQ)sYS&xPDQ18`7r^N$r*`7xdBD_S*gh- z#WB8#B}JJPzKMC6i7`M+f$Ur`J3c-$FS8^*Uaz3?7l%!5eoARhs$CH`&`6LIi$RPJ S%#4hT_ZiHtFqjo_0{H;maYa@D literal 0 HcmV?d00001 diff --git a/matrixmania/__pycache__/compute.cpython-312.pyc b/matrixmania/__pycache__/compute.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b5681ac3f91c181654d6b8326254d91b801d4c9 GIT binary patch literal 6390 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 literal 0 HcmV?d00001 diff --git a/matrixmania/compute.py b/matrixmania/compute.py index ce30e61..17469cb 100644 --- a/matrixmania/compute.py +++ b/matrixmania/compute.py @@ -1,6 +1,7 @@ from typing import List import math from tabulate import tabulate +from typing import Tuple def matmul(mat1: List[List[int]], mat2: List[List[int]]) -> List[List[int]]: """ @@ -119,6 +120,18 @@ def rot_3D(angle: float, axis: str) -> List[List[float]]: else: raise ValueError("Axis must be 'x', 'y', or 'z'.") +def project_ortho(point: Tuple[float, float, float], scale: float = 1) -> Tuple[float, float]: + """ + Retruns a 2d point with optional scaling + + ignores the z axis and if scaling needed scales the 2d point + + :param point: Coordinates of a 3d point + :param scale: scaling factor (else 1) + :return: A 2d point + """ + return scale * point[0], scale * point[1] + def main(): # Test matrix multiplication @@ -150,7 +163,6 @@ def main(): print("Matrix A:") print(tabulate(matrix_a)) - if __name__ == "__main__": main() diff --git a/tests/__pycache__/test_matmul.cpython-312-pytest-8.4.2.pyc b/tests/__pycache__/test_matmul.cpython-312-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c66b0b52a0b877635a5d0c95fadc5cd76416093 GIT binary patch literal 2293 zcmb^yU27aw^xm1-+3%!DNl1mtrduTgB{a2-sU&JD1z%d42Ze^fFxfjvC(i7y_s%xi zxC=r05V7DQLi6C0FH-Uw`~^OkTCs8s_~6sNsSyf!@|-(6v)dZ9554T3?|be!ch0%z z`(iOiU_JaH?fI0D-;s%z)+3It0r7w^!l+M{slr;IS2RijV>v}pqxoi#UQP#@<&5H~ zpIy!}{T^A)F#}+}Nv%{D9p1DwX$DRhG<=y2xl!9qMktqmil z`j}-}#u{Z=+_k3d_bga0Ovg4G80T|qzsKJt;>>`5b;-|~h6%ghi>V3{>%fpoQh?A+%n^HWBe&JctFKMfo0lz-`=m#d7D`B6w8RwR8B1JHf=iaL za_!PWq@J||N8ge&@C@=$r3vjhs~tZd{a z_inuzx+1h4E=TN&%3A6>JE2h0o3+t!}CM0Dx~Sxz(U9gTimHNe5Oq8b-%Xi z_;%F^T$#0nv*w})Ikc!w^=j4YoY%NKZLifhygfFA>^oH_1dWyEMZBXS1o#zX9uJJ- zePfWh5;2jBHwT%k0w0A^w2t3-@2!;&AX~9=jW?>bm0Qiq9ft?Ecx?mjNvzy(Lhfzd zaH^iOf_V!C?dVOMt~cd~x{ZjpR~_M1cp3cTrxbq!*df2<^1DmB)9`2(Z8JHI#gC|`bJ;P2;%kC+5LGRpU7BkpmZ zOw>Ob<<4ZHj>%`#OMP{Z{0UD=Y$5`p*_%r&V{*_4b{#?9q=Fz`&_&Ud_!5W*WF6+j zH*}q<`Jlr*FmOuXeCW@EjovJXT_6s7FFQ$Izbk~2{yQ-^L)2)4aTm`NN}8lhW{9Ah zFbr?QK9p?fx5*~8%$t_ZF-VTZ!Ljq6XR{!)3~5I7FHP=v!WA<2q2o7PRkEr>EUjOn z0#hiJ_&GrG)xkpXs&^gVV>a^ww<@5r1-HNm+g@A;utQ{abT@xesT^j9zc~BZ*{`-A zXV3jfXlm>*Gqn40XYzjGsSeyz6e;vQ!F6iH-7R|I(keRqM`2=X>89T~lI_e*Y zVw$^~+zX*E6Ol~!WPBX=oQ6t=h6u1Brm^cAp{w%d_-Xj-2(bQDIu8jyk2L0goS6@5 ptl_(F^NYaZ%O_p|@P|$*{f&@&)2M|TB1=~+8$5?fvSj0qg;?mWa;VE`_jDdKCIa_ ztt-2-svbD@1_%BCtnf#0KwLPLQV}gk95|rfDtybSGyC4N9aM>eB3Ab7%X4f-6 z|5&eA8IE5!m%{s;u|LQthLtPh%cy+G1QR@BTinc6Y_~1WVrR?cv|>f2xV%+H-G0Ef zD#AfI*W*q1DIK!W+7@2V4iqer~V7+t(6C`F(66LS0yCr-@M^waI-wC;~Ty?C-edgxJ z3*U6^yG7h$zK?}5uzRdo-5A+_X2@sn=L%cDm3b=bO$#tC1NsR@{J>gU8}Yj*-aOOk zoomXKwY3#eFEphtK_I)4(v{#&2kRyfBTL(eB5~nh!Iv@sWzZK9jn0dsIiPaT)%8wK z1yXrF=tZyXN0A3X2ij@e@gdOjxa{5RhLH*r3=^e@kor|m?xfvF7^rtEN^km+m-um@ z=RE0e2Xum7_`pOB)8raJ3VO-gP9gS{hdD-m;wxMkm9*PQ!$d)i?n%XeA!->ETEF$4(7D-mfh_ zyz!{k_{E{m6Q}XT<%c&iVSzoZ4%&_d~Nv`{{>ru=WTP!^RV%V5&%|42*|B+>#>!Gsp7qIRUT zFuwsV{-93<3j8~8O%XP&oEJVV2qIhuqGTYpoi-5E$s`_vMG_}SETfod8CXGEH(pTk zw?nm)7yVm^p`+yx#ca`kWB*)#o65fN|CK$wfk`y0x>Ar4oJ5B{nh^%|G6c6F zR7gb=moDc%SfV{kNJ7X5G4a7F5nWdWh73)c16_N>Og!^U2bC*vD!Nhd9-PG``h%6P apm=6;&VOg@0eiyE{^dCQ_3;7twn!EK_HHyfZ7^ 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 HB(VJ(FKhDo literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_transpose.cpython-312-pytest-8.4.2.pyc b/tests/__pycache__/test_transpose.cpython-312-pytest-8.4.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ffc1a67e79a9e42bf7e06bff27f237db07bea35 GIT binary patch literal 2046 zcmb_d&2Jk;6rb5$ufLO+v_PU(I7AfhC2A;Xp&~$vh!9evUWimHXtnWdoDFNQnb|aP zuq6xSP$VRLKx%{#3fxfc`~w`hq@-%ARS<`sd@JNoDO`AO*1NW#0uGFlH}Cts8UNnw zPx*X?!1|+_ao(qdJVGH_N}oAd1m+H5gi)82soa&CT2UyeY2^eBEqYm(mSi~zyW*y5 z>2exu>Mki~mKbJk zj9OC;`W`InV@Gmrq#|yxAN1K-%WeVVTlosZ@Jw@zu4^ItoSJ)zS)8~Iw>(E$M(8)aiH&7o3C z_@mJ!51nN!(hc@jBB~qhp91{1X*1*M5MH1_;bj7T4AfN3=6M@LKuB{Sa?m~trq1v zz4p%4l@H*YV&xj&ta~drnw52n*KTlc11?9bT$h)1-Ksm*3Z7U}0~PmE zv1`N*J3-h99D`JlL<_GGA$76~1Ri_J6nJ6Ps(f_^@9ReNQHbJT_wi=ril$_aP%@bP z!RsME74W$@=x3p%Nv6px5p)YaCO07pHQVYQjNE{cY~D`a|Naq>&3!(WvmV zUy0LZ*J#RBD`LR5~eR{{(YPt=s?r literal 0 HcmV?d00001 diff --git a/tests/test_projection.py b/tests/test_projection.py new file mode 100644 index 0000000..f6f0e80 --- /dev/null +++ b/tests/test_projection.py @@ -0,0 +1,14 @@ +from matrixmania.compute import project_ortho + +def test_project_ortho_no_scale(): + point = (1.0, 2.0, 3.0) + result = project_ortho(point) + expected = (1.0, 2.0) + assert result == expected + + +def test_project_ortho_with_scale(): + point = (1.0, 2.0, 3.0) + result = project_ortho(point, scale=100) + expected = (100.0, 200.0) + assert result == expected