Edge.fromTangent constructor
Implementation
factory Edge.fromTangent(Corner prev, Corner current) {
final clockwise = current.clockwise;
final transverse = (prev.clockwise != current.clockwise);
if (!transverse && prev.circle.radius == current.circle.radius) {
return Edge.sameRadiusDirectTangent(prev, current);
}
/* Setting the bigger circle as the first and the other as second. This is
* important in case of the direct tangent, as we will be using the
* section formula to find the external point, there. */
var (first, second) = (prev.circle.radius > current.circle.radius)
? (prev, current)
: (current, prev);
/* In case of direct tangent we will be getting the external point,
* Otherwise will be getting the internal point. */
final bothRadiusAreZero =
first.circle.radius == 0 && second.circle.radius == 0;
final transverseFactor = (transverse ? 1 : -1);
final commonPoint = (first.circle.center, second.circle.center)
.pointInBetween((bothRadiusAreZero
? (1, transverseFactor)
: (first.circle.radius, transverseFactor * second.circle.radius)));
//Angle between a single direct tangent and the line joining the centres.
final slopeDiff = Angle.fromSin(
second.circle.radius, (second.circle.center, commonPoint).distance);
final centerLine =
Line.fromTwoPoints((prev.circle.center, current.circle.center));
for (final value in const [true, false]) {
final tangent = centerLine.rotate(commonPoint, slopeDiff, value);
//Points of touch with the [prev] and [current] circles respectively
final first = tangent.perpendicularFoot(prev.circle.center);
final second = tangent.perpendicularFoot(current.circle.center);
//Checking if according to the direction tangent is correct.
if (areCorrectPoints(first, second, current.circle.center, clockwise)) {
return Edge(first, second);
}
}
throw PlatformException(
code: 'NO_CORRECT_TANGENTS',
details: 'No correct tangent found between the given two corners.',
);
}