I am writing a program that generates a fractal of a polynomial functions. To print out the result, I am using the given loop:
double xmin = xcenter - sizex/2;
double ymin = ycenter - sizey/2;
double width = sizex;
double height = sizey;
for(int i=0; i < M; i++){
for(int j=0; j < N; j++){
double a = xmin + i * width/M;
double b = ymin + j * height/N;
Complex z = new Complex(a, b);
// Call of the method that return me a color c
pic.set(i, j, c);
}
}
The pic object is a object of a class Picture and the method set sets the color of the pixel i, j to be c (everything is correct with this class).
I want the top right to have coordinates (xcenter + sizex/2 , ycenter + sizey/2)
Calling this function to a complex functions with roots in 0,0 and 3,3, this is what I get when xcenter=ycenter=0 and sizex = sizey = 6
you can check that the center point it darker (it is 0,0) and the other darker point should be at top right ( it should be 3,3) but it is on (3, -3). Calling this method to the root (-3, -3), I can check that the y axes is also inverted.
This is the last points calculated by my function and the root to where it converges is bellow it (as you can see, the method is correct)
2.991428571428571 + 2.9485714285714284i:
3.0 + 3.0i
2.991428571428571 + 2.9571428571428573i: 5
3.0 + 3.0i
2.991428571428571 + 2.9657142857142853i: 4
3.0 + 3.0i
2.991428571428571 + 2.974285714285714i: 4
3.0 + 3.0i
2.991428571428571 + 2.982857142857143i: 4
3.0 + 3.0i
2.991428571428571 + 2.991428571428571i: 4
What is wrong with this loop?
Computer screens and images have the top right point as (0,0) location, this is from the times of text screens, where first line first character is at the top-left position.
Thus use
double a = xmin + i * width/M;
double b = ymax - j * height/N;
for screen / picture location (i,j)
Related
I'm currently working on a raycaster in Java, and so far, I have the floor correctly textured. The problem, however, is that the floor doesn't scroll. In other words, when I move the camera in the projection, the floor stays the same, yet the walls move as expected. I'm really not sure what I'm doing wrong. I took almost all the code from this reference. Note that I took some liberties when pasting the code in that I used some pseudocode.
I tried applying a player offset to the tileX and tileY variables, e.g., tileX += player.x, and all I got was a floor that scrolls far too quickly and incorrectly.
for every ray:
... // other stuff relating to the walls above here.
int start = (int)(wallY + wallHeight + 1);
double directionCos = cos(rad(ray.getAngle()));
double directionSin = sin(rad(ray.getAngle()));
int textureDim = 16;
for (int y = start; y < screenHeight; y++) {
double distance = screenHeight / (2.f * y - screenHeight);
distance /= cos(rad(player.getAngle()) - rad(ray.getAngle()));
// The source I grabbed the code from actually appends the player's x and y to the tileX and tileY variables, but this completely messes up the textures when I try to.
double tileX = distance * directionCos;
double tileY = distance * directionSin;
int textureX = Math.floorMod((int)(tileX * textureDim), textureDim);
int textureY = Math.floorMod((int)(tileY * textureDim), textureDim);
int rgb = floorTexture.getRGB(textureX, textureY);
projectionFloor.setRGB((int)wallX, y, rgb);
}
Below is an image of the floor.
Below is an animation visualizing the problem.
Below is an animation visualizing what happens if I try to apply a player position offset:
Fixed it on my own. Turns out that, yes, you do have to account for the player's position (shocker!); the source I got the code from just didn't do it correctly.
DTPP = distance to projection plane.
for every pixel y from wallY + wallHeight + 1 to projectionHeight:
double r = y - this.getPreferredSize().height / 2.f;
double d = (CAMERA_HEIGHT * DTPP / r) / ANGLE;
double tileX = CAMERA_X + d * RAY_COSANGLE;
double tileY = CAMERA_Y + d * RAY_SINANGLE;
int textureX = Math.floorMod((int) (tileX * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
int textureY = Math.floorMod((int) (tileY * TEXTURE_SIZE /
TEXTURE_SCALE), TEXTURE_SIZE);
... (drawing occurs here)
This is for a visualization I am working on. I want to divide a rectangle in N equal parts. I want these parts to have a width of say (min. 1px, max 1.5px), depending on the width of the rectangle and I want this division to end with a remainder of 0 (so I don't have a larger than the rest part).
I have tried implementing Modulo: https://processing.org/reference/modulo.html but I am not sure this is the correct way. Any ideas?
//Generates coordinates within each line.
for (int j = 0; j < line_coordinates.length; j++) {
//Positions start of line draw on random X coordinate.
float xv = component_x1 + (j * (component_length / line_coordinates.length+1));
float yv = line_height;
//Defines available with for each item in a component.
float item_availablewidth = component_length / line_coordinates.length+1;
//Creates vector with X coordinate and Y noise affected coordinate.
line_coordinates[j] = new PVector(xv, y);
rectMode(CENTER);
noStroke();
fill(232, 45, 34);
rect(line_coordinates[j].x,
line_coordinates[j].y - (line_height / 2),
item_availablewidth * item_randomwidthcoefficient,
line_height);
println("line_coordinates[j].x1",
line_coordinates[j].x - ((item_availablewidth * item_randomwidthcoefficient) / 2)); //This is where X starts.
println("line_coordinates[j].x2",
line_coordinates[j].x + ((item_availablewidth * item_randomwidthcoefficient) / 2)); //This is where X is supposed to end.
//This is the first method I tried but I found out this separation needs to be dynamic.
float drawnline_separation = 2;
float drawnline_total = (item_availablewidth * item_randomwidthcoefficient) / drawnline_separation;
println("drawnline_total",
drawnline_total);
//For loop divides each item in vertical -axidrawable- lines separating them by a max
for (int l = 0; l <= drawnline_total; l++) {
float drawnline_x = lerp(line_coordinates[j].x - ((item_availablewidth * item_randomwidthcoefficient) / 2),
line_coordinates[j].x + ((item_availablewidth * item_randomwidthcoefficient) / 2),
l/drawnline_total);
println("drawnline_x", drawnline_x);
stroke(23);
noFill();
//Draws line.
line(drawnline_x,
line_coordinates[j].y,
drawnline_x,
line_coordinates[j].y + 25 );
}
}
//This is the print I am getting.
line_coordinates[j].x1 346.42535
line_coordinates[j].x2 353.44092
drawnline_total 3.5077777
drawnline_x 346.42535
drawnline_x 348.42535
drawnline_x 350.42535
drawnline_x 352.42535
I hope I am being clear! Please let me know if my explanation is very confusing.
I would like to create circles with a random diameter, position and color in a panel with the Graphics class in Java. It works fine, however I have the problem that often circles touch or overlap the border.
How can I make the circles fully stay within the panel?
Thanks in advance!
This is the code I use for creating the circles:
amount = rnd.nextInt(10);
for (int i = 0; i < amount; i++){
x = (50 + rnd.nextInt(panel.getWidth() - 50 + 1)) - 50;
y = (50 + rnd.nextInt(panel.getHeight() - 50 + 1)) - 50;
diameter = (rnd.nextInt(100));
gr.setColor(new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256)));
gr.fillOval(x, y, diameter, diameter);
gr.drawString("" + (panel.getHeight() - y), x, y);
}
x = (50 + rnd.nextInt(panel.getWidth() - 50 + 1)) - 50;
y = (50 + rnd.nextInt(panel.getHeight() - 50 + 1)) - 50;
diameter = (rnd.nextInt(100));
How can you calculation the x/y position if you don't know what the diameter of the circle is going to be?
First you need to calculate the diameter. Then you need to use the diameter to make sure the x/y plus the diameter is less than the width of the panel.
I don't understand the point of adding 50 and then subtracting 50. I would think the random number should be the width minus the diameter.
I want to render a cylinder in Opengl. For that i wrote an simple algorithm, that
generates me the points mesh by the parameters radius, height, xSubDivisions and ySubDivisions:
(Java)
for(int yDivision = 0; yDivision < yDivisionCount; yDivision++){
for(int xDivision = 0; xDivision < xDivisionCount; xDivision++){
float line[] = getVboLine(xDivision, yDivision, radius, height, xDivisionCount, yDivisionCount);
string.append(line[0] + ", " + line[1] + ", " + line[2] + ", " + line[3] + ", " + line[4] + ", ");
}
}
public float[] getVboLine(int xDivision, int yDivision, float radius, float height, int xDivisionCount, int yDivisionCount){
float xDegrees = 360.0f / xDivisionCount * xDivision;
float xRadian = (float) Math.toRadians(xDegrees);
float x = (float) Math.sin(xRadian) * radius;
float z = (float) Math.cos(xRadian) * radius;
float y = (float) yDivision * (height / (yDivisionCount - 1));
float s = xDegrees * (1.0f / 360.0f);
float t = yDivision * (1.0f / (yDivisionCount - 1));
return new float[]{
x, y, z, s, t
};
}
The result is actually an cylinder, (i created an IBO to render this points) but sometimes, with different inputs for x and yDivisions there is a strange gap in it.
I couldn't find a rule, but the values i found this bug with were 200, 100.
To debug i rendered only the points. The result was:
How is this possible? One points is just missing (where i added the reed circle with paint).
Where is the problem with my algorithm?
I am not JAVA coder but you are mixing int and float together
for example:
xDegrees = 360.0f / xDivisionCount * xDivision
[float] [float] [int] [int]
I would rather use this:
xDegrees = float(360*xDivision)/float(xDivisionCount)
multiplication should go always first (if operands are >= 1)
and division after that to preserve accuracy
some weird rounding could cause your problem but it would be more noticeable for lower xDivisionCount not bigger one
Bug breakpoint
add to your code last generated point
after new point computation compute the distance from last point
add if (|distance-some_avg_distance|>1e-10)
and add breakpoint inside
some_avg_distance set by distance that should be there (get it from trace)
this way you can breakpoint the point causing problems (or the next point to it)
so you can actually see what is wrong
my bet is that by rounding you get the same angle as prev/next point
and therefore you do not have missing point but some duplicate instead
you can check that also by Blending
I'm practicing for an exam, and I'm doing one of the practice problems. I have a method that takes two arguments: one for the radius of a circle, and one for the number of dots to place within that circle. The method is below:
private void drawDots(int radius, int numDots){
double ycord;
double xcord;
for(int q = 0; q < numDots; q++){
ycord = -radius + random()*(radius+radius+1);
xcord = pow((pow(radius,2)-pow(ycord,2)),0.5);
turt.moveTo(xcord,ycord);
turt.penDown();
turt.forward(0);
turt.penUp();
}
}
turt is an object I'm using to draw with, and penDown()/penUp() is placing and removing the object from the canvas respectively.
I'm trying to define the x-coordinate and y-coordinate of the turt object to stay within a radius. Say the radius is 100, and the number of dots is 200, how do I keep the object within that radius?
The question states that:
"To constain the dots to a circle of radius r, a random y-coord in the interval -r, r is chosen. To x-coord is then randomly chosen in the interval -b, b, where b = sqrt(r^2 - y^2)."
I'm just not sure how to make sense of this math. The code above was my best attempt, but the output is strange.
Here is my failed output:
The distance from the center (0,0) to a dot must be less than the radius of the circle, r. The distance can be expressed as sqrt(x² + y²). Therefore, if you choose your y coordinate randomly between [-r, r], you just have to make sure that your x coordinate respects the previous equation, hence your math.
Demonstration
sqrt(x² + y²) < r
x² + y² < r²
x² < r² - y²
x < sqrt(r² - y²)
#
Your algorithm should be as follows. Once you chose the y coordinate, you can randomly choose x as long as it respects the distance constraint.
private void drawDots(int radius, int numDots){
double y;
double x;
double xMax;
for (int q = 0; q < numDots; q++){
// y is chosen randomly
y = -radius + random() * (radius + radius + 1);
// x must respect x² + y² < r²
xMax = pow((pow(radius,2)-pow(ycord,2)), 0.5);
x = random() * 2 * xMax - xMax;
turt.moveTo(x, y);
turt.penDown();
turt.forward(0);
turt.penUp();
}
}
Take a look at the documentation for random, you will see by default it produces a number between 0 and 1.
Basically this means that the expression you are looking for is:
ycord=-radius+random()*(radius*2);
This gives you a point on the y axis between -radius and radius (consider if the random() returns 0 you get -radius, it it returns 1 you get -radius+(2*radius())=radius.
You calculation for the x co-ordinate is correct but it gives you the x coordinate point on the circle (lets call it b). I suspect you want to use a new random to select an x co-ordinate between b and -b.
At present you are drawing points on the circle, not inside it. That is because you are not following the guideline correctly.
b = pow((pow(radius,2)-pow(ycord,2)),0.5); // this should be b
xcord = -b + random()*(b+b);