Mở đầu
Bài viết hôm nay sẽ là một chủ đề khá thú vị xung quanh việc giới hạn giá trị geometry, điều này đã gây ra một số lỗi đáng kể với việc tính toán và dựng mô hình tham số.
Như đã biết thì cho phép ta lựa chọn 4 giới hạn khoanh vùng giá trị : Thấp, vừa, lớn và cực lớn.Việc thay đổi vùng cũng khiến hiệu suất tính toán trở nên nhanh hơn.
Lỗi là do đâu
Hãy thử nhìn hình đầu tiên này xem chuyện gì đang xảy ra :
Trông nó có vẻ ổn nhưng thực ra không ổn tí nào, vùng đang được chọn ở chế độ Medium, nó đã làm thiếu đi mất giá trị điểm nằm ngoài vùng Large của mình.Cùng xem hình bên dưới giải thích rõ hơn.
Khi chuyển về vùng Large, toạ độ điểm nhận về là đầy đủ với hai điểm ở giới hạn vùng Large có thể đọc được.Tuy nhiên nhìn kĩ hơn một chút, việc tính toán sau đó tìm điểm gần nhất chúng đã tính toán sai mất giá trị,khoảng cách xa hơn lại là điểm gần nhất ?.Kết quả phải trả về một con số điểm không âm thì lúc này mới đúng.Chốt ở đây lỗi này trước sau đó mình sẽ tiếp tục đi xử lí tiếp.
Ta quay trở lại với việc chia mặt trên đường, lúc này ta đang ở vùng Large và Curve lại bé nên cuối cùng ta lại bị cảnh báo và bắt quay lại về vùng Medium.Ta xem đây là vấn đề số 2 nhé.
Như thế nào mới là đúng bây giờ
Ta thử một ví dụ đơn giản nhé. Hình dưới cho phép tìm ra điểm gần nhất so với một điểm, có thể thấy khoảng cách 16 ngắn hơn nên kết quả trả về sẽ là điểm có toạ độ X = 12 từ danh sách.Lúc này kết quả là chính xác.
Giải quyết
Tuỳ chỉnh lại một chỗ :
Ta có thể viết một thư viện nhỏ để sửa lỗi cho việc này thông qua việc so sánh khoảng cách trước rồi mới tính điểm gần nhất, và vùng chuyển đổi sẽ là vùng Large.Tuy nhiên nó chỉ giải quyết cho ta được vấn đề thứ nhất nhưng không thể giải quyết triển để vấn đề số 2.
Viết lại cách tính khoảng cách bằng tuỳ chỉnh riêng :
Lấy một điểm xa nhất hoặc một điểm gần nhất đi so sánh với các điểm đang có.
public static Autodesk.DesignScript.Geometry.Point ClosestPointTo(Point point, List<Point> points)
{
XYZ psrc = point.ToXyz();
XYZ pclosest = null;
double num = Double.MaxValue;
foreach (Point p in points)
{
var xyz = p.ToXyz();
double dis = xyz.DistanceTo(psrc);
if (dis<num)
{
pclosest = xyz;
num = dis;
}
}
return pclosest.ToPoint();
}
def calculate_distance(p1, p2):
return ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5
def find_nearest_point(start_point, points):
min_distance = math.inf
index = 0
for i, point in enumerate(points):
distance = calculate_distance(start_point, point)
if min_distance > distance:
min_distance = distance
index = i
if points:
next_point = points.pop(index)
stack.append(next_point)
find_nearest_point(next_point, points)
Lúc này trông kết quả có vẻ ổn hơn rồi.
Cùng xem hai bức hình trước khi sửa và sau khi sửa một chỗ nhỏ :
Trước khi bị lỗi: Vòng tròn tính toán không đúng điểm gần nhất, hai đường vẽ từ điểm chia của mỗi vòng tròn chia sai so với vòng tròn bên cạnh tiếp nó.
Sau khi tính toán và làm lại thì mọi thứ trông đẹp hơn và tính toán đúng.Các điểm lúc này bố trí đều đặn với mặt phẳng pháp tuyến của nó và khoảng cách giữa các điểm được phân bổ đều nhau cho mỗi danh sách.Hai điểm nối đại diện cho một Adaptive tuỳ biến.
Tổng kết
Việc tính toán từ máy tính là rất nguy hiểm chứ không phải không , đôi khi một phép toán sai dù đúng công dụng của node, vì vậy hãy cẩn thận với Geometry Setting Range
trong Dynamo.