1 / 2
E8 Lie group or E8 lattice — zdjęcie 1
1 / 2

E8 Lie group or E8 lattice

Zamów wydruk tego modelu

Obliczymy ostateczną cenę na podstawie wybranego pliku. Sprawdzisz ją i zaakceptujesz przed płatnością.

Zapisane na tym urządzeniu.

Informacje o modelu

Źródło
Printables
Licencja
Creative Commons — Attribution — Noncommercial

E8 Lie group or E8 lattice (go with E8 Thick)

E8 root system projected onto its first three basis vectors.

Below is some code I generated in Gemini.

A simple game to learn the basics of E8. (some of the edu diags are sketch)

Below is a phyton script for blender. cut and paste it into the scripting window. hit play

# E8 Lattice Generation Script for Blender (Final Correction)
#
# Fixes a bug in edge generation where only the first edge was correctly placed.
# This version now correctly connects all vertices.

import bpy import bmesh import random from mathutils import Vector, Matrix

--- Configuration ---

Set the fraction of vertices to generate (1.0 = all, 0.25 = 25% random sample)

SAMPLING_FRACTION = 1.0

VERT_RADIUS = 0.08 # Radius of the spheres representing vertices EDGE_RADIUS = 0.02 # Radius of the cylinders representing edges COLLECTION_NAME = "E8_Lattice" # Name for the new collection

--- Helper Functions ---

def create_collection(name): """Creates a new collection or gets it if it already exists.""" if name in bpy.data.collections: return bpy.data.collections[name] else: new_collection = bpy.data.collections.new(name) bpy.context.scene.collection.children.link(new_collection) return new_collection

def get_e8_root_vectors(): """Generates the 240 root vectors of the E8 lattice.""" roots = set() # Type 1: (±1, ±1, 0, ..., 0) permutations. (112 vectors) for i in range(8): for j in range(i + 1, 8): for s1 in [-1, 1]: for s2 in [-1, 1]: v = [0] * 8 v[i] = s1 v[j] = s2 roots.add(tuple(v))

# Type 2: (±½, ±½, ..., ±½) with an even number of minus signs. (128 vectors)
for i in range(2**8):
    v = []
    neg_count = 0
    for k in range(8):
        if (i >> k) & 1:
            v.append(0.5)
        else:
            v.append(-0.5)
            neg_count += 1
    if neg_count % 2 == 0:
        roots.add(tuple(v))
        
# Scale roots by a factor of 2 for better visualization
return [Vector(r) * 2 for r in roots]

def create_mesh_object(name, collection, verts, faces, edges=None): """Creates a single mesh object from vertex, face, and edge data.""" if edges is None: edges = [] mesh = bpy.data.meshes.new(name) mesh.from_pydata(verts, edges, faces) mesh.update() obj = bpy.data.objects.new(name, mesh) collection.objects.link(obj) return obj

--- Core BMesh Generation Functions ---

def generate_vertices_mesh(name, vectors, radius, collection): """Generates a single object containing spheres for all vertices.""" print(f"Generating mesh for {len(vectors)} vertices...") if not vectors: return None

bm = bmesh.new()

for vec in vectors:
    loc_3d = Vector((vec[0], vec[1], vec[2]))
    bmesh.ops.create_icosphere(bm, subdivisions=2, radius=radius, matrix=Matrix.Translation(loc_3d))

obj = create_mesh_object(name, collection, [v.co for v in bm.verts], [[v.index for v in f.verts] for f in bm.faces])
bm.free()

obj.data.polygons.foreach_set('use_smooth', [True] * len(obj.data.polygons))
obj.data.update()

print("Vertex mesh created.")
return obj

def generate_edges_mesh(name, vectors, radius, collection): """Generates a single object containing cylinders for all edges.""" if not vectors or len(vectors) < 2: return None, 0 print("Calculating and generating edge mesh... (this is the slow part)")

bm = bmesh.new()
edge_count = 0
segments = 12

for i in range(len(vectors)):
    for j in range(i + 1, len(vectors)):
        v1 = vectors[i]
        v2 = vectors[j]

        # Check for connectivity (squared distance is 8.0 after scaling)
        if abs((v1 - v2).length_squared - 8.0) &lt; 0.001:
            p1 = Vector((v1[0], v1[1], v1[2]))
            p2 = Vector((v2[0], v2[1], v2[2]))
            
            # --- BUG FIX AREA ---
            # Robustly get the new cylinder's vertices by checking the mesh
            # state before and after the operator.
            verts_before = set(bm.verts)

            bmesh.ops.create_cone(
                bm,
                cap_ends=True,
                segments=segments,
                radius1=radius,
                radius2=radius,
                depth=(p1 - p2).length
            )
            
            new_verts = list(set(bm.verts) - verts_before)
            # --- END FIX ---
            
            # Calculate rotation and translation to position the cylinder
            direction = p2 - p1
            if direction.length &gt; 0: # Avoid issues with zero-length vectors
                location = p1 + direction / 2.0
                rotation_quat = direction.to_track_quat('Z', 'Y')
                
                # Apply the transformation to ONLY the new vertices
                bmesh.ops.rotate(bm, verts=new_verts, cent=Vector((0,0,0)), matrix=rotation_quat.to_matrix().to_4x4())
                bmesh.ops.translate(bm, verts=new_verts, vec=location)
            
            edge_count += 1
            if edge_count % 500 == 0:
                print(f"  ...processed {edge_count} edges...")

obj = create_mesh_object(name, collection, [v.co for v in bm.verts], [[v.index for v in f.verts] for f in bm.faces])
bm.free()

obj.data.polygons.foreach_set('use_smooth', [True] * len(obj.data.polygons))
obj.data.update()

print(f"Edge mesh with {edge_count} edges created.")
return obj, edge_count

--- Main Execution ---

def main(): """Main function to generate the E8 lattice.""" e8_collection = create_collection(COLLECTION_NAME)

for obj in e8_collection.objects:
    bpy.data.objects.remove(obj, do_unlink=True)

print("Generating 240 E8 root vectors...")
root_vectors = get_e8_root_vectors()

if SAMPLING_FRACTION &lt; 1.0:
    num_to_sample = int(len(root_vectors) * SAMPLING_FRACTION)
    sampled_vectors = random.sample(root_vectors, num_to_sample)
    print(f"Sampling {num_to_sample} of {len(root_vectors)} vertices ({SAMPLING_FRACTION * 100:.0f}%).")
else:
    sampled_vectors = root_vectors
    print("Using all 240 vertices.")

generate_vertices_mesh("E8_Vertices", sampled_vectors, VERT_RADIUS, e8_collection)
generate_edges_mesh("E8_Edges", sampled_vectors, EDGE_RADIUS, e8_collection)

print("\n✅ Finished! E8 lattice generated successfully.")

--- Run the Script ---

if name == "main": main()

Tagi