269 lines
9.7 KiB
Python
Executable file
269 lines
9.7 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
AeThex Logo Generator - Generative Art
|
|
Creates multiple logo variations programmatically
|
|
"""
|
|
|
|
import random
|
|
import math
|
|
from pathlib import Path
|
|
|
|
# Brand colors
|
|
COLORS = {
|
|
'purple_light': '#A855F7',
|
|
'purple': '#8B5CF6',
|
|
'purple_dark': '#7C3AED',
|
|
'cyan': '#06B6D4',
|
|
'cyan_light': '#22D3EE',
|
|
'white': '#FFFFFF',
|
|
}
|
|
|
|
def create_svg_header(width=200, height=200):
|
|
"""Create SVG header with gradients"""
|
|
return f'''<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {width} {height}" width="{width}" height="{height}">
|
|
<defs>
|
|
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" style="stop-color:{COLORS['purple_light']}"/>
|
|
<stop offset="100%" style="stop-color:{COLORS['purple_dark']}"/>
|
|
</linearGradient>
|
|
<linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" style="stop-color:{COLORS['cyan']}"/>
|
|
<stop offset="100%" style="stop-color:{COLORS['purple']}"/>
|
|
</linearGradient>
|
|
<filter id="glow">
|
|
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
|
<feMerge>
|
|
<feMergeNode in="coloredBlur"/>
|
|
<feMergeNode in="SourceGraphic"/>
|
|
</feMerge>
|
|
</filter>
|
|
</defs>
|
|
'''
|
|
|
|
def create_svg_footer():
|
|
return '</svg>'
|
|
|
|
# Logo Variation 1: Geometric Hexagon Network
|
|
def generate_hex_network():
|
|
svg = create_svg_header()
|
|
|
|
# Hexagon points
|
|
cx, cy = 100, 100
|
|
radius = 60
|
|
points = []
|
|
for i in range(6):
|
|
angle = math.pi / 3 * i - math.pi / 2
|
|
x = cx + radius * math.cos(angle)
|
|
y = cy + radius * math.sin(angle)
|
|
points.append(f"{x:.1f},{y:.1f}")
|
|
|
|
svg += f' <polygon points="{" ".join(points)}" fill="none" stroke="url(#grad1)" stroke-width="3"/>\n'
|
|
|
|
# Inner nodes (cloud network)
|
|
nodes = [
|
|
(70, 85), (100, 75), (130, 85),
|
|
(80, 105), (120, 105),
|
|
(100, 115)
|
|
]
|
|
|
|
# Connection lines
|
|
connections = [(0, 1), (1, 2), (3, 4), (0, 3), (2, 4), (1, 5), (3, 5), (4, 5)]
|
|
for start, end in connections:
|
|
x1, y1 = nodes[start]
|
|
x2, y2 = nodes[end]
|
|
svg += f' <line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke="{COLORS["cyan"]}" stroke-width="1.5" opacity="0.6"/>\n'
|
|
|
|
# Draw nodes
|
|
for x, y in nodes:
|
|
svg += f' <circle cx="{x}" cy="{y}" r="3" fill="{COLORS["cyan_light"]}" filter="url(#glow)"/>\n'
|
|
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 2: Abstract Letter A
|
|
def generate_letter_a(style='geometric'):
|
|
svg = create_svg_header()
|
|
|
|
if style == 'geometric':
|
|
# Modern geometric A
|
|
svg += ' <g transform="translate(100, 100)">\n'
|
|
svg += f' <path d="M -2 -40 L -35 35 L -25 35 L -8 -10 Z" fill="url(#grad1)"/>\n'
|
|
svg += f' <path d="M 2 -40 L 35 35 L 25 35 L 8 -10 Z" fill="url(#grad1)"/>\n'
|
|
svg += f' <rect x="-22" y="0" width="16" height="4" rx="2" fill="{COLORS["cyan"]}"/>\n'
|
|
svg += f' <rect x="6" y="0" width="16" height="4" rx="2" fill="{COLORS["cyan"]}"/>\n'
|
|
svg += f' <circle cx="-6" cy="2" r="2.5" fill="{COLORS["cyan_light"]}" filter="url(#glow)"/>\n'
|
|
svg += f' <circle cx="6" cy="2" r="2.5" fill="{COLORS["cyan_light"]}" filter="url(#glow)"/>\n'
|
|
svg += ' </g>\n'
|
|
|
|
elif style == 'rounded':
|
|
# Rounded A with flow
|
|
svg += ' <g transform="translate(100, 100)">\n'
|
|
svg += f' <path d="M 0 -40 Q -30 -10, -35 35 L -25 35 Q -22 -5, 0 -30 Z" fill="url(#grad1)"/>\n'
|
|
svg += f' <path d="M 0 -40 Q 30 -10, 35 35 L 25 35 Q 22 -5, 0 -30 Z" fill="url(#grad1)"/>\n'
|
|
svg += f' <ellipse cx="0" cy="5" rx="25" ry="6" fill="{COLORS["cyan"]}" opacity="0.7"/>\n'
|
|
svg += ' </g>\n'
|
|
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 3: Particle Cloud
|
|
def generate_particle_cloud():
|
|
svg = create_svg_header()
|
|
|
|
# Create cloud of particles forming "A" shape
|
|
random.seed(42) # Consistent randomness
|
|
|
|
# Generate particles
|
|
for i in range(80):
|
|
# A-shape distribution
|
|
y = random.uniform(40, 160)
|
|
|
|
# Make it A-shaped: narrower at top, wider at bottom
|
|
top_width = 20
|
|
bottom_width = 80
|
|
width = top_width + (bottom_width - top_width) * (y - 40) / 120
|
|
|
|
# Left or right side of A
|
|
side = random.choice([-1, 1])
|
|
x_offset = random.uniform(0, width/2) * side
|
|
|
|
# Middle gap (crossbar area)
|
|
if 90 < y < 110:
|
|
if abs(x_offset) < 15:
|
|
continue # Skip middle to create A shape
|
|
|
|
x = 100 + x_offset
|
|
|
|
# Vary size
|
|
radius = random.uniform(1, 3)
|
|
|
|
# Color gradient based on position
|
|
if y < 100:
|
|
color = COLORS['purple_light']
|
|
else:
|
|
color = COLORS['cyan'] if random.random() > 0.5 else COLORS['purple']
|
|
|
|
opacity = random.uniform(0.4, 1.0)
|
|
|
|
svg += f' <circle cx="{x:.1f}" cy="{y:.1f}" r="{radius:.1f}" fill="{color}" opacity="{opacity:.2f}"/>\n'
|
|
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 4: Minimalist Icon
|
|
def generate_minimal_icon():
|
|
svg = create_svg_header()
|
|
|
|
# Simple shapes only
|
|
svg += ' <g transform="translate(100, 100)">\n'
|
|
|
|
# Triangle (simplified A)
|
|
svg += f' <path d="M 0 -50 L -40 40 L 40 40 Z" fill="none" stroke="url(#grad1)" stroke-width="6" stroke-linejoin="round"/>\n'
|
|
|
|
# Connection bar
|
|
svg += f' <line x1="-20" y1="10" x2="20" y2="10" stroke="{COLORS["cyan"]}" stroke-width="6" stroke-linecap="round"/>\n'
|
|
|
|
# Small dots
|
|
svg += f' <circle cx="-20" cy="10" r="4" fill="{COLORS["cyan_light"]}"/>\n'
|
|
svg += f' <circle cx="20" cy="10" r="4" fill="{COLORS["cyan_light"]}"/>\n'
|
|
svg += f' <circle cx="0" cy="5" r="3" fill="{COLORS["white"]}"/>\n'
|
|
|
|
svg += ' </g>\n'
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 5: Infinity Engine
|
|
def generate_infinity():
|
|
svg = create_svg_header()
|
|
|
|
# Infinity symbol with code/cloud elements
|
|
svg += ' <g transform="translate(100, 100)">\n'
|
|
svg += f' <path d="M -60 0 C -60 -25, -40 -25, -20 0 C 0 25, 20 25, 40 0 C 60 -25, 60 -25, 60 0 C 60 25, 40 25, 20 0 C 0 -25, -20 -25, -40 0 C -60 25, -60 25, -60 0 Z" fill="none" stroke="url(#grad1)" stroke-width="5"/>\n'
|
|
|
|
# Nodes at intersections
|
|
positions = [(-20, 0), (20, 0), (-40, 12), (40, 12), (-40, -12), (40, -12)]
|
|
for x, y in positions:
|
|
svg += f' <circle cx="{x}" cy="{y}" r="3" fill="{COLORS["cyan_light"]}"/>\n'
|
|
|
|
svg += ' </g>\n'
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 6: Code Brackets
|
|
def generate_code_brackets():
|
|
svg = create_svg_header()
|
|
|
|
svg += ' <g transform="translate(100, 100)">\n'
|
|
|
|
# Left bracket
|
|
svg += f' <path d="M 20 -50 L -10 -50 L -30 -30 L -30 30 L -10 50 L 20 50" fill="none" stroke="url(#grad1)" stroke-width="5" stroke-linecap="round"/>\n'
|
|
|
|
# Right bracket
|
|
svg += f' <path d="M -20 -50 L 10 -50 L 30 -30 L 30 30 L 10 50 L -20 50" fill="none" stroke="url(#grad1)" stroke-width="5" stroke-linecap="round"/>\n'
|
|
|
|
# Center element (cloud)
|
|
svg += f' <circle cx="-8" cy="-5" r="8" fill="{COLORS["cyan"]}" opacity="0.7"/>\n'
|
|
svg += f' <circle cx="0" cy="-8" r="10" fill="{COLORS["cyan"]}" opacity="0.7"/>\n'
|
|
svg += f' <circle cx="8" cy="-5" r="8" fill="{COLORS["cyan"]}" opacity="0.7"/>\n'
|
|
svg += f' <rect x="-12" y="-5" width="24" height="10" fill="{COLORS["cyan"]}" opacity="0.7"/>\n'
|
|
|
|
svg += ' </g>\n'
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Logo Variation 7: Neural Network
|
|
def generate_neural_net():
|
|
svg = create_svg_header()
|
|
|
|
# Layer nodes
|
|
layer1 = [(50, 50), (50, 100), (50, 150)]
|
|
layer2 = [(100, 75), (100, 125)]
|
|
layer3 = [(150, 100)]
|
|
|
|
# Draw connections
|
|
svg += ' <g opacity="0.4">\n'
|
|
for n1 in layer1:
|
|
for n2 in layer2:
|
|
svg += f' <line x1="{n1[0]}" y1="{n1[1]}" x2="{n2[0]}" y2="{n2[1]}" stroke="{COLORS["purple"]}" stroke-width="1.5"/>\n'
|
|
for n2 in layer2:
|
|
for n3 in layer3:
|
|
svg += f' <line x1="{n2[0]}" y1="{n2[1]}" x2="{n3[0]}" y2="{n3[1]}" stroke="{COLORS["cyan"]}" stroke-width="1.5"/>\n'
|
|
svg += ' </g>\n'
|
|
|
|
# Draw nodes
|
|
for x, y in layer1:
|
|
svg += f' <circle cx="{x}" cy="{y}" r="6" fill="{COLORS["purple_light"]}" stroke="{COLORS["white"]}" stroke-width="2"/>\n'
|
|
for x, y in layer2:
|
|
svg += f' <circle cx="{x}" cy="{y}" r="8" fill="{COLORS["purple"]}" stroke="{COLORS["white"]}" stroke-width="2"/>\n'
|
|
for x, y in layer3:
|
|
svg += f' <circle cx="{x}" cy="{y}" r="10" fill="{COLORS["cyan"]}" stroke="{COLORS["white"]}" stroke-width="2"/>\n'
|
|
|
|
svg += create_svg_footer()
|
|
return svg
|
|
|
|
# Generate all variations
|
|
def main():
|
|
output_dir = Path('assets/generated-logos')
|
|
output_dir.mkdir(exist_ok=True)
|
|
|
|
variations = {
|
|
'hex-network.svg': generate_hex_network(),
|
|
'letter-a-geometric.svg': generate_letter_a('geometric'),
|
|
'letter-a-rounded.svg': generate_letter_a('rounded'),
|
|
'particle-cloud.svg': generate_particle_cloud(),
|
|
'minimal-icon.svg': generate_minimal_icon(),
|
|
'infinity-engine.svg': generate_infinity(),
|
|
'code-brackets.svg': generate_code_brackets(),
|
|
'neural-network.svg': generate_neural_net(),
|
|
}
|
|
|
|
for filename, svg_content in variations.items():
|
|
filepath = output_dir / filename
|
|
filepath.write_text(svg_content)
|
|
print(f"✓ Generated: {filepath}")
|
|
|
|
print(f"\n✅ Generated {len(variations)} logo variations in {output_dir}/")
|
|
print("\nOpen them in a browser to preview!")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|