.NET

Reply
Member
ydsoo8
Posts: 4
Registered: ‎09-11-2013
Message 1 of 8 (1,440 Views)
Accepted Solution

how to drawing a line tangent to two circles in C#?

1440 Views, 7 Replies
09-11-2013 09:54 AM

 how to drawing a line tangent to two circles in C#?

 

*Expert Elite*
_gile
Posts: 2,077
Registered: ‎04-29-2006
Message 2 of 8 (1,425 Views)

Re : how to drawing a line tangent to two circles in C#?

09-11-2013 10:54 AM in reply to: ydsoo8
*Expert Elite*
dgorsman
Posts: 5,097
Registered: ‎10-12-2006
Message 3 of 8 (1,419 Views)

Re: how to drawing a line tangent to two circles in C#?

09-11-2013 11:48 AM in reply to: ydsoo8

Break out the math (all that work in high school you never thought would be useful... who knew).  A line that is tangent to a circle will be at 90 degrees to the radius of that circle.  For a line to be tangent to two circles, you need to find a line that is perpendicular to the radius of each circle.  Under this cirumstance, the radii of both circles will be parallel.  From there its just a matter of having a line extending from each circles center to its respective radius, using the same angle for each, and the tangent line will connect them.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
Adopt. Adapt. Overcome. Or be overcome.
A good question will be halfway to a good answer.


Member
ydsoo8
Posts: 4
Registered: ‎09-11-2013
Message 4 of 8 (1,388 Views)

Re: how to drawing a line tangent to two circles in C#?

09-12-2013 09:34 AM in reply to: dgorsman

我的意思是想用C#实现  

LINE <enter>

TAN <enter>

Pick the first point

TAN <enter>

Pick the second point

<enter>

这样的一个功能,而不是将两圆的所有公切线都画出来,仅画出自已所需的一条公切线。

本人初学对autocad一些函数用法不熟悉。希望老师用C#代码将上述命令模拟出来。

本人英语水水很菜,只能写中文了

*Expert Elite*
_gile
Posts: 2,077
Registered: ‎04-29-2006
Message 5 of 8 (1,334 Views)

Re : how to drawing a line tangent to two circles in C#?

09-14-2013 01:18 AM in reply to: ydsoo8

Hi,

 

Here's an extension method for the CicularArc3d class.

It returns a List of LineSegment3d for the tangents between two circles (maybe 0, 2 or 4).

An exception is thrown if the circles do not lie on the same plane.

 

using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

namespace TangentsToCircle
{
    public static class Tangents
    {
        public static List<LineSegment3d> GetTangentsToCircle(this CircularArc3d circle, CircularArc3d other)
        {
            // check if circles lies on the same plane
            Vector3d normal = circle.Normal;
            Plane plane = new Plane(Point3d.Origin, normal);
            double elev1 = circle.Center.TransformBy(Matrix3d.WorldToPlane(plane)).Z;
            double elev2 = other.Center.TransformBy(Matrix3d.WorldToPlane(plane)).Z;
            if (!(normal.IsParallelTo(other.Normal) &&
                Math.Abs(elev1 - elev2) < Tolerance.Global.EqualPoint))
                throw new Autodesk.AutoCAD.Runtime.Exception(
                    Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);

            List<LineSegment3d> result = new List<LineSegment3d>();

            // check if a circle is not inside the other
            double dist = circle.Center.DistanceTo(other.Center);
            if (dist <= Math.Abs(circle.Radius - other.Radius))
                return result;

            CircularArc3d tmp1, tmp2;
            Point3d center;
            Point3d[] inters;
            Vector3d vec, vec1, vec2;

            // external tangents
            if (circle.Radius == other.Radius)
            {
                center = circle.Center;
                normal = circle.Normal;
                vec = other.Center - center;
                Line3d perp = new Line3d(center, vec.CrossProduct(normal));
                inters = circle.IntersectWith(perp);
                if (inters != null)
                {
                    result.Add(new LineSegment3d(inters[0], inters[0] + vec));
                    result.Add(new LineSegment3d(inters[1], inters[1] + vec));
                }
            }
            else
            {
                if (circle.Radius < other.Radius)
                {
                    tmp1 = circle;
                    circle = other;
                    other = tmp1;
                }
                center = circle.Center;
                normal = circle.Normal;
                vec = other.Center - center;
                tmp1 = new CircularArc3d(circle.Center, normal, circle.Radius - other.Radius);
                tmp2 = new CircularArc3d(center + vec / 2.0, normal, dist / 2.0);
                inters = tmp1.IntersectWith(tmp2);
                if (inters != null)
                {
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    result.Add(new LineSegment3d(center + vec1 * circle.Radius, other.Center + vec1 * other.Radius));
                    result.Add(new LineSegment3d(center + vec2 * circle.Radius, other.Center + vec2 * other.Radius));
                }
            }

            // crossing tangents
            if (circle.Radius + other.Radius < dist)
            {
                double ratio = (circle.Radius / (circle.Radius + other.Radius)) / 2.0;
                tmp1 = new CircularArc3d(center + vec * ratio, normal, dist * ratio);
                inters = circle.IntersectWith(tmp1);
                if (inters != null)
                {
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    result.Add(new LineSegment3d(center + vec1 * circle.Radius, other.Center + vec1.Negate() * other.Radius));
                    result.Add(new LineSegment3d(center + vec2 * circle.Radius, other.Center + vec2.Negate() * other.Radius));
                }
            }
            return result;
        }
    }
}

 

