Skip to content

Commit

Permalink
Merge pull request #83 from pygae/point_processing
Browse files Browse the repository at this point in the history
Point processing
  • Loading branch information
hugohadfield committed Feb 12, 2019
2 parents 2549e94 + b27b209 commit f58c081
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
13 changes: 13 additions & 0 deletions clifford/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,10 @@ class Layout(object):
gaDims -- 2**dims
einf -- if conformal returns einf
eo -- if conformal returns eo
names -- pretty-printing symbols for the blades
even -- dictionary of even permutations of blades to the canonical blades
Expand Down Expand Up @@ -595,6 +599,10 @@ def __init__(self, sig, bladeTupList, firstIdx=0, names=None):

self._metric = None

self.isconformal = False
self.einf = None
self.eo = None

# Python 2 and 3 compatibility fix
names_is_string = False
names_is_unicode = False
Expand Down Expand Up @@ -2576,6 +2584,11 @@ def conformalize(layout, added_sig=[1,-1]):
# setup null basis, and minkowski subspace bivector
eo = .5 ^ (en - ep)
einf = en + ep

layout_c.isconformal = True
layout_c.einf = einf
layout_c.eo = eo

E0 = einf ^ eo
I_base = layout_c.pseudoScalar*E0
# some convenience functions
Expand Down
57 changes: 57 additions & 0 deletions clifford/tools/point_processing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

import scipy.spatial
import numpy as np
from .. import MVArray


class GAConvexHull(scipy.spatial.ConvexHull):
"""
Uses scipy to produce an n_dims dimensional convex hull of the input points
if hull_dims is not provided it will use the dimension of the input layout
if hull_dims is provided it will use the first hull_dims basis vectors
"""
def __init__(self, points, hull_dims=None, incremental=False, qhull_options=None):

# Prep the GA specific stuff
self.layout = points[0].layout
if hull_dims is None:
hull_dims = self.layout.dims
self.algebra_dims = self.layout.dims
self.hull_dims = hull_dims
point_array = np.array([p.value[1:hull_dims+1] for p in points])

# Run the superclass constructor
scipy.spatial.ConvexHull.__init__(self, point_array,
incremental=incremental,
qhull_options=qhull_options)
# Keep the GAversion
self.GApoints = points

def conformal_facets(self):
"""
Returns the list of conformal points in each facet
"""
if self.layout.isconformal:
return [[self.GApoints[i] for i in s] for s in self.simplices]
else:
raise ValueError('Input points do not seem to be from a conformal algebra')

def conformal_rounds(self):
"""
Returns the conformal rounds made of the wedge
product of the edge simplices
"""
if self.layout.isconformal:
return [MVArray([self.GApoints[i] for i in s]).op().normal() for s in self.simplices]
else:
raise ValueError('Input points do not seem to be from a conformal algebra')

def conformal_flats(self):
"""
Returns the conformal flats made of the wedge
product of the edge simplices with einf
"""
if self.layout.isconformal:
return [(r^self.layout.einf).normal() for r in self.conformal_rounds()]
else:
raise ValueError('Input points do not seem to be from a conformal algebra')
56 changes: 56 additions & 0 deletions test/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,62 @@ def test_find_rotor_aligning_vectors(self):
testing.assert_almost_equal(r.value, r_2.value)


class PointProcessingTests(unittest.TestCase):
def test_convex_hull_vertices(self):
from clifford.tools.g3c import random_conformal_point
from clifford.tools.point_processing import GAConvexHull
point_list = [random_conformal_point() for i in range(100)]
hull = GAConvexHull(point_list, hull_dims=3)
conf_vertices = [hull.GApoints[i] for i in hull.vertices]

# from pyganja import GanjaScene, draw
# gs = GanjaScene()
# gs.add_objects(point_list, static=True, color=int('00000000', 16))
# gs.add_objects(conf_vertices, static=True, color=int('00FF0000', 16))
# draw(gs, scale=0.05)

def test_convex_hull_conformal_rounds(self):
from clifford.tools.g3c import random_conformal_point
from clifford.tools.point_processing import GAConvexHull
point_list = [random_conformal_point() for i in range(100)]
hull = GAConvexHull(point_list, hull_dims=3)
rounds = hull.conformal_rounds()

# from pyganja import GanjaScene, draw
# gs = GanjaScene()
# gs.add_objects(point_list, static=True, color=int('00000000', 16))
# gs.add_objects(rounds, color=int('00FF0000', 16))
# draw(gs, scale=0.05)

def test_convex_hull_conformal_flats(self):
from clifford.tools.g3c import random_conformal_point
from clifford.tools.point_processing import GAConvexHull

point_list = [random_conformal_point() for i in range(100)]
hull = GAConvexHull(point_list, hull_dims=3)
flats = hull.conformal_flats()

# from pyganja import GanjaScene, draw
# gs = GanjaScene()
# gs.add_objects(point_list, static=True, color=int('00000000', 16))
# gs.add_objects(flats, color=int('00FF0000', 16))
# draw(gs, scale=0.05)

def test_convex_hull_facets(self):
from clifford.tools.g3c import random_conformal_point
from clifford.tools.point_processing import GAConvexHull
point_list = [random_conformal_point() for i in range(100)]
hull = GAConvexHull(point_list, hull_dims=3)
facets = hull.conformal_facets()

# from pyganja import GanjaScene, draw
# gs = GanjaScene()
# gs.add_objects(point_list, static=True, color=int('00000000', 16))
# for f in facets:
# gs.add_facet(f, color=int('AAFF0000', 16))
# draw(gs, scale=0.05)



if __name__ == '__main__':
unittest.main()

0 comments on commit f58c081

Please sign in to comment.