2016-10-25 15 views
0

私はジュリアスの視覚化を扱う必要があります。 私のコードと多かれ少なかれ類似したものが見つかったので、私はまだこの問題を解決できません。誰もがここでそれを読むことができる場合 私は、チュートリアルを見つけましたが、そのrussintでリンクされていますジュリアスの可視化

https://habrahabr.ru/post/206516/#comment_7114136

ここでは私のコードです:

public class JuliaSet 
{ 

    ModelCanvas canvas; 

    public JuliaSet(ModelCanvas canvas, Complex c, int w, int h, int maxIter, 
    double xMin = Double.NaN, double yMin = Double.NaN, double xMax = Double.NaN, double yMax = Double.NaN) 
    { 
     this.canvas = canvas; 

     double r = CalculateR(c); 
     if (Double.IsNaN(xMin) || Double.IsNaN(xMax) || Double.IsNaN(yMin) || Double.IsNaN(yMax)) 
     { 
      xMin = -r; 
      yMin = -r; 
      xMax = r; 
      yMax = r; 
     } 
     //Logger.Instance.Log("R = " + r); 
     double xStep = Math.Abs(xMax - xMin)/w; 
     double yStep = Math.Abs(yMax - yMin)/h; 
     //XBitmap bmp = new XBitmap(w, h); 

     IDictionary<int, IDictionary<int, int>> xyIdx = new Dictionary<int, IDictionary<int, int>>(); 
     int maxIdx = 0; 
     for (int i = 0; i < w; i++) 
     { 
      xyIdx.Add(i, new Dictionary<int, int>()); 
      for (int j = 0; j < h; j++) 
      { 
       double x = xMin + i * xStep; 
       double y = yMin + j * yStep; 
       Complex z = new Complex(x, y); 
       IList<Complex> zIter = SqPolyIteration(z, c, maxIter, r); 
       int idx = zIter.Count - 1; 
       if (maxIdx < idx) 
       { 
        maxIdx = idx; // maxIdx = 1 
       } 
       xyIdx[i].Add(j, idx); 
      } 
     } 
     for (int i = 0; i < w; i++) 
     { 
      for (int j = 0; j < h; j++) 
      { 
       int idx = xyIdx[i][j]; 
       double x = xMin + i * xStep; 
       double y = yMin + j * yStep; 
       Complex z = new Complex(x, y); 
       //bmp.SetPixel(w - i - 1, j, ComplexHeatMap(idx, 0, maxIdx, z, r)); 
       this.canvas.SetPixel(w - i - 1, j, ComplexHeatMap(idx, 0, maxIdx, z, r)); 

      } 
     } 
     // return bmp; 
    } 

    public byte[] ComplexHeatMap(decimal value, decimal min, decimal max, Complex z, double r) 
    { 
     byte[] color = new byte[4]; 
     decimal val = (value - min)/(max - min); 
     color[3] = Convert.ToByte(255 * (Complex.abs(z)/r > 1 ? 1 : Complex.abs(z)/r)); 
     color[2] = Convert.ToByte(255 * (1 - val)); 
     color[1] = Convert.ToByte(255 * val); 
     color[0] = 255; 

     return color; 
    } 
    private static IList<Complex> SqPolyIteration(Complex z0, Complex c, int n, double r = 0) 
    { 
     IList<Complex> res = new List<Complex>(); 
     res.Add(z0); 
     for (int i = 0; i < n; i++) 
     { 
      if (r > 0) 
      { 
       if (Complex.abs(res.Last()) > r) 
       { 
        break; 
       } 
      } 
      res.Add((res.Last() * res.Last()) + c); 
     } 
     return res; 
    } 
    private double CalculateR(Complex c) 
    { 
     return (1+Math.Sqrt(1+4*Complex.abs(c)))/2; 
    } 
} 

