Пример #1
0
        /// 如果端点在前,返回true,否则是false
        /// <param name="ray"></param>
        /// <param name="p1">端点</param>
        /// <param name="p2">交点</param>
        private static void HitLineSeg(Ray ray, uint line, out Point p1, out Point p2, out bool b1, out bool b2)
        {
            LineSeg lineSeg = new LineSeg(ray.Origin, ray.NormalDirection * (float.MaxValue / 10000) + ray.Origin,
                                          LineSegs[line].Normal, 0);
            float p1l = ray.Direction.Magnitude();
            float p2l = float.MaxValue;

            p1 = new Point(LineSegs[line].Material, line, ray.Direction + ray.Origin);
            p2 = new Point();
            b1 = true;
            b2 = false;
            for (uint i = 0; i < LineSegs.Length; i++)
            {
                if (line == i)
                {
                    continue;
                }
                if (!LineSeg.IsIntersect(lineSeg, LineSegs[i], out Vector2 vector2))
                {
                    continue;
                }
                if (vector2 == p1.Position)
                {
                    continue;
                }
                if (vector2 == LineSegs[i].P1 || vector2 == LineSegs[i].P2)
                {
                    continue;
                }
                float l = (ray.Origin - vector2).Magnitude();
                if (l < p1l && b1)
                {
                    b1 = false;
                }
                if (l < p2l)
                {
                    p2l = l;
                    if (l < p1l || LineSegs[i].Normal * (ray.Origin - LineSegs[i].Position) < 0)
                    {
                        b2 = false;
                        continue;
                    }
                    p2 = new Point(LineSegs[i].Material, i, vector2);
                    b2 = true;
                }
            }
            if (b2 && (p2.Position == LineSegs[p2.Line].P1 || p2.Position == LineSegs[p2.Line].P2))
            {
                b2 = false;
            }
        }
Пример #2
0
        private static void Sampling(int x, int y, bool debug = false)
        {
            Vector2 Origin = new Vector2(x, y);
            Color32 color  = new Color32();

            if (World.IsInside(Origin, out Point p))
            {
                color = Materials[p.Materail].GetColor();
                Buff[y * Width * 4 + x * 4]     = color.B;
                Buff[y * Width * 4 + x * 4 + 1] = color.G;
                Buff[y * Width * 4 + x * 4 + 2] = color.R;
                Buff[y * Width * 4 + x * 4 + 3] = 1;
                return;
            }
            List <Point>[] points = new List <Point> [LineSegs.Length];
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new List <Point>();
            }
            foreach (LineSeg lineSeg in LineSegs)
            {
                float l = lineSeg.Normal * (Origin - lineSeg.Position);
                if (l < 0)
                {
                    continue;
                }
                bool isOnline = l == 0;
                HitLineSeg(new Ray(Origin, lineSeg.P1 - Origin), lineSeg.ID, out Point p1,
                           out Point p2, out bool b1, out bool b2);
                if (!isOnline)
                {
                    HitLineSeg(new Ray(Origin, lineSeg.P2 - Origin), lineSeg.ID, out Point p3,
                               out Point p4, out bool b3, out bool b4);
                    if (b3)
                    {
                        points[p3.Line].Add(p3);
                    }
                    if (b4)
                    {
                        points[p4.Line].Add(p4);
                    }
                }
                if (b1)
                {
                    points[p1.Line].Add(p1);
                }
                if (b2)
                {
                    points[p2.Line].Add(p2);
                }
            }

            foreach (List <Point> point in points)
            {
                if (point.Count < 2)
                {
                    continue;
                }
                if (point.Count == 2)
                {
                    if (point[0].Position == point[1].Position)
                    {
                        continue;
                    }
                    color += Math.Abs(Vector2.Angle(point[0].Position - Origin, point[1].Position - Origin)) /
                             Mathf.TwoPi * Materials[point[0].Materail].GetColor();
                    continue;
                }
                Point lastPoint = point[0];
                for (int i = 0; i < point.Count; i++)
                {
                    Point p1 = point[i];
                    if (p1.Position == lastPoint.Position && i != 0)
                    {
                        point.RemoveAt(i--);
                        continue;
                    }
                    lastPoint   = p1;
                    p1.Distance = (LineSegs[p1.Line].P1 - p1.Position).Magnitude();
                    point[i]    = p1;
                }
                if (point.Count % 2 == 1)
                {
                    continue;
                }
                point.Sort();
                for (int i = 0; i < point.Count; i += 2)
                {
                    color += Math.Abs(Vector2.Angle(point[i].Position - Origin, point[i + 1].Position - Origin)) /
                             Mathf.TwoPi * Materials[point[i].Materail].GetColor();
                }
            }

            Buff[y * Width * 4 + x * 4]     = color.B;
            Buff[y * Width * 4 + x * 4 + 1] = color.G;
            Buff[y * Width * 4 + x * 4 + 2] = color.R;
            Buff[y * Width * 4 + x * 4 + 3] = 1;

            #region debug

            //if (debug)
            //{
            //    foreach (List<Point> point in points)
            //    {
            //        if (point.Count % 2 == 1 && point.Count != 1)
            //        {
            //            Console.WriteLine(new Vector2(x, y));
            //            //foreach (Point point1 in point)
            //            //{
            //            //    DrawLine(LineSegs[point1.Line].P1, LineSegs[point1.Line].P2, new Color32(0, 0, 1));
            //            //}
            //            //foreach (Point point1 in point)
            //            //{
            //            //    DrawLine(Origin, point1.Position, new Color32(0, 0, 1));
            //            //}
            //            continue;
            //        }
            //        foreach (Point point1 in point)
            //        {
            //            DrawLine(Origin, point1.Position, new Color32(0, 1, 0));
            //        }
            //    }
            //}

            #endregion
        }