## Easy math for LC users

Moderators: Klaus, FourthWorld, heatherlaine, robinmiller, kevinmiller

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Easy math for LC users

Part #1
Which points of a set of points are closest to me/ any fixed point?
(or: Who is closest for trying to catch in the schoolyard?)
To make it easier for the kids among you the following is also attached as stack.

Code: Select all

``````-- script button "closest points", for explaining the approach
on mouseUp
lock screen; lock messages
put the points of grc "setOfPoints" into p0 -- any number of lines of points
put the loc of grc "redOval" into p1 -- the point of interest
put item 1 of p1 into x0; put item 2 of p1 into y0
-- now compute the distances with the help of a sum of absolute values
repeat for each line p in p0
if p is empty then next repeat
put cr & abs(x0 - item 1 of p) + abs(y0 - item 2 of p) &","& p after ds
end repeat
delete char 1 of ds
sort ds numeric by item 1 of each
put ds into fld "distances"
put item 2 to 3 of line 1 of ds into p2
set layer of grc "redOval" to top
set layer of grc "connectingLine" to top
show grc "connectingLine"
set points of grc "connectingLine" to p1 & cr & p2
unlock screen; unlock messages
end mouseUp

-- next two are the script of grc "redOval"
on mouseDown
hide grc "connectingLine"
grab me
end mouseDown

on mouseUp
send "mouseUp" to btn "closest points"
end mouseUp
``````
Useless for adults? No.

Imagine a certain product, say a TV.
On the vertical line you hace the prices, from low at bottom up to high at top.
In horizontal direction you have quality, from low at left to high at right.

Now set your prefered point (redOval) determining a price and a quality level.
Then compute the closest product point to your prefered point.

Having this it is easy to have more dimensions, say you split your "quality" criterium into three different kinds.
Then your points have four dimensions and you set your preference point again to a point (x1,x2,x3,x4) and compute the distances to the other points as above, simply using adding absolute values of four differences instead of two.
Very simple. Isn't it? Difficult is only to visualize four dimensions, but we don't need this for our decision.

Edit. Changed picture and stack, text of *describing field* in that was wrong, sorry (I made this originally for euclidian distance), scripts are unchanged.
Attachments
closestPoints.livecode.zip
Last edited by [-hh] on Mon Oct 20, 2014 12:06 pm, edited 3 times in total.
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #2
Closest RGB colors out of a set of colors to one fixed RGB color
(for example out of the set of webColors to any fixed RGB color)

Say you go shopping and your friend gives you a piece of tissue to buy a table-cloth with a solid color closest to this sample.
You make photos of the sample and the available table-clothes of correct size and compute the one that is closest in color. How would you do that?

RGBColors are in LC triples (for simplicity we leave aside the geeky (partly)transparent colors here) of kind (R,G,B) and we have to compute the distance of such colors to our sample (r0,g0,b0).

You know already a simple way? Yes, we could do it like in part #1 and compute
abs(r0-R) + abs(g0-G) + abs(b0-B) for each avilable (R,G,B).
This leads to one of the colors that has shortest distance to the color of our sample.

[Some may argue here, to use the euclidian distance
sqrt( abs(r0-R)^2 + abs(g0-G)^2 + abs(b0-B)^2)
would be better, because this measures the "direct" distance in 3D. But
= then the a user -- may be a kid -- has to understand what sqrt means
= we don't need the "direct" distance (the amount). We just need a simple "ranking" of distances that is, in most cases, identical to ranking given by the euclidian distances.
Certainly abs(x)^2 = x^2. I used nevertheless "abs" to make the comparison easier.]
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #3
Round to closest part of a fragmentation of positive numbers into N parts

A "fragmentation" means here that you divide a whole thing (say the amount of one dollar) into N pieces, where N is any fixed one of the natural numbers 1,2,3, ... (Quarters would be N=4).

From N=1 (that is rounding to integers) we see, that we have to give a decision rule if there are two next parts (here integers). For example for 1.5 we have to say whether we round up or down.
Say we always round up here in such indifferent cases, what is the most usual 'financial style' (if we have to pay).

