Spaces:
Sleeping
Sleeping
| # app.py - Main Hugging Face Spaces application | |
| import gradio as gr | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| from matplotlib.colors import LinearSegmentedColormap | |
| import io | |
| from PIL import Image | |
| import math | |
| class MathArtGenerator: | |
| def __init__(self, width=800, height=600): | |
| self.width = width | |
| self.height = height | |
| def generate_coordinates(self, x_range=(-10, 10), y_range=(-6, 6)): | |
| """Generate coordinate meshgrid""" | |
| x = np.linspace(x_range[0], x_range[1], self.width) | |
| y = np.linspace(y_range[0], y_range[1], self.height) | |
| return np.meshgrid(x, y) | |
| def mountain_function(self, X, Y, complexity=1.0, scale=1.0): | |
| """Generate mountain-like terrain""" | |
| mountains = ( | |
| 2 * scale * np.sin(0.5 * X) * np.cos(0.3 * Y) + | |
| 1.5 * scale * np.sin(0.8 * X + 1) * np.cos(0.2 * Y + 0.5) + | |
| scale * np.sin(1.2 * X + 2) * np.cos(0.4 * Y + 1) + | |
| 0.5 * scale * np.sin(2 * X) * np.cos(0.6 * Y) | |
| ) | |
| detail = complexity * ( | |
| 0.3 * np.sin(3 * X) * np.sin(4 * Y) + | |
| 0.2 * np.cos(5 * X + Y) + | |
| 0.1 * np.sin(8 * X) * np.cos(6 * Y) | |
| ) | |
| return mountains + detail | |
| def lightning_function(self, X, Y, intensity=1.0, branches=3): | |
| """Generate lightning patterns""" | |
| lightning = np.zeros_like(X) | |
| # Main bolt | |
| bolt_path = 2 * np.sin(0.5 * X) + 0.5 * np.sin(2 * X) | |
| main_bolt = np.abs(Y - bolt_path) < (0.1 + 0.05 * np.sin(5 * X)) | |
| lightning += intensity * main_bolt.astype(float) | |
| # Branches | |
| for i in range(int(branches)): | |
| offset = (i + 1) * 0.3 | |
| branch_path = bolt_path + offset * np.sin((i + 2) * X) | |
| branch = np.abs(Y - branch_path) < 0.05 | |
| lightning += 0.5 * intensity * branch.astype(float) | |
| return np.clip(lightning, 0, intensity) | |
| def wave_interference(self, X, Y, freq1=1.0, freq2=1.5, phase=0): | |
| """Create wave interference patterns""" | |
| wave1 = np.sin(freq1 * X + phase) * np.cos(freq1 * Y) | |
| wave2 = np.sin(freq2 * X) * np.cos(freq2 * Y + phase) | |
| return wave1 + wave2 | |
| def spiral_pattern(self, X, Y, spiral_factor=0.5, frequency=3): | |
| """Generate spiral patterns""" | |
| r = np.sqrt(X**2 + Y**2) | |
| theta = np.arctan2(Y, X) | |
| spiral = np.sin(frequency * theta + spiral_factor * r) | |
| return spiral * np.exp(-0.1 * r) # Fade with distance | |
| def fractal_noise(self, X, Y, octaves=4, persistence=0.5): | |
| """Generate fractal noise""" | |
| noise = np.zeros_like(X) | |
| amplitude = 1.0 | |
| frequency = 1.0 | |
| for i in range(octaves): | |
| noise += amplitude * ( | |
| np.sin(frequency * X) * np.cos(frequency * Y) + | |
| 0.5 * np.sin(2 * frequency * X + 1) * np.cos(2 * frequency * Y + 1) | |
| ) | |
| amplitude *= persistence | |
| frequency *= 2 | |
| return noise | |
| def create_mathematical_art( | |
| art_type="Landscape", | |
| width=800, | |
| height=600, | |
| color_scheme="Blue Mountains", | |
| complexity=1.0, | |
| scale=1.0, | |
| frequency1=1.0, | |
| frequency2=1.5, | |
| intensity=1.0 | |
| ): | |
| """Main function to generate mathematical art""" | |
| # Initialize generator | |
| generator = MathArtGenerator(width, height) | |
| X, Y = generator.generate_coordinates() | |
| # Generate based on selected type | |
| if art_type == "Landscape": | |
| image_data = generator.mountain_function(X, Y, complexity, scale) | |
| lightning = generator.lightning_function(X, Y, intensity, 3) | |
| image_data = image_data + 2 * lightning | |
| elif art_type == "Wave Interference": | |
| image_data = generator.wave_interference(X, Y, frequency1, frequency2) | |
| elif art_type == "Spiral Pattern": | |
| image_data = generator.spiral_pattern(X, Y, complexity, frequency1) | |
| elif art_type == "Fractal Noise": | |
| image_data = generator.fractal_noise(X, Y, int(frequency1), complexity) | |
| elif art_type == "Abstract Composition": | |
| mountains = generator.mountain_function(X, Y, complexity * 0.5, scale) | |
| waves = generator.wave_interference(X, Y, frequency1, frequency2) | |
| spirals = generator.spiral_pattern(X, Y, complexity, frequency1 * 2) | |
| image_data = mountains + waves * 0.5 + spirals * 0.3 | |
| # Apply color scheme | |
| color_schemes = { | |
| "Blue Mountains": ['#000033', '#000066', '#333366', '#666699', '#9999CC', '#CCCCFF', '#FFFFFF'], | |
| "Sunset": ['#000011', '#330000', '#660033', '#993366', '#CC6699', '#FFCCFF', '#FFFFFF'], | |
| "Forest": ['#001100', '#003300', '#006600', '#339933', '#66CC66', '#99FF99', '#FFFFFF'], | |
| "Ocean": ['#000044', '#003366', '#006699', '#3399CC', '#66CCFF', '#99FFFF', '#FFFFFF'], | |
| "Grayscale": ['#000000', '#333333', '#666666', '#999999', '#CCCCCC', '#FFFFFF'] | |
| } | |
| colors = color_schemes.get(color_scheme, color_schemes["Blue Mountains"]) | |
| cmap = LinearSegmentedColormap.from_list('custom', colors, N=256) | |
| # Create the plot | |
| plt.figure(figsize=(12, 8)) | |
| plt.imshow(image_data, cmap=cmap, extent=[-10, 10, -6, 6], origin='lower') | |
| plt.axis('off') | |
| plt.tight_layout() | |
| # Convert to PIL Image for Gradio | |
| buf = io.BytesIO() | |
| plt.savefig(buf, format='png', dpi=150, bbox_inches='tight', pad_inches=0) | |
| buf.seek(0) | |
| plt.close() | |
| return Image.open(buf) | |
| def create_polar_art(equation_type="Rose", petals=4, frequency=2.0, amplitude=3.0): | |
| """Generate polar coordinate art""" | |
| theta = np.linspace(0, 4 * np.pi, 10000) | |
| if equation_type == "Rose": | |
| r = amplitude * np.sin(petals * theta) | |
| elif equation_type == "Spiral": | |
| r = amplitude * theta / (2 * np.pi) * np.sin(frequency * theta) | |
| elif equation_type == "Cardioid": | |
| r = amplitude * (1 + np.cos(theta)) | |
| elif equation_type == "Lemniscate": | |
| r = amplitude * np.sqrt(np.abs(np.cos(2 * theta))) | |
| x = r * np.cos(theta) | |
| y = r * np.sin(theta) | |
| plt.figure(figsize=(10, 10)) | |
| plt.plot(x, y, linewidth=0.8, color='#3366CC', alpha=0.8) | |
| plt.axis('equal') | |
| plt.axis('off') | |
| plt.grid(False) | |
| plt.tight_layout() | |
| # Convert to PIL Image | |
| buf = io.BytesIO() | |
| plt.savefig(buf, format='png', dpi=150, bbox_inches='tight', pad_inches=0) | |
| buf.seek(0) | |
| plt.close() | |
| return Image.open(buf) | |
| # Gradio Interface | |
| def create_interface(): | |
| """Create the Gradio interface""" | |
| with gr.Blocks(title="Mathematical Art Generator", theme=gr.themes.Soft()) as interface: | |
| gr.Markdown(""" | |
| # 🎨 Mathematical Art Generator | |
| Create stunning mathematical art using various equations and patterns! | |
| Choose from different art types and customize parameters to generate unique mathematical visualizations. | |
| """) | |
| with gr.Tabs(): | |
| # Tab 1: Function-based Art | |
| with gr.TabItem("Function Art"): | |
| with gr.Row(): | |
| with gr.Column(): | |
| art_type = gr.Dropdown( | |
| choices=["Landscape", "Wave Interference", "Spiral Pattern", "Fractal Noise", "Abstract Composition"], | |
| value="Landscape", | |
| label="Art Type" | |
| ) | |
| color_scheme = gr.Dropdown( | |
| choices=["Blue Mountains", "Sunset", "Forest", "Ocean", "Grayscale"], | |
| value="Blue Mountains", | |
| label="Color Scheme" | |
| ) | |
| with gr.Row(): | |
| width = gr.Slider(400, 1200, value=800, step=100, label="Width") | |
| height = gr.Slider(300, 900, value=600, step=100, label="Height") | |
| with gr.Row(): | |
| complexity = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Complexity") | |
| scale = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Scale") | |
| with gr.Row(): | |
| frequency1 = gr.Slider(0.1, 5.0, value=1.0, step=0.1, label="Frequency 1") | |
| frequency2 = gr.Slider(0.1, 5.0, value=1.5, step=0.1, label="Frequency 2") | |
| intensity = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Intensity") | |
| generate_btn = gr.Button("🎨 Generate Art", variant="primary") | |
| with gr.Column(): | |
| function_output = gr.Image(label="Generated Mathematical Art") | |
| generate_btn.click( | |
| fn=create_mathematical_art, | |
| inputs=[art_type, width, height, color_scheme, complexity, scale, frequency1, frequency2, intensity], | |
| outputs=function_output | |
| ) | |
| # Tab 2: Polar Art | |
| with gr.TabItem("Polar Art"): | |
| with gr.Row(): | |
| with gr.Column(): | |
| equation_type = gr.Dropdown( | |
| choices=["Rose", "Spiral", "Cardioid", "Lemniscate"], | |
| value="Rose", | |
| label="Equation Type" | |
| ) | |
| with gr.Row(): | |
| petals = gr.Slider(2, 20, value=4, step=1, label="Petals/Parameter") | |
| frequency = gr.Slider(0.1, 10.0, value=2.0, step=0.1, label="Frequency") | |
| amplitude = gr.Slider(1.0, 10.0, value=3.0, step=0.1, label="Amplitude") | |
| generate_polar_btn = gr.Button("🌸 Generate Polar Art", variant="primary") | |
| with gr.Column(): | |
| polar_output = gr.Image(label="Generated Polar Art") | |
| generate_polar_btn.click( | |
| fn=create_polar_art, | |
| inputs=[equation_type, petals, frequency, amplitude], | |
| outputs=polar_output | |
| ) | |
| # Tab 3: Information | |
| with gr.TabItem("About"): | |
| gr.Markdown(""" | |
| ## 📐 Mathematical Art Types | |
| **Function Art:** | |
| - **Landscape**: Mountain ranges using trigonometric functions | |
| - **Wave Interference**: Overlapping sine and cosine waves | |
| - **Spiral Pattern**: Logarithmic and Archimedean spirals | |
| - **Fractal Noise**: Multi-octave noise patterns | |
| - **Abstract Composition**: Combination of multiple functions | |
| **Polar Art:** | |
| - **Rose**: r = a·sin(nθ) or r = a·cos(nθ) | |
| - **Spiral**: r = aθ combined with trigonometric functions | |
| - **Cardioid**: r = a(1 + cos(θ)) | |
| - **Lemniscate**: r² = a²cos(2θ) | |
| ## 🎛️ Parameter Guide | |
| - **Complexity**: Controls detail level and noise | |
| - **Scale**: Overall size/amplitude of patterns | |
| - **Frequency**: Speed of oscillations | |
| - **Intensity**: Brightness/contrast of effects | |
| ## 🚀 Deployment Notes | |
| This app generates mathematical art in real-time using NumPy and Matplotlib. | |
| Higher resolutions may take longer to generate. | |
| """) | |
| # Example generations on startup | |
| gr.Markdown("### 🎭 Example Gallery") | |
| with gr.Row(): | |
| gr.Examples( | |
| examples=[ | |
| ["Landscape", 800, 600, "Blue Mountains", 1.0, 1.0, 1.0, 1.5, 1.0], | |
| ["Wave Interference", 800, 600, "Ocean", 1.5, 1.0, 2.0, 3.0, 1.0], | |
| ["Spiral Pattern", 800, 600, "Sunset", 0.8, 1.2, 1.5, 1.0, 1.0], | |
| ], | |
| inputs=[art_type, width, height, color_scheme, complexity, scale, frequency1, frequency2, intensity], | |
| outputs=function_output, | |
| fn=create_mathematical_art, | |
| cache_examples=True | |
| ) | |
| return interface | |
| # Launch the app | |
| if __name__ == "__main__": | |
| interface = create_interface() | |
| interface.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=True | |
| ) | |
| # requirements.txt content for Hugging Face | |
| """ | |
| gradio>=4.0.0 | |
| numpy>=1.21.0 | |
| matplotlib>=3.5.0 | |
| Pillow>=9.0.0 | |
| """ | |
| # README.md content for Hugging Face | |
| readme_content = """ | |
| --- | |
| title: Mathematical Art Generator | |
| emoji: 🎨 | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: 4.0.0 | |
| app_file: app.py | |
| pinned: false | |
| license: mit | |
| --- | |
| # Mathematical Art Generator 🎨 | |
| Generate stunning mathematical art using various equations and mathematical functions! | |
| ## Features | |
| - **Function-based Art**: Create landscapes, wave patterns, spirals, and abstract compositions | |
| - **Polar Coordinate Art**: Generate roses, spirals, cardioids, and lemniscates | |
| - **Customizable Parameters**: Control complexity, scale, frequency, and color schemes | |
| - **Real-time Generation**: Interactive parameter adjustment with instant preview | |
| - **High-Quality Output**: Export-ready images with customizable resolution | |
| ## Art Types | |
| ### Function Art | |
| - **Landscape**: Mountain ranges using sine/cosine combinations | |
| - **Wave Interference**: Beautiful interference patterns | |
| - **Spiral Patterns**: Logarithmic and mathematical spirals | |
| - **Fractal Noise**: Multi-octave procedural patterns | |
| - **Abstract Compositions**: Complex mathematical combinations | |
| ### Polar Art | |
| - **Rose Curves**: r = a·sin(nθ) | |
| - **Spirals**: Various spiral equations | |
| - **Cardioid**: Heart-shaped curves | |
| - **Lemniscate**: Figure-eight patterns | |
| ## Usage | |
| 1. Choose your art type from the tabs | |
| 2. Adjust parameters to customize the output | |
| 3. Click "Generate Art" to create your mathematical masterpiece | |
| 4. Experiment with different settings for unique results! | |
| ## Mathematical Background | |
| This generator uses various mathematical concepts: | |
| - Trigonometric functions (sin, cos, tan) | |
| - Polar coordinates (r, θ) | |
| - Parametric equations | |
| - Fractal mathematics | |
| - Wave interference patterns | |
| Perfect for artists, mathematicians, educators, and anyone interested in the beauty of mathematical visualization! | |
| """ |