dhermes / bezier

Helper for Bézier Curves, Triangles, and Higher Order Objects
Apache License 2.0
266 stars 36 forks source link

Implicitization of a Bezier curve to fit an axis on Nomograms #316

Closed barkinb closed 9 months ago

barkinb commented 9 months ago

Hello, I am trying to find the equation of an axis on a nomogram/ alignment chart from x and y coordinates to the values on the axis.

So say I have a Bezier curve on the axis with an implicit equation of

4*(676x**2 - 2548xy - 698384x + 2401y**2 - 1250136y + 275528592)

generated using .impliticize()

where x and y are the x and y coordinates on the image.

Then there are three points on the axis l: (144, 150, 0.4) (81.5, 265.5, 0.1) (115.5, 181.5, 0.3) where the first two values are the x and y coordinates, and the third is the corresponding value on the axis.

Is there a way to create a mathematical relationship between the x and y points and the corresponding axis value through Python?

I want to find the equation to draw a statistical distribution on an axis and interact with the nomogram and the statistical distribution.

Thank you Here is the image of the program, the large points are the control points for the Bezier curve, and smaller points are the three axis points

https://github.com/barkinb/Level4Project/tree/feature/axisEquation

dhermes commented 9 months ago

A few questions:

barkinb commented 9 months ago

Hello @dhermes I just reran my program Control points are at : (174, 126) (78.0, 190.0) (82, 314)

4(529x2 - 2024xy - 666616x + 1936y2 - 1070616y + 248511036) Matrix([[2(44*s*2 - 90s + 87)], [2(23s*2 + 71s + 63)]])

Points on the axis (88, 268, 0.1) (145, 150, 0.4) (115.5, 181.5, 0.3)

I'm not sure where the "three points on the axis l:" has to do with the impliticized curve

So the control points are to fit the curve and the three points on the axis are 3 points selected to find the relationship between the bezier curve and the readings off the axis. I am trying to fit the points on the curve to the values on the axis so that I can later on draw segments on the curve based on the axis. I hope this makes sense :)

dhermes commented 9 months ago

I hope this makes sense :)

Unfortunately things still aren't adding up. For example:

In [1]: import bezier

In [2]: import numpy as np

In [3]: nodes = np.asfortranarray(
   ...:     [
   ...:         [174.0, 78.0, 82.0],
   ...:         [126.0, 190.0, 314.0],
   ...:     ]
   ...: )

In [4]: curve = bezier.Curve.from_nodes(nodes)

In [5]: curve.implicitize()
Out[5]: 80*(45*x**2 - 150*x*y - 35672*x + 125*y**2 - 63768*y + 14183376)

If you could include the code you're using to produce these values that'd be helpful.

barkinb commented 9 months ago

Hello @dhermes

The control points printed to terminal were slightly out of date, now I fixed those.

4225*x**2 - 20410*x*y - 3422292*x + 24649*y**2 - 11563904*y + 1980755928
Matrix([[157*s**2 - 66*s + 83], [65*s**2 - 256*s + 317]])
l:
  (83, 317)
  (50.0, 189.0)
  (174, 126)

The code to create the curves are on https://github.com/barkinb/Level4Project/blob/feature/axisEquation/src/app/Axis.py I tested this on my machine making the curve separately and it added up

Sorry about that

import bezier
import numpy as np

nodes = np.asfortranarray(
[
    [ 83.  ,50. ,174.],
    [317. ,189. ,126.]
])
curve = bezier.Curve.from_nodes(nodes)
print(curve.implicitize())
dhermes commented 9 months ago

OK, using the above as well as your 3 points from

(88, 268, 0.1)
(145, 150, 0.4)
(115.5, 181.5, 0.3)

we have the following plot:

Figure_1

Are you asking how to do a "nearest projection" of those points onto the curve?


The plot was produced by:

import bezier
import matplotlib.pyplot as plt
import numpy as np
import seaborn

def main():
    seaborn.set(style="white")

    nodes = np.asfortranarray(
        [
            [83.0, 50.0, 174.0],
            [317.0, 189.0, 126.0],
        ]
    )
    curve = bezier.Curve.from_nodes(nodes)

    fig = plt.figure()
    ax = fig.gca()
    curve.plot(num_pts=256, ax=ax)

    ax.plot([88.0, 145.0, 115.5], [268.0, 150.0, 181.5], marker="o", linestyle="None")
    ax.axis("scaled")

    plt.show()

if __name__ == "__main__":
    main()
barkinb commented 9 months ago

Hello @dhermes I am trying to create a relationship between any Bezier curve\line and the axis on these curves. Regardless of linear or logarithmic axis values to straight lines or curves axis.

dhermes commented 9 months ago

I'm sorry I still don't understand.

Unfortunately we're not making progress here, maybe you should reach out to someone locally? (Just need more clarity in what you're thinking.)

barkinb commented 9 months ago

I am so sorry I couldn't make it clear and explain it properly. What I am trying to do is create/find an equation where I can use the x and y coordinates to find the value on the axis itself.