Design of a math function

Design of a math function

mmawad
Enthusiast Enthusiast
1,104 Views
8 Replies
Message 1 of 9

Design of a math function

mmawad
Enthusiast
Enthusiast

I need help designing a function that does the following

There is 2 objects "A & C" each represented by 2 real type variables 

And we have a third object "B" but  we only have the first variable for it and need to estimate what the second variable value should be relative to the first 2 objects. 

By the way that first variable that we have will always be in between the other 2 objects first variables. 

The inputs are, 

(setq

         A1 40

         A2 500

         B1 50

         C1 60

         C2 900

)

And the result is B2 value. 

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

marko_ribar
Advisor
Advisor

Is B2=700 ?

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 3 of 9

marko_ribar
Advisor
Advisor
Accepted solution
(defun findb2 ( a1 b1 c1 a2 c2 / da1c1 db1c1 da1b1 da2c2 db2c2 db2a2 b2 )
  (setq da1c1 (- c1 a1))
  (setq db1c1 (- c1 b1))
  (setq da1b1 (- b1 a1))
  (setq da2c2 (- c2 a2))
  (setq db2c2 (* (/ db1c1 da1c1) da2c2))
  (setq db2a2 (* (/ da1b1 da1c1) da2c2))
  (setq b2 (+ a2 db2a2))
  (if (equal (- c2 b2) db2c2 1e-8)
    (progn
      (prompt "\nB2 = ")
      (princ (rtos b2 2 50))
    )
  )
  (princ)
)
Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 4 of 9

Kent1Cooper
Consultant
Consultant
Accepted solution

Given:

 

(setq
  A1 40
  A2 500
  B1 50
  C1 60
  C2 900

)

 

then:


(setq  B2
  (+
    A2 ; low end of range between x2 values
    (*
      (/ (float (- B1 A1)) (- C1 A1)); ratio of B1 position between A1 and C1
      (- C2 A2); overall x2 range
    ); *
  ); +
); setq

 

The (float) function is there to make at least one number be a real  number, because if all inputs are integers, the division result will also be an integer with any remainder ignored, throwing off the result.

Kent Cooper, AIA
0 Likes
Message 5 of 9

marko_ribar
Advisor
Advisor

Yes, I missed (float) function, so OP - if using my function must specify real numbers...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 6 of 9

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:
....
(setq db2c2 (* (/ db1c1 da1c1) da2c2)) (setq db2a2 (* (/ da1b1 da1c1) da2c2)) ....

That has the divide-integers problem.  Both of these calculations:

(/ db1c1 da1c1)
(/ da1b1 da1c1)

return zero when the inputs are as in Message 1.  So nothing gets added to the A2 value, the B2 result comes out as 500, and the prompt is not issued.

Kent Cooper, AIA
0 Likes
Message 7 of 9

marko_ribar
Advisor
Advisor

I explained in message 5 that OP needs to use real numbers if wanted to get correct result...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 8 of 9

Kent1Cooper
Consultant
Consultant

@marko_ribar wrote:

I explained in message 5 that OP needs to use real numbers if wanted to get correct result...


Yes -- it was posted while I was already writing Message 6.  But I have a few other comments:

I wonder about that  (if (equal ...  test, which seems unnecessary.  With real-number inputs, under what circumstances could it ever not  be equal?  And if there is such a circumstance, shouldn't there also be an 'else' expression notifying the User that something's amiss, rather than nothing at all being reported [as happened when I ran it with integer inputs]?

 

The precision number of 50 in the  (rtos)  function is serious overkill.  AutoCAD can only keep track of 16 significant figures, so you will never get anywhere close to 50 decimal places returned by anything:

  Command: (rtos 700 2 50)
  "700.0000000000000"

[only 13 decimal places]

 

A lot of your variables are used only once, so it doesn't seem necessary to save them -- just figure them at the place where they're used.  That's how my suggestion, which uses no  variables added beyond the inputs except B2, boiled down to its essence without comments and line breaks, is no more than just:

(setq B2 (+ A2 (* (/ (float (- B1 A1)) (- C1 A1)) (- C2 A2))))

 

And if the  (if (equal ...  test is really not needed, the db2c2 variable is also not needed.

Kent Cooper, AIA
0 Likes
Message 9 of 9

marko_ribar
Advisor
Advisor

You are right, check is not needed indeed, but according to math rules it should return T, only if assumed arithmetic operations are true... If for ex. there is another rule (B2 /= 700), but for ex. B2 = 500 + (900-500)*((50-40)/(60-40))^((50-40)/(60-40)) = 500 + 400*0.5^0.5 = 500 + 282.8427 = 782.8427, then my (if) statement wouldn't give T and therefore assumed arithmetics won't give any result... The question that we don't have answer to is answer to my first reply : Is B2=700 ?

Now as OP marked our solutions as correct, he/she assumed that B2=700 and so my (if) checking only confirms assumed logic and no matter not necessity it acts as proof that logic used is correct...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes