My goal is to give a linear probability to the random function.
That is, to give a higher probabiliy as lower the number`in a linear way.
However the code below gives a parabola like outcome…
Where am I wrong in my logic?
int t;
int[] num = new int[5050];
int[] h = new int[1000];
void setup() {
background(255);
size(1000, 600);
for (int i = 1; i <= 100; i++) {
for (int j = 100; j >= i; j--) {
num[t] = i;
t++;
}
}
for (int i = 0; i <= 999; i++) {
h[i] = num[int(random(0, 5499))];
line(i, height/2-3*h[i], i, height/2);
}
h = sort(h);
stroke(0, 0, 255);
for (int i = 0; i <= 999; i++) line(i, height-6*h[i], i, height);
}
The code you posted does not run the first list should be int[] num = new int[5500];
After that it is difficult to see how your algorithm is supposed to work, some comments in the code might help. I must say that your algorithm looks over complicated.
You might want to explain in more detail what you mean by
Ok, the first loop sets an array of 100 times 1, 99 times 2, 98 times 3, until 1 time 100.
This way if you chose a random index you have an ** almost** linear chance to pick lower values. I say ‘almost’, because now I realized that the graphic really has to be parabolic as you can see in the image with code below.
Now I have to.find some a formula that makes it really linear.
Any idea?
And yes, if the code is over complicated, please explain how.
int t;
int res = 45; // resolution
int[] num = new int[1050];
void setup() {
background(255);
size(1000, 600);
for (int i = 1; i <= res; i++) {
for (int j = res; j >= i; j--) {
num[t] = i;
t++;
}
}
for (int i = 0; i <= 1049; i++) {
line(i, height-15*num[i], i, height);
}
}
you’re def on the right track and it’s a good approach but you might want to check out this redblob article about probability. if you go down to the Asymmetry section and you change the values you will end up with the output you seek as shown below
Here is an image of what I managed to get. Looks good to me.
What is even better the solution is very uncomplicated .
float y_low, y_high;
float[] y;
void setup() {
size(640, 400);
background(255);
y = new float[width];
y_low = 0;
y_high = height / 2;
// Draw th graph
stroke(64);
for (int i = 0; i < y.length; i++) {
y[i] = randomLinear(y_low, y_high);
line(i, height / 2 - y[i], i, height / 2);
}
// Draw the sorted graph
y = sort(y);
stroke(255, 10, 100);
for (int i = 0; i < y.length; i++) {
line(i, height - y[i], i, height);
}
}
/**
Return a random value >= low and < high such
that the distribution is proportional to the
returned value.
*/
float randomLinear(float low, float high) {
float r = sqrt(2) * random(1/sqrt(2));
return r * (high - low) + low;
}
Thank you so much. This is exactly what I need. Meanwhile, I was writing a code to work with a table so that you can customize the random function like described in the site link given by @hotfooted . Later on, I will post it.
The idea of customizing the random function consists in creating an array of for instance 1000 integers, each with a value from 0 to, for instance, 500. Such an array can be created by drawing a line in a window from left to right with the height y giving the value of index x.
When these indexes are randomly accessed, the chance of picking a lower or higher value is determined by the shape of the line shown in the picture. Customized random tables are sometimes used in games. Another usage you can find on this topic.
The code will generate a one-line string of the customized random table in the console that can be copied/pasted into the other sketch.
float x, y, old_x, old_y, targetX, targetY;
float easing = 0.11; // increase for more details
boolean down, begin = true;
String str = "";
int i, j=0;
void setup() {
size(1000, 500);
smooth();
erase();
}
void draw() {
if (down) {
if (begin) {
old_x = 0;
old_y = mouseY;
x = mouseX;
y = mouseY;
begin = false;
}
targetX = mouseX;
targetY = mouseY;
x += (targetX - x) * easing;
y += (targetY - y) * easing;
line(old_x, old_y, x, y);
old_x = x;
old_y = y;
}
}
void mousePressed() {
if (mouseX > width-200 && mouseX < width-120 && mouseY < 30) send();
if (mouseX > width-100 && mouseY < 30) erase();
}
void mouseDragged() {
down = true;
}
void mouseReleased() {
down = false;
}
void send() {
// searching for black pixels is needed because when drawing
// some pixels may have been missed
down = false;
for ( i = 0; i <= width; i++) {
for (j = 0; j <= height; j++) {
color c = get(i, j);
if (c == color(0)) {
str += str(height-j)+',';
break;
}
}
}
println ("int[]num={"+str+"};");
exit();
}
void erase() {
begin = true;
stroke(0);
strokeWeight(2);
background(255);
fill(230);
rect(width-200, 5, 80, 30);
rect(width-100, 5, 80, 30);
fill(0);
text("Save", width-190, 25);
text("Clear", width-90, 25);
}