Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package raymarching.rm01;
- import prophecy.common.image.ImageSurface;
- import prophecy.common.image.RGB;
- import prophecy.common.image.RGBImage;
- import javax.swing.*;
- import java.awt.*;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- public class RM01 {
- public static void main(String[] args) {
- new RM01();
- }
- int swidth = 320, sheight = swidth*5/8;
- RGBImage simage;
- final double infinite = 1e10;
- final double minDist = 1e-4;
- final int maxIter = 100;
- final double overstep = 1.0;
- final double perspective = 0.75;
- final V cameraLocation = new V(0, 0, -0.4);
- final double zoom = 2.0;
- double time = 0;
- RM01() {
- simage = new RGBImage(swidth, sheight, Color.black);
- paint();
- final ImageSurface surface = new ImageSurface(simage);
- JButton button = new JButton("Next frame");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- step();
- paint();
- simage.flush();
- surface.setImage(simage);
- }
- });
- JFrame frame = new JFrame("Raymarching");
- frame.getContentPane().setLayout(new BorderLayout());
- frame.getContentPane().add(BorderLayout.CENTER, surface);
- frame.getContentPane().add(BorderLayout.SOUTH, button);
- frame.pack();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setVisible(true);
- }
- private void step() {
- ++time;
- }
- void paint() {
- for (int sy = 0; sy < sheight; sy++)
- for (int sx = 0; sx < swidth; sx++) {
- RGB color = renderPoint(sx, sy);
- simage.setPixel(sx, sy, color);
- }
- }
- private RGB renderPoint(int sx, int sy) {
- double x = (double) (sx - swidth / 2) / (swidth / 2);
- double y = (double) (sy - sheight / 2) / (swidth / 2);
- x /= zoom; y /= zoom;
- V v = new V(x, y, 0).plus(cameraLocation);
- V direction = new V(x*perspective, y*perspective, 1).normalize();
- RGB color = null;
- for (int iter = 0; iter < maxIter; iter++) {
- Dist dist = lookupDistance(v);
- if (dist.color != null) color = dist.color;
- if (dist.d == infinite)
- return new RGB(Color.white);
- else if (dist.d < minDist) {
- //System.out.println(iter);
- return color != null ? color : new RGB(Color.black);
- } else {
- //System.out.println(dist);
- v = v.plus(direction.times(dist.d*overstep));
- }
- }
- return new RGB(Color.gray);
- }
- private Dist lookupDistance(V v) {
- //return square(v);
- //return cube(v, 0.5);
- //return cube(rotateZ(Math.PI*0.125, v), 0.5);
- //return cube(rotateX(Math.PI*0.125, v), 0.25);
- return blackToWhiteCube(rotateY(Math.PI * 0.125 * time, v), 0.25);
- }
- private V rotateX(double angle, V v) {
- double sin = Math.sin(angle), cos = Math.cos(angle);
- return new V(v.x, v.y*cos-v.z*sin, v.y*sin+v.z*cos);
- }
- private V rotateY(double angle, V v) {
- double sin = Math.sin(angle), cos = Math.cos(angle);
- return new V(v.x*cos-v.z*sin, v.y, v.x*sin+v.z*cos);
- }
- private V rotateZ(double angle, V v) {
- double sin = Math.sin(angle), cos = Math.cos(angle);
- return new V(v.x*cos-v.y*sin, v.x*sin+v.y*cos, v.z);
- }
- private double square(V v) {
- if (Math.abs(v.x) < 0.5 && Math.abs(v.y) < 0.5) return 0.0; else return infinite;
- }
- private Dist blackCube(V v, double size) {
- return new Dist(new RGB(Color.black), cube(v, size));
- }
- private Dist blackToWhiteCube(V v, double size) {
- double c = ((Math.max(-size, Math.min(size, v.y))/size)+1)/2;
- return new Dist(new RGB(c), cube(v, size));
- }
- /* a cube centered at 0,0,0 with a length of size*2 in all 3 dimensions */
- private double cube(V v, double size) {
- double x = Math.abs(v.x)-size, y = Math.abs(v.y)-size, z = Math.abs(v.z)-size;
- return new V(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0)).len();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment