Reputation: 1853
I haven't been able to find an article or an stackoverflow question around this subject as I need it.
I'm making 2D game and I want to generate a random shaped asteroid. Every asteroid has a center, a X, Y
position, I want t generate let's say 8 vertices around it (the number of vertices is variable)
If I can achieve this shape now I want to add a random element, let's say a variable and random distance from the center to create a random rock shape.
I've researched some trigonometry concept called Polar to Cartisian Coordinates but haven't been able to figure out how to apply it to this goal. Although there's tutorials for it in Javascript, it uses libraries and functions that I would have to make in python from scratch.
EDIT: So your answer is focused on explaining the formula to get the vertices around the center, these are the things that I already know how to do,
1) Draw a polygon in the graphics library I'm using 2) Get random numbers
Thank you so much in advance!
Upvotes: 4
Views: 2261
Reputation: 117856
You can use the random
library to randomly sample in polar coordinates. Sample an orientation, then sample a radial distance. In the following example I chose that the orientation would be uniformly distributed in [0, 2*pi]
and the radius would be normally distributed with user input mean and standard deviation.
import random
import math
def generate_points(center_x, center_y, mean_radius, sigma_radius, num_points):
points = []
for i in range(num_points):
theta = random.uniform(0, 2*math.pi)
radius = random.gauss(mean_radius, sigma_radius)
x = center_x + radius * math.cos(theta)
y = center_y + radius * math.sin(theta)
points.append([x,y])
return points
As an example of how to call it
>>> generate_points(5.0, 7.0, 1.0, 0.1, 8)
[[4.4478263120757875, 6.018608023032151],
[4.407825651072504, 6.294849028359581],
[5.0570272843718085, 6.17834681191539],
[5.307793789416231, 6.156715230672773],
[4.368508167422119, 7.712616387293795],
[5.327972045495855, 5.917733119760926],
[5.748935178651789, 6.437863588580371],
[3.9312163910881033, 6.388093041756519]]
If you want the points to be wound in a particular order, then I would use something like numpy.linspace
to walk either clockwise or counterclockwise to sample theta. For example
import random
import math
import numpy as np
def generate_points(center_x, center_y, mean_radius, sigma_radius, num_points):
points = []
for theta in np.linspace(0, 2*math.pi - (2*math.pi/num_points), num_points):
radius = random.gauss(mean_radius, sigma_radius)
x = center_x + radius * math.cos(theta)
y = center_y + radius * math.sin(theta)
points.append([x,y])
return points
If you do not want to install numpy
you can write your own similar version of linspace
def linspace(start, stop, num_steps):
values = []
delta = (stop - start) / num_steps
for i in range(num_steps):
values.append(start + i * delta)
return values
Upvotes: 6
Reputation: 249133
An easy way would be to choose at random one or two or three non-adjacent vertices, and simply move them a random amount which is not more than the distance to the nearest vertex.
Upvotes: 0