すべてはチュートリアルが、すべてのものからコピーされます私は徐々にその色を中心に近づけていくサークルです。つまり、すべてのピクセルが同じ色の値になり、すべてのピクセルが設定されます。誰もがここで間違いを見つけることができるかもしれません、私はこれが特定の質問にあることを知っていますが、私はそれを私自身で解決できません。

同様に、ここでは、まあ、私は、Javaにコードを翻訳してきたし、それが正常に動作します(ピクセル/色を設定)

public class ModelCanvas 
{ 
    public int width; 
    public int height; 
    private byte[, ,] pixels; 
    private byte[] currentColor = { 0, 0, 0, 255 }; 


    public ModelCanvas(int width, int height) 
    { 
     this.height = height; 
     this.width = width; 

     pixels = new byte[width, height, 4]; 
     Array.Clear(pixels, 0, pixels.Length); 
    } 

    public void SetCurrentColor(byte r, byte g, byte b, byte alpha) 
    { 
     currentColor[0] = b; 
     currentColor[1] = g; 
     currentColor[2] = r; 
     currentColor[3] = alpha; 
    } 


    public void SetPixel(int x, int y) 
    { 
     SetPixel(x, y, currentColor); 
    } 

    public void SetPixel(int x, int y, byte[] colorData) 
    { 
     for (int i=0; i<4; i++) 
     { 
      pixels[x, y, i] = colorData[i]; 
     } 
    } 

    public WriteableBitmap GetWriteableBitmap() 
    { 
     int imageHeight = pixels.GetLength(1); 
     int imageWidth = pixels.GetLength(0); 

     WriteableBitmap wbitmap = new WriteableBitmap(imageWidth, imageHeight, 96, 96, PixelFormats.Bgra32, null); 

     byte[] pixels1d = new byte[imageWidth * imageHeight * 4]; 
     int index = 0; 
     for (int row = 0; row < imageHeight; row++) 
     { 
      for (int col = 0; col < imageWidth; col++) 
      { 
       for (int i = 0; i < 4; i++) 
        pixels1d[index++] = pixels[col, row, i]; 
      } 
     } 

     Int32Rect rect = new Int32Rect(0, 0, imageWidth, imageHeight); 
     int stride = 4 * imageWidth; 
     wbitmap.WritePixels(rect, pixels1d, stride, 0); 

     return wbitmap; 

    } 

} 
+0

cの値を変更しようとしましたか?ジュリアセットが取ることのできるさまざまな形が、使用されるcの値に依存します。 c = 0の場合、ジュリア集合は単位円である。 https://en.wikipedia.org/wiki/Julia_setの例を見てください。これは、異なるcのために設定されたJuliaの予想される形状を示しています。 –

+0

cは、2つの入力フィールドから1つを実数部、2番目の虚数部に設定します。多くの組み合わせを試してみました。 – GeekyNuns

+0