So for N=2 we would like to round to the closest of 0/2, 1/2, 2/2 between the integers.
That is roundTofragmentation(x,N) of the number x and N=2 should give for example
roundToFragmentation(1.24,2)=1
roundToFragmentation(1.25,2)=1.5
roundToFragmentation(1.70,2)=1.5
roundToFragmentation(1.75,2)=2

I'll try now to lead you to a general function in one minute (if you are in a hurry go directly to the code).

We can have the above by first multiplying the number x by 2, then round and then divide by 2:
roundToFragmentation(1.24,2) = round(2*1.24)/2 = 2/2 = 1
roundToFragmentation(1.25,2) = round(2*1.25)/2 = 3/2 = 1.5
roundToFragmentation(1.70,2) = round(2*1.70)/2 = 3/2 = 1.5
roundToFragmentation(1.25,2) = round(2*1.75)/2 = 4/2 = 2

Now the general funtion is clear:
We first have to multiply x by N, then round and then divide by N:

Code: Select all

``````function roundToFragmentation x, N
-- x is a positive number, N a positive
return round(x*N)/N
end roundTofragmentation
``````
Examples.
roundToFragmentation (1.34,3) = 4/3 = 1.33333333
roundToFragmentation (1.70,5) = 9/5 = 1.8

Obviously there are other ways to do this. I used the above form, because we can have now easily a modification if we want the "rational" number as return value, that is not the computed (round(x*N)/N) but a string of the from a/b.

Code: Select all

``````function roundToFragmentationAsString x, N
-- x is a positive number, N a positive integer
return round(x*N) & "/" & N
end roundToFragmentationAsString
``````
Examples.
roundToFragmentationAsString (1.34,3) returns "4/3"
roundToFragmentationAsString (1.70,5) returns "9/5"

These results are mostly more exact than the evaluated ones, for example
4/3 is 'exact' and 1.333333333333 is an approximation of this.

Try now:
This is the "fiftieth part" (multiple of 1/50) that is closest to sqrt(2)
For kids: sqrt(2) is simply the diagonal in a 1x1 square]

[This is the "seventh part" (multiple of 1/7) that is closest to pi.]

If you read and tried until here:
Here is an example for the beauty (beauty by simplicity) of LC and Math, isn't it? shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #4
Why calculating x/(1+x) isn't useless

Recently I heard in a bus (translated from german) "Math is so horrible, what a useless function is f(x)= x/(1+x) we have to discuss? My father said, you never will need this again, it's not worth to understand it."

What do you think?
I think it's not at all true, we really need it in *daily* life.

Why?
Say you have taxes (VAT) of x% = x/100=x0
[You can look at "%" being an abbreviation for multiplication by 1/100, for example 20% = 20/100 = 0.2 ]

Then the gross price (= end price) you have to pay for a good is:
gross price = (net price)*(1+x0) = 120% of the net price if x=20% (recall 1=100%).

How much is the tax that is contained in a given gross price?
This is obviously (net price)*x0/((net price)*(1+x0)) = x0/(1+x0).

This means, if you have a VAT of x% = x/100 = x0, then 100*x0/(1+x0)[%] is the percentage of tax (money amount) that is included in a gross price.

For a VAT of 20%=0.2 this is 100*0.2/1.2[%] = 100/6[%] = 16.67[%].
That is, if you have to put 100 GPB on the table for a good, then 16.67 GPB of this 100 GBP are VAT.

We write this as a function and use the rounding to the closest hundredth (Cent) from part #3 of this thread.

Code: Select all

``````function includedTax bp,tx
-- bp is the gross price, tx the tax as percent
put tx/100 into x
put bp*x/(1+x) into inclTax
return round(100*inclTax)/100 -- rounded to Cent
end includedTax
``````
Example.
includedTax(100,20) yields 16.67
includedTax(100,19) yields 15.97
includedTax(100,7) yields 6.54
includedTax(100,5) yields 4.76

If this was all pretty clear to you then simply forget my post. If not, then start to do more your own math, it's worth and fits perfectly to LC.

