Skip to content

Instantly share code, notes, and snippets.

@tahir-hassan
Created July 18, 2021 17:01
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tahir-hassan/0b1720be42bdcc9c6a06fdd864f3e7f7 to your computer and use it in GitHub Desktop.
Save tahir-hassan/0b1720be42bdcc9c6a06fdd864f3e7f7 to your computer and use it in GitHub Desktop.
PowerShell code to get a circle from three points on an arc.
class Point {
[double]$X;
[double]$Y;
Point([double]$x, [double]$y) {
$this.X = $x;
$this.Y = $y;
}
[Point]Add([double]$xDelta, [double]$yDelta) {
return [Point]::new($this.X + $xDelta, $this.Y + $yDelta);
}
[string]ToString() {
return "($($this.X),$($this.Y))";
}
}
class Circle {
[string]$Name;
[Point]$Origin;
[double]$Radius;
Circle([double]$x, [double]$y, [double]$r) {
$this.Origin = [Point]::new($x, $y);
$this.Radius = $r;
}
[Point]GetPoint([double]$angle) {
$cosDelta = [Math]::Cos($angle) * $this.Radius;
$sinDelta = [Math]::Sin($angle) * $this.Radius;
return $this.Origin.Add($cosDelta, $sinDelta);
}
}
function GetCircleFromPoints(
[Point]$Point1,
[Point]$Point2,
[Point]$Point3) {
function Square([double]$x) { [double][Math]::Pow($x, 2.0) };
$rhsTop = ((Square $Point1.X) - (Square $Point2.X) + (Square $Point1.Y) - (Square $Point2.Y))/2.0;
$rhsBottom = ((Square $Point2.X) - (Square $Point3.X) + (Square $Point2.Y) - (Square $Point3.Y))/2.0;
$topLeft = $Point1.X - $Point2.X;
$topRight = $Point1.Y - $Point2.Y;
$bottomLeft = $Point2.X - $Point3.X;
$bottomRight = $Point2.Y - $Point3.Y;
$originXCoeff = ($topLeft * $bottomRight) - ($bottomLeft * $topRight);
$originXCoeffValue = ($bottomRight * $rhsTop) - ($topRight * $rhsBottom);
$originX = $originXCoeffValue / $originXCoeff;
$originY = ((($Point1.X - $Point2.X) * $originX) - $rhsTop)/(-1 * ($Point1.Y - $Point2.Y));
$radius = [Math]::Sqrt((Square ($Point1.X - $originX)) + (Square ($Point1.Y - $originY)));
return [Circle]::new($originX, $originY, $radius);
}
# test code:
$circ = [Circle]::new(20.0, 10.0, 8);
$circ.Name = 'Original';
$point1 = $circ.GetPoint([Math]::PI * 0.1);
$point2 = $circ.GetPoint([Math]::PI * 0.25);
$point3 = $circ.GetPoint([Math]::PI * 0.35);
$circFromPoints = GetCircleFromPoints $point1 $point2 $point3;
$circFromPoints.Name = 'Derived';
$circ, $circFromPoints | Format-Table;
<#
Name Origin Radius
---- ------ ------
Original (20,10) 8
Derived (20,10) 7.99999999999994
#>
@rajanski
Copy link

rajanski commented Jan 4, 2022

Here is the same function in python:

from math import sqrt
def GetCircleFromPoints(Point1,Point2,Point3):

        rhsTop = ((Point1.x**2) - (Point2.x**2) + (Point1.y**2) - (Point2.y**2)) / 2.0
        rhsBottom = ((Point2.x**2) - (Point3.x**2) + (Point2.y**2) - (Point3.y**2)) / 2.0
        topLeft = Point1.x - Point2.x
        topRight = Point1.y - Point2.y
        bottomLeft = Point2.x - Point3.x
        bottomRight = Point2.y - Point3.y

        originXCoeff = (topLeft * bottomRight) - (bottomLeft * topRight)
        originXCoeffValue = (bottomRight * rhsTop) - (topRight * rhsBottom)
        originX = originXCoeffValue / originXCoeff

        originY = (((Point1.x - Point2.x) * originX) - rhsTop) / (-1 * (Point1.y - Point2.y))
        radius = sqrt(((Point1.x - originX)**2) + ((Point1.y - originY)**2))

        return originX, originY, radius

from shapely.geometry import Point
assert GetCircleFromPoints(Point((0,0)), Point((1,1)),Point((2,0))) == (1.0, 0.0, 1.0)

@tahir-hassan
Copy link
Author

Nice concise python code @rajanski.

It's the reason I'm looking into xonsh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment