Folding a selection of points on a 3D cube - algorithm

I am trying to find an effective algorithm for the following 3D Cube Selection problem:
Imagine a 2D array of Points (lets make it square of size x size) and call it a side.
For ease of calculations lets declare max as size-1
Create a Cube of six sides, keeping 0,0 at the lower left hand side and max,max at top right.
Using z to track the side a single cube is located, y as up and x as right
public class Point3D {
public int x,y,z;
public Point3D(){}
public Point3D(int X, int Y, int Z) {
x = X;
y = Y;
z = Z;
}
}
Point3D[,,] CreateCube(int size)
{
Point3D[,,] Cube = new Point3D[6, size, size];
for(int z=0;z<6;z++)
{
for(int y=0;y<size;y++)
{
for(int x=0;x<size;x++)
{
Cube[z,y,x] = new Point3D(x,y,z);
}
}
}
return Cube;
}
Now to select a random single point, we can just use three random numbers such that:
Point3D point = new Point(
Random(0,size), // 0 and max
Random(0,size), // 0 and max
Random(0,6)); // 0 and 5
To select a plus we could detect if a given direction would fit inside the current side.
Otherwise we find the cube located on the side touching the center point.
Using 4 functions with something like:
private T GetUpFrom<T>(T[,,] dataSet, Point3D point) where T : class {
if(point.y < max)
return dataSet[point.z, point.y + 1, point.x];
else {
switch(point.z) {
case 0: return dataSet[1, point.x, max]; // x+
case 1: return dataSet[5, max, max - point.x];// y+
case 2: return dataSet[1, 0, point.x]; // z+
case 3: return dataSet[1, max - point.x, 0]; // x-
case 4: return dataSet[2, max, point.x]; // y-
case 5: return dataSet[1, max, max - point.x];// z-
}
}
return null;
}
Now I would like to find a way to select arbitrary shapes (like predefined random blobs) at a random point.
But would settle for adjusting it to either a Square or jagged Circle.
The actual surface area would be warped and folded onto itself on corners, which is fine and does not need compensating ( imagine putting a sticker on the corner on a cube, if the corner matches the center of the sticker one fourth of the sticker would need to be removed for it to stick and fold on the corner). Again this is the desired effect.
No duplicate selections are allowed, thus cubes that would be selected twice would need to be filtered somehow (or calculated in such a way that duplicates do not occur). Which could be a simple as using a HashSet or a List and using a helper function to check if the entry is unique (which is fine as selections will always be far below 1000 cubes max).
The delegate for this function in the class containing the Sides of the Cube looks like:
delegate T[] SelectShape(Point3D point, int size);
Currently I'm thinking of checking each side of the Cube to see which part of the selection is located on that side.
Calculating which part of the selection is on the same side of the selected Point3D, would be trivial as we don't need to translate the positions, just the boundary.
Next would be 5 translations, followed by checking the other 5 sides to see if part of the selected area is on that side.
I'm getting rusty in solving problems like this, so was wondering if anyone has a better solution for this problem.
#arghbleargh Requested a further explanation:
We will use a Cube of 6 sides and use a size of 16. Each side is 16x16 points.
Stored as a three dimensional array I used z for side, y, x such that the array would be initiated with: new Point3D[z, y, x], it would work almost identical for jagged arrays, which are serializable by default (so that would be nice too) [z][y][x] but would require seperate initialization of each subarray.
Let's select a square with the size of 5x5, centered around a selected point.
To find such a 5x5 square substract and add 2 to the axis in question: x-2 to x+2 and y-2 to y+2.
Randomly selectubg a side, the point we select is z = 0 (the x+ side of the Cube), y = 6, x = 6.
Both 6-2 and 6+2 are well within the limits of 16 x 16 array of the side and easy to select.
Shifting the selection point to x=0 and y=6 however would prove a little more challenging.
As x - 2 would require a look up of the side to the left of the side we selected.
Luckily we selected side 0 or x+, because as long as we are not on the top or bottom side and not going to the top or bottom side of the cube, all axis are x+ = right, y+ = up.
So to get the coordinates on the side to the left would only require a subtraction of max (size - 1) - x. Remember size = 16, max = 15, x = 0-2 = -2, max - x = 13.
The subsection on this side would thus be x = 13 to 15, y = 4 to 8.
Adding this to the part we could select on the original side would give the entire selection.
Shifting the selection to 0,6 would prove more complicated, as now we cannot hide behind the safety of knowing all axis align easily. Some rotation might be required. There are only 4 possible translations, so it is still manageable.
Shifting to 0,0 is where the problems really start to appear.
As now both left and down require to wrap around to other sides. Further more, as even the subdivided part would have an area fall outside.
The only salve on this wound is that we do not care about the overlapping parts of the selection.
So we can either skip them when possible or filter them from the results later.
Now that we move from a 'normal axis' side to the bottom one, we would need to rotate and match the correct coordinates so that the points wrap around the edge correctly.
As the axis of each side are folded in a cube, some axis might need to flip or rotate to select the right points.
The question remains if there are better solutions available of selecting all points on a cube which are inside an area. Perhaps I could give each side a translation matrix and test coordinates in world space?