A test command:

 

using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(TangentsToCircle.CommandMethods))]

namespace TangentsToCircle
{
    public class CommandMethods
    {
        [CommandMethod("Test", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a circle: ");
            peo.SetRejectMessage("Only a circle.");
            peo.AddAllowedClass(typeof(Circle), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;
            ObjectId id1 = per.ObjectId;

            peo.Message = "\nSelect another circle: ";
            ObjectId id2;
            while (true)
            {
                per = ed.GetEntity(peo);
                if (per.Status != PromptStatus.OK)
                    return;
                id2 = per.ObjectId;
                if (id1 == id2)
                    ed.WriteMessage("\nThe second circle is the same as the first one.");
                else break;
            }

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Circle c1 = (Circle)tr.GetObject(id1, OpenMode.ForRead);
                    Circle c2 = (Circle)tr.GetObject(id2, OpenMode.ForRead);
                    CircularArc3d ca1 = new CircularArc3d(c1.Center, c1.Normal, c1.Radius);
                    CircularArc3d ca2 = new CircularArc3d(c2.Center, c2.Normal, c2.Radius);
                    List<LineSegment3d> lines = ca1.GetTangentsToCircle(ca2);
                    BlockTableRecord btr =
                        (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    foreach (LineSegment3d l in lines)
                    {
                        Line line = new Line(l.StartPoint, l.EndPoint);
                        btr.AppendEntity(line);
                        tr.AddNewlyCreatedDBObject(line, true);
                    }
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception exn)
            {
                ed.WriteMessage("\n" + exn.Message);
            }
            catch (System.Exception exn)
            {
                ed.WriteMessage("\n" + exn.Message);
            }
        }
    }
}

 

Gilles Chanteau
*Expert Elite*
_gile
Posts: 2,077
Registered: ‎04-29-2006
Message 6 of 8 (1,319 Views)

Re : how to drawing a line tangent to two circles in C#?

09-14-2013 09:40 AM in reply to: _gile

A better (more robust and xml documented) implementation.

 

using System;
using Autodesk.AutoCAD.Geometry;

namespace GeometryExtensions
{
    /// <summary>
    /// Tangent type enum
    /// </summary>
    [Flags]
    public enum TangentType { Inner = 1, Outer = 2 }