Start for example with this:
What value has the VAT to be, so that the included tax in a gross price of 100 GBP is 20 GBP?

I saw several interesting and good contributions of type "usable math" here in the forum. Come on, authors of these now "cold" threads, as Simon uses to say [direction of a touchMove, rotating points, length of a polygon, ...]. Let us collect them here, easy to find.
Could be also "educational" (usable for young studs, as some of mine here). Or open a thread "not so simple math", before I do.
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part#5: DIV and MOD
[This is again for beginners.]

Two important operators that are often 'avoided' are div and mod.
If N and M are non-negative integers (0,1,2,...), M not zero, then

N div M is the number of times M fits in N
N mod M is the remainder after fitting "full" Ms into N

That is
(+) N = (N div M)*M + (N mod M)
partly specialized (M=60)
(++) N = (N div 60)*60 + (N mod 60)
My memorizing technique is to remember not the definition of DIV and MOD but equation (+), together with an example and then derive from that the definition if needed.
For example you see also from (+) that N/M = (N div M) + (N mod M)/M.

Example.
Seconds to Minutes, that is M=60 [seconds]:

200 [seconds] = 3*60 + 20 [seconds]. That is 3 'full parts' of 60 (3 minutes), remaining 20 seconds.
200 div 60 =3 and 200 mod 60 = 20.

Use this when scripting a stopwatch.

Code: Select all

``````# start with a 'time-stamp':
put the seconds into iStartTime

# Later on, a timer has to compute the time gone with this:
put the seconds - iStartTime into s -- time gone in seconds

# Compute minutes:
put s div 60 into divMinutes
put s mod 60 into modSeconds
if modSeconds < 10 then put "0" before modSeconds
put modSeconds before iTime
``````
Now try yourself to get similarly hours from divMinutes and days from divHours. If you have this you are nearly done.

The attached stack does this, compare with your's.
The stack shows also how to fire a timer every full second -- operator MOD helps here again.
"The millisecs mod 1000" is the number of milliseconds gone in the current second. Subtracting this from the full second (= 1000 millisecs) gives the remaining number of milliseconds to wait until the full second:

Code: Select all

``````-- starts a handler (here named doIt) every full 1000 millisecs.
-- Here x is a parameter, for example a fixed start time
on doIt x
# your script here, see the example in the attached stack
send "doIt x" to me in (1000 - (the millisecs mod 1000)) millisecs
end doIt``````
Attachments
easyRaspiMath5.livecode.zip shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #6
Log-Plots or: Why logarithm is not only for math people.

One function that (besides other reasons) causes a lot of people rolling their eyes is the logarithm. No, don't stop reading. It's easy math, judge after reading this. We will only use it for motivating a logarithmic-scale-plot (semi-log graph).

Frequently such a graph is described by "a way of visualizing data that are related according to an exponential relationship. One axis is plotted on a logarithmic scale. This kind of plot is useful when one of the variables being plotted covers a large range of values" (Wikipedia). Correct, but not very helpful for non-math people. Let me try another approach.

We know, the human mind is by far smarter and faster when comparing visual impressions from an image than any machine, that has the same information about this image.

We can for example judge at once that the two marked differences on the left hand plot are (at about) the same, without knowing the exact values.
Say this is a plot of a time series of an economic variable (production costs or similar) then we see immediately
(1) value(2014)-value(2013) = value(2011)-value(2010),
that is, such an occurence shows:
the *absolute increase (the difference)* is from 2013 to 2014 the same as from 2010 to 2011.

