Mở đầu

Bài viết này sẽ giúp bạn kiểm tra tính giao nhau của các đối tượng như curve, detailine, line và grid.

Trong hình học không gian ba chiều , nếu hai đường thẳng không nằm trong cùng một mặt phẳng thì chúng được gọi là đường xiên và không có giao điểm. Nếu chúng nằm trong cùng một mặt phẳng thì có ba khả năng để xảy ra:

  1. Nếu chúng trùng nhau (không phải là các đường thẳng phân biệt) thì chúng có vô số điểm chung.
  2. Nếu chúng khác biệt nhưng có cùng hệ số góc thì chúng được cho là song song và không có điểm chung.
  3. Nếu không phải hai trường hợp bên trên chúng sẽ có một điểm giao nhau.

400px Line Line Intersection

Thông thường chúng ta sẽ sử dụng hàm có sẵn để tìm ra điểm giao, ở đây mình sẽ áp dụng IntersectionResultArray cho hàm để tìm ra điểm này

public static XYZ Intersection(this Autodesk.Revit.DB.Line line1, Autodesk.Revit.DB.Line line2)
{
IntersectionResultArray iResult = new IntersectionResultArray();
SetComparisonResult setComparisonResult = line1.Intersect(line2, out iResult);
if (setComparisonResult != SetComparisonResult.Disjoint)
return iResult.get_Item(0).XYZPoint;
return null;
}
view raw Intersection.cs hosted with ❤ by GitHub

Với Dynamo có thể sử dụng node intersect để tìm ra điểm giao nhanh chóng

 Image fb4acf7e 2da8 4597 a4ea 87f90eb9d9e9

Tìm điểm giao giữa mặt phẳng và line hoặc curve với IntersectionResultArray

public static XYZ Intersection(this Autodesk.Revit.DB.Plane plane, Autodesk.Revit.DB.Line line)
{
UV uv1, uv2;
plane.Project(line.Origin, out uv1, out double d);
plane.Project(line.Origin + line.Direction, out uv2, out double b);
XYZ xyz1 = plane.Origin + (uv1.U * plane.XVec) + (uv1.V * plane.YVec);
XYZ xyz2 = plane.Origin + (uv2.U * plane.XVec) + (uv2.V * plane.YVec);
Line projectedLine = Line.CreateUnbound(xyz1, xyz2 - xyz1);
IntersectionResultArray iResult = new IntersectionResultArray();
SetComparisonResult setComparisonResult = line.Intersect(projectedLine, out iResult);
if (setComparisonResult != SetComparisonResult.Disjoint)
return iResult.get_Item(0).XYZPoint;
return null;
}
view raw Intersection.cs hosted with ❤ by GitHub

Kết quả : Mình thử pick điểm và tìm ra điểm để xem điểm giao và kết quả đi sau sẽ là kết quả so sánh với điểm giao vừa tính toán để xem đúng không nhé.

Trường hợp trên rất khả thi, nhưng vấn đề với người đi làm thường chỉ sử dụng trường hợp này cho tìm các đối tượng bị giao như tường chéo hoặc đối tượng ống,...Nhưng nếu hai đường line hoặc curve của chúng giao với nhau khi kéo dài ra thì sao, lúc này bạn sẽ không thể dùng cách trên để giải quyết được nữa .

Lúc này mình sẽ phải làm tiếp công việc tiếp theo là giải bài toán phức tạp hơn một chút, sử dụng tính chất ma trận để tìm ra được điểm giao thay vì chiếu hoặc kéo dài đường line hoặc curve ra.

/// <summary>
/// Check Intersect Between Two Curve
/// </summary>
/// <param name="c1"></param>
/// <param name="c2"></param>
/// <returns></returns>
public static XYZ Intersection(this Curve c1, Curve c2)
{
XYZ p1 = c1.GetEndPoint(0);
XYZ q1 = c1.GetEndPoint(1);
XYZ p2 = c2.GetEndPoint(0);
XYZ q2 = c2.GetEndPoint(1);
XYZ v1 = q1 - p1;
XYZ v2 = q2 - p2;
XYZ w = p2 - p1;
XYZ p5 = null;
double c = (v2.X * w.Y - v2.Y * w.X)
/ (v2.X * v1.Y - v2.Y * v1.X);
if (!double.IsInfinity(c))
{
double x = p1.X + c * v1.X;
double y = p1.Y + c * v1.Y;
p5 = new XYZ(x, y, 0);
}
return p5;
}
view raw checkintersect.cs hosted with ❤ by GitHub

Trường hợp Line Trùng nhau : Tất nhiên là ta sẽ không thể giao hoán ma trận rồi và chúng tất nhiên sẽ bị overlap

 Image 52ba9b5b a430 466d 9942 89b461954fdb

Trường hợp song song cũng thế, chúng không thể tìm ra bất cứ điểm nào cho bạn nên sẽ không trả về cho bạn bất cứ đối tượng điểm nào bị giao

 Image 13dff289 95d9 49c5 9ef0 ffb252bac08a

Ngoài ra mình còn một nho nhỏ cần giải quyết ở cuối bài này rất hay sử dụng đó là việc tìm ra đường line hoặc curve đó đang nằm đứng hay đang nằm ngang

public static bool IsHorizontal(this Line Line)
{
double TOLERANCE = 0.0000001;
XYZ p1 = Line.GetEndPoint(0);
XYZ p2 = Line.GetEndPoint(1);
return Math.Abs(p1.Y - p2.Y) < TOLERANCE;
}
view raw IsHorizontal.cs hosted with ❤ by GitHub
public static bool IsVertical(this Line Line)
{
double TOLERANCE = 0.0000001;
XYZ p1 = Line.GetEndPoint(0);
XYZ p2 = Line.GetEndPoint(1);
return Math.Abs(p1.X - p2.X) < TOLERANCE;
}
view raw IsVertical.cs hosted with ❤ by GitHub

Mở rộng

Với các trường hợp kiểm tra giao nhau trên Dynamo và bị cảnh báo.

 Image fdaef92c ae96 4043 8f10 6c25d88346f0

Thông thường các điểm sẽ vượt ra ngoài giới hạn (Range) thông thường nên có bị cảnh báo màu vàng bạn cũng đừng nên hoang mang mà hãy cài đặt thay đổi thông số Range lên cao là được rồi.

 Image 136363fb 2dac 4ea8 a36c 5f6ff53c431b

Tham khảo

wikipedia thebuildingcoder