Position the circles in a way that they align along the circumference of a larger

I need help arranging a group of circles around another circle without any of them overlapping. I have all the radius measurements for each circle, as well as the coordinates for the target circle.

The target circle will always be large enough to contain all the smaller circles.

Refer to this diagram:

https://i.sstatic.net/9teFn.png:

interface Circle {
  radius: number;
  x: number;
  y: number;
}

const childRadii = [1, 3, 2, 5, 1, 2];

const largeCircle = { radius: 10, x: 0, y: 0 };

const arrangedCircles = positionCirclesOnCircle(largeCircle, childRadii);

function positionCirclesOnCircle(
  largeCircle: Circle,
  radii: number[]
): Circle[] {
  const arrangedCircles: Circle[] = [];
  //for each of our radii  find the correct x and y position along largeCircle
  for (let index = 0; index < radii.length; index++) {
    //find the x and y pos for this circle
    //push to arrangedCircles
  }
  return arrangedCircles;
}


I'm unsure of what equations or mathematical formulas to apply in order to determine the x and y positions for each of the child circles.

I came across a similar concept on a Math forum, but I'm struggling to convert it to TypeScript.

Answer №1

Assume that R represents the radius of the larger circle, while r[i] denotes the radii of the smaller circles for i = 0..n.

Let us position the first circle at the coordinates:

c[0] = (R, 0).

The subsequent circles will have centers at the following coordinates:

c[i] = (R * cos(f[i]), R * sin(f[i]))

Here,

f[i] = f[i-1] + 2 * arcsin((r[i] + r[i-1]) / (2 * R)) 
f[0] = 0

Employing Python and matplotlib to test this concept generates the depicted image. https://i.sstatic.net/wWXdQ.png

Regarding the fit:

  1. When the sum of two adjacent circles' radii exceeds the diameter of the larger circle, they cannot be positioned together.
  2. A value of f[i] > 2 * Pi signifies that no more non-overlapping circles can be accommodated.

Answer №2

Presented here is an innovative approach. I have deliberately steered clear of employing the "computationally expensive" functions arcsin, sin, and cos. Instead, I have substituted them with the use of the costly function sqrt exclusively. Feel free to modify the code below to suit your requirements.

import math
import numpy as np

def initial_child_cetner(large_circle, argument):
    cos_arg = math.cos(math.pi * argument / 180)
    sin_arg = math.sin(math.pi * argument / 180)
    rotation = np.array([[ cos_arg, -sin_arg],
                         [ sin_arg,  cos_arg]])
    initial_center = large_circle['radius'] * np.array([1., 0.])
    return rotation.dot(initial_center)

def cos_sin_angle(large_radius, chord):
    cos_angle = 1 - ( chord )**2 / (2*large_radius**2)  
    sin_angle = math.sqrt(1 - cos_angle**2)
    return cos_angle, sin_angle

def next_child_center(large_circle_center, current_child_center, large_radius, chord):
    cos_a, sin_a = cos_sin_angle(large_radius, chord)
    rotation = np.array([[ cos_a,  sin_a],
                         [-sin_a,  cos_a]])
    child_center_next =  large_circle_center + rotation.dot(current_child_center - large_circle_center)
    return child_center_next

def chain_of_child_circles(large_circle, child_radii, argument):
    n = len(child_radii)
    child_centers = np.empty((n, 2), dtype = float)
    child_centers[0, :] = initial_child_cetner(large_circle, argument)
    large_center = np.array([large_circle['x'], large_circle['y']])
    for i in range(n-1):
        chord = child_radii[i] + child_radii[i+1]
        child_centers[i+1, :] = next_child_center(large_center, 
                                                  child_centers[i, :], 
                                                  large_circle['radius'], 
                                                  chord) 
    return child_centers
    

childRadii = [1, 3, 2, 5, 1, 2]
largeCircle = { 'radius': 10, 'x': 0, 'y': 0 }

childCircleCenters = chain_of_child_circles(largeCircle, childRadii, -90)

fig, axs = plt.subplots()
axs.plot(childCircleCenters[:,0], childCircleCenters[:,1], 'bo')

axs.plot(childCircleCenters[:,0], childCircleCenters[:,1])


axs.set_aspect('equal')
plt.grid()
plt.show()

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

There was an issue converting the value {null} to the data type 'System.Int32', resulting in a 400 error

Attempting to make a POST request with some missing data is causing errors in my angular form. Here is the payload I am using: DeviceDetail{ deviceId:'332', sideId: null, deviceName:'test' } Unfortunately, I encountered a 400 bad re ...

Unable to display animation without first launching it on Rive web

I attempted to incorporate a Rive animation into my Angular web application <canvas riv="checkmark_icon" width="500" height="500"> <riv-animation name="idle" [play]="animate" (load)=&qu ...

How can you ensure a code snippet in JavaScript runs only a single time?

