QCAD Bugtracker

  • Status Closed
  • Percent Complete
    100%
  • Task Type Bug Report
  • Category QCAD (main)
  • Assigned To
    andrew
  • Operating System All
  • Severity Low
  • Priority Very Low
  • Reported Version 3.30.1
  • Due in Version Undecided
  • Due Date Undecided
  • Votes 1
    • CVH (27.07.2024)
  • Private
Attached to Project: QCAD Bugtracker
Opened by CVH - 27.07.2024
Last edited by andrew - 29.08.2024

FS#2592 - Draw > Circle > Circle2TP: Missing solutions with circles

Andrew,

Related topic: https://www.qcad.org/rsforum/viewtopic.php?f=32&t=10960

This special case of the Apollonius’ problem has generally up to 4 solutions.
Type 7: https://en.wikipedia.org/wiki/Special_cases_of_Apollonius%27_problem

Several test revealed that there are quite a few solutions missing.
See: CT2-limitations.dxf .. Layer: Expected Solutions .. Points displayed in Mode 35


First I adapted the code of Apollonius.getSolutionsPCC for each unsupported or incomplete case. It looked over-complicated even when simplified.

After a while I discovered that the origin of the flaws is:
- ShapeAlgorithms.getTangents(...); ... See FS#2588
- Apollonius.getCommonTangents(...); ... See  FS#2589 

getTangents() results differ depending the order of the circle shapes.
getCommonTangents() may fail all together.
Concentric or nested circles are excluded.
Typically both resources don’t return a tangent line for the case:
- Where circles touch internally/externally.
- A line and a circle shape.

That last is somewhat special ... We enter the realm of infinity. We know that some inversions of circles may result in an endless line or better: A circle with infinite radius.
The tangents of an endless line and a circle are 2 parallels that are tangent to the circle.
These two parallel lines are considered to be tangent at infinity.
And then it doesn’t matter how far apart the line and the circle are.



The code for Apollonius.getSolutionsPCC can then be simplified drastically.
All solutions (⩽4) in about 10 functional lines of code. ;-)
Based on an enhanced algorithm that returns all possible tangent shapes.

/**
 * \author Andrew Mustun, CVH © 2024
 * \return Solutions for circles (<=4) that are tangential to the two given circles
 * and the given point.
 */
Apollonius.getSolutionsPCC = function(point, circle1, circle2) {
    if (!isPointShape(point) ||
        !isCircleShape(circle1) ||
        !isCircleShape(circle2)) {

        return [];    // Empty, no solutions
    }

    // Relative sized inversion circle (FS#2590): 
    var rInv = circle1.getRadius();
    if (circle2.radius > circle1.radius) {
        rInv = circle2.getRadius();
    }
    var inversionCircle = new RCircle(point.getPosition(), rInv);

    // Construct inversion shapes:
    var c1Inverse = Apollonius.getInverseShape(circle1, inversionCircle);
    var c2Inverse = Apollonius.getInverseShape(circle2, inversionCircle);

    // Get all tangent shapes for given inversion shapes:
    // Exploits an enhanced algorithm by CVH
    var tangents = Apollonius.getAllTangents(c1Inverse, c2Inverse);

    // Return the re-inversion of all tangents (0-4 solutions):
    return Apollonius.getInverseShapes(tangents, inversionCircle);
};

There is the rare case that one of the solutions is a line (Circle with R=infinte).
But that is filtered out in Circle2TP.js

I included the above code as a js file: Apollonius.getSolutionsPCC.js
I also re-included the adapted tangents code ( FS#2589 ): Apollonius.getAllTangents.js

Regards,
CVH

Closed by  andrew
29.08.2024 13:57
Reason for closing:  Implemented

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing