/// 如果端点在前,返回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; } }
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 }