analitics

Pages

Showing posts with label math. Show all posts
Showing posts with label math. Show all posts

Wednesday, November 20, 2024

Python 3.13.0 : generates multiple deformed polygonal shapes .

Today I created this source code in python that generates eight random convex polygons. The idea was to create sprites for a 2D game: snowballs, boulders, or similar objects... Obviously I also used Sonet 3.5 artificial intelligence. You can find the source code on the pagure account in fedora.
#!/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()

Saturday, August 3, 2024

Blender 3D and python scripting - part 029.

This is a simple Blender 3D script that render images from myimage_000 to myimage_035 around object named Cube.
The script can be changed with any object and any steps for 0 to 360 degree.
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!

JAX is a Python library similar to NumPy for scientific computing and linear algebra, but designed to run on accelerators like Cuda-based GPUs and Google's TPUs.

Saturday, February 27, 2021

Python 2.7.18 : Kick Start Google - Boring Numbers.

Today I solved one of the problems required for solving Google Kick Start in 2020, see on my account.
Round H 2020 - Kick Start 2020 Boring Numbers (7pts, 12pts) Problem Ron read a book about boring numbers. According to the book, a positive number is called boring if all of the digits at even positions in the number are even and all of the digits at odd positions are odd. The digits are enumerated from left to right starting from 1. For example, the number 1478 is boring as the odd positions include the digits {1, 7} which are odd and even positions include the digits {4, 8} which are even. Given two numbers L and R, Ron wants to count how many numbers in the range [L, R] (L and R inclusive) are boring. Ron is unable to solve the problem, hence he needs your help.
Let's try to find the solution:
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))
Let's test it:
~/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
Then la last step is to test any number from range of given two numbers L and R.
The new source code is this:
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 = [] 
The final solution result to test all numbers in range given two numbers L and R can be see bellow:
~/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 .

This is a good 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 :