Create blob shape in list/array - algorithm

Is there any fast way of creating filled organic looking blob shapes in a list/array? (around 30x30 would be enough, nothing bigger)
I have referred to this post C++ create random shaped "blob" objects but the problem is that this creates an outline and is not fast as it has to loop through every integer angle.
Any ideas would be appreciated. I'm coding in python but just the plain algorithm would work :)
Thanks in advance!

Eventually I settled on using metaballs. Here's the code:
#dataclass
class Metaball:
center: tuple[int, int]
radius: float
def blob():
balls = [Metaball((randint(4, 11), randint(4, 11)), randint(2, 4)) for _ in range(randint(3, 4))]
result = []
for y in range(16):
result.append([])
for x in range(16):
if sum([(ball.radius / distance / 2) if (distance := dist(ball.center, (x, y))) else 10 for ball in balls]) > 1.2:
result[y].append("#")
else:
result[y].append(".")
return result
for row in blob():
for ch in row:
print(ch, end=" ")
print()

Related

Finding random x,y coordinates in a figure where you know the boundary

The goal is to find coordinates in a figure with an unknown shape. What IS known is a list of coordinates of the boundary of that figure, for example:
boundary = [(0,0),(1,0),(2,0),(3,0),(3,1),(3,2),(3,3),(2,3),(2,2),(1,2),(1,3),(0,3),(0,2),(0,1]
which would look something like this:
Square with a gab
This is a very basic example and i'd like to do it with very larg lists of very different kinds of figures.
The question is how to get a random coordinate that lies within the figure WITHOUT hardcoding the anything about the shape of the figure, because this will be unknown at the beginning? Is there a way to know for certain or is making an estimate the best option? How would I implement an estimate like that?
Here is tentative answer. You sample numbers in two steps.
Before, do preparation work - split your figure into simple elementary objects. In your case you split it into rectangles, often people triangulate and split it into triangles.
So you have number N of simple objects, each with area of Ai and total area A = Sum(Ai).
First sampling step - select which rectangle you pick point from.
In some pseudocode
r = randomU01(); // random value in [0...1) range
for(i in N) {
r = r - A_i/A;
if (r <= 0) {
k = i;
break;
}
}
So you picked up one rectangle with index k, and then just sample point uniformly in that rectangle
x = A_k.dim.x * randomU01();
y = A_k.dim.y * randomU01();
return (x + A_k.lower_left_corner.x, y + A_k.lower_left_corner.y);
And that is it. Very similar technique for triangulated figure.
Rectangle selection could be optimized by doing binary search or even more complicated alias method
UPDATE
If your boundary is generic, then the only good way to go is to triangulate your polygon using any good library out there (f.e. Triangle), then select one of the triangles based on area (step 1), then sample uniformly point in the triangle using two random U01 numbers r1 and r2,
P = (1 - sqrt(r1)) * A + (sqrt(r1)*(1 - r2)) * B + (r2*sqrt(r1)) * C
i.e., in pseudocode
r1 = randomU01();
s1 = sqrt(r1);
r2 = randomU01();
x = (1.0-s1)*A.x + s1*(1.0-r2)*B.x + r2*s1*C.x;
y = (1.0-s1)*A.y + s1*(1.0-r2)*B.y + r2*s1*C.y;
return (x,y);

Stata Mata Programming Conformability Error

Hi I need help in Stata's Mata programming language for the following Minimum Working Example.
I am trying to insert sub-matrices of dimension (1x200) (generated by a random normal draw) inside a pointer matrix of dimension 600x1 (V matrix).
mata:
T=600 //number of markets
K_S=1 //number of variables with stochastic coefficients
R=200 //number of random draws
st_matrix("T", T)
//pointers to the market specific random draws:
V=J(T,1,NULL) // T by 1 0 matrix
for(t=1;t<=T;t++){
V[t]=(rnormal(K_S,R,0,1)) //dimension K_S x R
}
end
The problem is I am getting a "rnormal(): 3200 conformability error"
Could you suggest what I am doing wrong.
Thanks
You are trying to assign a K_S x R matrix to a single cell in a column vector. A pointer has to be assigned, well, a pointer:
mata:
T = 600 // number of markets
K_S = 1 // number of variables with stochastic coefficients
R = 200 // number of random draws
st_matrix("T", T)
// pointers to the market specific random draws:
V = J(T, 1, NULL) // T by 1 0 matrix
for(t=1; t<=T; t++){
V[t]= &(rnormal(K_S, R, 0, 1)) //dimension K_S x R
}
end
In mata the & notation means pointer.

Calculating light intensity in a closed world

I am building a simulation in which there is world made of many squares. There are also objects designated as "suns", which illuminate the squares and update their "received intensity" each step.
For example:
In this image, the distance between the centres of squares is 32 units, and the received intensity (or R.I.) of each square is calculated with this formula:
R.I. = 100 / (distance between light source and square)^2
Written in a generic(and terrible) programming language, a function that calculates R.I. may look like this:
(define (calc-RI sq-x sq-y sn-x sn-y)
(return (/ 100
(+ (square (- sq-x sn-x))
(square (- sq-y sn-y))
)
)
)
)
...and, to accommodate multiple suns, the R.I. for each sun will be calculated separately and added together for each square. This is all well and good, until I felt the need to introduce a warping mechanic to this simulation: objects that move "outside" the edge of the world will "re-enter" the world from the other side, like in the game Asteroid.
This not only need to apply to other objects in the simulation, but also light.
So, what should the new function be for calculating the R.I. of each square? (Given that the function takes in the x and y coordinate of one square and one sun, and the width and height of the world, what would be the return of the given square's R.I. under the sun's influence?)
You can solve this by imagining that the grid is surrounded by copies of the original grid, one layer for each wrap. For each square in the original grid, calculate the light intensity that falls on each corresponding square, and sum the results.
In the above diagram, the black grid represents the world, and the blue grid represents the copies of the world grid. To find the light intensity for one wrap at the green square, add the simple intensities calculated at each of the blue squares to the simple intensity calculated for the green square. To calculate another wrap, add another layer of copies.
Here is some Lua code that implements this. Stars are represented in tables of the form:
stars = { { x=x1, y=y1 }, { x=x2, y=y2 },... }
In this implementation, a square containing a star is given an intensity of -1. This could be changed so that a square containing a star accumulates intensity like any other square. To use the functions, define a stars table, and call light_universe() with the grid_size (grids are taken to be square here), square_size, stars table, and number of wraps desired. Set wraps to zero, nil, or just omit this parameter, to obtain simple intensity calculations with no wrapping. The function light_universe() returns a table containing intensities for each square of the world grid. You can view the results by calling show_intensities() with the table returned from light_universe(), and the grid_size of the table. Note that the upper-left corner of the world grid has coordinate (1, 1).
The calculate_intensity() function first calculates the field_size of the field of grid copies. This is the size of the blue grid in the diagram, and is an odd multiple of grid_size, e.g., for 1 wrap the field_size is 3. Next, the world coordinates of the current star are transformed to the field coordinates star_x and star_y (the coordinates with respect to the blue grid in the diagram). Then the locations within the field corresponding to x and y are iterated over. These are the locations of the blue squares of the diagram. The first location is in the upper-left grid of the field, and has field coordinates that are equal to the world coordinates of the square of interest. For each location, the intensity is calculated and added to the running total, which is returned when the iteration is complete.
-- Intensity calculation with wraps
-- wraps = nil or wraps = 0 for simple calculation
function calculate_intensity(star, x, y, grid_size, square_size, wraps)
wraps = wraps or 0
local field_size = grid_size * (2 * wraps + 1) -- odd number of grids
local star_x = star.x + wraps * grid_size -- cdts of star in field
local star_y = star.y + wraps * grid_size
local intensity = 0
-- x and y are cdts wrt world grid, but also wrt first grid in field
for field_y = y, field_size, grid_size do
for field_x = x, field_size, grid_size do
local dx = square_size * (star_x - field_x)
local dy = square_size * (star_y - field_y)
local dist_sq = dx * dx + dy * dy
intensity = intensity + 100 / dist_sq
end
end
return intensity
end
function light_universe(grid_size, square_size, stars, wraps)
wraps = wraps or 0
local grid_intensities = {}
for i, star in ipairs(stars) do
for y = 1, grid_size do
grid_intensities[y] = grid_intensities[y] or {}
for x = 1, grid_size do
if x == star.x and y == star.y then
grid_intensities[y][x] = -1
elseif grid_intensities[y][x] ~= -1 then
grid_intensities[y][x] = (grid_intensities[y][x] or 0) +
calculate_intensity(star, x, y, grid_size, square_size, wraps)
end
end
end
end
return grid_intensities
end
function show_intensities(grid, grid_size)
for y = 1, grid_size do
for x = 1, grid_size do
local intensity = grid[y][x]
local fmt
if intensity ~= -1 then
fmt = (string.format("%10.5f", intensity))
else
fmt = string.format("%-10s", " Star")
end
io.write(fmt)
end
print()
end
end
Here is an interaction showing intensity with no wraps, corresponding to the example from your question.
> stars = { { x=1, y=1 } }
> light_grid = light_universe(3, 32, stars, 0)
> show_intensities(light_grid, 3)
Star 0.09766 0.02441
0.09766 0.04883 0.01953
0.02441 0.01953 0.01221
Here is the same situation with one wrap:
> light_grid = light_universe(3, 32, stars, 1)
> show_intensities(light_grid, 3)
Star 0.17054 0.16628
0.17054 0.12440 0.12023
0.16628 0.12023 0.11630
And with two wraps:
> light_grid = light_universe(3, 32, stars, 2)
> show_intensities(light_grid, 3)
Star 0.20497 0.20347
0.20497 0.15960 0.15811
0.20347 0.15811 0.15664
Here is a 7X7 grid with two stars, and one wrap:
> stars = { { x=1, y=1 }, { x=7, y=4 } }
> light_grid = light_universe(7, 32, stars, 1)
> show_intensities(light_grid, 7)
Star 0.13085 0.05729 0.04587 0.04728 0.06073 0.13366
0.14064 0.08582 0.05424 0.04640 0.04971 0.06411 0.09676
0.09676 0.06411 0.04971 0.04640 0.05424 0.08582 0.14064
0.13366 0.06073 0.04728 0.04587 0.05729 0.13085 Star
0.08469 0.05562 0.04574 0.04433 0.05218 0.08190 0.13222
0.06715 0.05619 0.04631 0.04302 0.04635 0.05627 0.06728
0.13073 0.08043 0.05075 0.04294 0.04439 0.05432 0.08347

Calculate x/y position on an image from latitude/longitude

I already did some research but none answer did fit to my problem:
I have an image (jpeg) that is represented by a latlonbox:
https://developers.google.com/kml/documentation/kmlreference?hl=de#latlonbox
So I have North, South, East and West information that form the image, right? Is the N/W the top left point and the S/E the bottom-rightt point?
The image has a size of 4000x2000. In my mvc application i reduced size to 1500x750 pixel.
Now I am trying to achieve to calculate the x/y position on this image by getting a latitude/longitude input. How can I achieve this?
I found this link:
http://code.google.com/p/geographical-dot-net/source/browse/trunk/GeographicalDotNet/GeographicalDotNet/Projection/GoogleMapsAPIProjection.cs
But I don't have any zoom information and I also don't understand how to start, because I have a jpeg and the kml information with latlonbox.
Thanks for any help
thanks for your reply! Yes, in my case the kilometers are very small, maybe only some hundred meters. I tried to solve it with two linear equations, would that be appropriate?
Using the first link, with the example of latlonbox I did the following:
WN: (-90,8714285289695/48,25475939255556) <=> X: (0/0)
ES: (-90,86591508839973/48,25207367852141) <=> Y: (1500/750)
E: -90,86591508839973
S: 48,25207367852141
W: -90,8714285289695
N: 48,25475939255556
Diff EW: 0,00551344056977
Diff_SN: 0,00268571403415
I define two functions:
f_X1: m*x_lon + b where f_X1 is the X coordinate and x_lon the longitude value
f_X2: m*x_lat + b where f_X2 is the Y coordinate and x_lat the latitude value
Function to get X-coordinate:
m = (1500/Diff_EW) = 272062 (rounded)
Insert a known X/Longitude-Pair in function f_X1:
1500 = E * 272062 + b
b = 1500 - (E * 272062)
b = 24722662 ( rounded)
=> f_X1: 272062x + 24722662
Same procedure to get f_X2:
m = (750/-Diff_SN) = - 279255(rounded)
Insert a known Y/Latitude-Pair in functon f_X2:
750 = S * (-279255) + b
b = 750 - (S*(-279255))
b = 13475382
f_X2: -279255x + 13475382
If I insert the values for East and West (E and W) I will get the X-coordinates (approximately 1500 and 0; deviates due to rounding)
If I insert the values for South and North (S and N) I will get the Y-coordinates (approximately 750 and 0; deviates due to rounding)
Is this a correct way to do it in this case? I assumed the function to be linear, I don't know if that's correct.
Thanks for any help.

Algorithm 2D Referential traduction

I am trying to build a function grapher,
The user enters xmin, xmax, ymin, ymax, function.
I got the x, y for all points.
Now i want to translate this initial referential to a Canvas starting at 0,0 up to
250,250.
Is there a short way or should i just check
if x < 0
new x = (x - xmin) * (250 / (xmax - xmin)) ?
etc ..
Also this basic approach does not optimise sampling.
For example if my function f(x) = 5 i dont need to sample the xrange in 500 points,
i only need two points. I could do some heuristic checks.
But for a function like sin(2/x) i need more sampling around x (-1,1) how would you aproach such a thing ?
Thanks
Instead of iterating over x in the original coordinates, iterate over the canvas and then transform back to the original coordinates:
for (int xcanvas = 0; xcanvas <= 250; i++) {
double x = ((xmax - xmin) * xcanvas / 250.0) + xmin;
double y = f(x);
int ycanvas = 250 * (y - ymin) / (ymax - ymin) + .5;
// Plot (xcanvas, ycanvas)
}
This gives you exactly one function evaluation for each column of the canvas.
You can estimate the derivative (if you have one).
You can use bidirectional (dichotomic) approach: estimate the difference and split the segment if necessary.
I think I would start by reasoning about this in terms of transformations from canvas to maths contexts.
(canvas_x, canvas_y) -> (maths_x, maths_y)
(maths_x, maths_y) -> (canvas_x, canvas_y)
maths_x -> maths_y
You iterate over the points that a displayable, looping over canvas_x.
This would translate to some simple functions:
maths_x = maths_x_from_canvas_x(canvas_x, min_maths_x, max_maths_x)
maths_y = maths_y_from_maths_x(maths_x) # this is the function to be plotted.
canvas_y = canvas_y_from_maths_y(maths_y, min_maths_y, max_maths_y)
if (canvas_y not out of bounds) plot(canvas_x, canvas_y)
Once you get here, it's relatively simple to write these simple functions into code.
Optimize from here.
I think that for this approach, you won't need to know too much about sample frequencies, because you sample at a rate appropriate for the display. It wouldn't be optimal - your example of y = 5 is a good example, but you'd be guaranteed not to sample more than you can display.

Resources