예제 #1
0
 public MyEdge(float _YMax, float _XMin, float _Coef, MyEdge _Next)
 {
     YMax        = _YMax;
     XMin        = _XMin;
     Coefficient = _Coef;
     Next        = _Next;
 }
예제 #2
0
 public MyEdge()
 {
     YMax        = 0;
     XMin        = 0;
     Coefficient = 0;
     Next        = null;
 }
예제 #3
0
        public MyEdge MergeSort(MyEdge head)
        {
            if (head == null || head.Next == null)
            {
                return(head);
            }
            MyEdge middle = GetMiddle(head);      //get the middle of the list
            MyEdge sHalf  = middle.Next;

            middle.Next = null;                               //split the list into two halfs

            return(Merge(MergeSort(head), MergeSort(sHalf))); //recurse on that
        }
예제 #4
0
        //Finding the middle element of the list for splitting
        public MyEdge GetMiddle(MyEdge head)
        {
            if (head == null)
            {
                return(head);
            }
            MyEdge slow, fast; slow = fast = head;

            while (fast.Next != null && fast.Next.Next != null)
            {
                slow = slow.Next; fast = fast.Next.Next;
            }
            return(slow);
        }
예제 #5
0
        //Merge subroutine to merge two sorted lists
        public MyEdge Merge(MyEdge a, MyEdge b)
        {
            MyEdge dummyHead = new MyEdge();
            MyEdge curr      = dummyHead;

            while (a != null && b != null)
            {
                if (a.XMin <= b.XMin)
                {
                    curr.Next = a; a = a.Next;
                }
                else
                {
                    curr.Next = b; b = b.Next;
                }
                curr = curr.Next;
            }
            curr.Next = (a == null) ? b : a;
            return(dummyHead.Next);
        }
