OK, so I’ve tried with different settings, but my attempt to make a Tangent-Tangent line between two arcs keeps failing.
The two arcs I have are defined as follows, and when “debug-previewing” the input arcs and t-para,eters, the indata looks like this, and still the resulting Line (line.IsValid == true) cannot be converted to a ToNurbsCurve() which returns null:
The documentation says it is seed value, but doesn’t say if there are some limitations. it could be good you post the curves and parameters that don’t work as it seems likely it is a bug.
OK, here I have the exact same code and the exact same curves which failed in the VS-code, but here it seems it doesn’t really matter what values I set for the t0, t1 parameters. < scratching head >
If I set t0 == 0, then there’s an interval on t1 (the upper arc) between 0.58 … 0.88 where the Line.TryBetweenCurves fails.
I don’t know how relevant that is, but a test-case using permutations for both sliders should be performed to spot the value intervals where the algorithm goes bananas.
The problem I have with this function is that I run a series of these curves with arcs, but with different values, and if I can’t predict at which value intervals the parameters fail, my algorithm becomes very shaky.
My solution to arbitrary located arcs with arbitrary radii:
In order to make the t0 & t1 (6.1 & 6.2) seed parameters closer to the final curve-curve tangent points (avoiding invalid result from the Line.TryCreateBetweenCurves()function), I made a helper function which approximates the t-parameters by performing ClosestPoint (6) from a rotated center-line (4) which is then moved away from perpendicularly the arcs (5).
See code far below.
The resulting t0 and t1 parameters can then safely be used in the Line.TryCreateBetweenCurves()function to get the tangent-tangent line between the arcs (7) :
// Remove these for production code:
private List<Curve> M_DebugCurves;
private List<Point3d> M_DebugPoints;
private List<Object> M_DebugGeo;
public bool GetApproximateCurveCurveParameters(Plane pln, Curve arc_a, Curve arc_b, out double t0, out double t1)
{
// -----------------------------------------------------
// 1. Line from arc-center to arc-center
//
// 2. Rotate this "center line" into parallel with the
// arcs circumference.
//
// 3. Move perpendiculary with distance = largest radius
//
// 4. ClosestPoint to Both Curves producing t0 & t2
// -----------------------------------------------------
// In order to get the center point of each Arc the
// (possibly) imperfect arc-curves are recreated as
// truly perfect Arcs :
var perfect_arc_a = new Arc(arc_a.PointAtStart, arc_a.TangentAtStart, arc_a.PointAtEnd);
var arc_a_center = perfect_arc_a.Center;
var perfect_arc_b = new Arc(arc_b.PointAtStart, arc_b.TangentAtStart, arc_b.PointAtEnd);
var arc_b_center = perfect_arc_b.Center;
var center_line = new Line(arc_a_center, arc_b_center).ToNurbsCurve();
M_DebugCurves.Add(center_line.DuplicateCurve());
// -------------------------------------------------
// Tilt the line to align with the arc's difference
// in radius
// -------------------------------------------------
// The rotation center should be from the smallest arc:
var rotation_center = perfect_arc_a.Radius < perfect_arc_b.Radius ? perfect_arc_a.Center : perfect_arc_b.Center;
var diff_radius = Math.Abs(perfect_arc_a.Radius - perfect_arc_b.Radius);
var center_distance = (arc_a.PointAtStart - arc_b.PointAtEnd).Length;
var arc_sin = Math.Asin(diff_radius / center_distance);
var trx = Transform.Rotation(arc_sin, pln.ZAxis, rotation_center);
var end_pt = center_line.PointAtEnd;
end_pt.Transform(trx);
center_line.SetEndPoint(end_pt);
M_DebugCurves.Add(center_line.DuplicateCurve());
// -------------------------------------------------
// Move the rotated center_line away perpendiculary from the
// arcs before performing ClosestPoint on them
// -------------------------------------------------
var center_line_direction = center_line.TangentAtEnd;
var rotated_plane = new Plane(rotation_center, center_line_direction, Vector3d.CrossProduct(pln.ZAxis, center_line_direction));
var max_radius = Math.Max(perfect_arc_a.Radius, perfect_arc_b.Radius) * 2;
center_line.Translate(rotated_plane.YAxis * max_radius);
M_DebugCurves.Add(center_line.DuplicateCurve());
// -------------------------------------------------
// get ClosestPoint parameter from each end of the
// distant line back to each each arc :
// -------------------------------------------------
arc_a.ClosestPoint(center_line.PointAtStart, out t0);
arc_b.ClosestPoint(center_line.PointAtEnd, out t1);
return true;
}