create circle through 3 points in 3D space lisp

create circle through 3 points in 3D space lisp

Anonymous
Not applicable
3,022 Views
8 Replies
Message 1 of 9

create circle through 3 points in 3D space lisp

Anonymous
Not applicable

Hello. I am trying to make a program to create a circle by three points in 3D space, but it doesn't work. I understand that I have to use a coordinate system ... but I don't know how.

 

I would be glad to any advice. Thank.

 

0 Likes
Accepted solutions (1)
3,023 Views
8 Replies
Replies (8)
Message 2 of 9

cadffm
Consultant
Consultant

 

 


@Anonymous wrote:

 I understand that I have to use a coordinate system ... but I don't know how.


Do you try to create the circle by api programming or by simple controlling the native autocad commands*?

*thats what every draftsman does every day

 

Draftsman version:

1. Start Command UCS, set 3 point on your drawing plane (perfectly the 3 points for the Circle tangents ).

2. Start command CIRCLE, option 3P, use

 

For simple (Command  ...) statements, these are the main steps.

Ask User for 3 Points,

save the current ucs, set the new one, create the circle, set old ucs back.

 

_

For API programming | we are waiting for your response

 

 

Sebastian

0 Likes
Message 3 of 9

Anonymous
Not applicable

Thanks for the advice. I'm going to try now.

0 Likes
Message 4 of 9

_gile
Consultant
Consultant
Accepted solution

Hi,

 

If you do not want to use commands, you can try something like this:

(defun gc:GetVector (p1 p2) (mapcar '- p2 p1))

(defun gc:CrossProduct (v1 v2)
  (list	(- (* (cadr v1) (caddr v2)) (* (caddr v1) (cadr v2)))
	(- (* (caddr v1) (car v2)) (* (car v1) (caddr v2)))
	(- (* (car v1) (cadr v2)) (* (cadr v1) (car v2)))
  )
)

(defun gc:MidPoint (p1 p2)
  (mapcar (function (lambda (x1 x2) (/ (+ x1 x2) 2.))) p1 p2)
)

(defun circleBy3Points (p1 p2 p3 / v1 v2 norm m1 m2 cen)
  (setq	v1   (gc:GetVector p1 p2)
	v2   (gc:GetVector p2 p3)
	norm (gc:CrossProduct v1 v2)
	m1   (gc:Midpoint p1 p2)
	m2   (gc:Midpoint p2 p3)
	cen  (inters m1
		     (mapcar '+ m1 (gc:CrossProduct v1 norm))
		     m2
		     (mapcar '+ m2 (gc:CrossProduct v2 norm))
		     nil
	     )
  )
  (entmakex
    (list
      (cons 0 "CIRCLE")
      (cons 10 (trans cen 0 norm))
      (cons 40 (distance cen p1))
      (cons 210 norm)
    )
  )
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 9

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

Thanks for the advice. I'm going to try now.


If you try by having the User pick the 3 points using (getpoint), using them to set a new UCS, and drawing a 3-point Circle through them, be aware that you will need to use (trans) on the points to draw the Circle, (trans)lating their coordinates from their WCS values that (getpoint) will return, to the current UCS's coordinates for those points that will be needed for the Circle command.  >Read about it.<

Kent Cooper, AIA
0 Likes
Message 6 of 9

_gile
Consultant
Consultant

@Kent1Cooper  a écrit :

@Anonymous wrote:

Thanks for the advice. I'm going to try now.


If you try by having the User pick the 3 points using (getpoint), using them to set a new UCS, and drawing a 3-point Circle through them, be aware that you will need to use (trans) on the points to draw the Circle, (trans)lating their coordinates from their WCS values that (getpoint) will return, to the current UCS's coordinates for those points that will be needed for the Circle command.  >Read about it.<


I do not agree, getpoint returns a point according to the current UCS coordinates.

Basically all functions related to the AutoCAD editor as the getXXX functions, ssget, entsel, command(-s), vl-cmdf, ... work with current coordinate system.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 9

_gile
Consultant
Consultant

Here's what it could be using _UCS and _CIRCLE commands:

;; get points in current UCS
(setq p1 (getpoint "\nFirst point: "))
(setq p2 (getpoint "\nSecond point: "))
(setq p3 (getpoint "\nThird point: "))

;; store WCS points
(setq wp1 (trans p1 1 0))
(setq wp2 (trans p2 1 0))
(setq wp3 (trans p3 1 0))

;; set new UCS
(command "_.UCS" "_3p" "_non" p1 "_non" p2 "_non" p3)

;; transform WCS points to the new UCS
(setq p1 (trans wp1 0 1))
(setq p2 (trans wp2 0 1))
(setq p3 (trans wp3 0 1))

;; draw the circle
(command "_.CIRCLE" "_3p" "_non" p1 "_non" p2 "_non" p3)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 9

Kent1Cooper
Consultant
Consultant

@_gile wrote:

.... you will need to use (trans) on the points to draw the Circle, (trans)lating their coordinates from their WCS values that (getpoint) will return, to the current UCS's coordinates ....


I do not agree, getpoint returns a point according to the current UCS coordinates.

Basically all functions related to the AutoCAD editor as the getXXX functions, ssget, entsel, command(-s), vl-cmdf, ... work with current coordinate system.


So they don't need to be (trans)lated from the WCS -- I should have said current-at-the-time CS.  [I may have had in mind what you get when extracting points from entity data, which would be in the WCS.]  But since you will need to get the 3 points before  you are in the UCS in which you want to draw the Circle [because they will be needed to establish that UCS], their coordinates will not be in terms of that UCS when you get to drawing the Circle, so they will still need to be (trans)lated.  [That's easier if starting in the WCS than if starting in some other UCS.]

Kent Cooper, AIA
Message 9 of 9

Anonymous
Not applicable

Thanks a lot, it works great!

0 Likes