コード例 #1
0
        //Input: Light list, graphics g, Physical object, screen index, medium index
        //Output: Change the Light list to the path casued by the Medium
        public static void MediumAlgoritem(List <Light> lightList, Graphics g, PhysicalObject obj, double n1, double n2)
        {
            Light  last       = lightList[lightList.Count - 1];
            PointF pi         = last.pi;
            PointF pf         = last.pf;
            PointF firstPoint = new PointF(pi.X, pi.Y);
            Color  lightColor = last.LightColor;
            Region mediumReg  = obj.GetRegion();
            Region rayReg     = last.GetRegion();
            double angle      = last.GetAngle();

            mediumReg.Intersect(rayReg); //Intersect area of lens and the last light
            if (!mediumReg.IsEmpty(g))
            {
                PointF hit = GetHitPoint(pf, mediumReg, g);
                bool   oppSide = false, isCritical = false;

                double alpha = 0, beta = 0, tempBeta = 0, criticalAngle = 0;//angles

                //getting hiting angle using math
                PointF[] points = obj.GetPoints();
                Light    first  = new Light(firstPoint, hit);
                Light    second = new Light(firstPoint, hit);//need to modified
                if (points.Length == 2)
                {
                    second = new Light(points[0], points[1]);
                }
                alpha = 90 - MathHelper.AngleBetweenLights(first, second);
                //

                if ((firstPoint.X - hit.X) * (obj.X - hit.X) > 0)
                {
                    oppSide = true;
                }

                //calculate critical angle
                if (!oppSide)
                {
                    if (n1 > n2)
                    {
                        criticalAngle = Math.Round(Math.Asin(n2 / n1) * 180 / Math.PI);
                    }
                    isCritical = criticalAngle != 0 && alpha >= criticalAngle;
                }
                else
                {
                    if (n2 > n1)
                    {
                        criticalAngle = Math.Round(Math.Asin(n1 / n2) * 180 / Math.PI);
                    }
                    isCritical = criticalAngle != 0 && alpha >= criticalAngle;
                }
                //

                if (isCritical)//act like a mirror
                {
                    MirrorAlgoritem(lightList, g, obj);
                }
                else
                {
                    if (!oppSide)
                    {
                        beta     = (Math.Asin(n1 / n2 * Math.Sin(alpha * Math.PI / 180)) * 180 / Math.PI); //snal law
                        beta     = Math.Round(beta);
                        tempBeta = beta;                                                                   //save beta value
                    }
                    else //opposite side
                    {
                        beta     = (Math.Asin(n2 / n1 * Math.Sin(alpha * Math.PI / 180)) * 180 / Math.PI); //snal law
                        tempBeta = Math.Round(beta);                                                       //save beta value
                        beta     = 180 - Math.Round(beta);
                    }
                    //fix light direction
                    float dirction = (firstPoint.Y - hit.Y) / (firstPoint.X - hit.X);
                    dirction = Math.Abs(dirction) / dirction;
                    if (oppSide)
                    {
                        dirction *= -1;
                    }
                    if (dirction == 1)
                    {
                        beta = 360 - beta;
                    }
                    //

                    if (alpha % 90 != 0)
                    {
                        lightList[lightList.Count - 1] = new Light(firstPoint, hit, lightColor);//light from the start to the hit point
                        lightList.Add(new Light(hit, MathHelper.GetEndLight(hit, beta + obj.Angle), lightColor));
                    }
                }
                //give information to data class
                if (Main_Form.highlightedIndex != -1)
                {
                    PhysicalObject highlighted = Main_Form.objectsList[Main_Form.highlightedIndex];
                    if (highlighted == obj)
                    {
                        MediumInfo.alphaAngle    = alpha;
                        MediumInfo.betaAngle     = tempBeta;
                        MediumInfo.mediumIndex   = n2;
                        MediumInfo.criticalAngle = criticalAngle;
                    }
                }
            }
        }
コード例 #2
0
        //Input: Light list, graphics g and a Physical object
        //Output: Change the Light list to the path casued by the Mirror
        public static void MirrorAlgoritem(List <Light> lightList, Graphics g, PhysicalObject obj)
        {
            Light  last       = lightList[lightList.Count - 1];
            PointF pi         = last.pi;
            PointF pf         = last.pf;
            PointF firstPoint = new PointF(pi.X, pi.Y);
            Color  lightColor = last.LightColor;
            Region mirrorReg  = obj.GetRegion();
            Region rayReg     = last.GetRegion();
            double angle      = last.GetAngle();
            bool   vertical   = false;


            mirrorReg.Intersect(rayReg); //Intersect area of lens and the last light
            if (!mirrorReg.IsEmpty(g))
            {
                PointF hit = GetHitPoint(pf, mirrorReg, g);

                lightList[lightList.Count - 1] = new Light(pi, hit, lightColor); //light from the start to the hit point

                double alpha = 180 - (angle - 2 * obj.Angle);

                //check if the light hiting the vertical part of the mirror
                PointF[] points = obj.GetPoints();
                if (points.Length == 4)
                {
                    PointF p1     = points[0];
                    PointF p2     = points[1];
                    PointF p3     = points[2];
                    PointF p4     = points[3];
                    float  x      = hit.X;
                    float  y      = hit.Y;
                    bool   check1 = x >= Math.Min(p1.X, p4.X) && x <= Math.Max(p1.X, p4.X) && y >= Math.Min(p1.Y, p4.Y) && y <= Math.Max(p1.Y, p4.Y);
                    bool   check2 = x >= Math.Min(p2.X, p3.X) && x <= Math.Max(p2.X, p3.X) && y >= Math.Min(p2.Y, p3.Y) && y <= Math.Max(p2.Y, p3.Y);
                    vertical = check1 || check2;
                    if (vertical)
                    {
                        alpha += 180;
                    }
                }
                lightList.Add(new Light(hit, MathHelper.GetEndLight(hit, alpha), lightColor)); //light from the hit point farther

                //draw image and give info
                Color  imageColor = Color.Blue;
                Mirror mirror     = obj as Mirror;
                if (mirror != null && mirror.ShowImage)
                {
                    //calc image
                    imageColor = mirror.ImageColor;
                    double beta      = alpha + 180;
                    double radius    = MathHelper.DistanceBetweenPointF(hit, firstPoint);
                    float  height    = (float)(radius * Math.Sin(beta * Math.PI / 180));
                    float  width     = (float)(radius * Math.Cos(beta * Math.PI / 180));
                    float  addWidth  = obj.X - hit.X;
                    float  addHeight = obj.Y - hit.Y;
                    //

                    //draw image
                    PointF imagePoint    = new PointF(obj.X + width + addWidth, obj.Y - height + addHeight);
                    double angleToRotate = obj.Angle;
                    if (angleToRotate >= 180 && angleToRotate <= 360)
                    {
                        angleToRotate = angleToRotate + 180;
                    }
                    imagePoint = MathHelper.RotatePointF(imagePoint, obj.CenterPoint, angleToRotate);
                    g.FillEllipse(new SolidBrush(imageColor), imagePoint.X - 5, imagePoint.Y - 5, 10, 10);
                    //

                    //give information to data class
                    if (Main_Form.highlightedIndex != -1)
                    {
                        PhysicalObject highlighted = Main_Form.objectsList[Main_Form.highlightedIndex];
                        if (highlighted == obj)
                        {
                            MirrorInfo.startPoint = firstPoint;
                            //MirrorInfo.imagePoint = imagePoint;
                        }
                    }
                }
                //
            }
        }