C
C#•6mo ago
~Eden

Splitting a number into equal distances (COMPLEX)

Okay the picture looks a little complicated so im going to try and explain it I want to use HSL HSL hue has a max value of 360 I want to divide this 360 to segments In the code I chose 3 segments So the first three value would be 0, 120, 240 (360 / 3), (360 / 3 * 1), (360 / 3 * 2) Now I want to choose a 3 more colors the best next set of unique colors are 60, 180, 300 (the middle of segment a) (middle seg b) (middle seg c) now I want the next 3 unique colors 36 156 276 (the other side) The yellow values are the next unique color The purple is just a location value lets say you want to find the Hue value for Yellow2 (first value for the second segment) The purple value for it is 9 so its value is 9x12 (12 being 360/30 [where 30 is the amount of desired segments])
int segments = 30;
int degrees = 360;
int deg_per_line = degrees / segments;

var segmentation = 3;
double segmentDegrees = degrees / segmentation;

List<int> segmentList = new();

Console.WriteLine($"\n\n\n");

for (int i = 0; i < segmentation; i++)
{
var val = i / (double)segmentation;
segmentList.Add((int)Math.Ceiling(val * degrees));
}

// Loop until x is zero
for (int i = segments; i > 0; i -= segmentation)
{
for (int e = 0; e < segmentation; e++)
Console.Write(segmentList[e] + " ");

// Calculate the remaining lines and the next slice
int remaining_lines = i - segmentation;
int next_slice = (int)Math.Ceiling((double)remaining_lines / segmentation / 2.0);

if (remaining_lines % 2 == 0)
next_slice -= 1;
//The following code is not correct maybe, its kind of a hack I got by trying random things
else if (next_slice % 2 == 0)
next_slice = next_slice * 2 - 1;

// Accumulate the degrees for each slice
for (int j = 0; j < segmentation; j++)
{
segmentList[j] = (int)(deg_per_line * next_slice + j * segmentDegrees);
}

Console.WriteLine();

if (remaining_lines <= 0)
return;
}
int segments = 30;
int degrees = 360;
int deg_per_line = degrees / segments;

var segmentation = 3;
double segmentDegrees = degrees / segmentation;

List<int> segmentList = new();

Console.WriteLine($"\n\n\n");

for (int i = 0; i < segmentation; i++)
{
var val = i / (double)segmentation;
segmentList.Add((int)Math.Ceiling(val * degrees));
}

