Skip to content

Instantly share code, notes, and snippets.

View marmakoide's full-sized avatar

Devert Alexandre marmakoide

View GitHub Profile
@marmakoide
marmakoide / unit_simplex.py
Created October 3, 2023 19:16
Unit simplex in N dimension, as a triangular matrix. 1st vertex is the origin.
import numpy
'''
Unit simplex in N dimension, as a triangular matrix,
only positive coeffs.
1st vertex is the origin, not in the returned matrix
I don't know if this algorithm have been discovered
before. I find it elegant, and I believe it can be
very accurate and stable with arbitrary precision numbers
@marmakoide
marmakoide / get_orthogonal_projection.py
Created April 27, 2023 07:54
Build an orthogonal projection that projects vectors on U's subspace
import numpy
def get_orthogonal_projection(U):
M = numpy.random.randn(U.shape[1], U.shape[1])
M[:U.shape[0]] = U
Q, R = numpy.linalg.qr(M.T)
M[U.shape[0]:] = Q.T[U.shape[0]:]
Q, R = numpy.linalg.qr(M.T)
@marmakoide
marmakoide / aabox-trianle-3d-intersection.py
Created November 15, 2022 10:14
Check if an axis aligned bounding box intersects the triangle [ABC]. Box extents are half the size of the box
def aabox_triangle_3d_intersecting(box_center, box_extents, ABC):
# Algorithm described in "Fast 3D Triangle-Box Overlap Testing" by Tomas Akenine-Moller
ABC = ABC - box_center
UVW = numpy.roll(ABC, -1, axis = 0) - ABC
# Check along triangle edges
for K in UVW:
P = numpy.dot(ABC, numpy.array([0, -K[2], K[1]]))
if max(-numpy.amax(P), numpy.amin(P)) > box_extents[1] * numpy.fabs(K[2]) + box_extents[2] * numpy.fabs(K[1]):
return False
@marmakoide
marmakoide / aabox-segment-3d-intersection.py
Created November 15, 2022 09:22
Check if an axis aligned bounding box intersects the segment [AB]. Box extents are half the size of the box
def aabox_segment_3d_intersecting(box_center, box_extents, A, B):
M = (A + B) / 2 - box_center
AB = B - A
if numpy.any(numpy.fabs(M) > box_extents + .5 * numpy.fabs(AB)):
return False
U = AB / numpy.sqrt(numpy.sum(AB ** 2))
abs_U = numpy.fabs(U)
abs_W = numpy.fabs(numpy.cross(U, M))
@marmakoide
marmakoide / point-in-convex-hull.py
Last active November 15, 2022 08:58
Test if a point is inside a convex hull
import numppy
from scipy.spatial import ConvexHull
def convex_hull_contains_point(hull, P):
for E in hull.equations:
if numpy.dot(P, E[:-1]) > -E[-1]:
return False
return True
@marmakoide
marmakoide / hull-centroid-2d.py
Created November 10, 2022 10:28
Computes the centroid (ie. center of mass) of a 2d convex hull
import numpy
from scipy.spatial import ConvexHull
def get_convex_hull_2d_centroid(hull):
C = numpy.zeros(2)
for i in range(hull.vertices.shape[0]):
Pi, Pj = hull.points[hull.vertices[i - 1]], hull.points[hull.vertices[i]]
C += numpy.cross(Pi, Pj) * (Pi + Pj)
return C / 6.
@marmakoide
marmakoide / README.md
Last active December 19, 2022 10:57
Returns N points spread over a torus. Returns normals, handle self-intersections.

Golden dot spiral on a torus

This code sample demonstrates how to generates a set of points that covers a torus, for any number of points. The trick is to use a spiral and the golden angle.

42 points 256 points 999 points
dot spiral, 42 points dot spiral, 256 points dot spiral, 999 points
@marmakoide
marmakoide / vectorized-julia.py
Created September 12, 2022 19:32
Demonstrates how to compute a Julia fractal efficiently in pure Python + Numpy
import numpy
from matplotlib import pyplot as plot
N = 256
C = -0.4 + 0.6j
max_epoch_count = 1024
# Initialization
T = numpy.linspace(-2., 2., N)
X = numpy.tile(T, (N, 1))
@marmakoide
marmakoide / power-triangulation.py
Last active September 19, 2022 09:53
Computes power triangulation in N dimensions
import numpy
from scipy.spatial import ConvexHull
def is_oriented_simplex(S):
M = numpy.concatenate([S, numpy.ones((S.shape[0], 1))], axis = 1)
return numpy.linalg.det(M) > 0
def get_power_triangulation(S, R):
@marmakoide
marmakoide / power-circumcenter.py
Last active September 8, 2022 12:50
Computes the N-dimension circumcenter of N + 1 points (the S array) and their N + 1 radiis (the R array)
import numpy
def get_power_circumcenter(S, R):
R_sqr = R ** 2
Sp = S[1:] - S[0]
Sp_norm_sqr = numpy.sum(Sp ** 2, axis = 1)
U = ((Sp_norm_sqr + R_sqr[0] - R_sqr[1:]) / (2 * Sp_norm_sqr))[:, None] * Sp + S[0]