private static Vector3?Intersects(Ray3 ray, BuildingWallSegment wallSegment) { var height = ray.Point.Y; if (height < wallSegment.Basement.Point1.Y || height > wallSegment.Basement.Point1.Y + wallSegment.Height) { return(null); } var ray2D = new Ray2(ray.Point.Xz, ray.Direction.Xz.Normalize()); var wallSeg2D = new LineSegment2(wallSegment.Basement.Point1.Xz, wallSegment.Basement.Point2.Xz); var inter2D = wallSeg2D.Intersect(ray2D); if (!inter2D.HasValue) { return(null); } return(new Vector3(inter2D.Value.X, ray.Point.Y, inter2D.Value.Y)); }
private static void GetExternalPart(LineSegment3 segment, BuildingPrimitive primitive, List <LineSegment3> results) { var invTransform = primitive.Transform.Invert(); var transformedSeg = new LineSegment3(segment.Point1 * invTransform, segment.Point2 * invTransform); var seg = new LineSegment2(transformedSeg.Point1.Xz, transformedSeg.Point2.Xz); if (primitive.Type == BuildingPrimitiveType.Rectangle) { var rect = new AaRectangle2(Vector2.Zero, primitive.Scale.X, primitive.Scale.Z); var conains1 = rect.ContainsPoint(seg.Point1); var conains2 = rect.ContainsPoint(seg.Point2); if (conains1 && conains2) { return; } if (!conains1 && !conains2) { var p = Vector2.Zero; int c = 0; foreach (var rectSegment in rect.GetSegments()) { var rsi = rectSegment.Intersect(seg); if (rsi.HasValue) { p += rsi.Value; c++; } } if (c > 0) { var t = ((p / c) - seg.Point1).Length() / (seg.Point2 - seg.Point1).Length(); var m = segment.Point1 + (segment.Point2 - segment.Point1) * t; GetExternalPart(new LineSegment3(segment.Point1, m), primitive, results); GetExternalPart(new LineSegment3(m, segment.Point2), primitive, results); return; } results.Add(segment); return; } var swap = conains1; if (swap) { CodingHelper.Swap(ref seg.Point1, ref seg.Point2); } var inter = seg.Intersect(new LineSegment2( new Vector2(-primitive.Scale.X, -primitive.Scale.Z), new Vector2(-primitive.Scale.X, primitive.Scale.Z))); if (inter.HasValue) { var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap); results.Add(rs1); return; } inter = seg.Intersect(new LineSegment2( new Vector2(primitive.Scale.X, -primitive.Scale.Z), new Vector2(primitive.Scale.X, primitive.Scale.Z))); if (inter.HasValue) { var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap); results.Add(rs1); return; } inter = seg.Intersect(new LineSegment2( new Vector2(-primitive.Scale.X, primitive.Scale.Z), new Vector2(primitive.Scale.X, primitive.Scale.Z))); if (inter.HasValue) { var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap); results.Add(rs1); return; } inter = seg.Intersect(new LineSegment2( new Vector2(-primitive.Scale.X, -primitive.Scale.Z), new Vector2(primitive.Scale.X, -primitive.Scale.Z))); if (inter.HasValue) { var rs1 = To3(seg.Point1, inter.Value, primitive.Transform, swap); results.Add(rs1); return; } var rs2 = segment; results.Add(rs2); return; } else { var circle = new Circle2(Vector2.Zero, primitive.Scale.X); var conains1 = circle.Contains(seg.Point1); var conains2 = circle.Contains(seg.Point2); if (conains1 && conains2) { return; } if (!conains1 && !conains2) { var rs1 = segment; results.Add(rs1); return; } var swap = conains1; if (swap) { CodingHelper.Swap(ref seg.Point1, ref seg.Point2); } var dpp = seg.Point2 - seg.Point1; var dpc = seg.Point1; var a = dpp.LengthSquared(); var b = Vector2.Dot(dpp, dpc); var c = dpc.LengthSquared() - circle.Radius.Sq(); var discr = b * b - a * c; if (discr < 0) { results.Add(segment); return; } if (discr < MathHelper.Eps5) { results.Add(segment); return; //var l = -b / a; //if (0 <= l && l <= 1) } { var sqrdscr = MathHelper.Sqrt(discr); var l1 = (-b + sqrdscr) / a; var l2 = (-b - sqrdscr) / a; if (0 <= l1 && l1 <= 1) { var rs1 = To3(seg.Point1, Vector2.Lerp(seg.Point1, seg.Point2, l1), primitive.Transform, swap); results.Add(rs1); } if (0 <= l2 && l2 <= 1) { var rs1 = To3(seg.Point1, Vector2.Lerp(seg.Point1, seg.Point2, l2), primitive.Transform, swap); results.Add(rs1); } } } }