citoreh commited on
Commit
98c3d8a
·
verified ·
1 Parent(s): 39bbfbc

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +383 -0
app.py ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py - Main Hugging Face Spaces application
2
+ import gradio as gr
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ from matplotlib.colors import LinearSegmentedColormap
6
+ import io
7
+ from PIL import Image
8
+ import math
9
+
10
+ class MathArtGenerator:
11
+ def __init__(self, width=800, height=600):
12
+ self.width = width
13
+ self.height = height
14
+
15
+ def generate_coordinates(self, x_range=(-10, 10), y_range=(-6, 6)):
16
+ """Generate coordinate meshgrid"""
17
+ x = np.linspace(x_range[0], x_range[1], self.width)
18
+ y = np.linspace(y_range[0], y_range[1], self.height)
19
+ return np.meshgrid(x, y)
20
+
21
+ def mountain_function(self, X, Y, complexity=1.0, scale=1.0):
22
+ """Generate mountain-like terrain"""
23
+ mountains = (
24
+ 2 * scale * np.sin(0.5 * X) * np.cos(0.3 * Y) +
25
+ 1.5 * scale * np.sin(0.8 * X + 1) * np.cos(0.2 * Y + 0.5) +
26
+ scale * np.sin(1.2 * X + 2) * np.cos(0.4 * Y + 1) +
27
+ 0.5 * scale * np.sin(2 * X) * np.cos(0.6 * Y)
28
+ )
29
+
30
+ detail = complexity * (
31
+ 0.3 * np.sin(3 * X) * np.sin(4 * Y) +
32
+ 0.2 * np.cos(5 * X + Y) +
33
+ 0.1 * np.sin(8 * X) * np.cos(6 * Y)
34
+ )
35
+
36
+ return mountains + detail
37
+
38
+ def lightning_function(self, X, Y, intensity=1.0, branches=3):
39
+ """Generate lightning patterns"""
40
+ lightning = np.zeros_like(X)
41
+
42
+ # Main bolt
43
+ bolt_path = 2 * np.sin(0.5 * X) + 0.5 * np.sin(2 * X)
44
+ main_bolt = np.abs(Y - bolt_path) < (0.1 + 0.05 * np.sin(5 * X))
45
+ lightning += intensity * main_bolt.astype(float)
46
+
47
+ # Branches
48
+ for i in range(int(branches)):
49
+ offset = (i + 1) * 0.3
50
+ branch_path = bolt_path + offset * np.sin((i + 2) * X)
51
+ branch = np.abs(Y - branch_path) < 0.05
52
+ lightning += 0.5 * intensity * branch.astype(float)
53
+
54
+ return np.clip(lightning, 0, intensity)
55
+
56
+ def wave_interference(self, X, Y, freq1=1.0, freq2=1.5, phase=0):
57
+ """Create wave interference patterns"""
58
+ wave1 = np.sin(freq1 * X + phase) * np.cos(freq1 * Y)
59
+ wave2 = np.sin(freq2 * X) * np.cos(freq2 * Y + phase)
60
+ return wave1 + wave2
61
+
62
+ def spiral_pattern(self, X, Y, spiral_factor=0.5, frequency=3):
63
+ """Generate spiral patterns"""
64
+ r = np.sqrt(X**2 + Y**2)
65
+ theta = np.arctan2(Y, X)
66
+ spiral = np.sin(frequency * theta + spiral_factor * r)
67
+ return spiral * np.exp(-0.1 * r) # Fade with distance
68
+
69
+ def fractal_noise(self, X, Y, octaves=4, persistence=0.5):
70
+ """Generate fractal noise"""
71
+ noise = np.zeros_like(X)
72
+ amplitude = 1.0
73
+ frequency = 1.0
74
+
75
+ for i in range(octaves):
76
+ noise += amplitude * (
77
+ np.sin(frequency * X) * np.cos(frequency * Y) +
78
+ 0.5 * np.sin(2 * frequency * X + 1) * np.cos(2 * frequency * Y + 1)
79
+ )
80
+ amplitude *= persistence
81
+ frequency *= 2
82
+
83
+ return noise
84
+
85
+ def create_mathematical_art(
86
+ art_type="Landscape",
87
+ width=800,
88
+ height=600,
89
+ color_scheme="Blue Mountains",
90
+ complexity=1.0,
91
+ scale=1.0,
92
+ frequency1=1.0,
93
+ frequency2=1.5,
94
+ intensity=1.0
95
+ ):
96
+ """Main function to generate mathematical art"""
97
+
98
+ # Initialize generator
99
+ generator = MathArtGenerator(width, height)
100
+ X, Y = generator.generate_coordinates()
101
+
102
+ # Generate based on selected type
103
+ if art_type == "Landscape":
104
+ image_data = generator.mountain_function(X, Y, complexity, scale)
105
+ lightning = generator.lightning_function(X, Y, intensity, 3)
106
+ image_data = image_data + 2 * lightning
107
+
108
+ elif art_type == "Wave Interference":
109
+ image_data = generator.wave_interference(X, Y, frequency1, frequency2)
110
+
111
+ elif art_type == "Spiral Pattern":
112
+ image_data = generator.spiral_pattern(X, Y, complexity, frequency1)
113
+
114
+ elif art_type == "Fractal Noise":
115
+ image_data = generator.fractal_noise(X, Y, int(frequency1), complexity)
116
+
117
+ elif art_type == "Abstract Composition":
118
+ mountains = generator.mountain_function(X, Y, complexity * 0.5, scale)
119
+ waves = generator.wave_interference(X, Y, frequency1, frequency2)
120
+ spirals = generator.spiral_pattern(X, Y, complexity, frequency1 * 2)
121
+ image_data = mountains + waves * 0.5 + spirals * 0.3
122
+
123
+ # Apply color scheme
124
+ color_schemes = {
125
+ "Blue Mountains": ['#000033', '#000066', '#333366', '#666699', '#9999CC', '#CCCCFF', '#FFFFFF'],
126
+ "Sunset": ['#000011', '#330000', '#660033', '#993366', '#CC6699', '#FFCCFF', '#FFFFFF'],
127
+ "Forest": ['#001100', '#003300', '#006600', '#339933', '#66CC66', '#99FF99', '#FFFFFF'],
128
+ "Ocean": ['#000044', '#003366', '#006699', '#3399CC', '#66CCFF', '#99FFFF', '#FFFFFF'],
129
+ "Grayscale": ['#000000', '#333333', '#666666', '#999999', '#CCCCCC', '#FFFFFF']
130
+ }
131
+
132
+ colors = color_schemes.get(color_scheme, color_schemes["Blue Mountains"])
133
+ cmap = LinearSegmentedColormap.from_list('custom', colors, N=256)
134
+
135
+ # Create the plot
136
+ plt.figure(figsize=(12, 8))
137
+ plt.imshow(image_data, cmap=cmap, extent=[-10, 10, -6, 6], origin='lower')
138
+ plt.axis('off')
139
+ plt.tight_layout()
140
+
141
+ # Convert to PIL Image for Gradio
142
+ buf = io.BytesIO()
143
+ plt.savefig(buf, format='png', dpi=150, bbox_inches='tight', pad_inches=0)
144
+ buf.seek(0)
145
+ plt.close()
146
+
147
+ return Image.open(buf)
148
+
149
+ def create_polar_art(equation_type="Rose", petals=4, frequency=2.0, amplitude=3.0):
150
+ """Generate polar coordinate art"""
151
+ theta = np.linspace(0, 4 * np.pi, 10000)
152
+
153
+ if equation_type == "Rose":
154
+ r = amplitude * np.sin(petals * theta)
155
+ elif equation_type == "Spiral":
156
+ r = amplitude * theta / (2 * np.pi) * np.sin(frequency * theta)
157
+ elif equation_type == "Cardioid":
158
+ r = amplitude * (1 + np.cos(theta))
159
+ elif equation_type == "Lemniscate":
160
+ r = amplitude * np.sqrt(np.abs(np.cos(2 * theta)))
161
+
162
+ x = r * np.cos(theta)
163
+ y = r * np.sin(theta)
164
+
165
+ plt.figure(figsize=(10, 10))
166
+ plt.plot(x, y, linewidth=0.8, color='#3366CC', alpha=0.8)
167
+ plt.axis('equal')
168
+ plt.axis('off')
169
+ plt.grid(False)
170
+ plt.tight_layout()
171
+
172
+ # Convert to PIL Image
173
+ buf = io.BytesIO()
174
+ plt.savefig(buf, format='png', dpi=150, bbox_inches='tight', pad_inches=0)
175
+ buf.seek(0)
176
+ plt.close()
177
+
178
+ return Image.open(buf)
179
+
180
+ # Gradio Interface
181
+ def create_interface():
182
+ """Create the Gradio interface"""
183
+
184
+ with gr.Blocks(title="Mathematical Art Generator", theme=gr.themes.Soft()) as interface:
185
+ gr.Markdown("""
186
+ # 🎨 Mathematical Art Generator
187
+
188
+ Create stunning mathematical art using various equations and patterns!
189
+ Choose from different art types and customize parameters to generate unique mathematical visualizations.
190
+ """)
191
+
192
+ with gr.Tabs():
193
+ # Tab 1: Function-based Art
194
+ with gr.TabItem("Function Art"):
195
+ with gr.Row():
196
+ with gr.Column():
197
+ art_type = gr.Dropdown(
198
+ choices=["Landscape", "Wave Interference", "Spiral Pattern", "Fractal Noise", "Abstract Composition"],
199
+ value="Landscape",
200
+ label="Art Type"
201
+ )
202
+ color_scheme = gr.Dropdown(
203
+ choices=["Blue Mountains", "Sunset", "Forest", "Ocean", "Grayscale"],
204
+ value="Blue Mountains",
205
+ label="Color Scheme"
206
+ )
207
+
208
+ with gr.Row():
209
+ width = gr.Slider(400, 1200, value=800, step=100, label="Width")
210
+ height = gr.Slider(300, 900, value=600, step=100, label="Height")
211
+
212
+ with gr.Row():
213
+ complexity = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Complexity")
214
+ scale = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Scale")
215
+
216
+ with gr.Row():
217
+ frequency1 = gr.Slider(0.1, 5.0, value=1.0, step=0.1, label="Frequency 1")
218
+ frequency2 = gr.Slider(0.1, 5.0, value=1.5, step=0.1, label="Frequency 2")
219
+
220
+ intensity = gr.Slider(0.1, 3.0, value=1.0, step=0.1, label="Intensity")
221
+
222
+ generate_btn = gr.Button("🎨 Generate Art", variant="primary")
223
+
224
+ with gr.Column():
225
+ function_output = gr.Image(label="Generated Mathematical Art")
226
+
227
+ generate_btn.click(
228
+ fn=create_mathematical_art,
229
+ inputs=[art_type, width, height, color_scheme, complexity, scale, frequency1, frequency2, intensity],
230
+ outputs=function_output
231
+ )
232
+
233
+ # Tab 2: Polar Art
234
+ with gr.TabItem("Polar Art"):
235
+ with gr.Row():
236
+ with gr.Column():
237
+ equation_type = gr.Dropdown(
238
+ choices=["Rose", "Spiral", "Cardioid", "Lemniscate"],
239
+ value="Rose",
240
+ label="Equation Type"
241
+ )
242
+
243
+ with gr.Row():
244
+ petals = gr.Slider(2, 20, value=4, step=1, label="Petals/Parameter")
245
+ frequency = gr.Slider(0.1, 10.0, value=2.0, step=0.1, label="Frequency")
246
+
247
+ amplitude = gr.Slider(1.0, 10.0, value=3.0, step=0.1, label="Amplitude")
248
+
249
+ generate_polar_btn = gr.Button("🌸 Generate Polar Art", variant="primary")
250
+
251
+ with gr.Column():
252
+ polar_output = gr.Image(label="Generated Polar Art")
253
+
254
+ generate_polar_btn.click(
255
+ fn=create_polar_art,
256
+ inputs=[equation_type, petals, frequency, amplitude],
257
+ outputs=polar_output
258
+ )
259
+
260
+ # Tab 3: Information
261
+ with gr.TabItem("About"):
262
+ gr.Markdown("""
263
+ ## 📐 Mathematical Art Types
264
+
265
+ **Function Art:**
266
+ - **Landscape**: Mountain ranges using trigonometric functions
267
+ - **Wave Interference**: Overlapping sine and cosine waves
268
+ - **Spiral Pattern**: Logarithmic and Archimedean spirals
269
+ - **Fractal Noise**: Multi-octave noise patterns
270
+ - **Abstract Composition**: Combination of multiple functions
271
+
272
+ **Polar Art:**
273
+ - **Rose**: r = a·sin(nθ) or r = a·cos(nθ)
274
+ - **Spiral**: r = aθ combined with trigonometric functions
275
+ - **Cardioid**: r = a(1 + cos(θ))
276
+ - **Lemniscate**: r² = a²cos(2θ)
277
+
278
+ ## 🎛️ Parameter Guide
279
+
280
+ - **Complexity**: Controls detail level and noise
281
+ - **Scale**: Overall size/amplitude of patterns
282
+ - **Frequency**: Speed of oscillations
283
+ - **Intensity**: Brightness/contrast of effects
284
+
285
+ ## 🚀 Deployment Notes
286
+
287
+ This app generates mathematical art in real-time using NumPy and Matplotlib.
288
+ Higher resolutions may take longer to generate.
289
+ """)
290
+
291
+ # Example generations on startup
292
+ gr.Markdown("### 🎭 Example Gallery")
293
+ with gr.Row():
294
+ gr.Examples(
295
+ examples=[
296
+ ["Landscape", 800, 600, "Blue Mountains", 1.0, 1.0, 1.0, 1.5, 1.0],
297
+ ["Wave Interference", 800, 600, "Ocean", 1.5, 1.0, 2.0, 3.0, 1.0],
298
+ ["Spiral Pattern", 800, 600, "Sunset", 0.8, 1.2, 1.5, 1.0, 1.0],
299
+ ],
300
+ inputs=[art_type, width, height, color_scheme, complexity, scale, frequency1, frequency2, intensity],
301
+ outputs=function_output,
302
+ fn=create_mathematical_art,
303
+ cache_examples=True
304
+ )
305
+
306
+ return interface
307
+
308
+ # Launch the app
309
+ if __name__ == "__main__":
310
+ interface = create_interface()
311
+ interface.launch(
312
+ server_name="0.0.0.0",
313
+ server_port=7860,
314
+ share=True
315
+ )
316
+
317
+ # requirements.txt content for Hugging Face
318
+ """
319
+ gradio>=4.0.0
320
+ numpy>=1.21.0
321
+ matplotlib>=3.5.0
322
+ Pillow>=9.0.0
323
+ """
324
+
325
+ # README.md content for Hugging Face
326
+ readme_content = """
327
+ ---
328
+ title: Mathematical Art Generator
329
+ emoji: 🎨
330
+ colorFrom: blue
331
+ colorTo: purple
332
+ sdk: gradio
333
+ sdk_version: 4.0.0
334
+ app_file: app.py
335
+ pinned: false
336
+ license: mit
337
+ ---
338
+
339
+ # Mathematical Art Generator 🎨
340
+
341
+ Generate stunning mathematical art using various equations and mathematical functions!
342
+
343
+ ## Features
344
+
345
+ - **Function-based Art**: Create landscapes, wave patterns, spirals, and abstract compositions
346
+ - **Polar Coordinate Art**: Generate roses, spirals, cardioids, and lemniscates
347
+ - **Customizable Parameters**: Control complexity, scale, frequency, and color schemes
348
+ - **Real-time Generation**: Interactive parameter adjustment with instant preview
349
+ - **High-Quality Output**: Export-ready images with customizable resolution
350
+
351
+ ## Art Types
352
+
353
+ ### Function Art
354
+ - **Landscape**: Mountain ranges using sine/cosine combinations
355
+ - **Wave Interference**: Beautiful interference patterns
356
+ - **Spiral Patterns**: Logarithmic and mathematical spirals
357
+ - **Fractal Noise**: Multi-octave procedural patterns
358
+ - **Abstract Compositions**: Complex mathematical combinations
359
+
360
+ ### Polar Art
361
+ - **Rose Curves**: r = a·sin(nθ)
362
+ - **Spirals**: Various spiral equations
363
+ - **Cardioid**: Heart-shaped curves
364
+ - **Lemniscate**: Figure-eight patterns
365
+
366
+ ## Usage
367
+
368
+ 1. Choose your art type from the tabs
369
+ 2. Adjust parameters to customize the output
370
+ 3. Click "Generate Art" to create your mathematical masterpiece
371
+ 4. Experiment with different settings for unique results!
372
+
373
+ ## Mathematical Background
374
+
375
+ This generator uses various mathematical concepts:
376
+ - Trigonometric functions (sin, cos, tan)
377
+ - Polar coordinates (r, θ)
378
+ - Parametric equations
379
+ - Fractal mathematics
380
+ - Wave interference patterns
381
+
382
+ Perfect for artists, mathematicians, educators, and anyone interested in the beauty of mathematical visualization!
383
+ """