参考:[shadertoy](https://www.shadertoy.com/)にいくつかのglsl実装があります。 – mlkn

答えて

1

を描画するためのコードです。

私がしたことは、さまざまなメソッドをJava同等のものに変換したことでした。

package toys; 

import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.util.ArrayDeque; 
import java.util.Deque; 
import java.util.HashMap; 
import java.util.Map; 

import javax.swing.JApplet; 

public class Julia extends JApplet { 
    private static final long serialVersionUID = 1L; 

    private BufferedImage image; 

    static class Complex { 
     double x,y; 

     public Complex(double x, double y) { 
      super(); 
      this.x = x; 
      this.y = y; 
     } 

     public static double abs(Complex last) { 
      return Math.hypot(last.x, last.y); 
     } 

     public Complex mul(Complex last) { 
      double z = x * last.x - y * last.y; 
      double w = x * last.y + y * last.x; 
      return new Complex(z,w); 
     } 

     public Complex add(Complex last) { 
      double z = x + last.x; 
      double w = y + last.y; 
      return new Complex(z,w); 
     } 

    } 
    public void JuliaSet(BufferedImage canvas, Complex c, int w, int h, int maxIter) { 
     double xMin = Double.NaN; 
     double yMin = Double.NaN; 
     double xMax = Double.NaN; 
     double yMax = Double.NaN; 

     double r = CalculateR(c); 
     if (Double.isNaN(xMin) || Double.isNaN(xMax) || Double.isNaN(yMin) || Double.isNaN(yMax)) 
     { 
      xMin = -r; 
      yMin = -r; 
      xMax = r; 
      yMax = r; 
     } 
     //Logger.Instance.Log("R = " + r); 
     double xStep = Math.abs(xMax - xMin)/w; 
     double yStep = Math.abs(yMax - yMin)/h; 
     //XBitmap bmp = new XBitmap(w, h); 


     Map<Integer, Map<Integer, Integer>> xyIdx = new HashMap<>(); 
     int maxIdx = 0; 
     for (int i = 0; i < w; i++) 
     { 
      xyIdx.put(i, new HashMap<>()); 
      for (int j = 0; j < h; j++) 
      { 
       double x = xMin + i * xStep; 
       double y = yMin + j * yStep; 
       Complex z = new Complex(x, y); 
       Deque<Complex> zIter = SqPolyIteration(z, c, maxIter, r); 
       int idx = zIter.size() - 1; 
       if (maxIdx < idx) 
       { 
        maxIdx = idx; // maxIdx = 1 
       } 
       xyIdx.get(i).put(j, idx); 
      } 
     } 
     for (int i = 0; i < w; i++) 
     { 
      for (int j = 0; j < h; j++) 
      { 
       int idx = xyIdx.get(i).get(j); 
       double x = xMin + i * xStep; 
       double y = yMin + j * yStep; 
       Complex z = new Complex(x, y); 
       //bmp.SetPixel(w - i - 1, j, ComplexHeatMap(idx, 0, maxIdx, z, r)); 
       canvas.setRGB(w - i - 1, j, ComplexHeatMap(idx, 0, maxIdx, z, r)); 


      } 
     } 
     // return bmp; 
    } 

    public int ComplexHeatMap(double value, double min, double max, Complex z, double r) 
    { 
     double val = (value - min)/(max - min); 
     byte red = (byte) (255 * (Complex.abs(z)/r > 1 ? 1 : Complex.abs(z)/r)); 
     byte g = (byte) (255 * (1 - val)); 
     byte b = (byte) (255 * val); 
     byte a = (byte) 255; 

     int color = (red<<16) + (g <<8) + (b) + (a << 24); 
     return color; 
    } 

    private static Deque<Complex> SqPolyIteration(Complex z0, Complex c, int n, double r) 
    { 
     Deque<Complex> res = new ArrayDeque<>(); 
     res.add(z0); 
     for (int i = 0; i < n; i++) 
     { 
      if (r > 0) 
      { 
       if (Complex.abs(res.getLast()) > r) 
       { 
        break; 
       } 
      } 
      res.add(res.getLast().mul(res.getLast()).add(c)); 
     } 
     return res; 
    } 
    private double CalculateR(Complex c) 
    { 
     return (1+Math.sqrt(1+4*Complex.abs(c)))/2; 
    } 

    int h,w; 
    @Override 
    public void paint(Graphics g) { 
     g.drawImage(image, 0, 0, null); 
    } 

    @Override 
    public void init() { 
     try { 
      h = 400; 
      w = 400; 
      image = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB); 
      this.JuliaSet(image, new Complex(0.285,0.), w, h, 20); 
//   System.arraycopy(source, 0, dest, 0, w*h); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } 


    } 
} 

これは正しい出力です。

enter image description here

だから私はあなたのC#バージョンと何が間違っているかわかりません。それは、複合型の実装にあるかもしれません。

+1

私は今までの中で最も愚かなミスを抱えていました。私のComplexクラスにあったので、正しい複素数を得られませんでした。 – GeekyNuns