    /// <summary>
    /// Provides extension methods for the CircularArc3d class.
    /// </summary>
    public static class CircularArc3dExtensions
    {
        /// <summary>
        /// Returns the tangents between the active CircularArc3d instance complete circle and another one.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the one passed as argument.
        /// Tangents are always returned in the same order: outer tangents before inner tangents, and for both,
        /// the tangent on the left side of the line from this circular arc center to the other one before the one on the right side. 
        /// </remarks>
        /// <param name="arc">The object to which this method applies.</param>
        /// <param name="other">The CircularArc3d to which searched for tangents.</param>
        /// <param name="flags">An enum value specifying which type of tangent is returned.</param>
        /// <returns>An array of LineSegment3d representing the tangents (maybe 2 or 4) or null if there is none.</returns>
        /// <exception cref="Autodesk.AutoCAD.Runtime.exception">eNonCoplanarGeometry is thrown if the objects do not lies on theme plane.</exception>
        public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, CircularArc3d other, TangentType flags)
        {
            // check if circles lies on the same plane
            Vector3d normal = arc.Normal;
            double elev1 = arc.Center.TransformBy(Matrix3d.WorldToPlane(normal)).Z;
            double elev2 = other.Center.TransformBy(Matrix3d.WorldToPlane(normal)).Z;
            if (!(normal.IsParallelTo(other.Normal) &&
                Math.Abs(elev1 - elev2) < Tolerance.Global.EqualPoint))
                throw new Autodesk.AutoCAD.Runtime.Exception(
                    Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);

            // check if a circle is inside the other
            double dist = arc.Center.DistanceTo(other.Center);
            if (dist - Math.Abs(arc.Radius - other.Radius) <= Tolerance.Global.EqualPoint)
                return null;

            // check if circles overlap
            bool overlap = arc.Radius + other.Radius >= dist;
            if (overlap && flags == TangentType.Inner)
                return null;

            CircularArc3d tmp1, tmp2;
            Point3d[] inters;
            Vector3d vec1, vec2, vec = other.Center - arc.Center;
            int i, j;
            LineSegment3d[] result = new LineSegment3d[(int)flags == 3 && !overlap ? 4 : 2];

            // outer tangents
            if (flags.HasFlag(TangentType.Outer))
            {
                if (arc.Radius == other.Radius)
                {
                    Line3d perp = new Line3d(arc.Center, vec.CrossProduct(normal));
                    inters = arc.IntersectWith(perp);
                    vec1 = (inters[0] - arc.Center).GetNormal();
                    vec2 = (inters[1] - arc.Center).GetNormal();
                    i = vec.GetAngleTo(vec1, normal) < vec.GetAngleTo(vec2, normal) ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment3d(inters[0], inters[0] + vec);
                    result[j] = new LineSegment3d(inters[1], inters[1] + vec);
                }
                else
                {
                    Point3d center = arc.Radius < other.Radius ? other.Center : arc.Center;
                    tmp1 = new CircularArc3d(center, normal, Math.Abs(arc.Radius - other.Radius));
                    tmp2 = new CircularArc3d(arc.Center + vec / 2.0, normal, dist / 2.0);
                    inters = tmp1.IntersectWith(tmp2);
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    i = vec.GetAngleTo(vec1, normal) < vec.GetAngleTo(vec2, normal) ? 0 : 1;
                    j = i ^ 1;
                    result[i] = new LineSegment3d(arc.Center + vec1 * arc.Radius, other.Center + vec1 * other.Radius);
                    result[j] = new LineSegment3d(arc.Center + vec2 * arc.Radius, other.Center + vec2 * other.Radius);
                }
            }

            // inner tangents
            if (flags.HasFlag(TangentType.Inner) && !overlap)
            {
                double ratio = (arc.Radius / (arc.Radius + other.Radius)) / 2.0;
                tmp1 = new CircularArc3d(arc.Center + vec * ratio, normal, dist * ratio);
                inters = arc.IntersectWith(tmp1);
                vec1 = (inters[0] - arc.Center).GetNormal();
                vec2 = (inters[1] - arc.Center).GetNormal();
                i = vec.GetAngleTo(vec1, normal) < vec.GetAngleTo(vec2, normal) ? 2 : 3;
                j = i == 2 ? 3 : 2;
                result[i] = new LineSegment3d(arc.Center + vec1 * arc.Radius, other.Center + vec1.Negate() * other.Radius);
                result[j] = new LineSegment3d(arc.Center + vec2 * arc.Radius, other.Center + vec2.Negate() * other.Radius);
            }
            return result;
        }