// Loop until x is zero
for (int i = segments; i > 0; i -= segmentation)
{
for (int e = 0; e < segmentation; e++)
Console.Write(segmentList[e] + " ");

// Calculate the remaining lines and the next slice
int remaining_lines = i - segmentation;
int next_slice = (int)Math.Ceiling((double)remaining_lines / segmentation / 2.0);

if (remaining_lines % 2 == 0)
next_slice -= 1;
//The following code is not correct maybe, its kind of a hack I got by trying random things
else if (next_slice % 2 == 0)
next_slice = next_slice * 2 - 1;

// Accumulate the degrees for each slice
for (int j = 0; j < segmentation; j++)
{
segmentList[j] = (int)(deg_per_line * next_slice + j * segmentDegrees);
}

Console.WriteLine();

if (remaining_lines <= 0)
return;
}
No description
22 Replies
~Eden
~Eden•6mo ago
The code above prints
0 120 240
60 180 300
36 156 276
84 204 324
24 144 264
36 156 276
12 132 252
36 156 276
0 120 240
12 132 252
0 120 240
60 180 300
36 156 276
84 204 324
24 144 264
36 156 276
12 132 252
36 156 276
0 120 240
12 132 252
As you can see, the place where the value goes wrong is the second printed "36 156 276" which is i=5 Can anyone help me diagnose my code and make it work without my hack above? I am open to different approaches for this as long as the colors are as unique as they can be 🙂 this started as me just wanting to find the first 30 unique values but ended as a challenge I wanted to complete. It was so difficult to me that I decided to extend that challenge here 😛
~Eden
~Eden•6mo ago
sorry for the bad pictures it looked fine when I did it on my pc 😮
No description
Keswiik
Keswiik•6mo ago
What's the purpose of doing this? You could achieve a similar result by dividing 360 / segments and then segmentSize * i. Your code also isn't properly formatted.
boiled goose
boiled goose•6mo ago
he tried
```csharp
i don't know how it's not formatted, is it automatically escaped in some way?
~Eden
~Eden•6mo ago
alright working on it now 🙂
~Eden
~Eden•6mo ago
No description
~Eden
~Eden•6mo ago
im adding numbrs now
~Eden
~Eden•6mo ago
No description
~Eden
~Eden•6mo ago
if (remaining_lines <= 0)
return;
if (remaining_lines <= 0)
return;
^ Testing if formatting works for me, it didnt yesterday for some reason how would you order the different segments though? I want to grab the next unique color thats my problem if I seperate the first segment 0 -> 120 where 0 has a point and 120 has a point The next most unique color is at 60 and in your output it say its 15 does that make sense? same, i am breaking my head over the ordering lol i feel like it has to do with the moudulus of the first value based on the row amount but i still havent fully wrapped my head around it
~Eden
~Eden•6mo ago
No description
~Eden
~Eden•6mo ago
it only works on this 12 list though i would sort the 4 groups based on the modulus take the first 0 then the first 1 then the first 2 then the first 3 and repeat for the remaining but I actually need the inverse of mod because im using the sorted list to get the values im not sure if that even works my brain is having a difficult time understanding LOL @my profile explains my gameplay in case the above somehow helps you? also changed your code a bit
var list = GetDegrees().OrderBy(t => t.Item2);
int index = 0;
foreach (var degree in list)
{
if (index != degree.Item2)
Console.WriteLine();

Console.Write(degree.Item1 + " ");
index = degree.Item2;
}


static List<(double, int)> GetDegrees(int segments = 3, int pointCount = 30)
{
List<(double, int)> list = new();

pointCount /= segments;
double segment = 360.0 / segments;
double d = segment / pointCount;

for (int i = 0; i < pointCount; ++i)
{
double inc = i * d;
for (int j = 0; j < segments; j++)
list.Add((Math.Floor(segment * j + inc), i));
}

return list;
}
var list = GetDegrees().OrderBy(t => t.Item2);
int index = 0;
foreach (var degree in list)
{
if (index != degree.Item2)
Console.WriteLine();

Console.Write(degree.Item1 + " ");
index = degree.Item2;
}


static List<(double, int)> GetDegrees(int segments = 3, int pointCount = 30)
{
List<(double, int)> list = new();

pointCount /= segments;
double segment = 360.0 / segments;
double d = segment / pointCount;

for (int i = 0; i < pointCount; ++i)
{
double inc = i * d;
for (int j = 0; j < segments; j++)
list.Add((Math.Floor(segment * j + inc), i));
}

return list;
}
now the segment count and point count are dynamic oh you figured out the order? that is the part im stuck on 🙂 can I see it? alright thank you for your time 🙂 any luck? 🙂 A This works really great! I have trouble modifiying it though I want to specify the amount of points I want to return
static double[] GetColors(int n = 3, int pointCount = 30)
{
int N = pointCount / n;

... your code here

double d = (360.0 / n) / N;
static double[] GetColors(int n = 3, int pointCount = 30)
{
int N = pointCount / n;

... your code here

double d = (360.0 / n) / N;
See my above example (linking it here) for how I changed the code so that the segment and point count are dynamic I might want only 20 points in which case your method returns extra colors which doesnt give the most unique colors for 20 points the part I think its messing up on is the Math.Pow but im having trouble understanding what its doing so I am not sure n should be the amount of c's
Console.WriteLine($"{c},{c + 120},{c + 240}");
Console.WriteLine($"{c},{c + 120},{c + 240}");
it would be better described as segments instead of n when I set n=2 in your code shouldnt I expect
0,120,240
60,180,300
0,120,240
60,180,300
? instead I get
0,120,240
60,180,300
30,150,270
90,210,330
0,120,240
60,180,300
30,150,270
90,210,330
same with n=1 i expect the result to be
0,120,240
0,120,240
instead of
0,120,240
60,180,300
0,120,240
60,180,300
not quite- when n=5 i expect 15 numbers 5 * 3c's meeaning 5 rows instead I get
0,120,240
60,180,300
30,150,270
90,210,330
15,135,255
75,195,315
45,165,285
105,225,345
7.5,127.5,247.5
67.5,187.5,307.5
22.5,142.5,262.5
82.5,202.5,322.5
37.5,157.5,277.5
97.5,217.5,337.5
52.5,172.5,292.5
112.5,232.5,352.5
0,120,240
60,180,300
30,150,270
90,210,330
15,135,255
75,195,315
45,165,285
105,225,345
7.5,127.5,247.5
67.5,187.5,307.5
22.5,142.5,262.5
82.5,202.5,322.5
37.5,157.5,277.5
97.5,217.5,337.5
52.5,172.5,292.5
112.5,232.5,352.5
i should be getting
0,120,240
60,180,300
30,150,270
90,210,330
15,135,255
0,120,240
60,180,300
30,150,270
90,210,330
15,135,255
does that make sense? what does your n mean? i might be misunderstanding how to use your n
i like chatgpt
i like chatgpt•6mo ago
In my code, one component consists of 2^n segments. I am focusing on the left component only. - if n=0 there is only 1 segment: 0 - if n=1 there are 2 segments: 0 and 60 - if n=2 there are 4 segments: 0, 30, 60, 90 - if n=3 there are 8 segments: 0 + 120*i/8 where 0<=i<8. - etc
~Eden
~Eden•6mo ago
this still fails at n=5 i should be seeing 5 rows
i like chatgpt
i like chatgpt•6mo ago
foreach (var c in YourGetColors(5))
{
Console.WriteLine($"{c},{c + 120},{c + 240}");
}

static double[] YourGetColors(int n = 2)
{
int mine = (int)Math.Ceiling(Math.Log2(n));
return MyGetColors(mine).Take(n).ToArray();
}

static double[] MyGetColors(int n = 2)
{
if (n < 0) throw new Exception("n must not be negative.");

int N = (int)Math.Pow(2, n);
double[] array = new double[N];
int i = 0;

array[i++] = 0;
if (n == 0) return array;

array[i] = 60;
if (n == 1) return array;

double d = 120.0 / N;

int rightDelta = (int)Math.Pow(2, n - 1);
array[i++] = d * rightDelta;

for (int s = 0; s <= n - 2; ++s)
{
int multiplier = (int)Math.Pow(2, n - 2 - s);
for (int t = 1; t <= (int)Math.Pow(2, s); ++t)
{
int left = (2 * t - 1) * multiplier;
int right = left + rightDelta;
array[i++] = d * left;
array[i++] = d * right;
}
}

return array;
}
foreach (var c in YourGetColors(5))
{
Console.WriteLine($"{c},{c + 120},{c + 240}");
}

static double[] YourGetColors(int n = 2)
{
int mine = (int)Math.Ceiling(Math.Log2(n));
return MyGetColors(mine).Take(n).ToArray();
}

static double[] MyGetColors(int n = 2)
{
if (n < 0) throw new Exception("n must not be negative.");

int N = (int)Math.Pow(2, n);
double[] array = new double[N];
int i = 0;

array[i++] = 0;
if (n == 0) return array;

array[i] = 60;
if (n == 1) return array;

double d = 120.0 / N;

int rightDelta = (int)Math.Pow(2, n - 1);
array[i++] = d * rightDelta;

for (int s = 0; s <= n - 2; ++s)
{
int multiplier = (int)Math.Pow(2, n - 2 - s);
for (int t = 1; t <= (int)Math.Pow(2, s); ++t)
{
int left = (2 * t - 1) * multiplier;
int right = left + rightDelta;
array[i++] = d * left;
array[i++] = d * right;
}
}

return array;
}
I made typos in the previous code, I wanted to type Ceiling but I typed Floor.
~Eden
~Eden•6mo ago
This is getting really close! I think theres a calculation mistake though If I put n=10 I expect 30 numbers 360/30 = 12 The numbers should start at 0 and all numbers should be a multiple of 12 but im seeing numbers like 67.5 This is close enough for me though, i greatly appriciate the help youve given me 🙂 At this point, having these numbers close enough to the real values is perfectly fine. Just wanted to make that clear
i like chatgpt
i like chatgpt•6mo ago
Just focus on the left component, so when your n=10 then each segment must be 120/10=12 unit apart. But with this value, you no longer get evenly bisected segments. Your scenario (n): |---------------------------| |------------|--------------| |-------|----------|---------| My scenario (2^n): |---------------------------| |------------|--------------| |-----|------|-------|-------|
~Eden
~Eden•6mo ago
i think its better to focus on the point count(amount of numbers) instead of categorizing it by segments my original code has it by segments which mislead you possibly I apologize!
i like chatgpt
i like chatgpt•6mo ago
But it does not make sense to divide with your scenario. I will show the illustration.
i like chatgpt
i like chatgpt•6mo ago
How do you divide evenly?
No description
~Eden
~Eden•6mo ago
well in this case I would divide it by doing 0 24 48 72 96 120 1 4 2 5 3 6
i like chatgpt
i like chatgpt•6mo ago
It is not symmetrical. In my scenario the number of dots always in the form of 1 + 2^n
~Eden
~Eden•6mo ago
its not symmetrical, but I dont want it to be i want the most unique colors for all the points
int number = 10;
// Calculate the square root of the list count
var sqrt = (int)Math.Floor(Math.Sqrt(number));

// Project each pair into a new pair with the second item as the sorting key
List<int> sortedList = Enumerable.Range(1, number)
.Select((x, index) =>
{
double newIndex = ((index % sqrt) * sqrt) + ((double)index / sqrt);
return (x, newIndex);
})
// Sort the list by the second item of each pair
.OrderBy(pair => pair.Item2)
// Extract only the first item from each pair
.Select(pair => pair.Item1)
// Convert to a list
.ToList();
int number = 10;
// Calculate the square root of the list count
var sqrt = (int)Math.Floor(Math.Sqrt(number));

// Project each pair into a new pair with the second item as the sorting key
List<int> sortedList = Enumerable.Range(1, number)
.Select((x, index) =>
{
double newIndex = ((index % sqrt) * sqrt) + ((double)index / sqrt);
return (x, newIndex);
})
// Sort the list by the second item of each pair
.OrderBy(pair => pair.Item2)
// Extract only the first item from each pair
.Select(pair => pair.Item1)
// Convert to a list
.ToList();
Got a spiral sorter (ty chat gpt for the idea!) Now I just need to connect this to the number generator 😛 oh nevermind its not sorting by MOST unique when it goes to bigger numbers ughhh but its accurate with its numbers 😉
var list = GeneratePoints(30);
var sqrt = (int)Math.Floor(Math.Sqrt(list.Count));

static List<int> GeneratePoints(int x)
{
List<int> points = [];

int increment = 360 / x;

// Loop from 0 to 360 with the increment
for (int i = 0; i < 360; i += increment)
points.Add(i);

return points;
}


list = list.Select((x, index) =>
{
double newIndex = ((index % sqrt) * sqrt) + ((double)index / sqrt);
return (x, newIndex);
})
.OrderBy(pair => pair.Item2)
.Select(pair => pair.Item1)
.ToList();



PrintList(list);


static void PrintList(List<int> list)
{

foreach (var item in list)
{
Console.Write(item + " " + "\n");
}
Console.WriteLine();
}
var list = GeneratePoints(30);
var sqrt = (int)Math.Floor(Math.Sqrt(list.Count));

static List<int> GeneratePoints(int x)
{
List<int> points = [];

int increment = 360 / x;

// Loop from 0 to 360 with the increment
for (int i = 0; i < 360; i += increment)
points.Add(i);

return points;
}


list = list.Select((x, index) =>
{
double newIndex = ((index % sqrt) * sqrt) + ((double)index / sqrt);
return (x, newIndex);
})
.OrderBy(pair => pair.Item2)
.Select(pair => pair.Item1)
.ToList();



PrintList(list);


static void PrintList(List<int> list)
{

foreach (var item in list)
{
Console.Write(item + " " + "\n");
}
Console.WriteLine();
}