Видя, как День Святого Валентина быстро приближается, я решил создать сердце. Так что я нашел this heart from mathematica.se:Как исправить это сердце?
Я играл в Mathematica (решена г, переключая некоторые переменные вокруг), чтобы получить это уравнение для г-значения сердца, при х и у значения (нажмите для полного размера):
Я точно портирую это уравнение на Java, имея дело с несколькими недоступных случаями:
import static java.lang.Math.cbrt;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
...
public static double heart(double xi, double yi) {
double x = xi;
double y = -yi;
double temp = 5739562800L * pow(y, 3) + 109051693200L * pow(x, 2) * pow(y, 3)
- 5739562800L * pow(y, 5);
double temp1 = -244019119519584000L * pow(y, 9) + pow(temp, 2);
//
if (temp1 < 0) {
return -1; // this is one possible out of bounds location
// this spot is the location of the problem
}
//
double temp2 = sqrt(temp1);
double temp3 = cbrt(temp + temp2);
if (temp3 != 0) {
double part1 = (36 * cbrt(2) * pow(y, 3))/temp3;
double part2 = 1/(10935 * cbrt(2)) * temp3;
double looseparts = 4.0/9 - 4.0/9 * pow(x, 2) - 4.0/9 * pow(y, 2);
double sqrt_body = looseparts + part1 + part2;
if (sqrt_body >= 0) {
return sqrt(sqrt_body);
} else {
return -1; // this works; returns -1 if we are outside the heart
}
} else {
// through trial and error, I discovered that this should
// be an ellipse (or that it is close enough)
return Math.sqrt(Math.pow(2.0/3, 2) * (1 - Math.pow(x, 2)));
}
}
Единственная проблема заключается в том, что, когда temp1 < 0
, я не могу просто вернуться -1
, как я:
if (temp1 < 0) {
return -1; // this is one possible out of bounds location
// this spot is the location of the problem
}
Это не поведение сердца в этой точке. Как это, когда я пытаюсь сделать мое изображение:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static java.lang.Math.cbrt;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
public class Heart {
public static double scale(int x, int range, double l, double r) {
double width = r - l;
return (double) x/(range - 1) * width + l;
}
public static void main(String[] args) throws IOException {
BufferedImage img = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB);
// this is actually larger than the max heart value
final double max_heart = 0.679;
double max = 0.0;
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
double xv = scale(x, img.getWidth(), -1.2, 1.2);
double yv = scale(y, img.getHeight(), -1.3, 1);
double heart = heart(xv, yv); //this isn't an accident
// yes I don't check for the return of -1, but still
// the -1 values return a nice shade of pink: 0xFFADAD
// None of the other values should be negative, as I did
// step through from -1000 to 1000 in python, and there
// were no negatives that were not -1
int r = 0xFF;
int gb = (int) (0xFF * (max_heart - heart));
int rgb = (r << 16) | (gb << 8) | gb;
img.setRGB(x, y, rgb);
}
}
ImageIO.write(img, "png", new File("location"));
}
// heart function clipped; it belongs here
}
я получаю это:
Посмотрите на этот провал на вершине! Я попытался изменить эту проблемную -1
к .5
, в результате чего в этом:
Теперь сердце есть рога. Но становится ясно, когда это проблемное состояние if
выполнено.
Как исправить эту проблему? Мне не нужна дыра в моем сердце наверху, и я не хочу рогатого сердца. Если бы я мог закрепить рожки в форме сердца и правильно покрасить все остальное, это было бы прекрасно. В идеале, две стороны сердца собирались вместе как точка (сердца имеют небольшую точку в соединении), но если они изогнуты вместе, как показано на рогах, это тоже будет хорошо. Как я могу это достичь?
'double heart = heart (xv, yv);' - вы не проверяете результат, чтобы быть> = 0 –
@ Lashane Я полностью осознаю, но -1 производит приятный розовый оттенок для своего диапазона (не спрашивайте меня, как). Это не устраняет проблему, о которой я прошу. Все нестандартные значения обрезанных производят неотрицательные числа (проверено на python) – Justin