#!/usr/bin/env python3
"""
SVG Polygon Generator
This script generates multiple deformed polygonal shapes and saves them as separate SVG files.
Each polygon maintains convex properties while having controlled random deformations.
Features:
- Generates 8 unique polygonal shapes
- Controls deformation through radial and angular factors
- Maintains convex properties
- Exports each shape to a separate SVG file
- Uses random colors for visual distinction
Usage:
python generate_svgs.py
Output:
Creates 8 SVG files named 'polygon_1.svg' through 'polygon_8.svg'
"""
from lxml import etree
import random
import math
from pathlib import Path
def create_svg_root():
"""Create and return a base SVG root element with standard attributes."""
root = etree.Element("svg")
root.set("width", "500")
root.set("height", "500")
root.set("xmlns", "http://www.w3.org/2000/svg")
return root
def calculate_points(center_x: float, center_y: float, radius: float,
num_sides: int, deform_factor: float) -> list:
"""
Calculate polygon points with controlled deformation.
Args:
center_x: X coordinate of polygon center
center_y: Y coordinate of polygon center
radius: Base radius of the polygon
num_sides: Number of polygon sides
deform_factor: Maximum allowed deformation factor
Returns:
List of tuples containing (x, y) coordinates
"""
points = []
angle_step = 2 * math.pi / num_sides
for i in range(num_sides):
angle = i * angle_step
radial_deform = random.uniform(-deform_factor, deform_factor)
angular_deform = random.uniform(-deform_factor/2, deform_factor/2)
modified_angle = angle + angular_deform
modified_radius = radius * (1 + radial_deform)
x = center_x + modified_radius * math.cos(modified_angle)
y = center_y + modified_radius * math.sin(modified_angle)
points.append((x, y))
return points
def generate_deformed_shapes():
"""Generate multiple deformed polygons and save them to separate SVG files."""
# Base parameters
num_sides = 8
center_x = 250
center_y = 250
base_radius = 150
max_deformation = 0.15
output_dir = Path("generated_polygons")
# Create output directory if it doesn't exist
output_dir.mkdir(exist_ok=True)
for i in range(8):
root = create_svg_root()
points = calculate_points(center_x, center_y, base_radius,
num_sides, max_deformation)
path = etree.SubElement(root, "path")
path_data = f"M {points[0][0]} {points[0][1]}"
path_data += "".join(f" L {p[0]} {p[1]}" for p in points[1:])
path_data += " Z"
path.set("d", path_data)
path.set("fill", "none")
path.set("stroke", f"#{random.randint(0, 16777215):06X}")
path.set("stroke-width", "2")
path.set("opacity", "0.7")
# Save individual SVG file
output_file = output_dir / f"polygon_{i+1}.svg"
tree = etree.ElementTree(root)
tree.write(str(output_file), pretty_print=True,
xml_declaration=True, encoding='utf-8')
print(f"Generated {num_sides} polygons in {output_dir}")
if __name__ == "__main__":
generate_deformed_shapes()
Is a blog about python programming language. You can see my work with python programming language, tutorials and news.
Wednesday, November 20, 2024
Python 3.13.0 : generates multiple deformed polygonal shapes .
Saturday, August 3, 2024
Blender 3D and python scripting - part 029.
import bpy
import math
# Set the object that the camera will orbit around
#target_object = bpy.data.objects["MyObject"]
# Create a new empty object
empty = bpy.data.objects.new("Empty", None)
# Set the empty object's location to the origin point
empty.location = (0, 0, 0)
# Set the starting position for the camera
camera = bpy.data.objects["Camera"]
# Set the number of degrees to rotate the camera around the object
degrees = 360
# Set the distance that the camera should be from the object
distance = 7.6
# Set the speed at which the camera should orbit
speed = 10
# Set the direction in which the camera should orbit (1 for clockwise, -1 for counter-clockwise)
direction = 1
# Set the camera to track the object
bpy.ops.object.select_all(action="DESELECT")
camera.select_set(True)
# Set the distance to origin point
camera.location = (-distance, 0, 0)
bpy.context.view_layer.objects.active = camera
# Remove all constraints from the object "Cube"
bpy.data.objects['Cube'].select_get()
bpy.context.view_layer.objects.active = bpy.data.objects['Cube']
bpy.ops.object.constraints_clear()
# Add a track to constraint to the object and set it
bpy.ops.object.constraint_add(type="TRACK_TO")
bpy.ops.object.track_set(type="TRACKTO")
# Set the target object as the tracking target
bpy.data.objects['Cube'].select_get()
bpy.context.view_layer.objects.active = bpy.data.objects['Cube']
# Select the file image format
bpy.context.scene.render.image_settings.file_format = 'PNG'
# Animate the camera orbiting around the object
for frame in range(0, 36):
# Set the current frame
bpy.context.scene.frame_set(frame)
# Calculate the new position for the camera based on its distance from the object
x = distance * math.sin(math.radians(frame*speed*direction))
y = distance * math.cos(math.radians(frame*speed*direction))
camera.location = (x,y,0)
# Set the output path for the rendered image
bpy.context.scene.render.filepath = "C:\\tmp\\myimage_" + str(frame).zfill(3) + ".png"
# Render the frame and save it to the output file
bpy.ops.render.render(write_still=True)
Wednesday, June 5, 2024
News : JAX in 100 Seconds by Fireship!
Saturday, February 27, 2021
Python 2.7.18 : Kick Start Google - Boring Numbers.
import math
print("Round H 2020 - Kick Start 2020: Detect is positive number is called boring.\n")
nr = int(input("get natural positive number: "))
all_cond = []
# detect if the number is odd or even number
def detect_odd_even(num):
if (num % 2) == 0:
#print("{0} is Even number".format(num))
detect = True
else:
#print("{0} is Odd number".format(num))
detect = False
return detect
# check if is an boring number.
def boring_number(num):
for p,num in enumerate(str(num),1):
print(p,num)
if (detect_odd_even(p) == detect_odd_even(int(num))): all_cond.append(True)
else:
all_cond.append(False)
# check the number is
boring_number(nr)
# print result if the positive number is boring
if (all(all_cond) == True): print("{0} is an positive boring number".format(nr))
else:
print("{0} is not a positive boring number".format(nr))
~/mathissues$ python math_003.py
Round H 2020 - Kick Start 2020: Detect is positive number is called boring.
get natural positive number: 345
(1, '3')
(2, '4')
(3, '5')
345 is an positive boring number
import math
print("Round H 2020 - Kick Start 2020: Detect is positive number is called boring.\n")
#nr = int(input("get natural positive number: "))
all_cond = []
# detect if the number is odd or even number
def detect_odd_even(num):
if (num % 2) == 0:
#print("{0} is Even number".format(num))
detect = True
else:
#print("{0} is Odd number".format(num))
detect = False
return detect
# check if is an boring number.
def boring_number(num):
for p,num in enumerate(str(num),1):
print(p,num)
if (detect_odd_even(p) == detect_odd_even(int(num))): all_cond.append(True)
else:
all_cond.append(False)
# check the number is
#boring_number(nr)
# print result if the positive number is boring
nr1 = int(input("get firt natural positive number: "))
nr2 = int(input("get firt natural positive number: "))
if nr1 < nr2:
n1 = nr1
n2 = nr2
else:
n1 = nr2
n2 = nr1
for all_nr in range(n1,n2):
all_cond = []
boring_number(all_nr)
print(all_nr)
# print result if the positive number is boring
if (all(all_cond) == True): print("{0} is an positive boring number".format(all_nr))
else: print("{0} is not a positive boring number".format(all_nr))
all_cond = []
~/mathissues$ python math_003.py
Round H 2020 - Kick Start 2020: Detect is positive number is called boring.
get firt natural positive number: 11
get firt natural positive number: 16
(1, '1')
(2, '1')
11
11 is not a positive boring number
(1, '1')
(2, '2')
12
12 is an positive boring number
(1, '1')
(2, '3')
13
13 is not a positive boring number
(1, '1')
(2, '4')
14
14 is an positive boring number
(1, '1')
(2, '5')
15
15 is not a positive boring number
Tuesday, October 10, 2017
The online editor for python and google .
Like any online editor, some python modules are not available for online security reasons.
I do not know what python modules are implemented in this online editor.
I tested just sys and math python modules.
The Google Apps come with this tool integration like application for Google drive:
Edit your python file directly in your browser:
- Save it to Google Drive integrated with Google Drive
- Test it in your browser with Skulpt
- Use autocompletion code (CTRL+SPACE)
- No registration required and totally free
- Export your file
- Work offline
New python libraries partially supported: numpy, matplotlib.
Thursday, September 13, 2012
Simple python script - Voronoi diagram
Today I show you how to make Voronoi diagram using python.
I use this to make textures for underwater.
This is just one example. But you can improve to control all cells of voronoi diagram.
The theory say:
In mathematics, a Voronoi diagram is a special kind of decomposition of a metric space, determined by distances to a specified family of objects (subsets) in the space. These objects are usually called the sites or the generators...Source : wikipedia.
I used the euclidean distance to make the Voronoi diagram because it's the most familiar case.
About wikipedia - Euclidean_distance: In mathematics, the Euclidean distance or Euclidean metric is the "ordinary" distance between two points that one would measure with a ruler, and is given by the Pythagorean formula...
My python script use the next python modules:
PIL - this allow me to use image functions.
random - this module give me... random numbers.
math - some math functions.
Let's see the source code :
from PIL import Image
import random
import math
Now I make the function named gen_voronoi.
This take the height and width of the output image and the number of cells.
The function has some random variables for red , green , blue - nr,ng,nb.
The function hypot is not accessible directly so we need to import math module and using math static object.
The return value is the Euclidean norm : sqrt(x*x + y*y).
def gen_voronoi(w, h, cells):
image = Image.new("RGB", (w, h))
putpixel = image.putpixel
img_x, img_y = image.size
nx = []
ny = []
nr = []
ng = []
nb = []
for i in range(cells):
nx.append(random.randrange(img_x))
ny.append(random.randrange(img_y))
nr.append(random.randrange(256))
ng.append(random.randrange(256))
nb.append(random.randrange(256))
for y in range(img_y):
for x in range(img_x):
dmin = math.hypot(img_x-1, img_y-1)
j = -1
for i in range(cells):
d = math.hypot(nx[i]-x, ny[i]-y)
if d < dmin:
dmin = d
j = i
putpixel((x, y), (nr[j], ng[j], nb[j]))
image.save("output.png", "PNG")
image.show()
Use the function to make the output.png image.
gen_voronoi(200, 200, 55)
The result is :