Jump to content

I'm working on a Kaleidoscope plugin:need help V2!


MadJik

Recommended Posts

This plugin will have several versions, I will just start with a simple one.

For now I am able to create like a pie chart to help to cut the picture and select (manually) one piece for the repeating reflection.

Imagine a pie cut into 12 equal portions.

Then we select one of these portion to be the one to duplicate.

Then we read as usualy :

for(int y = rect.Top; y < rect.Bottom; y++) {

for (int x = rect.Left; x < rect.Right; x++) {

...

The tricky part for me now is to determin for dst[x,y] what is the corresponding src[x,y] knowing :

- it is a pixel from the selected portion...

- and for ode portion (dst) we have to apply a symetric reflection...

Any (all) idea/suggestion are welcome.

I visited some developper forum or math forum but I find nothing really helping me!

Link to comment
Share on other sites

Some previews:

Random kaleidoscopes generator:

(the first is retouched : blur, color levels etc, the others are raw versions)

kalg1.jpgkalg2.jpgkalg3.jpg

Image "kaleidoscopor":

Original:

jici2.jpg

Actual result (I'm missing symetric rotation one part on two):

jici2k.jpg

(I've added the lines)

Expected result:

jici2k2.jpg

(I've added the lines)

Does anyone could help me for the symetric rotation?

Link to comment
Share on other sites

If you reflect it once along any of those axes and then begin to rotate that bigger piece, you should have it.

Thus, every other piece is reflected along its own normal axis*; so, the destination pixel will be drawn from the point on the other side of that normal axis at the same distance from the axis.

Questions?

*That normal axis would be the one that bisects the triangle, as so:

normaxwa5.jpg

The axis runs from A to D, where D is the midpoint of line BC.

~~

Link to comment
Share on other sites

Ah... Yeah, well I guess you can't do much if you're using that, then... But if you want to remake it, just take any triangle as your source pixels, and then your destination pixels will draw from that triangle, with a rotational offset depending on the triangle the destination is in, and also possibly a mirror offset (along that "normal" axis), also depending on the triangle the destination is in.

~~

Link to comment
Share on other sites

  • 2 weeks later...

I'm working on a generator using triangles.

Sometimes it works and sometimes not.

Example:

example.jpg

Anyhow the rendering shows strange lines not linked to the final result...

While rendering:

rendering.jpg

And the final result could be corrupted with some remaining lines...

Result:

final.jpg

This is the code (used with a normal three slider UI):

using KaleidoGen.Properties;
using PaintDotNet;
using PaintDotNet.Effects;
using System;
using System.Drawing;


namespace KaleidoGen
{
 //Kaleidoscope generator based on http://sprott.physics.wisc.edu/pickover/ekscop.html
 //Thanks to Dr. Cliff Pickover for this article.
 //Thanks to Nemerle http://www.developpez.net/forums/member.php?s=de428a11138f7d0dcb6c474af5d673aa&u=25295
 //who gave me this link...
 public class KaleidoGen
     : Effect
 {
   int reseed = 0;

   public override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length)
   {
     ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters;
     int tkNbTriangles = (int)token.Amount1;   // Nb of triangles to draw
     int tkOverlay = (int)token.Amount2;       // Overlay between quarters
     int KWidth = (int)token.Amount3;          // Width of a square

     int x1, x2, x3, y1, y2, y3, ba, br, bg, bb, sav;
     int px1, px2, px3, py1, py2, py3;

     PdnRegion selectionRegion = EnvironmentParameters.GetSelection(srcArgs.Bounds);
     Rectangle selection = this.EnvironmentParameters.GetSelection(srcArgs.Bounds).GetBoundsInt();
     long CenterX = (long)(((selection.Right - selection.Left) / 2) + selection.Left);
     long CenterY = (long)(((selection.Bottom - selection.Top) / 2) + selection.Top);

     if (KWidth > (int)(CenterX * 2)) { KWidth = (int)(CenterX * 2); }
     if (KWidth > (int)(CenterY * 2)) { KWidth = (int)(CenterY * 2); }
     Random randinit = new Random();

     if (reseed == 0)
     {
       reseed = randinit.Next((int)(CenterX * CenterY));
     }

     lock (dstArgs.Graphics)
     {

       // Make sure we don't draw outside of our current rectangle of intrest
       dstArgs.Graphics.Clip = new Region(selection);
       // Set Antialiasing ON
       dstArgs.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

       for (int i = startIndex; i < startIndex + length; ++i)
       {
         Random rand = new Random(reseed);
         Rectangle rect = rois[i];
         // Copy existing image (source) to destination
         for (int y = rect.Top; y < rect.Bottom; ++y)
         {
           for (int x = rect.Left; x < rect.Right; ++x)
           {
             dstArgs.Surface[x, y] = srcArgs.Surface[x, y];
           }
         }

         for (int tr = 0; tr < tkNbTriangles; ++tr)
         {
           x1 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;
           x2 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;
           x3 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;
           y1 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;
           y2 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;
           y3 = rand.Next(Math.Abs(KWidth + tkOverlay)) - tkOverlay;

           //br = (byte)(col * (int)(rand.Next(16) * 16 * colF));
           ba = (byte)(rand.Next(256));
           br = (byte)(rand.Next(256));
           bg = (byte)(rand.Next(256));
           bb = (byte)(rand.Next(256));

           SolidBrush myBrush = new SolidBrush(Color.FromArgb(ba, br, bg, bb));

           if (x1 > y1) { sav = x1; x1 = y1; y1 = sav; }
           if (x2 > y2) { sav = x2; x2 = y2; y2 = sav; }
           if (x3 > y3) { sav = x3; x3 = y3; y3 = sav; }

           for (int pt = 0; pt < 8; ++pt)
           {
             switch (pt)
             {
               case 0:
                 px1 = x1;
                 px2 = x2;
                 px3 = x3;
                 py1 = y1;
                 py2 = y2;
                 py3 = y3;
                 break;
               case 1:
                 px1 = x1;
                 px2 = x2;
                 px3 = x3;
                 py1 = -y1;
                 py2 = -y2;
                 py3 = -y3;
                 break;
               case 2:
                 px1 = -x1;
                 px2 = -x2;
                 px3 = -x3;
                 py1 = -y1;
                 py2 = -y2;
                 py3 = -y3;
                 break;
               case 3:
                 px1 = -x1;
                 px2 = -x2;
                 px3 = -x3;
                 py1 = y1;
                 py2 = y2;
                 py3 = y3;
                 break;
               case 4:
                 px1 = y1;
                 px2 = y2;
                 px3 = y3;
                 py1 = x1;
                 py2 = x2;
                 py3 = x3;
                 break;
               case 5:
                 px1 = y1;
                 px2 = y2;
                 px3 = y3;
                 py1 = -x1;
                 py2 = -x2;
                 py3 = -x3;
                 break;
               case 6:
                 px1 = -y1;
                 px2 = -y2;
                 px3 = -y3;
                 py1 = -x1;
                 py2 = -x2;
                 py3 = -x3;
                 break;
               default:
                 px1 = -y1;
                 px2 = -y2;
                 px3 = -y3;
                 py1 = x1;
                 py2 = x2;
                 py3 = x3;
                 break;
             }

             // Create points that define polygon (x,y).
             Point point1 = new Point((int)(CenterX + px1), (int)(CenterY + py1));
             Point point2 = new Point((int)(CenterX + px2), (int)(CenterY + py2));
             Point point3 = new Point((int)(CenterX + px3), (int)(CenterY + py3));
             Point[] Piece = { point1, point2, point3 };
             dstArgs.Graphics.FillPolygon(myBrush, Piece);
           }
         }
       }
     }
   }

   public override EffectConfigDialog CreateConfigDialog()
   {
     ThreeAmountsConfigDialog dialog = new ThreeAmountsConfigDialog();
     dialog.Amount1Label = Strings.KaleidoGen_Amount1_Name;
     dialog.Amount1Minimum = +1;
     dialog.Amount1Maximum = +100;
     dialog.Amount1Default = 10;

     dialog.Amount2Label = Strings.KaleidoGen_Amount2_Name;
     dialog.Amount2Minimum = -200;
     dialog.Amount2Maximum = +200;
     dialog.Amount2Default = 50;

     dialog.Amount3Label = Strings.KaleidoGen_Amount3_Name;
     dialog.Amount3Minimum = +1;
     dialog.Amount3Maximum = +1000;
     dialog.Amount3Default = 300;

     dialog.Text = Strings.KaleidoGen_Name;

     return dialog;
   }
   public KaleidoGen()
     : base(Strings.KaleidoGen_Name, Resources.KaleidoGen, null, EffectDirectives.None, true)
   {
   }

 }
}

As you could see I use the Clip...

Link to comment
Share on other sites

MadJik, sure, you are using clipping, but I do not believe you are using it correctly.

You are clipping to your selection not to your ROI.

Remember, your render routine is being passed in an ARRAY of rectangles of interest (ROI). You are not processing through all of them. As you do, you need to clip to each one of them as you are rendering the image.

Link to comment
Share on other sites

I've moved down the 'clip' instruction in the ROI for/loop.

It seems a bit better, but still not enought for publishing...

I give up for now on this projet.

This is the last source version.

If anyone got a better solution, please let me know on this topic...

The DLL is included in the zip...

Don't add this version in the PPP

test001.png

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...