I have a scenario where I need to dynamically save my .env content from the AWS secrets manager, but I only want to do this once when the server starts. What would be the best approach for this situation? My project is utilizing TypeScript: getSecrets(&qu ...

core.js:15723 ERROR TypeError: Unable to access the 'OBJECT' property because it is undefined

Whenever I attempt to run this function, I encounter an issue. My goal is to retrieve the latitude and longitude of an address from Google's API. This error message pops up: core.js:15723 ERROR TypeError: Cannot read property 'geometry' of ...

Issue with hydration when logging in with Next-Auth in NextJS 13.4

Step-by-step Instructions: 'node -v' -> v18.16.1 'npx -v' -> 9.8.0 To start, I created a new Next.js app by running npx create-next-app@latest in the terminal within my app folder. Here is a link to the package.json file. Nex ...

Utilize FastClick for improved speed and response on

I have been trying to use FastClick in my TypeScript project with FastClick.d.ts. My TSC configuration uses "module: commonjs" and I am bundling everything with Webpack. However, I am having trouble referencing FastClick properly. When I try to import Fas ...

"Firebase function fails to return Typescript class variable, resulting in 'undefined'

Being someone with a background in python/golang, I am now delving into ionic2. There seems to be an issue that I can't quite figure out due to my current level of knowledge in this stack. Perhaps I just need a way to reference the outer scope of this ...

Building secure and responsive routes using next.js middleware

After setting up my routes.ts file to store protected routes, I encountered an issue with dynamic URLs not being properly secured. Even though regular routes like '/profile' were restricted for unauthenticated users, the dynamic routes remained a ...

Angular 2 file upload encountering CORS issue leading to 401 unauthorized error

Encountered a "401 Unauthorized" error in Chrome and Firefox while attempting to upload files using angular 2 CLI to an apache2-server with a PHP backend. Despite trying three different node modules, the issue persists from the OPTIONS-preflight stage, ...

Having trouble updating properties of child components in Angular

I have a data filtering functionality where I enter values in a filter popup and successfully retrieve results. I then store this data in local storage to retain it when navigating back from another page. However, upon returning to the filter component, I ...

Combining numerous interfaces into a unified interface in Typescript

I'm struggling to comprehend interfaces in Typescript, as I am facing difficulty in getting them to function according to my requirements. interface RequestData { [key: string]: number | string | File; } function makeRequest(data: RequestData) { ...

Calculating binomial coefficients using Python

Recently, I've been trying to find a way to address an issue with the following code snippet: #defining a function that computes the factorial of an integer def fac(b): if b==1: return 1 else: return b * fac(b-1) #takes two integers and ...

Experimenting with PIXI.js and Jest within a React Single Page Application

I am currently working on a react application that utilizes PIXI.js and @inlet/react-pixi for animations. During testing with Jest, I encountered the following errors: Error: Uncaught [TypeError: Cannot read properties of null (reading 'stage' ...

callbacks in amazon-cognito-identity-js

When working with amazon-cognito-identity-js, I encountered an issue with the callback function. This is what it currently looks like: cognitoUser?.getUserAttributes((err, results) => { if (err) { console.log(err.message || JSON.stringify(err)); ...

Embracing the "export ... from" feature in the TypeScript compiler

Can the tsc compiler handle this particular export statement? export {PromiseWrapper, Promise, PromiseCompleter} from 'angular2/src/facade/promise'; Your assistance is greatly appreciated! ...

What is the process of 'initializing' an object in TypeScript?

Is it possible that retrieving a json from a mongodb database and casting it does not trigger the typescript constructor? What could be causing this issue? I have a Team class export class Team { transformations: { [transformationId: string]: Transfor ...

Can you give me some insights about what an Action Creator is?

function createRefDoneAction(widgetsArray: widget[]): WidgetAction { return { type: actionTypes.REFRESH_WIDGET_DONE, widgets: widgetsArray }; } Could you please clarify the necessity of having two sets of parameters (e.g. 'wid ...

Extract keys from a list of interface keys to create a sub-list based on the type of value

Issue Can the keys that map to a specified value type be extracted from a TypeScript interface treated as a map? For example, consider the WindowEventMap in lib.dom.d.ts... interface WindowEventMap extends GlobalEventHandlersEventMap, WindowEventHan ...

The feature of Nuxt 3's tsconfig path seems to be malfunctioning when accessed from the

Take a look at my file structure below -shared --foo.ts -web-ui (nuxt project) --pages --index.vue --index.ts --tsconfig.json This is the tsconfig for my nuxt setup. { // https://v3.nuxtjs.org/concepts/typescript "exte ...

Google's reCAPTCHA issue: systemjs not found

Currently, I am attempting to integrate Google's reCAPTCHA into an Angular application by following a helpful tutorial found here. However, I have encountered a problem as the systemjs.config.js file seems to be missing from my Angular CLI project. An ...