Now look at the right hand log-plot (= 'semi-log graph'). This means we don't have values above each year, but logarithm of these values (now from another variable). Again we see
(2) log( value(2014) ) - log( value(2013) ) = log( value(2011) ) - log( value(2000) ),
and this means,
the *relative increase (the factor)* is from 2013 to 2014 about the same as from 2010 to 2011 (see explanation below.)
This is all to have in mind (and is for me the main reason to use a log plot):
• Linear plots are good for allowing direct comparison of *differences* between values.
For example a pair of values that is changing from 40 million to 30 million Euro and another pair, changing from 80 million to 70 million Euro, have the same vertical distance (of 10 million Euro) in the plot.
• Log plots (semi-Log graphs) are good for allowing direct comparison of *factors* between values.
For example a pair of values that is changing from 4000 to 7000 nanoseconds and another pair, changing from 40 to 70 nanoseconds, have the same vertical distance (of log(7/4) nanoseconds) in the plot.
[[ Why this is so uses only "main" properties of the log-function.
For a>0 and b>0:
(3) log(a) = log(b) if and only if a=b.
(4) log(a) - log(b) = log (a/b)
From (4) it follows, applied to (2), that
log ( value(2014) / value(2013) ) = log ( value(2011) / value(2010) ).
Now (3) says, we can remove log on both sides to get
value(2014) / value(2013) = value(2011) / value(2000).
This means the factors are equal. Recall for that
value(2014)= factor1*value(2013) and value(2011)= factor2*value(2010).
This is basic math, all you have to "accept" and apply are the properties (3) and (4)!
]]

Note.
• Instead of comparing changes between pairs for equality we could also compare changes between pairs for being greater/smaller.
• Pairs that are compared can be chosen freely, no need to be consecutive.
• The above is true for *any* 'kind' of logarithm, you can replace all "log" by "log2" above, or replace all "log" by "Ln" (logarithmus naturalis) above.
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #7 (Medium difficulty).
How to transform a rectangle to a semi-circle.

I was asked to post the math for the transform used in my post "Factor 14" of subforum "Talking Livecode".
I'll describe you not that one, but how to transform a rectangle to a semi-circle, like the following one. It's simpler to explain because you see the "points". This will go into the RaspiCollection as "Run-LED", as soon as it's fast enough (or LC 7 is fast enough).

The first image shows a polygon-matrix, a polygon in "matrix-form". Imagine you have a rectangular table and each entry is a "big" pixel. With LC you can have it by setting the points of a polygon object and separate these points by empty lines.
Then you have width*height=(num of columns)*(num of rows) pixels, that are indexed in the form (x,y), where x is the row number and y is the column number.
We first write all pixels relative to the polygon's center (well be our origin). You have to adjust all the following by the "size" of the "pixels", below it's one, in the image it's 10 or so.

Code: Select all

