public virtual void Draw(IMandelOutput Output, int c_width, int c_height) { int starttime = System.Environment.TickCount; Output.InitDraw(); double ival = c_radius / (c_width / 2); Complex c_begin = new Complex(c_cent.Real - c_radius, c_cent.Imaginary - ival * (c_height / 2)); if (c_haschanged || (c_LayerDataHash != c_LayerData.GetHashCode()) || (c_calc == null)) { foreach (var it in c_LayerData) if (it.c_default) { c_calc = c_factory.GenFractalCalc(c_LayerData, c_fractaltype, c_function, it); break; } c_haschanged = false; c_LayerDataHash = c_LayerData.GetHashCode(); } c_calc.InitData(c_LayerData, c_param,c_lineprocess?c_width:c_width*c_height); if (c_lineprocess) { // soronkenti feldologozas // elkuldjuk a szamokat for (int y=0; y<c_height; y++) { for (int x=0; x<c_width; x++) { Complex pos = new Complex(c_begin.Real+x*ival,c_begin.Imaginary+y*ival); if (c_type==MandelType.MANDEL_TYPE_MANDEL) { c_calc.AddPoint(x,y,pos,pos); } else if (c_type==MandelType.MANDEL_TYPE_INVJULIA) { c_calc.AddPoint(x,y,c_julia,pos); } else { c_calc.AddPoint(x,y,pos,c_julia); } } c_calc.EndSend(); for (int x=0; x<c_width; x++) { int px,py; List<ProcessLayer> pl; c_calc.GetPoint(out px, out py, out pl); for (int i = 0; i < c_LayerData.Count; i++) c_LayerData[i].LoadFrom(pl[i]); PutPoint(Output, 1, px, py); if (c_callback != null) c_callback.SetPoint(x, y); } c_calc.EndGet(y==c_height-1); Output.NextLine(1, y+1); if (c_callback != null) c_callback.SetLine(y+1); } } else { // globalis feldolgozas -- sok adat eseten hamar fagyashoz vezethet (szekvencialis programnal 2000x2000-es meret felett, parhuzamos esetben mar 400x400 meret korul is gondjaink lesznek, legalabbis adatcsatornas modszer alkalmazasa eseten // elkuldjuk a szamokat for (int y=0; y<c_height; y++) { for (int x=0; x<c_width; x++) { Complex pos = new Complex(c_begin.Real+x*ival,c_begin.Imaginary+y*ival); if (c_type == MandelType.MANDEL_TYPE_MANDEL) { c_calc.AddPoint(x, y, pos, pos); } else if (c_type == MandelType.MANDEL_TYPE_INVJULIA) { c_calc.AddPoint(x, y, c_julia, pos); } else { c_calc.AddPoint(x, y, pos, c_julia); } } } c_calc.EndSend(); // fogadjuk a szamokat for (int y=0; y<c_height; y++) { for (int x=0; x<c_width; x++) { int px, py; List<ProcessLayer> pl; c_calc.GetPoint(out px, out py, out pl); for (int i = 0; i < c_LayerData.Count; i++) c_LayerData[i].LoadFrom(pl[i]); PutPoint(Output, 1, px, py); if (c_callback != null) c_callback.SetPoint(x, y); } Output.NextLine(0, y+1); if (c_callback != null) c_callback.SetLine(y + 1); } c_calc.EndGet(true); } Output.EndDraw(); int endtime = System.Environment.TickCount; c_timeused = ((double)(endtime - starttime)) / 1000.0; }
public abstract void PutPoint(IMandelOutput Output, int flags, int x, int y);
public override void PutPoint(IMandelOutput Output, int flags, int x, int y) { ColorValue c; bool inside = false; foreach (var it in c_layers) { if ((it.c_calcdata.c_default) && (it.c_calcdata.c_isin)) inside = true; } int n = 0; if (inside) Output.PutPoint(n, flags, x, y, c_inscol); else Output.PutPoint(n, flags, x, y, c_outcol); foreach (var it in c_layers) { n++; if (((inside) && it.c_type.HasFlag(LayerType.LAYER_TYPE_INSIDE)) || ((!inside) && it.c_type.HasFlag(LayerType.LAYER_TYPE_OUTSIDE))) { double bv = -1; double min = 0; double max = 0; switch (it.c_dataused) { case DataUsed.LAYER_DATAUSED_ITER: bv = it.c_calcdata.c_n; min = 0; max = it.c_calcdata.c_nlimit; break; case DataUsed.LAYER_DATAUSED_VALUE: bv = it.c_calcdata.c_calc; min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_X_REAL: bv = it.c_calcdata.c_x.Real; min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_X_IMAG: bv = it.c_calcdata.c_x.Imaginary; min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_X_ARG: bv = it.c_calcdata.c_x.Phase; min = 0; max = Math.PI; break; case DataUsed.LAYER_DATAUSED_X_ABS: bv = Complex.Abs(it.c_calcdata.c_x); min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_RES_REAL: bv = it.c_calcdata.c_resx.Real; min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_RES_IMAG: bv = it.c_calcdata.c_resx.Imaginary; min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_RES_ARG: bv = it.c_calcdata.c_resx.Phase; min = 0; max = Math.PI; break; case DataUsed.LAYER_DATAUSED_RES_ABS: bv = Complex.Abs(it.c_calcdata.c_resx); min = it.c_param1; max = it.c_param2; break; case DataUsed.LAYER_DATAUSED_RES_N: bv = it.c_calcdata.c_resn; min = 0; max = it.c_calcdata.c_nlimit; break; } if (it.c_cycle == 1) { if (min < max) { if (bv < min) bv = min; if (bv > max) bv = max; } else { if (bv > min) bv = min; if (bv < max) bv = max; } } double value = 0; if (bv == min) value = 0; else if (bv == max) value = 1; else if (min != 0) { if (it.c_interp == Interp.LAYER_INTERP_LOG) { value = (Math.Log(bv) - Math.Log(min)) / (Math.Log(max) - Math.Log(min)) * it.c_cycle; } else if (it.c_interp == Interp.LAYER_INTERP_EXP) { value = (Math.Exp(bv) - Math.Exp(min)) / (Math.Exp(max) - Math.Exp(min)) * it.c_cycle; } else { value = (bv - min) / (max - min) * it.c_cycle; } } else { value = (bv - min) / (max - min) * it.c_cycle; } if (!inside) { double newalpha = it.c_alpha; double newvalue = it.c_value; double newsaturation = it.c_saturation; double iter = it.c_calcdata.c_n; if (newalpha > 0) { if (it.c_alphaextr.HasFlag(LayerExtra.LAYER_EXTRA_INC)) { if (it.c_alphaextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newalpha = Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newalpha; else newalpha = (iter / ((double)it.c_calcdata.c_nlimit)) * (newalpha); } else if (it.c_alphaextr.HasFlag(LayerExtra.LAYER_EXTRA_DEC)) { if (it.c_alphaextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newalpha = newalpha - Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newalpha; else newalpha = newalpha - (iter / ((double)it.c_calcdata.c_nlimit)) * newalpha; } } if (newvalue > 0) { if (it.c_valueextr.HasFlag(LayerExtra.LAYER_EXTRA_INC)) { if (it.c_valueextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newvalue = Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newvalue; else newvalue = (iter / ((double)it.c_calcdata.c_nlimit)) * (newvalue); } else if (it.c_valueextr.HasFlag(LayerExtra.LAYER_EXTRA_DEC)) { if (it.c_valueextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newvalue = newvalue - Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newvalue; else newvalue = newvalue - (iter / ((double)it.c_calcdata.c_nlimit)) * newvalue; } } if (newsaturation > 0) { if (it.c_saturationextr.HasFlag(LayerExtra.LAYER_EXTRA_INC)) { if (it.c_saturationextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newsaturation = Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newsaturation; else newsaturation = (iter / ((double)it.c_calcdata.c_nlimit)) * (newsaturation); } else if (it.c_saturationextr.HasFlag(LayerExtra.LAYER_EXTRA_DEC)) { if (it.c_saturationextr.HasFlag(LayerExtra.LAYER_EXTRA_LOG)) newsaturation = newsaturation - Math.Log(iter) / Math.Log(((double)it.c_calcdata.c_nlimit)) * newsaturation; else newsaturation = newsaturation - (iter / ((double)it.c_calcdata.c_nlimit)) * newsaturation; } } c = it.c_gr.getPoint(value, it.c_cycle != 1); c.Blend(newalpha, newsaturation, newvalue); Output.PutPoint(n, flags, x, y, c); } else { c = it.c_gr.getPoint(value, it.c_cycle != 1); c.Blend(it.c_alpha, it.c_value, it.c_saturation); Output.PutPoint(n, flags, x, y, c); } } } }