snippetcsharpMinor
C# code to derive tangential points between two circles to create a trapezoid
Viewed 0 times
derivecreatepointscirclestwobetweentrapezoidcodetangential
Problem
These are the steps to determine coordinates of the 4 points (P1, P2, P3, P4) that make up a tangential trapezoid connecting to circles. Another way of looking at it is to think of the tangential segments of being the parts of a belt that would not be wrapped around the pulleys. The math should work regardless of the orientation of the two circles in coordinate space.
Code (usage @ bottom):
```
internal class TrapezoidBuilder
{
private const double RadiansToDegrees = 180/Math.PI;
private readonly double _bufferDistanceC0;
private readonly double _bufferDistanceC1;
private readonly Point _pointC0;
private readonly Point _pointC1;
public TrapezoidPoints TrapezoidPoints;
public TrapezoidBuilder(Point pointC0, Point pointC1, double bufferDistanceC0, double bufferDistanceC1)
{
_pointC0 = pointC0;
_pointC1 = pointC1;
_bufferDistanceC0 = bufferDistanceC0;
_bufferDistanceC1 = bufferDistanceC1;
TrapezoidPoints = new TrapezoidPoints();
CalculateTrapezoidPoints();
}
public void CalculateTrapezoidPoints()
{
// Get the angle of the line C0-C1 in degrees. This will be used in conjunction with angleA to determine the vector of these points
double angleRelativeToPositiveXAxis = CalculateAngleRelativeToXAxis(_pointC0, _pointC1);
// Get angleA
double angleA = CalculateAngleA(_pointC0, _pointC1, _bufferDistanceC0, _bufferDistanceC1);
//// Calculate P1 and P2 coordinates first
double positiveAngle = angleRelativeToPositiveXAxis + angleA;
double cosPositiveAngle = Math.Cos(positiveAngle/RadiansToDegrees);
double valueToAddToC0X = cosPositiveAngle*_bufferDistanceC0;
// Set P1's X coordinate
TrapezoidPoints.P1.X = _pointC0.X + valueToAddToC0X;
double valueToAddToC1X = cosPositiveAngle*_bufferDistanceC1;
// Set P2's X coordinate
TrapezoidPoints.P2.X = _pointC1.X + valueToAddToC1X;
Code (usage @ bottom):
```
internal class TrapezoidBuilder
{
private const double RadiansToDegrees = 180/Math.PI;
private readonly double _bufferDistanceC0;
private readonly double _bufferDistanceC1;
private readonly Point _pointC0;
private readonly Point _pointC1;
public TrapezoidPoints TrapezoidPoints;
public TrapezoidBuilder(Point pointC0, Point pointC1, double bufferDistanceC0, double bufferDistanceC1)
{
_pointC0 = pointC0;
_pointC1 = pointC1;
_bufferDistanceC0 = bufferDistanceC0;
_bufferDistanceC1 = bufferDistanceC1;
TrapezoidPoints = new TrapezoidPoints();
CalculateTrapezoidPoints();
}
public void CalculateTrapezoidPoints()
{
// Get the angle of the line C0-C1 in degrees. This will be used in conjunction with angleA to determine the vector of these points
double angleRelativeToPositiveXAxis = CalculateAngleRelativeToXAxis(_pointC0, _pointC1);
// Get angleA
double angleA = CalculateAngleA(_pointC0, _pointC1, _bufferDistanceC0, _bufferDistanceC1);
//// Calculate P1 and P2 coordinates first
double positiveAngle = angleRelativeToPositiveXAxis + angleA;
double cosPositiveAngle = Math.Cos(positiveAngle/RadiansToDegrees);
double valueToAddToC0X = cosPositiveAngle*_bufferDistanceC0;
// Set P1's X coordinate
TrapezoidPoints.P1.X = _pointC0.X + valueToAddToC0X;
double valueToAddToC1X = cosPositiveAngle*_bufferDistanceC1;
// Set P2's X coordinate
TrapezoidPoints.P2.X = _pointC1.X + valueToAddToC1X;
Solution
- It's not clear to me what are
buffer0andbuffer1? If these represent the radius values (like C1-P1 line forbuffer1), then perhapsradius0(andradius1) would be a better name here.
- I'd create and use a data class for each point-radius pair. Say,
InputPointclass withPointandRadiusor something similar.
- I'd separate constructor and results. The results are calculations that should not be part of the constructor. Take, for example, the class named
UriBuilderin .NET: you can construct it, change the inputs, and only when you call the property namedUri- you get the calculated uri. The same should apply here, too. Constructing a class gives us an instance with a valid state. Calculations - in their own methods or property-getters (that are practically methods, by the way). SoTrapezoidPointsshould be the returned type of aGetTrapezoidmethod (or maybeTryGetTrapezoidif this pattern apply here), and not part of the class' state.
Context
StackExchange Code Review Q#11858, answer score: 2
Revisions (0)
No revisions yet.