``````## Transform each pixel (x,y) as follows.
put the width of grc p into polyCols
put the height of grc p into polyRows
put polyCols div 2 into x0; put polyRows div 2 into y0
put x-x0 into px; put y-y0 into py
-- The main math:
put (px/polyCols)*pi into cc
add 40 to py -- creates the inner circle, away from the origin
put py*sin(cc) into px
put py*cos(cc) into py``````
Now replace the point (x,y) of the 'matrix-polygon' by (px,py).
[The last two lines are, with cc running in a range of length pi, the formula for a semi-circle of radius py. That is, we create from every row of the polygon-matrix an own semi-circle with increasing radius.]
After all you have to move the loc of the grc (after setting it's points) or set it's relativePoints to all the (px,py).

That's all, really everything: Math is beautiful, isn't it?
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #8
Points and Rects (see attached stack).
• Usage is demonstrated with an interactive graphic of draggable rects.
• The enclosing rects and intersections are computed and marked by 'marching ants'.
• Intersections are correctly mixed colors by use of the ink property 'srcAnd'.
• The stack (one card and its script) is creatable by the script of one single button. This demonstrates making layout by scripting.
• Scripts are commented, especially the use of two animations (may be interesting for teachers):
+ showing an outline by moving cursor along it
+ shrinking and growing a rect (inset/outset)
Speed of animations is for Raspi or PPC, others may have to throttle down.
.
Attachments pointsAndRects.png (15.25 KiB) Viewed 5399 times
pointsAndRects2.livecode.zip
shiftLock happens

SparkOut
Posts: 2015
Joined: Sun Sep 23, 2007 4:58 pm

### Re: Easy math for LC users

Hermann, I'm sorry I don't have any sort of award for you to show appreciation, but I have to write and say thank you very much for your greatly valuable contributions. This thread and the raspi ones in particular are hugely welcome, and here I have learned some things that are apparently simple yet which have always escaped my comprehension. Your clear and elegant explanation has helped me see some of the beauty behind the mystery of maths. It will never make me love it, but I shall not be so afraid of it in future.
Vielen Dank!

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

What makes me proud and is an award of its own is that you and some other users of your high level read this.
SparkOut wrote:... I shall not be so afraid of it [math] in future ...
You are obviously ready for "Not-so-easy math for LC users" shiftLock happens

Einherjar
Posts: 18
Joined: Thu Dec 12, 2013 7:38 pm

### Re: Easy math for LC users

Brilliant, thanks for sharing.

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #9
Relations I (also preparation for Raspi collection stack #70)

The kind of math relations we use here are very simple ones. You know them, you use them all day, for graphics and images. [No specific advanced math names here, I'll try to explain for non-math users.]

A POINT (x,y) is a pair of integers, the first coordinate denotes x units of a horizontal dimension, the second coordinate denotes y units of a vertical dimension. These coordinates may be limited by lower and upper finite bounds.
Examples.
Think of your (physical) screen pixels or the pixels of an image, *number* them (1-based) from left to right and top to bottom. Then (7,3) is the pixel in column 7 of row 3.

A finite 2D-UNIVERSE is a collection of a *finite* number of points (c1,c2) that are defined by there first coordinate c1 and their second coordinate c2.
Examples.
All pixels of your main screen, an image, the points of your card window.
Mostly the finite 2-D Universe is clear or could simply be taken to be "large", e.g. within the limits of +/- 2^128 for first and second coordinate. That's why it is often not mentioned when speaking of a finite 2D-Relation.

A finite RELATION (in a finite 2D-Universe) is any well defined subset of the points of that universe. Well defining are for example these methods:

a. a simple enumeration of the points (x,y) (=the elements of our relation)
for example: "4,3"&cr&"4,4"&cr&"4,5"&cr&"4,6"&cr&"4,7"&cr&"5,5"&cr&"6,5"&cr& \
"7,3"&cr&"7,4"&cr&"7,5"&cr&"7,6"&cr&"7,7""
b. a "functional rule", for example: all points (x,y) with y = 10 + 1/2*x
c. a "relational rule", for example: all points (x,y) with (x-20)^2 + (y-20)^2 <= 64
or: all points (x,y) with x = 10*sin(t) and y=10*cos(t) for some parameter/angle t
d. a "logical rule", for example: all points (x,y) with x <= y or y > 42

If it is clear from the context where we are, we speak shortly of a (MxN)-relation.
A (MxN)-relation is any well defined subset of points (i,j) with integer coordinates, where 1<=i<=M and 1<=j<=N. That is
= our universe is a collection of left-to-right and top-to-bottom numbered points
= our relations are subsets defined by enumerations or "rules".

Example 1: We define the highlighted pixels (ON) of our Raspi 84x48-miniLCD display as (84x48)-relations.
Example 2: We define the up to 320*480 points of a polygon graphic on a 320x480 "pixels" iPhone4 display as (320x480)-relations, and so on ...

[Note 1. (For advanced users) I we use high-res coordinates then, of course, we can transform this to integer coordinates by scaling up and apply our methods to these. Or we have a "fractal" look at it: Each point with integer coords becomes an own new universe by looking closer at it and so on, until we have (soon) integer coords. In other words: You may imagine, that our 320x480 display is one of your ultra-high-res-pixels in 'close-view'.]

[Note 2. (For advanced users) One of the biggest producers of display errors is the usual mixing of *numbering* coords and *measuring* coords.
For example: There is no pixel (0,0) in numbering coords, because we count 1-based.(0,0) is the origin of measuring coords.
The measuring rect (0,0,7,4) is 7 pixels wide and 4 pixels high, the corresponding 28 points for a polygon graphic are (1,1),(2,1) ... (7,4).
This is my advice: If you think in pixels then think of the (virtual) "center" of that pixel, not at the left/right/top/bottom of that. This doesn't change numbering coords and solves your 1-pixel offsets by "misleading" measuring coords.]

To close this part, the very simple examples (a)-(d) from above.
Take the 84x48-miniLCD display as universe, then the examples above yield the following displays. Note that for example (3,11.5), where 11.5=10+1/2*3, is NOT element of the relation -- we cannot divide pixels, the condition is always that a point (x,y) belongs to the display (that it is a pixel). Enumeration a: A small H.
Rule b: Because we divide x (the column index)
by 2, every second column only can be occupied.
relations-i-12.png (21.06 KiB) Viewed 4331 times Rule c: A filled "circle". If the rule were "... =64" we would get only 4 points!
Rule d: A simple list of inequalities.
relations-i-34.png (29.77 KiB) Viewed 4331 times
The examples above show, that one of the main arising problems will be "how to round in such a way that the deviation from the 'ideal' curve (the math model) is minimal?".

[Edit. Improved some wording]
Last edited by [-hh] on Tue Feb 02, 2016 2:00 pm, edited 1 time in total.
shiftLock happens

[-hh]
VIP Livecode Opensource Backer Posts: 2094
Joined: Thu Feb 28, 2013 11:52 pm
Location: Göttingen, DE

### Re: Easy math for LC users

Part #10
Relations II (also preparation for Raspi collection stack #70)

This is now a stack for "exercising/playing" with our 'special' relations.
We will use these techniques for generating 'screens' of our (virtual) miniDisplay.
============================
Edit.
I was asked to give some very "basic" examples first:
For all examples choose an origin (x0,y0) by setting for example
local x0=42, y0=24
in the top "params" field. Then select button "Logic" and type in the bottom field (enterInField evaluates the field):
• abs(x-x0) < 3 [ yields a centered vertical line, play with the limit "3" ]
• abs(y-y0) < 3 [ yields a centered horizontal line, play with the limit "3" ]
• Both of the above, once connected by "AND", once connected by "OR".
[ "AND" gives a centered square, "OR" yields a centered cross ]
• abs((x-x0) - 1*(y-y0)) < 3 [ a centered increasing line ]
• abs((x-x0) + 1*(y-y0)) < 3 [ a centered decreasing line ]
• Both of the above, once connected by "AND", once connected by "OR".
[ "AND" gives a centered diamond, "OR" yields a centered X-cross ]
Also replace in the last two examples the factor/slope "1*" for example by "1.8*" (you could try to hit the edges of the display).
• abs(((x-x0)/23)^2+((y-y0)/23)^2 -1) < .05 [ yields a centerd circle ]
• abs(((x-x0)/23)^2+((y-y0)/23)^2 -1) < .1
OR (x-x0-8)^2+(y-y0+6)^2 < 6
OR (x-x0+8)^2+(y-y0+6)^2 < 6
OR ( abs( ((x-x0)/12)^2+((y-y0-10)/4)^2 -1) < .3 AND y > 34 )
[ a smiley, play with the limits of the inequalities ]
============================
There are slightly advanced 14 examples in the stack of kind
[p]= "relational rules" (indicated by btn 'polar')
[l]= "logical rules" (indicated by btn 'logic').

[l] circle2, [l] fish,[l] hashTag, [p] lissajous, [p] sinus1, [l] sinus2, [p] spiral, [l] star, [l] yinyang, [l] diamond-filled, [l] diamond-border, [l] ellipse-filled, [l] ellipse-border and [l] linearInequalities.

["functional rules" can be made with both [p] and [l], we will use such examples in Raspi stack #70].

You may change (parameters of) these examples as a first usage of this stack.

The radio buttons below btn "Examples" show optimized approaches:
They use well-known math routines that give best approximations of the integer pixels to the ideal 'math model'.
This is best illustrated with the simplest example "Lines". The attached image shows the solution of the problem how to to distribute the pixel-steps to the total vertical distance (that is, to 'best-approximate' the given slope).

The math behind that is not complicated but sadly impossible to describe in short -- if you are interested please read the scripts, what will soon explain the math.

Attachments
relations-ii.livecode.zip
The 'Relations'-stack  