3-Point Circle & Arc Functions
See also Geometric Functions
Introduction
On this page I demonstrate a set of geometric functions which may be used to construct a Circle or Arc from three supplied points.
Each function may be tested with a non-dynamic or dynamic test program, the latter demonstrating real-time entity modification to create the illusion of a dynamic effect - this technique is unfortunately underpinned by the grread function to monitor user input, hence restricting the use of standard AutoCAD functionality such as Object Snap, Tracking, Orthomode, etc.
Finally, I utilise my Arc->Bulge function, taken from my set of Bulge Conversion Functions, to construct a function to create a 'PolyArc' (LWPolyline Arc Segment) from three supplied points.
3-Point Circle
Function Syntax | (LM:3PCircle <p1> <p2> <p3>) |
Current Version | 1.0 |
Donate |
Arguments | ||
---|---|---|
Symbol | Type | Description |
p1, p2, p3 | List | Points through which to construct the Circle |
Returns | ||
Type | Description | |
List | List of: (<center> <radius>) of Circle |
Function Description
This function will return a list of the center and radius of a circle whose circumference passes through three supplied points.
The function will return nil if the circle is undefined, such as the case if the three supplied points are collinear.
;; 3-Point Circle - Lee Mac ;; Returns the Center and Radius of the Circle defined ;; by three supplied points. (defun LM:3PCircle ( p1 p2 p3 / cn m1 m2 ) (setq m1 (mid p1 p2) m2 (mid p2 p3) ) (if (setq cn (inters m1 (polar m1 (+ (angle p1 p2) (/ pi 2.)) 1.0) m2 (polar m2 (+ (angle p2 p3) (/ pi 2.)) 1.0) nil ) ) (list cn (distance cn p1)) ) ) ;; Midpoint - Lee Mac ;; Returns the midpoint of two points (defun mid ( a b ) (mapcar (function (lambda ( a b ) (/ (+ a b) 2.0))) a b) )
Demonstration of Implementations of 3PCircle Function
Test Programs
Here are two programs with which to test the above LM:3PCircle function. 3PCircle will construct a circle from three selected points; 3PGrCircle will prompt for two points, then display a real-time preview of the circle whilst the user selects the third point.
(defun c:3PCircle ( / p1 p2 p3 lst ) (if (and (setq p1 (getpoint "\nSpecify 1st Point: ")) (setq p2 (getpoint "\nSpecify 2nd Point: " p1)) (setq p3 (getpoint "\nSpecify 3rd Point: " p2)) (setq lst (LM:3PCircle (trans p1 1 0) (trans p2 1 0) (trans p3 1 0))) ) (entmake (append '((0 . "CIRCLE")) (mapcar 'cons '(10 40) lst))) ) (princ) ) (defun c:3PGrCircle ( / p1 p2 p3 lst cir ) (if (and (setq p1 (getpoint "\nSpecify 1st Point: ")) (setq p2 (getpoint "\nSpecify 2nd Point: " p1)) (setq p3 (cadr (grread t 13 0))) (setq lst (LM:3PCircle (setq p1 (trans p1 1 0)) (setq p2 (trans p2 1 0)) (trans p3 1 0))) (setq cir (entmakex (append '((0 . "CIRCLE")) (mapcar 'cons '(10 40) lst)))) (setq cir (list (cons -1 cir))) (princ "\nSpecify 3rd Point: ") ) (while (= 5 (car (setq gr (grread t 13 0)))) (if (setq lst (LM:3PCircle p1 p2 (trans (cadr gr) 1 0))) (entmod (append cir (mapcar 'cons '(10 40) lst))) ) ) ) (princ) )
3-Point Arc
Function Syntax | (LM:3PArc <p1> <p2> <p3>) |
Current Version | 1.0 |
Donate |
Arguments | ||
---|---|---|
Symbol | Type | Description |
p1, p2, p3 | List | Points through which to construct the Arc |
Returns | ||
Type | Description | |
List | List of: (<center> <start angle> <end angle> <radius>) of Arc |
Function Description
This function will return a list of the center, start angle, end angle and radius of an arc passing through three supplied points, two of which are the endpoints of the arc.
The return values are ordered to be consistent with my 'LM:Arc->Bulge' and 'LM:Bulge->Arc' functions as part of my Bulge Conversion Functions.
The function will return nil if the arc is undefined, such as the case if the three supplied points are collinear.
;; 3-Point Arc - Lee Mac ;; Returns the Center, Start/End Angle and Radius of the ;; Arc defined by three supplied points. (defun LM:3PArc ( p1 p2 p3 / cn m1 m2 ) (setq m1 (mid p1 p2) m2 (mid p2 p3) ) (if (setq cn (inters m1 (polar m1 (+ (angle p1 p2) (/ pi 2.)) 1.0) m2 (polar m2 (+ (angle p2 p3) (/ pi 2.)) 1.0) nil ) ) (append (list cn) (if (LM:Clockwise-p p1 p2 p3) (list (angle cn p3) (angle cn p1)) (list (angle cn p1) (angle cn p3)) ) (list (distance cn p1)) ) ) ) ;; Midpoint - Lee Mac ;; Returns the midpoint of two points (defun mid ( a b ) (mapcar (function (lambda ( a b ) (/ (+ a b) 2.0))) a b) ) ;; Clockwise-p - Lee Mac ;; Returns T if p1,p2,p3 are clockwise oriented (defun LM:Clockwise-p ( p1 p2 p3 ) (< (* (- (car p2) (car p1)) (- (cadr p3) (cadr p1))) (* (- (cadr p2) (cadr p1)) (- (car p3) (car p1))) ) )
Demonstration of Implementations of 3PArc Function
Test Programs
Here are again two programs with which to test the above LM:3PArc function. 3PArc will construct an arc from three selected points; 3PGrArc will prompt for two points, then display a real-time preview of the arc whilst the user selects the third point.
(defun c:3PArc ( / p1 p2 p3 lst ) (if (and (setq p1 (getpoint "\nSpecify 1st Point: ")) (setq p2 (getpoint "\nSpecify 2nd Point: " p1)) (setq p3 (getpoint "\nSpecify 3rd Point: " p2)) (setq lst (LM:3PArc (trans p1 1 0) (trans p2 1 0) (trans p3 1 0))) ) (entmake (append '((0 . "ARC")) (mapcar 'cons '(10 50 51 40) lst))) ) (princ) ) (defun c:3PGrArc ( / p1 p2 p3 lst arc ) (if (and (setq p1 (getpoint "\nSpecify 1st Point: ")) (setq p2 (getpoint "\nSpecify 2nd Point: " p1)) (setq p3 (cadr (grread t 13 0))) (setq lst (LM:3PArc (setq p1 (trans p1 1 0)) (setq p2 (trans p2 1 0)) (trans p3 1 0))) (setq arc (entmakex (append '((0 . "ARC")) (mapcar 'cons '(10 50 51 40) lst)))) (setq arc (list (cons -1 arc))) (princ "\nSpecify 3rd Point: ") ) (while (= 5 (car (setq gr (grread t 13 0)))) (if (setq lst (LM:3PArc p1 p2 (trans (cadr gr) 1 0))) (entmod (append arc (mapcar 'cons '(10 50 51 40) lst))) ) ) ) (princ) )
3-Point PolyArc
Finally, below is a program, 3PPolyArc, which utilises a combination of my LM:3PArc and LM:Arc->Bulge functions to create a 3-Point 'PolyArc' - that is, an LWPolyline arc segment constructed from three points.
(defun c:3PPolyArc ( / p1 p2 p3 lst ) (if (and (setq p1 (getpoint "\nSpecify 1st Point: ")) (setq p2 (getpoint "\nSpecify 2nd Point: " p1)) (setq p3 (getpoint "\nSpecify 3rd Point: " p2)) (setq lst (LM:3PArc (trans p1 1 0) (trans p2 1 0) (trans p3 1 0))) (setq lst (apply 'LM:Arc->Bulge lst)) ) (entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") '(90 . 2) '(70 . 0) (cons 10 (car lst)) (cons 42 (caddr lst)) (cons 10 (cadr lst)) ) ) ) (princ) ) ;; Arc to Bulge - Lee Mac 2011 ;; cen - Centre ;; ang1 - Start Angle ;; ang2 - End Angle ;; rad - Radius ;; Returns: (<vertex> <vertex> <bulge>) (defun LM:Arc->Bulge ( cen ang1 ang2 rad ) (list (polar cen ang1 rad) (polar cen ang2 rad) ( (lambda ( a ) (/ (sin a) (cos a))) (/ (rem (+ pi pi (- ang2 ang1)) (+ pi pi)) 4.)) ) )
See also Geometric Functions