        /// <summary>
        /// Returns the tangents between the active CircularArc3d instance complete circle and a point.
        /// </summary>
        /// <remarks>
        /// Tangents start points are on the object to which this method applies, end points on the point passed as argument.
        /// Tangents are always returned in the same order: the tangent on the left side of the line from the circular arc center
        /// to the point before the one on the right side. 
        /// </remarks>
        /// <param name="arc">The object to which this method applies.</param>
        /// <param name="pt">The Point3d to which tangents are searched</param>
        /// <returns>An array of LineSegement3d representing the tangents (2) or null if there is none.</returns>
        /// <exception cref="Autodesk.AutoCAD.Runtime.exception">eNonCoplanarGeometry is thrown if the objects do not lies on theme plane.</exception>
        public static LineSegment3d[] GetTangentsTo(this CircularArc3d arc, Point3d pt)
        {
            // check if circle and point lies on the plane
            Vector3d normal = arc.Normal;
            double elev1 = arc.Center.TransformBy(Matrix3d.WorldToPlane(normal)).Z;
            double elev2 = pt.TransformBy(Matrix3d.WorldToPlane(normal)).Z;
            if (Math.Abs(elev1 - elev2) < Tolerance.Global.EqualPoint)
                throw new Autodesk.AutoCAD.Runtime.Exception(
                    Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);

            // check if the point is inside the circle
            Point3d center = arc.Center;
            if (pt.DistanceTo(center) <= arc.Radius)
                return null;

            Vector3d vec = pt.GetVectorTo(center) / 2.0;
            CircularArc3d tmp = new CircularArc3d(pt + vec, arc.Normal, vec.Length);
            Point3d[] inters = arc.IntersectWith(tmp);
            LineSegment3d[] result = new LineSegment3d[2];
            int i = vec.GetAngleTo(inters[0] - center, normal) < vec.GetAngleTo(inters[1] - center, normal) ? 0 : 1;
            int j = i ^ 1;
            result[i] = new LineSegment3d(inters[0], pt);
            result[j] = new LineSegment3d(inters[1], pt);
            return result;
        }
    }
}

 

A test command which draws a closed polyline  along the outer tangents and the trimmed selected circles.

 

        [CommandMethod("JoinCircles", CommandFlags.Modal)]
        public void JoinCircles()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a circle: ");
            peo.SetRejectMessage("Only a circle.");
            peo.AddAllowedClass(typeof(Circle), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;
            ObjectId id1 = per.ObjectId;

            peo.Message = "\nSelect another circle: ";
            ObjectId id2;
            while (true)
            {
                per = ed.GetEntity(peo);
                if (per.Status != PromptStatus.OK)
                    return;
                id2 = per.ObjectId;
                if (id1 == id2)
                    ed.WriteMessage("\nThe second circle is the same as the first one.");
                else break;
            }

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Circle c1 = (Circle)tr.GetObject(id1, OpenMode.ForRead);
                    Circle c2 = (Circle)tr.GetObject(id2, OpenMode.ForRead);
                    CircularArc3d ca1 = new CircularArc3d(c1.Center, c1.Normal, c1.Radius);
                    CircularArc3d ca2 = new CircularArc3d(c2.Center, c2.Normal, c2.Radius);
                    LineSegment3d[] lines = ca1.GetTangentsTo(ca2, TangentType.Outer);
                    if (lines != null)
                    {
                        BlockTableRecord btr =
                            (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                        Vector3d vec = c1.Center.GetVectorTo(c2.Center);
                        Plane plane = new Plane(Point3d.Origin, c1.Normal);
                        double a1 = vec.GetAngleTo(ca1.Center.GetVectorTo(lines[1].StartPoint), ca1.Normal) -
                            vec.GetAngleTo(ca1.Center.GetVectorTo(lines[0].StartPoint), ca1.Normal);
                        double a2 = vec.Negate().GetAngleTo(ca2.Center.GetVectorTo(lines[0].EndPoint), ca1.Normal) -
                            vec.Negate().GetAngleTo(ca2.Center.GetVectorTo(lines[1].EndPoint), ca1.Normal);
                        Polyline pline = new Polyline(4);
                        pline.AddVertexAt(0, lines[0].StartPoint.Convert2d(plane), Math.Tan(a1 / 4.0), 0.0, 0.0);
                        pline.AddVertexAt(1, lines[1].StartPoint.Convert2d(plane), 0.0, 0.0, 0.0);
                        pline.AddVertexAt(2, lines[1].EndPoint.Convert2d(plane), Math.Tan(a2 / 4.0), 0.0, 0.0);
                        pline.AddVertexAt(3, lines[0].EndPoint.Convert2d(plane), 0.0, 0.0, 0.0);
                        pline.Closed = true;
                        pline.Normal = c1.Normal;
                        pline.Elevation = c1.Center.TransformBy(Matrix3d.WorldToPlane(c1.Normal)).Z;
                        btr.AppendEntity(pline);
                        tr.AddNewlyCreatedDBObject(pline, true);
                        c1.UpgradeOpen();
                        c2.UpgradeOpen();
                        c1.Erase();
                        c2.Erase();
                    }
                    tr.Commit();
                }
            }
            catch (System.Exception exn)
            {
                ed.WriteMessage("\nError: " + exn.Message);
            }
        }

 

Gilles Chanteau
Member
ydsoo8
Posts: 4
Registered: ‎09-11-2013
Message 7 of 8 (1,308 Views)

Re : how to drawing a line tangent to two circles in C#?

09-15-2013 12:50 AM in reply to: _gile

谢谢你的回复. 可能你没有理解我所表达的意思。虽然你的代码没有实现我所想要的功能,但是我可以根所据你的代码进行更改来实现。

Thank you for your reply. You may not understand what I mean. Although your code does not realize what I want, but I can change according to your code to achieve.. Then I will put out the modified code.

Member
ydsoo8
Posts: 4
Registered: ‎09-11-2013
Message 8 of 8 (1,299 Views)

Re : how to drawing a line tangent to two circles in C#?