Found a pretty good solution that requires little effort to implement.
Create a storage for a Hollow Cube with a size of n + 2, where n is the size of the cube contained in the data. This satisfies the : sides are touching but do not overlap or share certain points.
This will simplify calculations and translations by creating a lookup array that uses Cartesian coordinates.
With a single translation function to take the coordinates of a selected point, get the 'world position'.
Using that function we can store each point into the cartesian lookup array.
When selecting a point, we can again use the same function (or use stored data) and subtract (to get AA or min position) and add (to get BB or max position).
Then we can just lookup each entry between the AA.xyz and BB.xyz coordinates.
Each null entry should be skipped.
Optimize if required by using a type of array that return null if z is not 0 or size-1 and thus does not need to store null references of the 'hollow cube' in the middle.
Now that the cube can select 3D cubes, the other shapes are trivial, given a 3D point, define a 3D shape and test each part in the shape with the lookup array, if not null add it to selection.
Each point is only selected once as we only check each position once.
A little calculation overhead due to testing against the empty inside and outside of the cube, but array access is so fast that this solution is fine for my current project.

Related

Rectangle rotation challenge: count the number of (integer) points inside a rotated rectangle on the Cartesian plane

I encountered this challenge in
codesignal (The core, question 49).
Here is the problem:
A rectangle with sides equal to even integers a and b is drawn on the Cartesian plane. Its center (the intersection point of its diagonals) coincides with the point (0, 0), but the sides of the rectangle are not parallel to the axes; instead, they are forming 45 degree angles with the axes.
How many points with integer coordinates are located inside the given rectangle (including on its sides)?
Example:
I also have the solution in JS, by another user:
function solution(a, b) {
var pointsA = Math.floor(Math.sqrt(a * a / 2)),
pointsB = Math.floor(Math.sqrt(b * b / 2));
return (pointsA * pointsB + Math.floor((pointsA + pointsB) / 2)) * 2 + 1;
}
However I cannot understand it. Although the theme of the challenge is nested loop, I still want to understand the math behind this solution. Please explain it to me. Thank you.
The diagonal of a grid cell has length √2. So the number of oblique rows contained in the rectangle is determined by the integer parts of a/√2 and b/√2. The count of grid nodes is just the product of these numbers of rows, with an adjustment term that accounts for the parities of every other row.

How can you iterate linearly through a 3D grid?

