(polar zen (angle zen (mapcar '(lambda (x) (* 0.5 x))(mapcar '+ start end))) rad)
which means ..Hi Kerry
thanks - you were to quick for my edit above. I'm sorry. But nevertheless, I have to learn a lot about the "vlax-curve" functions.
(defun _mid (ename / ep)
(if (not (vl-catch-all-error-p (setq ep (vl-catch-all-apply 'vlax-curve-getendparam (list ename)))))
(vlax-curve-getpointatdist ename (/ (vlax-curve-getdistatparam ename ep) 2.))
)
)
;; (_mid (car (entsel)))
ronjonp,
Mine is similar ; except I multiply by 0.5 instead of dividing by 2.0
And perhaps efficiency is affected if the value or it's reciprocal is an integer.
On binary hardware, a multiply or divide by two is a simple shift-by-one, which is as easy as it gets.Usually if you're compiling your code and the compiler actually optimizes for that yes. If AutoLisp does it in FAS or even in its interpreted state I'm not sure. Also these are floating point numbers, so a simple shifting of bits isn't exactly how it happens: rather an increment/decrement of the exponent (might even be faster). So if ALisp's interpreter and/or compiler recognises multiplication / division by 2, then yes it should perform faster, else it'll use the longwinded way - in which case multiplication will always be faster.
_$ (quickbench '((/ 123456 2) (* 123456 2) (* 123456 0.5) (/ 123456 2.0) (/ 123456. 2) (* 123456. 2) (* 123456. 0.5) (/ 123456. 2.0) (/ 123456 3) (* 123456 3) (* 123456 0.3333333333333333) (/ 123456 3.0) (/ 123456. 3) (* 123456. 3) (* 123456. 0.33333333333333333333333333333333) (/ 123456. 3.0)))
Benchmarking ................ done for 32768 iterations. Sorted from fastest.
Statement Increment Time(ms) Normalize Relative
--------------------------------------------------------------------------------
(/ 123456 3) 32768 1137 1137 1.08
(* 123456 2) 32768 1170 1170 1.05
(/ 123456.0 3.0) 32768 1171 1171 1.05
(* 123456 3) 32768 1185 1185 1.04
(* 123456.0 0.333333) 32768 1185 1185 1.04
(/ 123456 2) 32768 1186 1186 1.04
(/ 123456.0 2) 32768 1186 1186 1.04
(/ 123456 3.0) 32768 1187 1187 1.04
(* 123456 0.5) 32768 1201 1201 1.03
(/ 123456.0 3) 32768 1201 1201 1.03
(* 123456.0 3) 32768 1202 1202 1.02
(/ 123456 2.0) 32768 1216 1216 1.01
(* 123456.0 2) 32768 1217 1217 1.01
(* 123456.0 0.5) 32768 1217 1217 1.01
(* 123456 0.333333) 32768 1218 1218 1.01
(/ 123456.0 2.0) 32768 1232 1232 1.00
--------------------------------------------------------------------------------
< .. >
As for the OP: If you want to find all sorts of other calcs on arcs, I've found this (http://www.afralisp.net/archive/lisp/Bulges1.htm) to be a great resource.
Hi
interesting discussions here. The "vlax-curve"-functions are great, but how to handle it with an basic algorithm for pocket calculators?
But, back to the roots...
I saw that my "solution" I posted above has some lacks - especially if the "included angle > pi".
Example: I have two following red lines with points A - B - C. With A - B - C I can create an arc, and with 3P-arc-calculation I can calculate CEN and RAD. But how to calculate the included angle, if the arc is > PI or if the arc runs over the "0 PI"? How to calculate the MID?
EDIT: Solution:Code: [Select](polar zen (angle zen (mapcar '(lambda (x) (* 0.5 x))(mapcar '+ start end))) rad)
which means ..
- calculate the middle of START and END (helppoint)
- calculate the point with Polar from centre with direction to helppoint and with length of radius
Should do it ...
< .. > but how to handle it with an basic algorithm for pocket calculators?
...I think Peter wants a solution that is purely mathematical , not object/entity based....Yes, this was my original target. But in the meantime I see that the "cost/efficiency ratio" of the pure mathematical solution is very bad; I hoped it could be a "two liner".
Thanks Owen, I like it:And perhaps efficiency is affected if the value or it's reciprocal is an integer.
On binary hardware, a multiply or divide by two is a simple shift-by-one, which is as easy as it gets.
Ok. This is the mathematical solution in WCS, assuming valid points. Return mid point of arc drawn in trigonometric direction....I think Peter wants a solution that is purely mathematical , not object/entity based....Yes, this was my original target. But in the meantime I see that the "cost/efficiency ratio" of the pure mathematical solution is very bad; I hoped it could be a "two liner".
But it is not, and I'm very happy with the entity-based solution you showed me. So I don't want to waste your time any longer, for me it is solved.
(But if somebody has a solution and wants to share it - it would be appreciated)
...Compatible with WCS points in planes parallel to WCS plane.And based on an arc which turns counter-clockwise. And now I see (sorry again, the last days were a little bit stressing) that my first posting was not precise as it should be ...
...Compatible with WCS points in planes parallel to WCS plane.And based on an arc which turns counter-clockwise.
One of the many benefits of AutoLISP is the ability to utilize entities etc. as part of the solution to problems, these benefits where met with great skepticism when civil/survey software really started to take advantage of this in the late 80's. Many worried the accuracy would be lost, when in reality the exact opposite happened.And by doing so you are actually using ACad as if it's a Math library where someone's already written all the needed calculation functions for you. It's nothing dissimilar from someone using the Math library in DotNet to calculate stuff like GCD instead of rolling their own function(s).
In future , please don't change the content of the original post in any significant manner because it makes following the thread very difficult for anyone attempting to follow along later.
<...>
It is also a waste of the time of anyone who is attempting to help you.
I have an arc, given with startpoint, endpoint, radius and centre <...> I have no idea how to calculate the MID of the arc
;; For 3D ARC
(defun defl (a b c / d)
;_Get 3 point inter angle
;_by Ymg
(abs (- (setq d (- (angle b a) (angle b c)))
(* (fix (/ d pi)) (+ pi pi)))))
;; Product
(defun v^v (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)))))
;; Unit
(defun v2u (v / d)
(setq d (sqrt (apply (function +) (mapcar (function *) v v))))
(if (/= d 0)
(mapcar (function (lambda (x) (/ x d))) v)))
;;
(defun amid (a b c / n s d e f p)
;; a -- the Start Point of Arc in WCS
;; b -- the point on Arc in WCS
;; c -- the End Point of Arc in WCS
(setq n (v2u (v^v (mapcar '- b a) (mapcar '- c a)))
a (trans a 0 n)
b (trans b 0 n)
c (trans c 0 n));_trans wcs points into ocs
;; main routine
(setq s (car
(trans (mapcar (function -) b c) 0 (mapcar (function -) a c))) ;_check B side of AC
s (/ s (abs s)) ;_sign
d (defl C A B) ;_ang α
e (defl A C B) ;_ang β
f (/ (+ d e) 2.) ;_ang γ
d (- (angle a c) (* s f)) ;_new direction of AM
e (+ (angle c a) (* s f)) ;_new direction of CM
)
(setq p (inters a
(mapcar '+ a (list (cos d) (sin d)))
c
(mapcar '+ c (list (cos e) (sin e)))
nil)) ;_intersect with v1 v2 based on A C
(trans p n 0);_trans result
)
;; For test in WCS
(defun c:test (/ a b c m)
(if (and
(setq a (getpoint "\nSelect Start Point of Arc :"))
(setq b
(getpoint
a
"\nSelect One Point on the Arc (Not Start or End Point) :"))
(setq c (getpoint b "Select End Point of Arc :"))
(not (vl-some 'equal (list a b c) (list b c a))))
(progn
(setq m (amid a b c))
(entmake (list (cons 0 "LINE")
(cons 10 a)
(cons 11 m)))
)
)
(princ)
)
Nice code Lee ! :-)
To get 3P-ARC midpoint , I write some one method , but too long . I hope it can be simplified .
Nice code Lee ! :-)
Thanks! :-)To get 3P-ARC midpoint , I write some one method , but too long . I hope it can be simplified .
Here is my version:Code - Auto/Visual Lisp: [Select]
To test:Code - Auto/Visual Lisp: [Select]
) ) ) )