{"id":19671237,"url":"https://github.com/cgohlke/transformations","last_synced_at":"2025-10-10T23:13:21.318Z","repository":{"id":44550267,"uuid":"242421511","full_name":"cgohlke/transformations","owner":"cgohlke","description":"Homogeneous transformation matrices and quaternions.","archived":false,"fork":false,"pushed_at":"2025-08-01T03:21:59.000Z","size":381,"stargazers_count":99,"open_issues_count":1,"forks_count":17,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-08T14:42:29.621Z","etag":null,"topics":["linear-algebra","matrix","python","quaternion"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/transformations","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cgohlke.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-22T22:36:53.000Z","updated_at":"2025-09-03T20:08:20.000Z","dependencies_parsed_at":"2024-06-18T17:06:45.480Z","dependency_job_id":"05f7880e-3d19-4abb-aebf-344ef9df3993","html_url":"https://github.com/cgohlke/transformations","commit_stats":{"total_commits":68,"total_committers":2,"mean_commits":34.0,"dds":0.3970588235294118,"last_synced_commit":"17f30dc3eb9a1113da64233e342535caafa4bca7"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/cgohlke/transformations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Ftransformations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Ftransformations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Ftransformations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Ftransformations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cgohlke","download_url":"https://codeload.github.com/cgohlke/transformations/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cgohlke%2Ftransformations/sbom","scorecard":{"id":272529,"data":{"date":"2025-08-11","repo":{"name":"github.com/cgohlke/transformations","commit":"fb491fa9a6225829bc5fb8c077af533340b0b3cd"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Maintained","score":5,"reason":"6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/wheel.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/wheel.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/cgohlke/transformations/wheel.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/wheel.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/cgohlke/transformations/wheel.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/wheel.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/cgohlke/transformations/wheel.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-17T13:44:14.430Z","repository_id":44550267,"created_at":"2025-08-17T13:44:14.430Z","updated_at":"2025-08-17T13:44:14.430Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279005430,"owners_count":26083883,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linear-algebra","matrix","python","quaternion"],"created_at":"2024-11-11T17:08:13.344Z","updated_at":"2025-10-10T23:13:21.310Z","avatar_url":"https://github.com/cgohlke.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"..\n  This file is generated by setup.py\n\nHomogeneous Transformation Matrices and Quaternions\n===================================================\n\nTransformations is a Python library for calculating 4x4 matrices for\ntranslating, rotating, reflecting, scaling, shearing, projecting,\northogonalizing, and superimposing arrays of 3D homogeneous coordinates\nas well as for converting between rotation matrices, Euler angles,\nand quaternions. Also includes an Arcball control object and\nfunctions to decompose transformation matrices.\n\nThe transformations library is no longer actively developed.\n\n:Author: `Christoph Gohlke \u003chttps://www.cgohlke.com\u003e`_\n:License: BSD-3-Clause\n:Version: 2025.8.1\n\nQuickstart\n----------\n\nInstall the transformations package and all dependencies from the\n`Python Package Index \u003chttps://pypi.org/project/transformations/\u003e`_::\n\n    python -m pip install -U transformations\n\nSee `Examples`_ for using the programming interface.\n\nSource code and support are available on\n`GitHub \u003chttps://github.com/cgohlke/transformations\u003e`_.\n\nRequirements\n------------\n\nThis revision was tested with the following requirements and dependencies\n(other versions may work):\n\n- `CPython \u003chttps://www.python.org\u003e`_ 3.11.9, 3.12.10, 3.13.5, 3.14.0rc 64-bit\n- `NumPy \u003chttps://pypi.org/project/numpy/\u003e`_ 2.3.2\n\nRevisions\n---------\n\n2025.8.1\n\n- Drop support for Python 3.10, support Python 3.14.\n\n2025.1.1\n\n- Drop support for Python 3.9, support Python 3.13.\n\n2024.5.24\n\n- Fix docstring examples not correctly rendered on GitHub.\n\n2024.4.24\n\n- Support NumPy 2.\n\n2024.1.6\n\n- Remove support for Python 3.8 and numpy 1.22 (NEP 29).\n\n2022.9.26\n\n- Add dimension check on superimposition_matrix (#2).\n\n2022.8.26\n\n- Update metadata\n- Remove support for Python 3.7 (NEP 29).\n\n2021.6.6\n\n- Remove support for Python 3.6 (NEP 29).\n\n2020.1.1\n\n- Remove support for Python 2.7 and 3.5.\n\n2019.4.22\n\n- Fix setup requirements.\n\nNotes\n-----\n\nTransformations.py is no longer actively developed and has a few known issues\nand numerical instabilities. The module is mostly superseded by other modules\nfor 3D transformations and quaternions:\n\n- `Pytransform3d \u003chttps://github.com/dfki-ric/pytransform3d\u003e`_\n- `Scipy.spatial.transform\n  \u003chttps://github.com/scipy/scipy/tree/main/scipy/spatial/transform\u003e`_\n- `Transforms3d \u003chttps://github.com/matthew-brett/transforms3d\u003e`_\n  (includes most code of this module)\n- `Numpy-quaternion \u003chttps://github.com/moble/quaternion\u003e`_\n- `Blender.mathutils \u003chttps://docs.blender.org/api/master/mathutils.html\u003e`_\n\nThe API is not stable yet and is expected to change between revisions.\n\nThis Python code is not optimized for speed. Refer to the transformations.c\nmodule for a faster implementation of some functions.\n\nDocumentation in HTML format can be generated with epydoc.\n\nMatrices (M) can be inverted using numpy.linalg.inv(M), be concatenated using\nnumpy.dot(M0, M1), or transform homogeneous coordinate arrays (v) using\nnumpy.dot(M, v) for shape (4, -1) column vectors, respectively\nnumpy.dot(v, M.T) for shape (-1, 4) row vectors (\"array of points\").\n\nThis module follows the \"column vectors on the right\" and \"row major storage\"\n(C contiguous) conventions. The translation components are in the right column\nof the transformation matrix, i.e. M[:3, 3].\nThe transpose of the transformation matrices may have to be used to interface\nwith other graphics systems, e.g. OpenGL's glMultMatrixd(). See also [16].\n\nCalculations are carried out with numpy.float64 precision.\n\nVector, point, quaternion, and matrix function arguments are expected to be\n\"array like\", i.e. tuple, list, or numpy arrays.\n\nReturn types are numpy arrays unless specified otherwise.\n\nAngles are in radians unless specified otherwise.\n\nQuaternions w+ix+jy+kz are represented as [w, x, y, z].\n\nA triple of Euler angles can be applied/interpreted in 24 ways, which can\nbe specified using a 4 character string or encoded 4-tuple:\n\n  *Axes 4-string*: e.g. 'sxyz' or 'ryxy'\n\n  - first character : rotations are applied to 's'tatic or 'r'otating frame\n  - remaining characters : successive rotation axis 'x', 'y', or 'z'\n\n  *Axes 4-tuple*: e.g. (0, 0, 0, 0) or (1, 1, 1, 1)\n\n  - inner axis: code of axis ('x':0, 'y':1, 'z':2) of rightmost matrix.\n  - parity : even (0) if inner axis 'x' is followed by 'y', 'y' is followed\n    by 'z', or 'z' is followed by 'x'. Otherwise odd (1).\n  - repetition : first and last axis are same (1) or different (0).\n  - frame : rotations are applied to static (0) or rotating (1) frame.\n\nReferences\n----------\n\n1.  Matrices and transformations. Ronald Goldman.\n    In \"Graphics Gems I\", pp 472-475. Morgan Kaufmann, 1990.\n2.  More matrices and transformations: shear and pseudo-perspective.\n    Ronald Goldman. In \"Graphics Gems II\", pp 320-323. Morgan Kaufmann, 1991.\n3.  Decomposing a matrix into simple transformations. Spencer Thomas.\n    In \"Graphics Gems II\", pp 320-323. Morgan Kaufmann, 1991.\n4.  Recovering the data from the transformation matrix. Ronald Goldman.\n    In \"Graphics Gems II\", pp 324-331. Morgan Kaufmann, 1991.\n5.  Euler angle conversion. Ken Shoemake.\n    In \"Graphics Gems IV\", pp 222-229. Morgan Kaufmann, 1994.\n6.  Arcball rotation control. Ken Shoemake.\n    In \"Graphics Gems IV\", pp 175-192. Morgan Kaufmann, 1994.\n7.  Representing attitude: Euler angles, unit quaternions, and rotation\n    vectors. James Diebel. 2006.\n8.  A discussion of the solution for the best rotation to relate two sets\n    of vectors. W Kabsch. Acta Cryst. 1978. A34, 827-828.\n9.  Closed-form solution of absolute orientation using unit quaternions.\n    BKP Horn. J Opt Soc Am A. 1987. 4(4):629-642.\n10. Quaternions. Ken Shoemake.\n    http://www.sfu.ca/~jwa3/cmpt461/files/quatut.pdf\n11. From quaternion to matrix and back. JMP van Waveren. 2005.\n    http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm\n12. Uniform random rotations. Ken Shoemake.\n    In \"Graphics Gems III\", pp 124-132. Morgan Kaufmann, 1992.\n13. Quaternion in molecular modeling. CFF Karney.\n    J Mol Graph Mod, 25(5):595-604\n14. New method for extracting the quaternion from a rotation matrix.\n    Itzhack Y Bar-Itzhack, J Guid Contr Dynam. 2000. 23(6): 1085-1087.\n15. Multiple View Geometry in Computer Vision. Hartley and Zissermann.\n    Cambridge University Press; 2nd Ed. 2004. Chapter 4, Algorithm 4.7, p 130.\n16. Column Vectors vs. Row Vectors.\n    http://steve.hollasch.net/cgindex/math/matrix/column-vec.html\n\nExamples\n--------\n\n.. code-block:: python\n\n    \u003e\u003e\u003e alpha, beta, gamma = 0.123, -1.234, 2.345\n    \u003e\u003e\u003e origin, xaxis, yaxis, zaxis = [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]\n    \u003e\u003e\u003e I = identity_matrix()\n    \u003e\u003e\u003e Rx = rotation_matrix(alpha, xaxis)\n    \u003e\u003e\u003e Ry = rotation_matrix(beta, yaxis)\n    \u003e\u003e\u003e Rz = rotation_matrix(gamma, zaxis)\n    \u003e\u003e\u003e R = concatenate_matrices(Rx, Ry, Rz)\n    \u003e\u003e\u003e euler = euler_from_matrix(R, 'rxyz')\n    \u003e\u003e\u003e numpy.allclose([alpha, beta, gamma], euler)\n    True\n    \u003e\u003e\u003e Re = euler_matrix(alpha, beta, gamma, 'rxyz')\n    \u003e\u003e\u003e is_same_transform(R, Re)\n    True\n    \u003e\u003e\u003e al, be, ga = euler_from_matrix(Re, 'rxyz')\n    \u003e\u003e\u003e is_same_transform(Re, euler_matrix(al, be, ga, 'rxyz'))\n    True\n    \u003e\u003e\u003e qx = quaternion_about_axis(alpha, xaxis)\n    \u003e\u003e\u003e qy = quaternion_about_axis(beta, yaxis)\n    \u003e\u003e\u003e qz = quaternion_about_axis(gamma, zaxis)\n    \u003e\u003e\u003e q = quaternion_multiply(qx, qy)\n    \u003e\u003e\u003e q = quaternion_multiply(q, qz)\n    \u003e\u003e\u003e Rq = quaternion_matrix(q)\n    \u003e\u003e\u003e is_same_transform(R, Rq)\n    True\n    \u003e\u003e\u003e S = scale_matrix(1.23, origin)\n    \u003e\u003e\u003e T = translation_matrix([1, 2, 3])\n    \u003e\u003e\u003e Z = shear_matrix(beta, xaxis, origin, zaxis)\n    \u003e\u003e\u003e R = random_rotation_matrix(numpy.random.rand(3))\n    \u003e\u003e\u003e M = concatenate_matrices(T, R, Z, S)\n    \u003e\u003e\u003e scale, shear, angles, trans, persp = decompose_matrix(M)\n    \u003e\u003e\u003e numpy.allclose(scale, 1.23)\n    True\n    \u003e\u003e\u003e numpy.allclose(trans, [1, 2, 3])\n    True\n    \u003e\u003e\u003e numpy.allclose(shear, [0, math.tan(beta), 0])\n    True\n    \u003e\u003e\u003e is_same_transform(R, euler_matrix(axes='sxyz', *angles))\n    True\n    \u003e\u003e\u003e M1 = compose_matrix(scale, shear, angles, trans, persp)\n    \u003e\u003e\u003e is_same_transform(M, M1)\n    True\n    \u003e\u003e\u003e v0, v1 = random_vector(3), random_vector(3)\n    \u003e\u003e\u003e M = rotation_matrix(angle_between_vectors(v0, v1), vector_product(v0, v1))\n    \u003e\u003e\u003e v2 = numpy.dot(v0, M[:3, :3].T)\n    \u003e\u003e\u003e numpy.allclose(unit_vector(v1), unit_vector(v2))\n    True","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgohlke%2Ftransformations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcgohlke%2Ftransformations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcgohlke%2Ftransformations/lists"}