Assume we have a 3D grid that spans some 3D space. This grid is made out of cubes, the cubes need not have integer length, they can have any possible floating point length.
Our goal is, given a point and a direction, to check linearly each cube in our path once and exactly once.
So if this was just a regular 3D array and the direction is say in the X direction, starting at position (1,2,0) the algorithm would be:
for(i in number of cubes)
{
grid[1+i][2][0]
}
But of course the origin and the direction are arbitrary and floating point numbers, so it's not as easy as iterating through only one dimension of a 3D array. And the fact the side lengths of the cubes are also arbitrary floats makes it slightly harder as well.
Assume that your cube side lengths are s = (sx, sy, sz), your ray direction is d = (dx, dy, dz), and your starting point is p = (px, py, pz). Then, the ray that you want to traverse is r(t) = p + t * d, where t is an arbitrary positive number.
Let's focus on a single dimension. If you are currently at the lower boundary of a cube, then the step length dt that you need to make on your ray in order to get to the upper boundary of the cube is: dt = s / d. And we can calculate this step length for each of the three dimensions, i.e. dt is also a 3D vector.
Now, the idea is as follows: Find the cell where the ray's starting point lies in and find the parameter values t where the first intersection with the grid occurs per dimension. Then, you can incrementally find the parameter values where you switch from one cube to the next for each dimension. Sort the changes by the respective t value and just iterate.
Some more details:
cell = floor(p - gridLowerBound) / s <-- the / is component-wise division
I will only cover the case where the direction is positive. There are some minor changes if you go in the negative direction but I am sure that you can do these.
Find the first intersections per dimension (nextIntersection is a 3D vector):
nextIntersection = ((cell + (1, 1, 1)) * s - p) / d
And calculate the step length:
dt = s / d
Now, just iterate:
if(nextIntersection.x < nextIntersection.y && nextIntersection.x < nextIntersection.z)
cell.x++
nextIntersection.x += dt.x
else if(nextIntersection.y < nextIntersection.z)
cell.y++
nextIntersection.y += dt.y
else
cell.z++
nextIntersection.z += dt.z
end if
if cell is outside of grid
terminate
I have omitted the case where two or three cells are changed at the same time. The above code will only change one at a time. If you need this, feel free to adapt the code accordingly.
Well if you are working with floats, you can make the equation for the line in direction specifiedd. Which is parameterized by t. Because in between any two floats there is a finite number of points, you can simply check each of these points which cube they are in easily cause you have point (x,y,z) whose components should be in, a respective interval defining a cube.
The issue gets a little bit harder if you consider intervals that are, dense.
The key here is even with floats this is a discrete problem of searching. The fact that the equation of a line between any two points is a discrete set of points means you merely need to check them all to the cube intervals. What's better is there is a symmetry (a line) allowing you to enumerate each point easily with arithmetic expression, one after another for checking.
Also perhaps consider integer case first as it is same but slightly simpler in determining the discrete points as it is a line in Z_2^8?

Determine if a point is in the union of rectangles

I have a set of axis parallel 2d rectangles defined by their top left and bottom right hand corners(all in integer coordinates). Given a point query, how can you efficiently determine if it is in one of the rectangles? I just need a yes/no answer and don't need to worry about which rectangle it is in.
I can check if (x,y) is in ((x1, y1), (x2, y2)) by seeing if x is between x1 and x2 and y is between y1 and y2. I can do this separately for each rectangle which runs in linear time in the number of rectangles. But as I have a lot of rectangles and I will do a lot of point queries I would like something faster.
The answer depends a little bit on how many rectangles you have. The brute force method checks your coordinates against each rectangular pair in turn:
found = false
for each r in rectangles:
if point.x > r.x1 && point.x < r.x2:
if point.y > r.y1 && point.y < r.y2
found = true
break
You can get more efficient by sorting the rectangles into regions, and looking at "bounding rectangles". You then do a binary search through a tree of ever-decreasing bounding rectangles. This takes a bit more work up front, but it makes the lookup O(ln(n)) rather than O(n) - for large collections of rectangles and many lookups, the performance improvement will be significant. You can see a version of this (which looks at intersection of a rectangle with a set of rectangles - but you easily adapt to "point within") in this earlier answer. More generally, look at the topic of quad trees which are exactly the kind of data structure you would need for a 2D problem like this.
A slightly less efficient (but faster) method would sort the rectangles by lower left corner (for example) - you then need to search only a subset of the rectangles.
If the coordinates are integer type, you could make a binary mask - then the lookup is a single operation (in your case this would require a 512MB lookup table). If your space is relatively sparsely populated (i.e. the probability of a "miss" is quite large) then you could consider using an undersampled bit map (e.g. using coordinates/8) - then map size drops to 8M, and if you have "no hit" you save yourself the expense of looking more closely. Of course you have to round down the left/bottom, and round up the top/right coordinates to make this work right.
Expanding a little bit with an example:
Imagine coordinates can be just 0 - 15 in x, and 0 - 7 in y. There are three rectangles (all [x1 y1 x2 y2]: [2 3 4 5], [3 4 6 7] and [7 1 10 5]. We can draw these in a matrix (I mark the bottom left hand corner with the number of the rectangle - note that 1 and 2 overlap):
...xxxx.........
...xxxx.........
..xxxxx.........
..x2xxxxxxx.....
..1xx..xxxx.....
.......xxxx.....
.......3xxx.....
................
You can turn this into an array of zeros and ones - so that "is there a rectangle at this point" is the same as "is this bit set". A single lookup will give you the answer. To save space you could downsample the array - if there is still no hit, you have your answer, but if there is a hit you would need to check "is this real" - so it saves less time, and savings depend on sparseness of your matrix (sparser = faster). Subsampled array would look like this (2x downsampling):
.oxx....
.xxooo..
.oooxo..
...ooo..
I use x to mark "if you hit this point, you are sure to be in a rectangle", and o to say "some of these are a rectangle". Many of the points are now "maybe", and less time is saved. If you did more severe downsampling you might consider having a two-bit mask: this would allow you to say "this entire block is filled with rectangles" (i.e. - no further processing needed: the x above) or "further processing needed" (like the o above). This soon starts to be more complicated than the Q-tree approach...
Bottom line: the more sorting / organizing of the rectangles you do up front, the faster you can do the lookup.
My favourite for a variety of 2D geometry queries is Sweep Line Algorithm. It's widely utilize in CAD software, which would be my wild guess for the purpose of your program.
Basically, you order all points and all polygon vertices (all 4 rectangle corners in your case) along X-axis, and advance along X-axis from one point to the next. In case of non-Manhattan geometries you would also introduce intermediate points, the segment intersections.
The data structure is a balanced tree of the points and polygon (rectangle) edge intersections with the vertical line at the current X-position, ordered in Y-direction. If the structure is properly maintained it's very easy to tell whether a point at the current X-position is contained in a rectangle or not: just examine Y-orientation of the vertically adjacent to the point edge intersections. If rectangles are allowed to overlap or have rectangle holes it's just a bit more complicated, but still very fast.
The overall complexity for N points and M rectangles is O((N+M)*log(N+M)). One can actually prove that this is asymptotically optimal.
Store the coordinate parts of your rectangles to a tree structure. For any left value make an entry that points to corresponding right values pointing to corresponding top values pointing to corresponding bottom values.
To search you have to check the x value of your point against the left values. If all left values do not match, meaning they are greater than your x value, you know the point is outside any rectangle. Otherwise you check the x value against the right values of the corresponding left value. Again if all right values do not match, you're outside. Otherwise the same with top and bottom values. Once you find a matching bottom value, you know you are inside of any rectangle and you are finished checking.
As I stated in my comment below, there are much room for optimizations, for example minimum left and top values and also maximum right and botom values, to quick check if you are outside.
The following approach is in C# and needs adaption to your preferred language:
public class RectangleUnion
{
private readonly Dictionary<int, Dictionary<int, Dictionary<int, HashSet<int>>>> coordinates =
new Dictionary<int, Dictionary<int, Dictionary<int, HashSet<int>>>>();
public void Add(Rectangle rect)
{
Dictionary<int, Dictionary<int, HashSet<int>>> verticalMap;
if (coordinates.TryGetValue(rect.Left, out verticalMap))
AddVertical(rect, verticalMap);
else
coordinates.Add(rect.Left, CreateVerticalMap(rect));
}
public bool IsInUnion(Point point)
{
foreach (var left in coordinates)
{
if (point.X < left.Key) continue;
foreach (var right in left.Value)
{
if (right.Key < point.X) continue;
foreach (var top in right.Value)
{
if (point.Y < top.Key) continue;
foreach (var bottom in top.Value)
{
if (point.Y > bottom) continue;
return true;
}
}
}
}
return false;
}
private static void AddVertical(Rectangle rect,
IDictionary<int, Dictionary<int, HashSet<int>>> verticalMap)
{
Dictionary<int, HashSet<int>> bottomMap;
if (verticalMap.TryGetValue(rect.Right, out bottomMap))
AddBottom(rect, bottomMap);
else
verticalMap.Add(rect.Right, CreateBottomMap(rect));
}
private static void AddBottom(
Rectangle rect,
IDictionary<int, HashSet<int>> bottomMap)
{
HashSet<int> bottomList;
if (bottomMap.TryGetValue(rect.Top, out bottomList))
bottomList.Add(rect.Bottom);
else
bottomMap.Add(rect.Top, new HashSet<int> { rect.Bottom });
}
private static Dictionary<int, Dictionary<int, HashSet<int>>> CreateVerticalMap(
Rectangle rect)
{
var bottomMap = CreateBottomMap(rect);
return new Dictionary<int, Dictionary<int, HashSet<int>>>
{
{ rect.Right, bottomMap }
};
}
private static Dictionary<int, HashSet<int>> CreateBottomMap(Rectangle rect)
{
var bottomList = new HashSet<int> { rect.Bottom };
return new Dictionary<int, HashSet<int>>
{
{ rect.Top, bottomList }
};
}
}
It's not beautiful, but should point you in the right direction.

Sort a set of 3-D points in clockwise/counter-clockwise order

In 3-D space I have an unordered set of, say, 6 points; something like this:
(A)*
(C)*
(E)*
(F)*
(B)*
(D)*
The points form a 3-D contour but they are unordered. For unordered I mean that they are stored in an
unorderedList = [A - B - C - D - E - F]
I just want to reorganize this list starting from an arbitrary location (let's say point A) and traversing the points clockwise or counter-clockwise. Something like this:
orderedList = [A - E - B - D - F - C]
or
orderedList = [A - C - F - D - B - E]
I'm trying to implement an algorithm as simple as possible, since the set of points in mention corresponds to a N-ring neighborhood of each vertex on a mesh of ~420000 points, and I have to do this for each point on the mesh.
Some time ago there was a similar discussion regarding points in 2-D, but for now it's not clear for me how to go from this approach to my 3-D scenario.
The notion of "clockwise" or "counterclockwise" is not well-defined without an axis and orientation! (proof: What if you looked at those points from the other side of your monitor screen, or flipped them, for example!)
You must define an axis and orientation, and specify it as an additional input. Ways to specify it include:
a line (1x=2y=3z), using the right-hand rule
a (unit) vector (A_x, A_y, A_z), using the right-hand rule; this is the preferred way to do so
In order to determine the orientation, you have to look deeper at your problem: You must define a "up" and "down" size of the mesh. Then for each set of points, you must take the centroid (or another "inside" point) and construct a unit vector pointing "up" which is normal to the surface. (One way to do this would be to find the least-squares-fit plane, then find the two perpendicular vectors through that point, picking the one in the "up" direction.)
You will need to use any of the above suggestions to determine your axis. This will allow you to reformulate your problem as follows:
Inputs:
the set of points {P_i}
an axis, which we shall call "the z-axis" and treat as a unit vector centered on the centroid (or somewhere "inside") of the points
an orientation (e.g. counterclockwise) chosen by one of the above methods
Setup:
For all points, pick two mutually-orthogonal unit vectors to the axis, which we shall call "the y-axis" and "the x-axis". (Just rotate the z-axis unit-vector 90 degrees in two directions, http://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations )
Algorithm:
For each point P, project P onto the x-axis and y-axis (using the dot product), then use http://en.wikipedia.org/wiki/Atan2
Once you have the angles, you can just sort them.
I can't attest for the efficiency of this code, but it works, and you can optimize parts of it as needed, I'm just not good at it.
Code is in C#, using system collection classes, and linq.
Vector3 is a class with floats x, y, z, and static vector math functions.
Node is a class with Vector3 variable called pos
//Sort nodes with positions in 3d space.
//Assuming the points form a convex shape.
//Assuming points are on a single plain (or close to it).
public List<Node> sortVerticies( Vector3 normal, List<Node> nodes ) {
Vector3 first = nodes[0].pos;
//Sort by distance from random point to get 2 adjacent points.
List<Node> temp = nodes.OrderBy(n => Vector3.Distance(n.pos, first ) ).ToList();
//Create a vector from the 2 adjacent points,
//this will be used to sort all points, except the first, by the angle to this vector.
//Since the shape is convex, angle will not exceed 180 degrees, resulting in a proper sort.
Vector3 refrenceVec = (temp[1].pos - first);
//Sort by angle to reference, but we are still missing the first one.
List<Node> results = temp.Skip(1).OrderBy(n => Vector3.Angle(refrenceVec,n.pos - first)).ToList();
//insert the first one, at index 0.
results.Insert(0,nodes[0]);
//Now that it is sorted, we check if we got the direction right, if we didn't we reverse the list.
//We compare the given normal and the cross product of the first 3 point.
//If the magnitude of the sum of the normal and cross product is less than Sqrt(2) then then there is more than 90 between them.
if ( (Vector3.Cross( results[1].pos-results[0].pos, results[2].pos - results[0].pos ).normalized + normal.normalized).magnitude < 1.414f ) {
results.Reverse();
}
return results;
}

Fast Collision Detection for Circle Insertion into 2D Plane

I know there are lots of posts about collision detection generally for sprites moving about a 2D plane, but my question is slightly different.
I'm inserting circles into a 2D plane. The circles have variable radii. I'm trying to optimize my method of finding a random position within the plane where I can insert a new circle without it colliding with any other circles already on the plane. Right now I'm using a very "un-optimized" approach that simply generates a random point within the plane and then checks it against all the other circles on the plane.
Are there ways to optimize this? For this particular app, the bounds of the plane can only hold 20-25 circles at a time and typically there are between 5-10 present. As you would expect, when the number of circles approaches the max that can fit, you have to test many points before finding one that works. It gets very slow.
Note: safeDistance is the radius of the circle I want to add to the plane.
Here's the code:
- (CGPoint)getSafePosition:(float)safeDistance {
// Point must be far enough from edges
// Point must be far enough from other sprites
CGPoint thePoint;
BOOL pointIsSafe = NO;
int sd = ceil(safeDistance);
while(!pointIsSafe) {
self.pointsTested++; // DEBUG
// generate a random point inside the plane boundaries to test
thePoint = CGPointMake((arc4random() % ((int)self.manager.gameView.frame.size.width - sd*2)) + sd,
(arc4random() % ((int)self.manager.gameView.frame.size.height - sd*2)) + sd);
if(self.manager.gameView.sprites.count > 0) {
for(BasicSprite *theSprite in self.manager.gameView.sprites) {
// get distance between test point and the sprite position
float distance = [BasicSprite distanceBetweenPoints:thePoint b:theSprite.position];
// check if distance is less than the sum of the min safe distances of the two entities
if(distance < (safeDistance + [theSprite minSafeDistance])) {
// point not safe
pointIsSafe = NO;
break;
}
// if we get here, the point did not collide with the last tested point
pointIsSafe = YES;
}
}
else {
pointIsSafe = YES;
}
}
return thePoint;
}
Subdivide your window into w by h blocks. You'll be maintaining a w by h array, dist. dist[x][y] contains the size of the largest circle that can be centred at (x, y). (You can use pixels as blocks, although we'll be updating the entire array with each circle placed, so you may want to choose larger blocks for improved speed, at the cost of slightly reduced packing densities.)
Initialisation
Initially, set all dist[x][y] to min(x, y, w - x, h - y). This encodes the limits given by the bounding box that is the window.
Update procedure
Every time you add a circle to the window, say one positioned at (a, b) with radius r, you need to update all elements of dist.
The update required for each position (x, y) is:
dist[x][y] = min(dist[x][y], sqrt((x - a)^2 + (y - b)^2) - r);
(Obviously, ^2 here means squaring, not XOR.) Basically, we are saying: "Set dist[x][y] to the minimum distance to the circle just placed, unless the situation is already worse than that." dist values for points inside the circle just placed will be negative, but that doesn't matter.
Finding the next location
Then, when you want to insert the next circle of radius q, just scan through dist looking for a location with dist value >= q. (If you want to randomly choose such a location, find the complete list of valid locations and then randomly choose one.)
Honestly, with only 20-25 circles, you're not going to get much of a speed boost by using a fancier algorithm or data structure (e.g. a quadtree or a kd-tree). Everything is fast for small n.
Are you absolutely sure this is the bottleneck in your application? Have you profiled? If yes, then the way you're going to speed this up is through microoptimization, not through advanced algorithms. Are you making lots of iterations through the while loop because most of the plane is unsafe?
You could split your plane in lots of little rectangles (slightly quadtree-related) and save which rectangles are hit by at least one of the circles.
When you look for a insertion-point, you'll just have to look for some "empty" ones (which doesn't need any random jumps and is possible in constant time).
The number and constellation of rectangles can be computed by the radius.
Just an outline, since this solution is fairly involved.
If you want to guarantee you always find a place to put a circle if it's possible, you can do the following. Consider each existing circle C. We will try to find a location where we can place the new circle so that it is touching C. For each circle D (other than C) that is sufficiently close to C, there will be a range of angles where placing a new circle at one of those angles around C will make it intersect with D. Some geometry will give you that range. Similarly, for each of the four boundaries that are close enough to C, there will be a range of angles where placing a new circle at one of those angles will make it intersect with the boundary. If all these intervals cover all 360 degrees around C, then you cannot place a circle adjacent to C, and you will have to try the next circle, until there are no more candidates for C. If you find a place to put the new circle, you can move it some random distance away from C so that all your new circles do not have to be adjacent to an existing circle if that is not necessary.

Resources