예제 #6
0
        public void FillScanLines()
        {
            int y = 0;
            int R, G, B;

            float cosNL;
            float lighVectLen;
            float normVectLen;
            float distLen;
            float refVectLen;
            float refPointVectLen;
            float cosVrVp;

            float[] Vr = new float[3];
            float[] Vp = new float[3];

            Point RefPos = new Point(WorkspacePictureBox.Image.Width / 2, WorkspacePictureBox.Image.Height / 2);

            Color objCol;
            Color objCol2;
            Color ligCol = LightColorBoxPB.BackColor;
            Color normVectCol;
            Color distPix;
            Color distNX;
            Color distNY;

            MyEdge temp = null;

            UpdateEdges();
            Bitmap bitmap = new Bitmap(WorkspacePictureBox.Width, WorkspacePictureBox.Height);

            while (GET[y] == null && GET2[y] == null)
            {
                y++;
            }
            AET  = null;
            AET2 = null;
            while (y < WorkspacePictureBox.Height)
            {
                // Add lists from y bucket to AET
                if (GET[y] != null && AET == null)
                {
                    AET = GET[y];
                }
                else if (AET != null)
                {
                    if (GET[y] != null)
                    {
                        temp = AET;
                        while (temp.Next != null)
                        {
                            temp = temp.Next;
                        }
                        temp.Next = GET[y];
                    }

                    // Sort AET by x
                    AET = MergeSort(AET);

                    // TO_TEST Remove from AET elems for which y = yMax
                    temp = AET;
                    while (temp != null && temp.Next != null)
                    {
                        if (temp.Next.YMax <= y)
                        {
                            temp.Next = temp.Next.Next;
                        }
                        temp = temp.Next;
                    }

                    if (AET.YMax <= y)
                    {
                        AET = AET.Next;
                    }

                    if (AET != null && AET.YMax <= y)
                    {
                        AET = AET.Next;
                    }

                    // Fill pixs between crossings
                    temp = AET;

                    while (temp != null && temp.Next != null)
                    {
                        for (int i = (int)temp.XMin; i < temp.Next.XMin; i++)
                        {
                            if (Tri1ColConstRB.Checked)
                            {
                                objCol = Tri1ColorBoxPB.BackColor;
                            }
                            else    // From texture
                            {
                                objCol = tri1ColText.GetPixel(i % (tri1ColText.Width - 1) + 1, y % (tri1ColText.Height - 1) + 1);
                            }

                            Point mouse = PointToClient(MousePosition);

                            // Bąbelek aka "bubble"
                            if (BubbleCB.Checked && (i - PointToClient(MousePosition).X) * (i - PointToClient(MousePosition).X) + (y - PointToClient(MousePosition).Y) * (y - PointToClient(MousePosition).Y) <= r * r)
                            {
                                // Oblicznie wektorów bąbelka
                                N[2]  = (float)Math.Sqrt(r * r - Math.Sqrt(i * i + y * y));
                                N[0]  = (i - mouse.X) / N[2];
                                N[1]  = (y - mouse.Y) / N[2];
                                N[2] /= N[2];
                            }
                            else if (NormalVectTextRB.Checked)
                            {
                                normVectCol = normVectText.GetPixel(i % (normVectText.Width), y % (normVectText.Height));
                                N[2]        = normVectCol.B;
                                N[0]        = (normVectCol.R - 127) / N[2];
                                N[1]        = (normVectCol.G - 127) / N[2];
                                N[2]       /= N[2];
                            }
                            else
                            {
                                N = new float[] { 0, 0, 1 }
                            };

                            if (DisturbTextRB.Checked)
                            {
                                distPix = disturbText.GetPixel(i % (disturbText.Width), y % (disturbText.Height));
                                distNX  = disturbText.GetPixel((i + 1) % (disturbText.Width), y % (disturbText.Height));
                                distNY  = disturbText.GetPixel(i % (disturbText.Width), (y + 1) % (disturbText.Height));

                                D[0]    = 1 * ((distNX.R + distNX.G + distNX.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                D[1]    = 1 * ((distNY.R + distNY.G + distNY.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                D[2]    = -N[0] * ((distNX.R + distNX.G + distNX.B) - (distPix.R + distPix.G + distPix.B)) / 3 - N[1] * ((distNY.R + distNY.G + distNY.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                distLen = (float)Math.Sqrt(D[0] * D[0] + D[1] * D[1] + D[2] * D[2]);
                                if (distLen != 0)
                                {
                                    D[0] /= distLen;
                                    D[1] /= distLen;
                                    D[2] /= distLen;
                                }
                            }

                            Np[0]       = N[0] + D[0];
                            Np[1]       = N[1] + D[1];
                            Np[2]       = N[2] + D[2];
                            normVectLen = (float)Math.Sqrt(Np[0] * Np[0] + Np[1] * Np[1] + Np[2] * Np[2]);

                            Np[0] /= normVectLen;
                            Np[1] /= normVectLen;
                            Np[2] /= normVectLen;

                            if (LighSourVectAnimRB.Checked)
                            {
                                L[0]        = lightPos[0] - i;
                                L[1]        = lightPos[1] - y;
                                L[2]        = 100f;
                                lighVectLen = (float)Math.Sqrt(L[0] * L[0] + L[1] * L[1] + L[2] * L[2]);

                                L[0] /= lighVectLen;
                                L[1] /= lighVectLen;
                                L[2] /= lighVectLen;
                            }

                            cosNL = Math.Max(0, (Np[0] * L[0] + Np[1] * L[1] + Np[2] * L[2]));

                            // Normalized (both divided by 255) and denormalized (result multiplied by 255)
                            R = (int)(objCol.R / 255f * ligCol.R * cosNL);
                            G = (int)(objCol.G / 255f * ligCol.G * cosNL);
                            B = (int)(objCol.B / 255f * ligCol.B * cosNL);

                            if (ReflectorCB.Checked)
                            {
                                Vr[0]      = mouse.X - RefPos.X;
                                Vr[1]      = mouse.Y - RefPos.Y;
                                Vr[2]      = refHeight;
                                refVectLen = (float)Math.Sqrt(Vr[0] * Vr[0] + Vr[1] * Vr[1] + Vr[2] * Vr[2]);
                                Vr[0]     /= refVectLen;
                                Vr[1]     /= refVectLen;
                                Vr[2]     /= refVectLen;

                                Vp[0]           = i - RefPos.X;
                                Vp[1]           = y - RefPos.Y;
                                Vp[2]           = refHeight;
                                refPointVectLen = (float)Math.Sqrt(Vp[0] * Vp[0] + Vp[1] * Vp[1] + Vp[2] * Vp[2]);
                                Vp[0]          /= refPointVectLen;
                                Vp[1]          /= refPointVectLen;
                                Vp[2]          /= refPointVectLen;

                                cosVrVp = Vr[0] * Vp[0] + Vr[1] * Vp[1] + Vr[2] * Vp[2];
                                cosVrVp = (float)Math.Pow(cosVrVp, K);
                                R       = (int)(R * (1 + cosVrVp));
                                G       = (int)(G * (1 + cosVrVp));
                                B       = (int)(B * (1 + cosVrVp));
                                if (R > 255)
                                {
                                    R = 255;
                                }
                                if (G > 255)
                                {
                                    G = 255;
                                }
                                if (B > 255)
                                {
                                    B = 255;
                                }
                            }

                            bitmap.SetPixel(i, y, Color.FromArgb(R, G, B));
                        }
                        temp = temp.Next.Next;
                    }
                    // For each edge in AET update x (x+=1/m)
                    temp = AET;
                    while (temp != null)
                    {
                        temp.XMin += temp.Coefficient;
                        temp       = temp.Next;
                    }
                }

                // TRIANGLE no 2, not DRY
                temp = null;
                // Add lists from y bucket to AET
                if (GET2[y] != null && AET2 == null)
                {
                    AET2 = GET2[y];
                }
                else if (AET2 != null)
                {
                    if (GET2[y] != null)
                    {
                        temp = AET2;
                        while (temp.Next != null)
                        {
                            temp = temp.Next;
                        }
                        temp.Next = GET2[y];
                    }

                    // Sort AET by x
                    AET2 = MergeSort(AET2);

                    // TO_TEST Remove from AET elems for which y = yMax
                    temp = AET2;
                    while (temp != null && temp.Next != null)
                    {
                        if (temp.Next.YMax <= y)
                        {
                            temp.Next = temp.Next.Next;
                        }
                        temp = temp.Next;
                    }

                    if (AET2.YMax <= y)
                    {
                        AET2 = AET2.Next;
                    }

                    if (AET2 != null && AET2.YMax <= y)
                    {
                        AET2 = AET2.Next;
                    }

                    // Fill pixs between crossings
                    temp = AET2;

                    while (temp != null && temp.Next != null)
                    {
                        for (int i = (int)temp.XMin; i < temp.Next.XMin; i++)
                        {
                            if (Tri2ColConstRB.Checked)
                            {
                                objCol2 = Tri2ColorBoxPB.BackColor;
                            }
                            else    // From texture
                            {
                                objCol2 = tri2ColText.GetPixel(i % (tri2ColText.Width - 1) + 1, y % (tri2ColText.Height - 1) + 1);
                            }

                            Point mouse = PointToClient(MousePosition);
                            // Bąbelek aka "bubble"
                            if (BubbleCB.Checked && (i - PointToClient(MousePosition).X) * (i - PointToClient(MousePosition).X) + (y - PointToClient(MousePosition).Y) * (y - PointToClient(MousePosition).Y) <= r * r)
                            {
                                N[2]  = (float)Math.Sqrt(r * r - Math.Sqrt(i * i + y * y));
                                N[0]  = (i - mouse.X) / N[2];
                                N[1]  = (y - mouse.Y) / N[2];
                                N[2] /= N[2];
                            }
                            else if (NormalVectTextRB.Checked)
                            {
                                normVectCol = normVectText.GetPixel(i % (normVectText.Width), y % (normVectText.Height));
                                N[2]        = normVectCol.B;
                                N[0]        = (normVectCol.R - 127) / N[2];
                                N[1]        = (normVectCol.G - 127) / N[2];
                                N[2]       /= N[2];
                            }
                            else
                            {
                                N = new float[] { 0, 0, 1 }
                            };

                            if (DisturbTextRB.Checked)
                            {
                                distPix = disturbText.GetPixel(i % (disturbText.Width), y % (disturbText.Height));
                                distNX  = disturbText.GetPixel((i + 1) % (disturbText.Width), y % (disturbText.Height));
                                distNY  = disturbText.GetPixel(i % (disturbText.Width), (y + 1) % (disturbText.Height));

                                D[0]    = 1 * ((distNX.R + distNX.G + distNX.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                D[1]    = 1 * ((distNY.R + distNY.G + distNY.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                D[2]    = -N[0] * ((distNX.R + distNX.G + distNX.B) - (distPix.R + distPix.G + distPix.B)) / 3 - N[1] * ((distNY.R + distNY.G + distNY.B) - (distPix.R + distPix.G + distPix.B)) / 3;
                                distLen = (float)Math.Sqrt(D[0] * D[0] + D[1] * D[1] + D[2] * D[2]);
                                if (distLen != 0)
                                {
                                    D[0] /= distLen;
                                    D[1] /= distLen;
                                    D[2] /= distLen;
                                }
                            }


                            Np[0]       = N[0] + D[0];
                            Np[1]       = N[1] + D[1];
                            Np[2]       = N[2] + D[2];
                            normVectLen = (float)Math.Sqrt(Np[0] * Np[0] + Np[1] * Np[1] + Np[2] * Np[2]);

                            Np[0] /= normVectLen;
                            Np[1] /= normVectLen;
                            Np[2] /= normVectLen;

                            if (LighSourVectAnimRB.Checked)
                            {
                                L[0]        = lightPos[0] - i;
                                L[1]        = lightPos[1] - y;
                                L[2]        = 100f;
                                lighVectLen = (float)Math.Sqrt(L[0] * L[0] + L[1] * L[1] + L[2] * L[2]);

                                L[0] /= lighVectLen;
                                L[1] /= lighVectLen;
                                L[2] /= lighVectLen;
                            }

                            cosNL = Math.Max(0, (Np[0] * L[0] + Np[1] * L[1] + Np[2] * L[2]));

                            // Normalized (both divided by 255) and denormalized (result multiplied by 255)
                            R = (int)(objCol2.R / 255f * ligCol.R * cosNL);
                            G = (int)(objCol2.G / 255f * ligCol.G * cosNL);
                            B = (int)(objCol2.B / 255f * ligCol.B * cosNL);


                            if (ReflectorCB.Checked)
                            {
                                Vr[0]      = mouse.X - RefPos.X;
                                Vr[1]      = mouse.Y - RefPos.Y;
                                Vr[2]      = refHeight;
                                refVectLen = (float)Math.Sqrt(Vr[0] * Vr[0] + Vr[1] * Vr[1] + Vr[2] * Vr[2]);
                                Vr[0]     /= refVectLen;
                                Vr[1]     /= refVectLen;
                                Vr[2]     /= refVectLen;

                                Vp[0]           = i - RefPos.X;
                                Vp[1]           = y - RefPos.Y;
                                Vp[2]           = refHeight;
                                refPointVectLen = (float)Math.Sqrt(Vp[0] * Vp[0] + Vp[1] * Vp[1] + Vp[2] * Vp[2]);
                                Vp[0]          /= refPointVectLen;
                                Vp[1]          /= refPointVectLen;
                                Vp[2]          /= refPointVectLen;

                                cosVrVp = Vr[0] * Vp[0] + Vr[1] * Vp[1] + Vr[2] * Vp[2];
                                cosVrVp = (float)Math.Pow(cosVrVp, K);
                                R       = (int)(R * (1 + cosVrVp));
                                G       = (int)(G * (1 + cosVrVp));
                                B       = (int)(B * (1 + cosVrVp));
                                if (R > 255)
                                {
                                    R = 255;
                                }
                                if (G > 255)
                                {
                                    G = 255;
                                }
                                if (B > 255)
                                {
                                    B = 255;
                                }
                            }

                            bitmap.SetPixel(i, y, Color.FromArgb(R, G, B));
                        }
                        temp = temp.Next.Next;
                    }
                    // For each edge in AET update x (x+=1/m)
                    temp = AET2;
                    while (temp != null)
                    {
                        temp.XMin += temp.Coefficient;
                        temp       = temp.Next;
                    }
                }
                y++;
            }
            WorkspacePictureBox.Image.Dispose();
            WorkspacePictureBox.Image = bitmap;
        }
예제 #7
0
        public void UpdateEdges()
        {
            float  x1 = Points[0].X, y1 = Points[0].Y;
            float  x2 = Points[1].X, y2 = Points[1].Y;
            float  coef = (x2 - x1) / (y2 - y1);
            MyEdge temp = new MyEdge(Math.Max(Points[0].Y, Points[1].Y), Points[Points[0].Y < Points[1].Y ? 0 : 1].X, coef, null);
            int    iNext;

            float  x3 = Points[3].X, y3 = Points[3].Y;
            float  x4 = Points[4].X, y4 = Points[4].Y;
            float  coef2 = (x4 - x3) / (y4 - y3);
            MyEdge temp2 = new MyEdge(Math.Max(Points[3].Y, Points[4].Y), Points[Points[3].Y < Points[4].Y ? 3 : 4].X, coef2, null);
            int    iNext2;

            for (int i = 0; i < GET.Length; i++)
            {
                GET[i]  = null;
                GET2[i] = null;
            }

            GET[(int)Math.Min(Points[0].Y, Points[1].Y)] = temp;
            GET2[(int)Math.Min(y3, y4)] = temp2;

            for (int i = 1; i < Points.Length / 2; i++)
            {
                if (i == 2)
                {
                    iNext  = 0;
                    iNext2 = 3;
                }
                else
                {
                    iNext  = i + 1;
                    iNext2 = iNext + 3;
                }
                x1   = Points[i].X;
                y1   = Points[i].Y;
                x2   = Points[iNext].X;
                y2   = Points[iNext].Y;
                coef = (x2 - x1) / (y2 - y1);

                x3    = Points[i + 3].X;
                y3    = Points[i + 3].Y;
                x4    = Points[iNext2].X;
                y4    = Points[iNext2].Y;
                coef2 = (x4 - x3) / (y4 - y3);

                int ind = (int)Math.Min(Points[i].Y, Points[iNext].Y);
                if (Points[i].Y != Points[iNext].Y)
                {
                    if (GET[ind] == null)
                    {
                        GET[ind] = new MyEdge(Math.Max(Points[i].Y, Points[iNext].Y), Points[Points[i].Y < Points[iNext].Y ? i : iNext].X, coef, null);
                    }
                    else
                    {
                        temp = GET[ind];
                        while (temp.Next != null)
                        {
                            temp = temp.Next;
                        }
                        temp.Next = new MyEdge(Math.Max(Points[i].Y, Points[iNext].Y), Points[Points[i].Y < Points[iNext].Y ? i : iNext].X, coef, null);
                    }
                }

                int ind2 = (int)Math.Min(Points[i + 3].Y, Points[iNext2].Y);
                if (Points[i + 3].Y != Points[iNext2].Y)
                {
                    if (GET2[ind2] == null)
                    {
                        GET2[ind2] = new MyEdge(Math.Max(Points[i + 3].Y, Points[iNext2].Y), Points[Points[i + 3].Y < Points[iNext2].Y ? i + 3 : iNext2].X, coef2, null);
                    }
                    else
                    {
                        temp = GET2[ind2];
                        while (temp.Next != null)
                        {
                            temp = temp.Next;
                        }
                        temp.Next = new MyEdge(Math.Max(Points[i + 3].Y, Points[iNext2].Y), Points[Points[i + 3].Y < Points[iNext2].Y ? i + 3 : iNext2].X, coef2, null);
                    }
                }
            }
        }