calculate a point between two other points

calculate a point between two other points

Anonymous
Not applicable
385 Views
62 Replies
Message 1 of 63

calculate a point between two other points

Anonymous
Not applicable
Hello group,

Using LISP, how would one calc a point (p3), between two other points (p1
and p2), a given distance (dist) from p1?
Example:

p1 = (2.0 2.5 0.0)
p2 = (6.5 2.2 1.0)
dist = 1.5
p3 = ?

I'm sure there is a simple formula, however, I failed 3rd grade math five
times.
--
Eric S. eschneider@jensenprecast.com
0 Likes
386 Views
62 Replies
Replies (62)
Message 41 of 63

Anonymous
Not applicable
Not exactly. If you pass in (0 0 0) and (12 12 12) you get (3.4641 3.4641
3.4641). You'll get 6 back as a midpoint for the Z ordinate only if the X
and Y ordinates are identical in both points.

--
Attitudes are contagious. Is yours worth catching?
http://www.acadx.com

"Cadentity.com" wrote in message
news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
> I'm not debating that it doesn't return the x,y and z.
>
> It's suppose to return in space the proper location of z.
>
> If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
0 Likes
Message 42 of 63

Anonymous
Not applicable
(setq p1 '(10.0 10.0 10.0)
p2 '(0.0 0.0 0.0)
dist (/ (distance p1 p2) 2.0)
) ;_ closes setq

(point-on-line p1 p2 dist) returns: (5.0 5.0 5.0)

Isn't this what you want?

--
R. Robert Bell, MCSE
Xtending the Power
www.acadx.com

"Cadentity.com" wrote in message
news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
| I'm not debating that it doesn't return the x,y and z.
|
| It's suppose to return in space the proper location of z.
|
| If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
|
| rudy@cadentity.com
|
0 Likes
Message 43 of 63

Anonymous
Not applicable
correct.

Frank Oquendo wrote in message
news:61A91B8475702D596FA8148CA4C85F71@in.WebX.SaUCah8kaAW...
> Not exactly. If you pass in (0 0 0) and (12 12 12) you get (3.4641 3.4641
> 3.4641). You'll get 6 back as a midpoint for the Z ordinate only if the X
> and Y ordinates are identical in both points.
>
> --
> Attitudes are contagious. Is yours worth catching?
> http://www.acadx.com
>
> "Cadentity.com" wrote in message
> news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
> > I'm not debating that it doesn't return the x,y and z.
> >
> > It's suppose to return in space the proper location of z.
> >
> > If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
>
0 Likes
Message 44 of 63

Anonymous
Not applicable
You can't do that.

You have to account for a negative 'z' also.

R. Robert Bell wrote in message
news:8775501B4C07A9DBE833652C1A32712F@in.WebX.SaUCah8kaAW...
> (setq p1 '(10.0 10.0 10.0)
> p2 '(0.0 0.0 0.0)
> dist (/ (distance p1 p2) 2.0)
> ) ;_ closes setq
>
> (point-on-line p1 p2 dist) returns: (5.0 5.0 5.0)
>
> Isn't this what you want?
>
> --
> R. Robert Bell, MCSE
> Xtending the Power
> www.acadx.com
>
> "Cadentity.com" wrote in message
> news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
> | I'm not debating that it doesn't return the x,y and z.
> |
> | It's suppose to return in space the proper location of z.
> |
> | If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
> |
> | rudy@cadentity.com
> |
>
0 Likes
Message 45 of 63

Anonymous
Not applicable
(setq p1 '(10.0 10.0 10.0)
p2 '(0.0 0.0 -10.0)
dist (/ (distance p1 p2) 2.0)
) ;_ closes setq

(point-on-line p1 p2 dist) returns: (5.0 5.0 0.0)

--
R. Robert Bell, MCSE
Xtending the Power
www.acadx.com

"Cadentity.com" wrote in message
news:A9663A2EDBD564067002575908014277@in.WebX.SaUCah8kaAW...
| You can't do that.
|
| You have to account for a negative 'z' also.
|
| R. Robert Bell wrote in message
| news:8775501B4C07A9DBE833652C1A32712F@in.WebX.SaUCah8kaAW...
| > (setq p1 '(10.0 10.0 10.0)
| > p2 '(0.0 0.0 0.0)
| > dist (/ (distance p1 p2) 2.0)
| > ) ;_ closes setq
| >
| > (point-on-line p1 p2 dist) returns: (5.0 5.0 5.0)
| >
| > Isn't this what you want?
| >
| > --
| > R. Robert Bell, MCSE
| > Xtending the Power
| > www.acadx.com
| >
| > "Cadentity.com" wrote in message
| > news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
| > | I'm not debating that it doesn't return the x,y and z.
| > |
| > | It's suppose to return in space the proper location of z.
| > |
| > | If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
| > |
| > | rudy@cadentity.com
| > |
| >
|
0 Likes
Message 46 of 63

Anonymous
Not applicable
Yes. I reviewed your post.

Duhp! Bart!

In it's self the function doesn't actually divide the distance.

Perhaps I missed it.

The distance must be divided before, "I see, said the blind man".

Slap! Slap! wake-up!

rudy@cadentity.com

R. Robert Bell wrote in message
news:5F0E45EA2954BFFF8904BDB357B641BF@in.WebX.SaUCah8kaAW...
> (setq p1 '(10.0 10.0 10.0)
> p2 '(0.0 0.0 -10.0)
> dist (/ (distance p1 p2) 2.0)
> ) ;_ closes setq
>
> (point-on-line p1 p2 dist) returns: (5.0 5.0 0.0)
>
> --
> R. Robert Bell, MCSE
> Xtending the Power
> www.acadx.com
>
> "Cadentity.com" wrote in message
> news:A9663A2EDBD564067002575908014277@in.WebX.SaUCah8kaAW...
> | You can't do that.
> |
> | You have to account for a negative 'z' also.
> |
> | R. Robert Bell wrote in message
> | news:8775501B4C07A9DBE833652C1A32712F@in.WebX.SaUCah8kaAW...
> | > (setq p1 '(10.0 10.0 10.0)
> | > p2 '(0.0 0.0 0.0)
> | > dist (/ (distance p1 p2) 2.0)
> | > ) ;_ closes setq
> | >
> | > (point-on-line p1 p2 dist) returns: (5.0 5.0 5.0)
> | >
> | > Isn't this what you want?
> | >
> | > --
> | > R. Robert Bell, MCSE
> | > Xtending the Power
> | > www.acadx.com
> | >
> | > "Cadentity.com" wrote in message
> | > news:EB6BC9ABC39566C5FF31495BB7B77E54@in.WebX.SaUCah8kaAW...
> | > | I'm not debating that it doesn't return the x,y and z.
> | > |
> | > | It's suppose to return in space the proper location of z.
> | > |
> | > | If one 'z' is at 0 and the other 'z' is at 12, the midpoint is 6.
> | > |
> | > | rudy@cadentity.com
> | > |
> | >
> |
>
0 Likes
Message 47 of 63

Anonymous
Not applicable
In this case, a faster version of what I wrote would
be largely pointless, because in a scenario where you
would be calling the code many times, to find multiple
points on the same line, the code should be optimized
to eliminate all redundant expressions whose results
are constant for the line (e.g., the distance between
the endpoints and the delta).

Jadranko Stjepanovic wrote:
>
> This one is faster (45%, roughly measured):
>
> (defun point-along-line (p1 p2 dist / sc)
> (setq sc (/ dist (distance p1 p2)))
> (mapcar '(lambda (p1 p2) (+ p1 (* sc (- p2 p1)))) p1 p2)
> )
>
> This one is slightly slower than the previous one, but wont fail with
> "divide by zero error" if p1 equals p2:
>
> (defun point-along-line (p1 p2 dist / d sc)
> (if (zerop (setq d (distance p1 p2)))
> p1
> (progn
> (setq sc (/ dist d))
> (mapcar '(lambda (p1 p2) (+ p1 (* sc (- p2 p1)))) p1 p2)
> )
> )
> )
>
> This one is short and funny:
>
> (c:cal "pld(p1,p2,d)")
>
> Jadranko
>
> Tony Tanzillo wrote in message <39A44FAA.16A37871@worldnet.att.net>...
> >What Frank posted doesn't work in the 3D case, as
> >original example requires.
> >
> >;; (point-on-line )
> >;;
> >;; Returns a point on the line -
> >;; a specified distance from
> >
> >(defun point-on-line (p1 p2 dist / sc)
> > (setq sc (/ dist (distance p1 p2)))
> > (mapcar '+ p1
> > (mapcar '*
> > (mapcar '- p2 p1)
> > (list sc sc sc)
> > )
> > )
> >)
> >

--

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes
Message 48 of 63

Anonymous
Not applicable
Tony,

In my opinion it's not pointless to write more efficient code, especially if
it doesn't introduce negative impacts on the other side (size, complexity,
portability...).
Basically, both solutions are based on the same algorithm. Mine is just
coded in a more efficient way, and I think it makes sense to do so.

Regards,
Jadranko

Tony Tanzillo wrote in message <39A583E7.AB502BA0@worldnet.att.net>...
>In this case, a faster version of what I wrote would
>be largely pointless, because in a scenario where you
>would be calling the code many times, to find multiple
>points on the same line, the code should be optimized
>to eliminate all redundant expressions whose results
>are constant for the line (e.g., the distance between
>the endpoints and the delta).
>
>Jadranko Stjepanovic wrote:
>>
>> This one is faster (45%, roughly measured):
>>
>> (defun point-along-line (p1 p2 dist / sc)
>> (setq sc (/ dist (distance p1 p2)))
>> (mapcar '(lambda (p1 p2) (+ p1 (* sc (- p2 p1)))) p1 p2)
>> )
>>
>> This one is slightly slower than the previous one, but wont fail with
>> "divide by zero error" if p1 equals p2:
>>
>> (defun point-along-line (p1 p2 dist / d sc)
>> (if (zerop (setq d (distance p1 p2)))
>> p1
>> (progn
>> (setq sc (/ dist d))
>> (mapcar '(lambda (p1 p2) (+ p1 (* sc (- p2 p1)))) p1 p2)
>> )
>> )
>> )
>>
>> This one is short and funny:
>>
>> (c:cal "pld(p1,p2,d)")
>>
>> Jadranko
>>
>> Tony Tanzillo wrote in message <39A44FAA.16A37871@worldnet.att.net>...
>> >What Frank posted doesn't work in the 3D case, as
>> >original example requires.
>> >
>> >;; (point-on-line )
>> >;;
>> >;; Returns a point on the line -
>> >;; a specified distance from
>> >
>> >(defun point-on-line (p1 p2 dist / sc)
>> > (setq sc (/ dist (distance p1 p2)))
>> > (mapcar '+ p1
>> > (mapcar '*
>> > (mapcar '- p2 p1)
>> > (list sc sc sc)
>> > )
>> > )
>> >)
>> >
>
>--
>
>Checkout the AcadX(tm) ActiveX Extension Library at:
>
> http://www.caddzone.com/acadx/acadx.htm
>
>/*********************************************************/
>/* Tony Tanzillo Design Automation Consulting */
>/* Programming & Customization for AutoCAD & Compatibles */
>/* ----------------------------------------------------- */
>/* tony.tanzillo@worldnet.att.net */
>/* http://www.caddzone.com */
>/*********************************************************/
0 Likes
Message 49 of 63

Anonymous
Not applicable
Cliff,

I don't think it makes too much sense to avoid (distance) function, except
for recreational purposes.
What makes sense, if you want efficient code, is to avoid transcedental
functions like (expt).
So, my suggestion for improvement of your function is to replace

(lambda (a b) (expt (- a b) 2.0))

with:

(lambda (a b ) (* (- a b) (- a b)))

or even better, with:

(lambda (a b / c) (* (setq c (- a b)) c))

Now, let's sit and wait Robert with performance results...

Jadranko

Cliff Middleton wrote in message
<47769F75527D27E7BD40F621D5C688F8@in.WebX.SaUCah8kaAW>...
>I should point out the obvious lack of knowlege behind this statement. Not
>only should the (angle) function be excluded but it must be excluded since
>it projects the angle between 3D points onto the current construction
plane.
>This is why (polar p1 (angle p1 p2) d) while fine for 2D points, does not
>return the correct coord for 3D points.
>
>What I should have asked for was to exclude the (distance) function. I
find
>that it helps to retard the atrophy of brain cells to "manually" do the
math
>that we normally rely on functions to do for us plus I learn things (like
>the caveat of the angle function with 3D points).
>
>So I offer the following for comments, processing speed analysis,
>whatever...
>
>(defun point-on-line (p1 p2 d1 / d2 sc)
> (setq
> d2 (sqrt (apply '+ (mapcar '(lambda (a b) (expt (- a b) 2.0)) p1 p2)))
> sc (/ d1 d2)
> )
> (mapcar '(lambda (a b) (+ a (* sc (- b a)))) p1 p2)
>)
>
>Credit to my son for the formula to calculate the distance between two
>points [there may be other and better ways to lispify it] and the
>(mapcar...) is from Mr. Stjepanovics contribution.
>
>Thank you for the clinic and happy trails, all.
>
>Cliffo
>
0 Likes
Message 50 of 63

Anonymous
Not applicable
Jadranko Stjepanovic wrote:
>
> Tony,
>
> In my opinion it's not pointless to write more efficient code, especially if
> it doesn't introduce negative impacts on the other side (size, complexity,
> portability...).

Sorry, I don't agree.

For this particular task, the only case where more
effecient code would be important, is the case where
it must be called numerous times, to find multiple
points on a line.

And, neither my code, or your 'faster' version
of it, is the most effecient way to do that.

If the code is not used frequently, the *extremely*
tiny performance difference between them is of little
importance, and would *never* be noticable.

I post plenty of functions here that could be optimzed
to be faster, but in many cases, they would have to be
written differently in order to be useful in any scenario
where a very high frequency of use would make effeciency
imporatant.

When it comes to finding a single point on a line, the
few milliseconds that your code saves is insignificant.

For finding multiple points on a single line, given a
list of distances, then effeciency does become important,
but nither my code or yours offers maximum effeciency
for that task.

--

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes
Message 51 of 63

Anonymous
Not applicable
Stop telling me it doesn't work, and show me how
it doesn't work. It works fine for me, so you must
be doing something wrong.

Post a transcript of your command line showing the
arguments and result.

"Cadentity.Com" wrote:
>
> Here's a repeat of my reply, since my message disappeared.
>
> I don't use running object snaps, that a bad habit.
>
> Your function still doesn't return the right point.
>
> --
> rudy@cadentity.com
> Practical Utilities for Productive Solutions
>
> Tony Tanzillo wrote in message
> news:39A47E59.4102C2E8@worldnet.att.net...
> > "Cadentity.com" wrote:
> > >
> > > I tried it and it returned the same 'Z' as one of the points.
> > >
> > > ..........
> > >
> > > I tried it (3)three times, differing points
> >
> > Try turning off your object snap.
> >
> > --
> >
> > Checkout the AcadX(tm) ActiveX Extension Library at:
> >
> > http://www.caddzone.com/acadx/acadx.htm
> >
> > /*********************************************************/
> > /* Tony Tanzillo Design Automation Consulting */
> > /* Programming & Customization for AutoCAD & Compatibles */
> > /* ----------------------------------------------------- */
> > /* tony.tanzillo@worldnet.att.net */
> > /* http://www.caddzone.com */
> > /*********************************************************/

--

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes
Message 52 of 63

Anonymous
Not applicable
Tony Tanzillo wrote in message <39A672F1.3231E497@worldnet.att.net>...
>Jadranko Stjepanovic wrote:
>>
>> Tony,
>>
>> In my opinion it's not pointless to write more efficient code, especially
if
>> it doesn't introduce negative impacts on the other side (size,
complexity,
>> portability...).
>
>Sorry, I don't agree.

I don't understand why. If you can use faster function without any
additional cost, why should you use a slower one?

>For this particular task, the only case where more
>effecient code would be important, is the case where
>it must be called numerous times, to find multiple
>points on a line.

Not exactly. You can use it to find multiple points on multiple lines...
Sure it's not optimized to find multiple poinnts on a single line. It was
not intended to be.

>And, neither my code, or your 'faster' version
>of it, is the most effecient way to do that.

Probably not. I'll be happy to see more efficient one, and I wouldn't be
suprised if it will be written by you. But until then my function is faster
(not only 'faster') than yours 🐵

>If the code is not used frequently, the *extremely*
>tiny performance difference between them is of little
>importance, and would *never* be noticable.
>

The 'tiny performance difference' is 11% according to Roberts measurments
and roughly 50% according to mine. In some sceniarios it will not be
noticable, but I still think it's very brave to claim it will *never* be
noticable.

>I post plenty of functions here that could be optimzed
>to be faster, but in many cases, they would have to be
>written differently in order to be useful in any scenario
>where a very high frequency of use would make effeciency
>imporatant.
>
>When it comes to finding a single point on a line, the
>few milliseconds that your code saves is insignificant.
>
>For finding multiple points on a single line, given a
>list of distances, then effeciency does become important,
>but nither my code or yours offers maximum effeciency
>for that task.
>
This is not 'no additional cost' case. This is special case which requires
special approach. I was talking about *minor* change in code which results
in *more than measurable* performance difference.

This is not about point-on-line function, this is about writing the good and
efficient code. You can write many other functions 'your' way or 'mine'.
When performance differences in all that code add up, it will probably
result in noticable performance difference of complete application.

I see this newsgorup as a forum for promoting good programing practices, and
you as one of the major contributors from whom I learned a lot. That's why I
was surprised by lack of olympic spirit in your replay to benign and
constructive post.

Thanks again for your posts,
Jadranko

P.S. For firefighters on duty among readers of this newsgroup, this is still
academic discussion.
0 Likes
Message 53 of 63

Anonymous
Not applicable
Only saved about 4%, in my (un)scientific tests.

--
R. Robert Bell, MCSE
Xtending the Power
www.acadx.com

"Jadranko Stjepanovic" wrote in message
news:4648EEDDE705AFE6301148E167327D20@in.WebX.SaUCah8kaAW...
| Cliff,
|
| (lambda (a b / c) (* (setq c (- a b)) c))
|
| Now, let's sit and wait Robert with performance results...
|
0 Likes
Message 54 of 63

Anonymous
Not applicable
Thanks for the tip Jadranko and for the speed test Robert.

(funny...every time I see this thread I hear the tune "this is the song that
never ends...")

Cliff (can't wait to check this thread Monday) Middleton

Jadranko Stjepanovic wrote in message
news:4648EEDDE705AFE6301148E167327D20@in.WebX.SaUCah8kaAW...
| Cliff,
|
| I don't think it makes too much sense to avoid (distance) function, except
| for recreational purposes.
| What makes sense, if you want efficient code, is to avoid transcedental
| functions like (expt).
| So, my suggestion for improvement of your function is to replace
|
| (lambda (a b) (expt (- a b) 2.0))
|
| with:
|
| (lambda (a b ) (* (- a b) (- a b)))
|
| or even better, with:
|
| (lambda (a b / c) (* (setq c (- a b)) c))
|
| Now, let's sit and wait Robert with performance results...
|
| Jadranko
|
| Cliff Middleton wrote in message
| <47769F75527D27E7BD40F621D5C688F8@in.WebX.SaUCah8kaAW>...
| >I should point out the obvious lack of knowlege behind this statement.
Not
| >only should the (angle) function be excluded but it must be excluded
since
| >it projects the angle between 3D points onto the current construction
| plane.
| >This is why (polar p1 (angle p1 p2) d) while fine for 2D points, does not
| >return the correct coord for 3D points.
| >
| >What I should have asked for was to exclude the (distance) function. I
| find
| >that it helps to retard the atrophy of brain cells to "manually" do the
| math
| >that we normally rely on functions to do for us plus I learn things (like
| >the caveat of the angle function with 3D points).
| >
| >So I offer the following for comments, processing speed analysis,
| >whatever...
| >
| >(defun point-on-line (p1 p2 d1 / d2 sc)
| > (setq
| > d2 (sqrt (apply '+ (mapcar '(lambda (a b) (expt (- a b) 2.0)) p1 p2)))
| > sc (/ d1 d2)
| > )
| > (mapcar '(lambda (a b) (+ a (* sc (- b a)))) p1 p2)
| >)
| >
| >Credit to my son for the formula to calculate the distance between two
| >points [there may be other and better ways to lispify it] and the
| >(mapcar...) is from Mr. Stjepanovics contribution.
| >
| >Thank you for the clinic and happy trails, all.
| >
| >Cliffo
| >
|
0 Likes
Message 55 of 63

Anonymous
Not applicable
So which, now, is the very fastest?
--
Eric S. eschneider@jensenprecast.com

P.S. See what I've gone and started?
0 Likes
Message 56 of 63

Anonymous
Not applicable
Jadranko's is faster, but the difference is
totally imperceptible for anything less than
10,000 iterations.

If somoeone maintains that performance and
effeciency is so important in this case, to
make an such an issue of it, then they're
using the wrong programming language from
the outset.

Eric Schneider wrote:
>
> So which, now, is the very fastest?
> --
> Eric S. eschneider@jensenprecast.com
>
> P.S. See what I've gone and started?

--

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes
Message 57 of 63

Anonymous
Not applicable
Out of curiousity,why wouldnt one use the faster function? More overhead?
More complex code?
--
Eric S. eschneider@jensenprecast.com
0 Likes
Message 58 of 63

Anonymous
Not applicable
There are plenty of times when the pursuit of performance becomes academic.
However, I'd agree with Jadranko on this one: if chasing down those two
milliseconds doesn't add unnecessary complexity to the code, there's no real
reason not to do so.

--
Attitudes are contagious. Is yours worth catching?
http://www.acadx.com

Eric Schneider wrote in message
news:51E4EC615B281377D00F0B344B174129@in.WebX.SaUCah8kaAW...
> Out of curiousity,why wouldnt one use the faster function? More overhead?
> More complex code?
> --
> Eric S. eschneider@jensenprecast.com
>
0 Likes
Message 59 of 63

Anonymous
Not applicable
Jadranko Stjepanovic wrote:
>
> I don't understand why. If you can use faster function without any
> additional cost, why should you use a slower one?

I didn't say you should not use a slower one. In purely
academic terms, you should always use the faster code,
when performance is important.

What I am trying to tell you, is that the way both
of these two functions are written, precludes their
use in any scenario where effeciency/performance is
important.

That is because they are both separate functions that
must be called once for each line (or each point on
the same line), and it is the overhead of multiple
function calls that makes both of them ineffecient
for any iterative use.

> Not exactly. You can use it to find multiple points on
> multiple lines...

It doesn't matter whether it's a single point on many
lines, or many points on a single line. Either way, the
encapsulation of the code to get one point on line line,
is NOT an effecient approach, when the goal is to use
the code iteratively, to process multiple lines, or
to get mutlipole points on a single line.

So, What I'm trying to impress on you, is that while the
version of the function you posted is definitely faster
than the one I posted, it really does not matter, in any
scenario where the use of either is appropriate.

I'm not trying to belittle your point, and it is
well taken. What I am trying to say to you is that
it's pointless to make an issue of such a minute
performance difference for two versions of a function
when both of them are approriate only for *infrequent*
use, not for iterative use. And, if infrequent use is
the only scenario where either of these two functions
are valid, then it is the infrequent use of either
that is what makes the minute performance difference
largely irrelevant.

--

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes
Message 60 of 63

Anonymous
Not applicable
Eric Schneider wrote:
>
> Out of curiousity,why wouldnt one use the faster function? More overhead?
> More complex code?
> --
> Eric S. eschneider@jensenprecast.com

You can in some cases, make a case for using a slower
version of a function, for the sake of more readable
and maintainable code, but I don't think that in this
case it would be valid, and I am not suggestiong that
you should not use the faster one. By all means, use
Jadranko's version. However, in any context where its
use is what I consider valid, there is little-to-no
performance benefit.

Neiether version of the function posted is appropriate
for use in a scenario where the relative effeciency of
either would have any perceptible difference, because
neither the slow or the faster version of this function
is an effecient approach in a scenario where it is being
used iteratively (the only scenario where effeciency is
meaningful).

For example:

(setq list-of-lines
'(( )...) ;; A list of many lines
)

;; Process each line against a single distance,
;; and get a list of points (one for each line)
;; back:

(mapcar
'(lambda (line)
(point-on-line (car line) (cadr line) dist)
)
lines
)

That was an example of using (point-on-line)
iteratively, where the distance is a constant.

Here is another example of using (point-on-line)
iteratively, where the line is a constant, and
there are many distances:

(setq distances '( ...))
(setq p1 (Getpoint....)
(setq p2 (getpoint...)

(mapcar
'(lambda (distance)
(point-on-line p1 p2 distance)
)
list-of-distances
)

Both examples are ineffecient ways to go about using
the code in (point-on-line) iteratively, because of
the overhead of having to make a seperate function
call (to point-on-line) for each iteration.

Reason: Making calls to a user-defined function has
a fixed amount of overhead associated with it, and
in this case, it can be completely avoided by not
making numerous calls to a version of (point-on-line)
that's designed to handle only one point on one line.

Instead, you should encapsulate the iteration into
another version of (point-on-line) that takes either
many lines, or many distances, and does not have to
call another user-defined function once for each item
it processes, in order to get the job done.

The following should demonstrate my point, and I hope,
and put an end to this.

;=== POLTEST.LSP =====================================

;; Original point-on-line function (Tony):

(defun point-on-line (p1 p2 dist)
(setq sc (/ dist (distance p1 p2)))
(mapcar '+ p1
(mapcar '*
(mapcar '- p2 p1)
(list sc sc sc)
)
)
)

;; Faster point-on-line function (Jadranko):

(defun point-on-line2 (p1 p2 dist / sc)
(setq sc (/ dist (distance p1 p2)))
(mapcar '(lambda (p1 p2) (+ p1 (* sc (- p2 p1)))) p1 p2)
)

;; A third version of (point-on-line) that
;; is specifically designed and optimized
;; for iterative use (multiple points on a
;; single line):

(defun points-on-line (p1 p2 offsets / delta x y z dx dy dz)
(setq delta (mapcar '- p2 p1))
(setq len (distance p1 p2))
(setq dx (car delta) dy (cadr delta) dz (caddr delta))
(setq x (car p1) y (cadr p1) z (caddr p1))
(mapcar
'(lambda (dist / sc)
(setq sc (/ dist len))
(list (+ x (* dx sc))
(+ y (* dy sc))
(+ z (* dz sc))
)
)
offsets
)
)

;; =================================================
;;
;; The following test code builds a list of
;; 200 doubles, and then uses each of the above
;; three functions to obtain a list of 200 points
;; that lie on a single line, at the 200 specified
;; distances from the start of the line.
;;
;; The first two test wrappers call each of
;; the two original (point-on-line) functions
;; 200 times using (mapcar).
;;
;; The third wrapper calls (points-on-line) once,
;; since it need be called only once to return the
;; same result as the 200 iterative calls to each
;; of the two versions of (point-on-line).
;;
;; All of the test wrappers repeat the operation
;; 100 times, to scale up the relative difference
;; of the results.
;;
;; The purpose of this is to demonstrate that
;; a function designed to perform a given process
;; on a single item, is not necessarily the most
;; effecient approach when that same process must
;; be iteratively applied to many items.

;; Test wrappers for the above 3 functions:

(defun points-on-line-1 ( / rslt)
(setq rslt
(time
'(repeat 100
(mapcar
'(lambda (dist)
(point-on-line p1 p2 dist)
)
offsets
)
)
)
)
(princ
(strcat
"\nPoints-on-line-1 (Tony): "
(rtos rslt 2 4)))
)

(defun points-on-line-2 ( / rslt)
(setq rslt
(time
'(repeat 100
(mapcar
'(lambda (dist)
(point-on-line2 p1 p2 dist)
)
offsets
)
)
)
)
(princ
(strcat
"\nPoints-on-line-2 (Jadranko): "
(rtos rslt 2 4)))
)

(defun points-on-line-3 ( / rslt)
(setq rslt
(time
'(repeat 100
(points-on-line p1 p2 offsets)
)
)
)
(princ
(strcat
"\nPoints-on-line-3 (optimized): "
(rtos rslt 2 4)))
)

(defun time (expr)
(/ (abs (- (getvar "millisecs")
(progn (eval expr) (getvar "millisecs"))
)
)
1000.0
)
)

(defun C:TEST ( / offsets i)
(setq i 1.0)
(repeat 200
(setq offsets (cons (setq i (1+ i)) offsets))
)
(setq p1 '(5.0 10.0 12.0) p2 '(500.0 400.0 200.0))
(points-on-line-1)
(points-on-line-2)
(points-on-line-3)
(princ)
)

;; --------------------------------------------------------

My results are as follows:

Command: TEST
Points-on-line-1 (Tony): 2.3530
Points-on-line-2 (Jadranko): 1.3420
Points-on-line-3 (optimized): 0.4110

If there is a lesson here, it is that taking a 'library'
of 'reusable' functions, that attempt to shrink-wrap or
encapsulate various discrete tasks, and simply using them
blindly as-is, can ultimately lead to inferior code, in
terms of effeciency and performance.

Checkout the AcadX(tm) ActiveX Extension Library at:

http://www.caddzone.com/acadx/acadx.htm

/*********************************************************/
/* Tony Tanzillo Design Automation Consulting */
/* Programming & Customization for AutoCAD & Compatibles */
/* ----------------------------------------------------- */
/* tony.tanzillo@worldnet.att.net */
/* http://www.caddzone.com */
/*********************************************************/
0 Likes