09-15-2013 02:41 AM in reply to: _gile
struct lineDist
        {
            public Line  l;
            public double dist;
        }
        [CommandMethod("tt")]
        static public void test() 
        {
            Point3d pickedP1;
            Point3d pickedP2;

            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a circle: ");
            peo.SetRejectMessage("Only a circle.");
            peo.AddAllowedClass(typeof(Circle), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;
            ObjectId id1 = per.ObjectId;
            pickedP1 = per.PickedPoint;

            peo.Message = "\nSelect another circle: ";
            ObjectId id2;
            while (true)
            {
                per = ed.GetEntity(peo);
                if (per.Status != PromptStatus.OK)
                    return;
                id2 = per.ObjectId;
                pickedP2 = per.PickedPoint;
                if (id1 == id2)
                    ed.WriteMessage("\nThe second circle is the same as the first one.");
                else break;
            }

            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Circle c1 = (Circle)tr.GetObject(id1, OpenMode.ForRead);
                    Circle c2 = (Circle)tr.GetObject(id2, OpenMode.ForRead);
                    CircularArc3d ca1 = new CircularArc3d(c1.Center, c1.Normal, c1.Radius);
                    CircularArc3d ca2 = new CircularArc3d(c2.Center, c2.Normal, c2.Radius);
                    List<LineSegment3d> lines = ydsCommands.GetTangentsToCircle(ca1, ca2);
                    BlockTableRecord btr =
                        (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    List<lineDist> ld = new List<lineDist>(lines.Count);
                    double dist = 0;
                    lineDist ldx = new lineDist();
                    foreach (LineSegment3d l in lines)
                    {
                        Line line = new Line(l.StartPoint, l.EndPoint);
                        dist = line.GetClosestPointTo(pickedP1, true).DistanceTo(pickedP1) + line.GetClosestPointTo(pickedP2, true).DistanceTo(pickedP2);
                        ldx.l = line;
                        ldx.dist = dist;
                        ld.Add(ldx);
                    }
                    foreach (lineDist d in ld)
                    {
                        if (d.dist < ldx.dist)
                        {
                            ldx = d;
                        }
                    }
                    btr.AppendEntity(ldx.l);
                    tr.AddNewlyCreatedDBObject(ldx.l, true);
                    tr.Commit();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception exn)
            {
                ed.WriteMessage("\n" + exn.Message);
            }
            catch (System.Exception exn)
            {
                ed.WriteMessage("\n" + exn.Message);
            }
        }
         public static List<LineSegment3d> GetTangentsToCircle(CircularArc3d circle, CircularArc3d other)
        {
            // check if circles lies on the same plane
            Vector3d normal = circle.Normal;
            Plane plane = new Plane(Point3d.Origin, normal);
            double elev1 = circle.Center.TransformBy(Matrix3d.WorldToPlane(plane)).Z;
            double elev2 = other.Center.TransformBy(Matrix3d.WorldToPlane(plane)).Z;
            if (!(normal.IsParallelTo(other.Normal) &&
                Math.Abs(elev1 - elev2) < Tolerance.Global.EqualPoint))
                throw new Autodesk.AutoCAD.Runtime.Exception(
                    Autodesk.AutoCAD.Runtime.ErrorStatus.NonCoplanarGeometry);

            List<LineSegment3d> result = new List<LineSegment3d>();

            // check if a circle is not inside the other
            double dist = circle.Center.DistanceTo(other.Center);
            if (dist <= Math.Abs(circle.Radius - other.Radius))
                return result;

            CircularArc3d tmp1, tmp2;
            Point3d center;
            Point3d[] inters;
            Vector3d vec, vec1, vec2;

            // external tangents
            if (circle.Radius == other.Radius)
            {
                center = circle.Center;
                normal = circle.Normal;
                vec = other.Center - center;
                Line3d perp = new Line3d(center, vec.CrossProduct(normal));
                inters = circle.IntersectWith(perp);
                if (inters != null)
                {
                    result.Add(new LineSegment3d(inters[0], inters[0] + vec));
                    result.Add(new LineSegment3d(inters[1], inters[1] + vec));
                }
            }
            else
            {
                if (circle.Radius < other.Radius)
                {
                    tmp1 = circle;
                    circle = other;
                    other = tmp1;
                }
                center = circle.Center;
                normal = circle.Normal;
                vec = other.Center - center;
                tmp1 = new CircularArc3d(circle.Center, normal, circle.Radius - other.Radius);
                tmp2 = new CircularArc3d(center + vec / 2.0, normal, dist / 2.0);
                inters = tmp1.IntersectWith(tmp2);
                if (inters != null)
                {
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    result.Add(new LineSegment3d(center + vec1 * circle.Radius, other.Center + vec1 * other.Radius));
                    result.Add(new LineSegment3d(center + vec2 * circle.Radius, other.Center + vec2 * other.Radius));
                }
            }

            // crossing tangents
            if (circle.Radius + other.Radius < dist)
            {
                double ratio = (circle.Radius / (circle.Radius + other.Radius)) / 2.0;
                tmp1 = new CircularArc3d(center + vec * ratio, normal, dist * ratio);
                inters = circle.IntersectWith(tmp1);
                if (inters != null)
                {
                    vec1 = (inters[0] - center).GetNormal();
                    vec2 = (inters[1] - center).GetNormal();
                    result.Add(new LineSegment3d(center + vec1 * circle.Radius, other.Center + vec1.Negate() * other.Radius));
                    result.Add(new LineSegment3d(center + vec2 * circle.Radius, other.Center + vec2.Negate() * other.Radius));
                }
            }
            return result;
        }

 

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community