I've been trying to implement trapezoid rule for double integral. I've tried many approaches, but I can't get it to work right.
static double f(double x) {
return Math.exp(- x * x / 2);
}
// trapezoid rule
static double trapezoid(double a, double b, int N) {
double h = (b - a) / N;
double sum = 0.5 * h * (f(a) + f(b));
for (int k = 1; k < N; k++)
sum = sum + h * f(a + h*k);
return sum;
}
I understand the method for a single variable integral, but I don't know how to do it for a 2D integral, say: x + (y*y).
Could someone please explain it briefly?
If you're intent on using the trapezoid rule then you would do it like so:
// The example function you provided.
public double f(double x, double y) {
return x + y * y;
}
/**
* Finds the volume under the surface described by the function f(x, y) for a <= x <= b, c <= y <= d.
* Using xSegs number of segments across the x axis and ySegs number of segments across the y axis.
* #param a The lower bound of x.
* #param b The upper bound of x.
* #param c The lower bound of y.
* #param d The upper bound of y.
* #param xSegs The number of segments in the x axis.
* #param ySegs The number of segments in the y axis.
* #return The volume under f(x, y).
*/
public double trapezoidRule(double a, double b, double c, double d, int xSegs, int ySegs) {
double xSegSize = (b - a) / xSegs; // length of an x segment.
double ySegSize = (d - c) / ySegs; // length of a y segment.
double volume = 0; // volume under the surface.
for (int i = 0; i < xSegs; i++) {
for (int j = 0; j < ySegs; j++) {
double height = f(a + (xSegSize * i), c + (ySegSize * j));
height += f(a + (xSegSize * (i + 1)), c + (ySegSize * j));
height += f(a + (xSegSize * (i + 1)), c + (ySegSize * (j + 1)));
height += f(a + (xSegSize * i), c + (ySegSize * (j + 1)));
height /= 4;
// height is the average value of the corners of the current segment.
// We can use the average value since a box of this height has the same volume as the original segment shape.
// Add the volume of the box to the volume.
volume += xSegSize * ySegSize * height;
}
}
return volume;
}
Hope this helps. Feel free to ask any questions you may have about my code (warning: The code is untested).
Many ways to do it.
If you already know it for 1d you could make it like this:
write a function g(x) that calculates the 1d integral over f(x,y) for a fixed x
then integrate the 1d integral over g(x)
Success :)
That way you can basically have as many dimensions as you like. Though it scales poorly. For larger problems it might be neccesary to use monte carlo integration.
Consider using the class jhplot.F2D from the DataMelt Java program. You can integrate and visualize 2D functions doing something like:
f1=F2D("x*y",-1,1,-1,1) # define in a range
print f1.integral()
Related
This converter assumes H, S, and L are contained in the set [0, 1].
But I want H to be between [0, 359] (0 and 359 included) and S & L between [0, 100] (0 and 100 included) and I don't know how to do it (in Java as well).
I took this converter from here.
public class testdos {
public static void main(String[] args) {
// hslToRgb([0, 359], [0, 100], [0, 100]);
}
public static int[] hslToRgb(float h, float s, float l) {
// i added this sysout line
System.out.println("HSL(" + h + "," + s + "," + l + ")");
float r, g, b;
if (s == 0f) {
r = g = b = l; // achromatic
} else {
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
float p = 2 * l - q;
r = hueToRgb(p, q, h + 1f / 3f);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1f / 3f);
}
int[] rgb = { to255(r), to255(g), to255(b) };
// and i added this to print it, don't know if its the best way to do it
System.out.print("RGB(");
for (int i = 0; i < rgb.length; i++) {
if ((i + 1) != rgb.length) {
System.out.print(rgb[i] + ",");
}
else {
System.out.print(rgb[i]);
}
}
System.out.println(")");
return rgb;
}
public static int to255(float v) {
return (int) Math.min(255, 256 * v);
}
/** Helper method that converts hue to rgb */
public static float hueToRgb(float p, float q, float t) {
if (t < 0f)
t += 1f;
if (t > 1f)
t -= 1f;
if (t < 1f / 6f)
return p + (q - p) * 6f * t;
if (t < 1f / 2f)
return q;
if (t < 2f / 3f)
return p + (q - p) * (2f / 3f - t) * 6f;
return p;
}
}
The hslToRgb() method you provided accepts three parameters of float data type. The value range that must be provided to all of these parameters is: 0.0f to 1.0f:
int[] hslToRgb(float h, float s, float l) { ... }
Instead you want to supply a specific range values to these parameters which in turn makes the method much easier to utilize in layman's terms with respect to what needs to actually be supplied.
H (0° to 360° as in Degrees)
S (0% to 100% as in Percent)
L (0% to 100% as in Percent)
It's all a matter of doing a little division. This can be done as the parameters are supplied to the method or built into the method which appears to be what you want. The latter is somewhat more advantageous since you don't need to remember the formula (regardless of how simple it is) to carry out those divisions when applying the arguments to the hslToRgb() method.
Doing the math before passing arguments:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
float hue = (float) 65/360;
float saturation = (float) 36/100;
float lightness = (float) 87/100;
int[] rgb = hslToRgb(hue, saturation, lightness);
Doing the math when passing arguments:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
int[] rgb = hslToRgb((float)65/360, (float)36/100, (float)87/100);
Who cares! Let the method figure it out:
// Hue is: 65° Saturation is: 36% Lightness is: 87%
int[] rgb = hslToRgb(65, 36, 87);
This last example requires a little bit of code to be added to the hslToRgb() method. It's nothing major but before we get into that you need to be sure to realize that for color accuracy, Hue, Saturation, and Lightness arguments can be given respectively in floating point degree and floating point percentage values. In other words, supplying arguments such as:
int[] rgb = hslToRgb(65, 36, 87);
AND
int[] rgb = hslToRgb(65.8, 36.2, 87.5);
are to be considered valid calls with valid arguments. With the slight code addition to the hslToRgb() method, either or can be supplied, for example:
int[] rgb = hslToRgb(0.1806f, 36, 87.5);
This is a valid call with valid arguments and will produce the very same RGB values as the other above examples.
Modifying the hslToRgb() method:
Simply add these three lines of code to the top of the hslToRGB() method:
public static int[] hslToRGB(float h, float s, float l) {
if (h > 1.0f) { h = (h < 0 ? 0 : h > 360 ? 360 : h) / 360; }
if (s > 1.0f) { s = (s < 0 ? 0 : s > 100 ? 100 : s) / 100; }
if (l > 1.0f) { l = (l < 0 ? 0 : l > 100 ? 100 : l) / 100; }
// .... the rest of method code here ....
}
What are these three lines of code doing?
With these lines of code the Hue (h) argument can be supplied as a set [0.0 to 1.0] or a set [0.0 to 360.0] or a set [0 to 360]. The Saturation (s) and Lightness (l) arguments can be supplied as a set [0.0 to 1.0] or a set [0.0 to 100.0] or a set [0 to 100]. If any argument supplied is less than its minimum range (0) then it is defaulted to that arguments specific minimum which for all arguments would be 0. On the same hand, if any argument supplied is greater than its maximum range then it is defaulted to that arguments specific maximum.
Since all three lines of code are basically doing the same thing for each specific argument, we'll explain the first line:
if (h > 1.0f) { h = (h < 0 ? 0 : h > 360 ? 360 : h) / 360; }
The condition for the if statement (h > 1.0f) checks to see if the supplied Hue (h) argument is within the set of [0.0 to 1.0]. If the argument supplied is greater than 1.0 then it must be supplied as a literal degree value and the if statement condition is true therefore running the code contained within this statement's code block which consists of nested Ternary Operator statements. If the if statement condition is false then the supplied value is merely used. Ultimately, if the condition is true then we want to take the supplied argument and divide it by 360 but first we use the nested Ternary Operator statements to ensure the argument supplied is within valid range (0 to 360):
h < 0 ? 0 :
If the supplied argument (h) is less than 0 (such as an arbitrary value of -22 or -0.202) then the h is set to hold a default of 0 otherwise we check to see if the argument value is greater then 360:
: h > 360 ? 360 :
If the supplied argument (h) is greater than 360 (such as an arbitrary value of 365 or 378.8) then the h is set to hold a default of 360 otherwise it is deemed that the argument supplied is indeed within the proper range and we'll use it therefore dividing the supplied value by 360;
: h) / 360
How you might use this method:
int[] rgb = hslToRGB(65, 36, 87);
System.out.println("RGB is: " + java.util.Arrays.toString(rgb));
String hex = "#" + Integer.toHexString(new Color(rgb[0], rgb[1], rgb[2]).getRGB() & 0x00ffffff);
System.out.println("In Hexadecimal: " + hex.toUpperCase());
Console Output:
RGB is: [232, 234, 210]
In Hexadecimal: #E8EAD2
You divide by the h, s, and l range to get the numbers between 0 and 1. You also start class names with an upper-case character.
Edited to add: Why do I have to start class names with an upper-case character?
Because it's the Java convention, and so you can write code like:
Testdoc testdoc = new TestDoc();
and visually see the difference between the Testdoc class name and the testdoc field name.
Here's the revised code.
public class Testdos {
public static void main(String[] args) {
// hslToRgb([0, 359], [0, 100], [0, 100]);
}
/**
* Converts an HSL color value to RGB. Conversion formula adapted from
* http://en.wikipedia.org/wiki/HSL_color_space. Assumes h, s, and l are
* contained in the set [0, 1] and returns r, g, and b in the set [0, 255].
*
* #param h The hue
* #param s The saturation
* #param l The lightness
* #return int array, the RGB representation
*/
public static int[] hslToRgb(float h, float s, float l) {
// i added this sysout line
System.out.println("HSL(" + h + "," + s + "," + l + ")");
h /= 359.0;
s /= 100.0;
l /= 100.0;
float r, g, b;
if (s == 0f) {
r = g = b = l; // achromatic
} else {
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
float p = 2 * l - q;
r = hueToRgb(p, q, h + 1f / 3f);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1f / 3f);
}
int[] rgb = { to255(r), to255(g), to255(b) };
// and i added this to print it, don't know if its the best way to do it
System.out.print("RGB(");
for (int i = 0; i < rgb.length; i++) {
if ((i + 1) != rgb.length) {
System.out.print(rgb[i] + ",");
} else {
System.out.print(rgb[i]);
}
}
System.out.println(")");
return rgb;
}
public static int to255(float v) {
return (int) Math.min(255, 256 * v);
}
/** Helper method that converts hue to rgb */
public static float hueToRgb(float p, float q, float t) {
if (t < 0f)
t += 1f;
if (t > 1f)
t -= 1f;
if (t < 1f / 6f)
return p + (q - p) * 6f * t;
if (t < 1f / 2f)
return q;
if (t < 2f / 3f)
return p + (q - p) * (2f / 3f - t) * 6f;
return p;
}
}
I want to create a "spiral effect" with particles (or any entities) in Java.
I'm new to objective programming (and also Java), so I started with something easier. I firstly created a Path object that has a value of Locations[] signed to it, it gets from the user a: Start location, End location, and double value, that tells him, how much space between each location in the path he has.
private void setLocations() {
//initialize vars
Location start = getStart();
World world = start.getWorld();
Location[] locations = new Location[amount];
double x = start.getX();
double y = start.getY();
double z = start.getZ();
//loop that will set values for locations
for (int i = 0; i < amount; i++) {
locations[i] = new Location(
world,
x + dividedDistanceX * (i + 1),
y + dividedDistanceY * (i + 1),
z + dividedDistanceZ * (i + 1)
);
}
this.locations = locations;
}
Now you might be asking what is the amount? So simply it's the number of points that are created when the object is initialized. It's simple math like getting the longest distance from point to point, and then dividing it by the value of space between each point.
Now the situation gets a little more complicated, so I prepared graphics for you:)
I want to rotate points around the longest axis to form some form of a spiral, and I want from user to set the maximum distance between the starting point and the new one.
Something like this:
And another graph of the sinusoid around one vector (x, y)
Honestly, I need some help.
Here's GitHub object link
Things I know I need to do:
Get the axis around which I will rotate point (it's the longest distance between points)
Add some value to the rest values (x+something, y+something)
Add angle, that point will rotate with, (for example each point will be rotated by 22,5).
Okay, so i did it, it wasn't even that hard:
public Location[] createSpiral(double radius, float angle, Location[] path) {
final int length = path.length;
Location[] result = path.clone();
Location start = path[0];
Location end = path[length - 1];
double startX = start.getX();
double startY = start.getY();
double startZ = start.getZ();
double endX = end.getX();
double endY = end.getY();
double endZ = end.getZ();
double distanceX = setDistance(startX, endX);
double distanceY = setDistance(startY, endY);
double distanceZ = setDistance(startZ, endZ);
double highestOffset = getHighestOffset(new double[]{distanceX, distanceY, distanceZ});
if (highestOffset == abs(distanceX)) {
for (int i = 0; i < length; i++) {
double sin = radius * sin(angle * i / length);
double cos = radius * cos(angle * i / length);
result[i].setY(result[i].getY() + cos);
result[i].setZ(result[i].getZ() + sin);
}
} else if (highestOffset == abs(distanceY)) {
for (int i = 0; i < length; i++) {
double sin = radius * sin(angle * i / length);
double cos = radius * cos(angle * i / length);
result[i].setX(result[i].getX() + cos);
result[i].setZ(result[i].getZ() + sin);
}
} else if (highestOffset == abs(distanceZ)) {
for (int i = 0; i < length; i++) {
double sin = radius * sin(angle * i / length);
double cos = radius * cos(angle * i / length);
result[i].setX(result[i].getX() + cos);
result[i].setY(result[i].getY() + sin);
}
} else {
return path;
}
return result;
}
It's just
double sin = radius * sin(angle * i / length);
double cos = radius * cos(angle * i / length);
and adding those values to corresponding X, Y if Z has the highest distance from a location, etc.
The rest of the code and methods are located in the GitHub link above.
I found a practice java class and I am trying to get all points on the line segment such that for every point x and y are both integers but I am having trouble of implementing it. I am just looking for a formula I can use to solve the problem. or explain me how it get point (3,2). Thanks
/**
*
* #return an array containing all points on the line segment such that for every point in the array,
* both x and y are integers
* For example, if there is a line from (1,1) to (5,3), the only other point for which both x and y are
* integers is (3,2). Thus the method should return the array containing (1,1), (3,2) and (5,3)
* The order of points in the array returned should be from the point with lower x
* (use Point a as the starting point in case a.x == b.x).
*
* Hence if a = (5,1) and b=(1,3), the method returns an array such that
* first item is (1,3), second is (3,2) and third is (5,1)
*/
public Point[] getPointsOnCrosshair() {
Point[] points = new Point[20];
int counter = 0;
//getting slope of the line
double rise = this.b.y - this.a.y;
double run = this.b.x - this.a.x;
double m = rise/run;
System.out.println(m);
//getting value of c -> y = mx + c
double c = a.y - (m * a.x);
int start = 0;
int end = 0;
if (b.x >= a.x){
start = a.x;
end = b.x;
}
else{
start = b.x;
end = a.x;
}
// slope intercept y - y1 = m (x-x1)
// y = (m (x-x1)) + y1
double y = 0;
for (int a = start; a <= end; a++){
y = (m * a) + c;
if (y == (int) y){
points[counter] = new Point(a, (int) y);
counter++;
}
}
return points;
}
First, determine if the line is mostly horizontal or mostly vertical.
▉ ▉ ▉
▉ ▉ ▉
▉ ▉ ▉
▉
▉
▉
If it is mostly horizontal, you iterate x from a.x to b.x and calculate y.
If it is mostly vertical, you iterate y from a.y to b.y and calculate x.
I'll leave it to you to build the right formula, or to go find it on the web, i.e. do some research.
Brute force solution is really simple:
int p1x = 1;
int p1y = 1;
int p2x = 5;
int p2y = 3;
int xdiff = p2x - p1x;
int ydiff = p2y - p1y;
for (int x = p1x + 1; x < p2x; ++x) {
float y = ((float) x - p1x) / xdiff * ydiff + p1y;
if (((int) y) == y) { // check if xx.0
System.out.print(x);
System.out.print(", ");
System.out.println((int)y);
}
}
But I'm sure there's a more elegant way, maybe using prime factorization
is supposed to calculate the coordinates of a projectile launched with respect to time (steps of 100ms), with a linear equation, and it outputs linear numbers, but if i plot this equation with CalcMe.com (math tool) it makes a parabolic plot
InVel = Double.parseDouble(jTextField1.getText());
g = Double.parseDouble(jTextField8.getText());
y = 1;
while(y >= -1) {
t += 100;
x = InVel * TimeUnit.MILLISECONDS.toSeconds(t) * Math.cos(45);
y = InVel * TimeUnit.MILLISECONDS.toSeconds(t) * Math.sin(45) - (1 / 2) * g * Math.pow(TimeUnit.MILLISECONDS.toSeconds(t), 2);
//System.out.print(Double.toString(x));
//System.out.printf(" ");
System.out.print(Double.toString(y));
System.out.printf("%n");
}
jTextField6.setText(Double.toString(x));
the code is in java
g is constant (9.8)
and invel is given by user so its constant too
g is the gravity and invel the initial velocity of the projectile
the equation is:x=invel*time*cos(45) and y=invel*time*sin(45)-(1/2)*g*t^2
anyone can help me?
Your milisecond to second value conversion method TimeUnit.MILLISECONDS.toSeconds(t) is the main fact. Its returning long value which one you are wanted double. Please take a look on below code. Probably its your answer. Just replace hard-coded value with your jTextField
public static void main(String[] args) {
double InVel = Double.parseDouble("10.555");
double g = Double.parseDouble("9.8");
double y = 1;
double x=0;
double t=0;
while(y >= -1) {
t += 100;
double timeInSeconds = (t / (double)1000) % (double)60;
x = InVel * timeInSeconds * Math.cos(45);
y = InVel * timeInSeconds * Math.sin(45) - ((double) 1 / (double) 2) * g * Math.pow(timeInSeconds, 2);
//System.out.print(Double.toString(x));
//System.out.printf(" ");
System.out.println("X = " + x + " Y = " + Double.toString(y));
System.out.printf("%n");
}
}
I have been searching the internet for about a day and I can not seem to find an algorithm to find all points within a bounding box.
Picture:
The accuracy also needs to be 8 decimal digits long.
Example:
(0,0)
(0,0.00000001)
(0,0.00000002)
etc..
(80,80.45356433)
I don't know what exactly you mean by finding all points inside a box. There is just too many!
I would suggest using an Identifier function, i.e., given a point (x, y), I(x, y) = 1 if and only if the point (x, y) is inside your box.
A call to the identifier in your example requires $4$ comparisons.
public class Box {
/**
* Identifier function.
* #param x x-coordinate of input point
* #param y y-coordinate of input point
* #return True if and only if the given point is inside the box.
*/
public boolean IsInside(double x, double y) {
return (this.x_min <= x) && (this.x_max >= x) &&
(this.y_max >= y) && (this.y_min <= y);
}
double x_min, x_max, y_min, y_max; // or do it with left top width and height
}
I hope it helps.
long p = (long)Math.pow(10, 8);
long start = 90 * p;
long end = 180 * p;
for (long i = start; i < end; i++) {
for (long j = start; j < end; j++) {
System.out.println("(" + (double)i / p + "," + (double)j / p + ")");
}
}
will take a while