Calculate Geometry NURBSTo row values from Points in Scratch

Started by RailwayKen, August 23, 2024, 02:35:17 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yacine

I then asked it to give a jupyter notebook code to tinker with the curve.

import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, FloatSlider
import svgwrite
from IPython.display import display, SVG

def clothoid(A, L, num_points=100):
    """Berechnet Punkte entlang einer Clothoide (Übergangsbogen)"""
    t = np.linspace(0, L, num_points)
    x = t - (t**5)/(40*A**4) + (t**9)/(3456*A**8)
    y = (t**3)/(6*A**2) - (t**7)/(336*A**6) + (t**11)/(42240*A**10)
    return x, y

def circular_arc(R, theta, num_points=100):
    """Berechnet Punkte entlang eines Kreisbogens"""
    t = np.linspace(0, theta, num_points)
    x = R * np.sin(t)
    y = R * (1 - np.cos(t))
    return x, y

def check_constraints(V, R, h, s=1.435):
    """Überprüft die Nebenbedingungen"""
    a_c = (V**2) / R  # Zentripetalbeschleunigung
    a_u = a_c - 9.81 * h / s  # Unausgeglichene Seitenbeschleunigung
   
    constraints = {
        'max_lateral_acceleration': abs(a_u) <= 1.0,  # m/s^2
        'max_superelevation': h <= 150,  # mm
        'min_radius': R >= 150  # m (beispielhaft)
    }
    return constraints

def calculate_transition_length(V, R, h):
    """Berechnet die Länge des Übergangsbogens"""
    return max(0.0147 * (V**3) / R, h * V / (11.8 * 1000) * 3600)

def plot_curve(x, y, constraints_met):
    """Plottet die Kurve mit Matplotlib"""
    fig, ax = plt.subplots(figsize=(10, 6))
    color = 'green' if all(constraints_met.values()) else 'red'
    ax.plot(x, y, color=color)
    ax.set_aspect('equal', 'box')
    ax.set_xlabel('X (m)')
    ax.set_ylabel('Y (m)')
    ax.set_title('Bahnkurve')
    plt.close(fig)  # Verhindert doppelte Anzeige in Jupyter
    return fig

def generate_svg(x, y, params, constraints_met):
    """Generiert eine SVG-Darstellung der Kurve"""
    dwg = svgwrite.Drawing(size=('100%', '100%'), viewBox=('0 0 1000 600'))
   
    # Skalierung der Punkte auf SVG-Koordinaten
    x_scaled = 50 + (x - np.min(x)) * 900 / (np.max(x) - np.min(x))
    y_scaled = 550 - (y - np.min(y)) * 500 / (np.max(y) - np.min(y))
   
    # Zeichnen der Kurve
    points = list(zip(x_scaled, y_scaled))
    color = 'green' if all(constraints_met.values()) else 'red'
    dwg.add(dwg.polyline(points=points, stroke=color, fill='none', stroke_width=2))
   
    # Hinzufügen von Textinformationen
    dwg.add(dwg.text(f"V = {params['V']:.0f} km/h", insert=(50, 30), font_size=20))
    dwg.add(dwg.text(f"R = {params['R']:.0f} m", insert=(50, 60), font_size=20))
    dwg.add(dwg.text(f"h = {params['h']:.0f} mm", insert=(50, 90), font_size=20))
   
    return dwg.tostring()

@interact(V=FloatSlider(min=10, max=300, step=10, value=100, description='V (km/h)'),
          R=FloatSlider(min=100, max=5000, step=100, value=1000, description='R (m)'),
          theta=FloatSlider(min=0.1, max=np.pi/2, step=0.1, value=np.pi/4, description='θ (rad)'),
          h=FloatSlider(min=0, max=200, step=10, value=100, description='h (mm)'))
def update_plot(V, R, theta, h):
    # Umrechnung von km/h in m/s
    V_ms = V / 3.6
   
    # Berechnung der Übergangsbogenlänge
    L = calculate_transition_length(V, R, h)
   
    # Berechnung der Kurvengeometrie
    A = np.sqrt(R * L)
    x_trans, y_trans = clothoid(A, L)
    x_arc, y_arc = circular_arc(R, theta)
   
    # Verschiebung und Rotation des Kreisbogens
    rotation_matrix = np.array([[np.cos(L/(2*R)), -np.sin(L/(2*R))],
                                [np.sin(L/(2*R)), np.cos(L/(2*R))]])
    x_arc_rotated, y_arc_rotated = np.dot(rotation_matrix, [x_arc, y_arc])
    x_arc_translated = x_arc_rotated + x_trans[-1]
    y_arc_translated = y_arc_rotated + y_trans[-1]
   
    # Zusammenfügen der Kurventeile
    x = np.concatenate([x_trans, x_arc_translated])
    y = np.concatenate([y_trans, y_arc_translated])
   
    # Überprüfung der Constraints
    constraints_met = check_constraints(V_ms, R, h)
   
    # Plotting
    fig = plot_curve(x, y, constraints_met)
    plt.show()
   
    # SVG-Generierung und Anzeige
    svg_string = generate_svg(x, y, {'V': V, 'R': R, 'h': h}, constraints_met)
    display(SVG(svg_string))
   
    # Ausgabe der Parameter und Constraints
    print(f"Übergangsbogenlänge: {L:.2f} m")
    for constraint, met in constraints_met.items():
        print(f"{constraint}: {'Erfüllt' if met else 'Nicht erfüllt'}")
Yacine

Yacine

Et voila, it made an interactive curve display.

You cannot view this attachment.
Yacine

Yacine

Miniconda is the main tool. (You'll need later to install some additional libraries, but this is rather easy). I cannot emphasize enough how much of an improvement this tool is, compared to what my generation used to use (calculator, conversion tables, later excel, and for a few of us Mathcad and the like). Jupyter Notebook is to calculations what the internet is to a "book" library. The world at your finger tips.

But one could of course ask the AI to translate this into a Visio/VBA solution.

----

I could have dived deeper in the subject to really understand it, but I don't own a railway model and usually travel by car. So sorry, I focused only on the engineering tools, not the real content.

But exciting world nevertheless. Reminds me of: https://visguy.com/vgforum/index.php?topic=1703.0
Yacine

wapperdude

@Yacine:  interesting presentation.  Quite thorough.  Curve design/engineering becomes very critical as "bullet" trains are embraced.  From my reading, transition between straight to curve is a key point in terms of minimizing lateral forces, jerkiness, etc.  Extend this to high speed roller coaster design and structural integrity.  It all comes back to physics of motion. 

It would be nice, at least to this person's interest, to see a VBA solution.  In your spare time.  Don't want to derail your focus from other needs.
Visio 2019 Pro

wapperdude

Visio 2019 Pro

wapperdude

#35
...and now the teaser...
With the goals of easing highway congestion, long travel times, associated pollution, improving traveler's experience, might the marriage of the bullet train with high speed roller coaster be the enticement needed to encourage the traveler to freely forsake their individualistic modes of transportation?  Just a thought.   Wheee!!!  🤔😂
Visio 2019 Pro

Yacine

Quote from: wapperdude on September 01, 2024, 02:17:21 PM@Yacine:  interesting presentation.  Quite thorough.  Curve design/engineering becomes very critical as "bullet" trains are embraced.  From my reading, transition between straight to curve is a key point in terms of minimizing lateral forces, jerkiness, etc.  Extend this to high speed roller coaster design and structural integrity.  It all comes back to physics of motion. 

It would be nice, at least to this person's interest, to see a VBA solution.  In your spare time.  Don't want to derail your focus from other needs.
Can't remember having ever received such a polite and gentleman like request. I'll frame it and hang it over my bed.  ;D

And yes, we could do more, but would need more input about the necessary functionality.

I could envision a smartshape with
- props that hold all the relevant curve data
- control points acting as sliders and linked to certain props via setAtRef-stuff
- options to show certain values as graphics - curvature comb, superelevation, ..., critical values and so on.
- maybe trace the path of the radii centers
- since Ken has abandoned the idea of a pure shapesheet solution, we can now work with CallThis functions.
- basically every thing useful for dimensioning the curve.
- an option to switch off all the extra labels, when done, so the curve can be used in regular drawings.

I don't know enough about the workflow and the constraints. Ken would need elaborate on this, to let us build something nice.

And thinking of the article that Wayne mentioned, add an option to optimize the curve with different methods - e.g. a prop field to choose the method A, B, or C and have the macro react in a SELECT CASE structure.
You cannot view this attachment.
Yacine

Yacine

Quote from: wapperdude on September 01, 2024, 04:08:17 PM...and now the teaser...
With the goals of easing highway congestion, long travel times, associated pollution, improving traveler's experience, might the marriage of the bullet train with high speed roller coaster be the enticement needed to encourage the traveler to freely forsake their individualistic modes of transportation?  Just a thought.  Wheee!!!  🤔😂
Yep, but people won't give up their comfort so easily. Either add tremendous possibilities for overcoming the last mile by rent and share options (car, bike, roller) or make it easier to drive your car onto a train.
Yacine

wapperdude

QuoteCan't remember having ever received such a polite and gentleman like request. I'll frame it and hang it over my bed.  ;D

😆😆😆.  Well, I was thinking of your follow-up suggestion of taking that code example of yours and let that super smart, chatty AI buddy of yours do the conversion to VBA.  I do recognize that sometimes you two get distracted with bunny trail discussions, but, nonetheless, anticipate a quaint, solution.  Long live model railroading!!! 

Oh.  One of those bunny trails might be the addition of those various options.  Perhaps as a subsequent addendum?!?

"I've been working on the railroad, ..."
Visio 2019 Pro

wapperdude

Here's a bunny trail... the implementations and discussions that lead to spiral concoctions revolve around avoiding infinite (instantaneous) direction change, i.e., impulse spike in lateral force.  Interestingly, no one talks about impulse response.  Ooops.  Unintended bunny trail.  What was determined was this gradual increase in curvature rate that maximizes at the midpoint and then backs away.  Well, more or less true.  Looking at the visual of these curves, the likeness to a parabolic shape is quite striking.  Perhaps, parabolic curves might be a worthy investigation?  Perhaps, that's been done and discarded???  Where's JuneThe2nd? 
Visio 2019 Pro

RailwayKen

I am using a particular spiral because the real railroads I am modelling use that spiral. (There are other spirals in use on railways around the world. For example, I've been told the Indian Railways use a cubic spiral. All sorts of curves have been tried over the years, including parabolic segments and curves designed around making the differentials of certain angular accelerations into a smooth curve.)

Current Solution-- It works!
Shape Data (Prop.cells) contain radius, length of spiral, and the number of points to be plotted.
Say we choose to plot only 11 points. This means our shape will have 10 line segments.
The Scratch section has 11 rows
The rows calculate the x,y coordinates at distances (0, 0.1, 0.2, 0.3... 1) * Ls

Geometry1 row 1 is MoveTo 0, 0.
Geometry1 rows 2-11 is LineTo the x,y from Scratch.

Strictly speaking, I am not plotting the spiral itself, but chords of the spiral. This is probably good enough for laying commercially available flex track-- especially since my actual solution is plotting 100 points just because I can. (VBA code populates the Scratch and Geomtry1 rows.)

Limitation
To align this spiral with the circular curve it transitions to, I need to be able to plot a line of length Radius perpendicular to the last point on the spiral. With a NURBs, this would have bene trivial-- but of course the NURBS itself is mathematically not trivial.

If we use "=ANGLEALONGPATH(Geomtery1.path,1) + 90 deg" on our 10-segment spiral, we won't get the perpendicular we are looking for but only a crude approximation that is not close enough to avoid kinking the track. However, as with calculus, the smaller we make our spiral-chord-segments, the more accurate our approximation becomes. We could plot 10,000 points, but this slows calculation to a crawl.

Solution to the limitation
We really only need to know the perpendicular to the last point on the spiral. There is no requirement that the points be equidistant. So rather than plot 10,000+ points, we could plot an arbitrary small number of points provided that points n-1 and n are sufficiently close together to make the error in angle negligible.

To do this, I inserted a row n-1 that is x,y at distance along path 0.9999999*Ls.
So if we have "10" chords, the x,y coordinates are plotted for distances 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.9999999, 1)*Ls.

End Result and Can we see it
I am troubleshooting some bugs, but the concept works. Since there appears to be interest, I'll intend to post a working sample here within a few days or so.

The end result is straight track--entrance spiral--circular curve--exit spiral--straight track. This looks sort of like a parabola, but it's not one.

Nikolay

Have nothing to offer, since I don't even understand the problem, I am just curious - why a specific type of spiral is used for railways (it is for transition between straight lines, right, or?) and why is it so important to have this specific type of spiral on Visio drawing?

Why is it not an arc of a circle for example, is it bad somehow? Maybe I'm completely missing the point, but the thing you are trying to draw is basically a connector line that joins two straight lines (it's not a "spiral", it's a small arc of that spiral)?  Will anyone who looks at the drawing actually figure out that difference?

Or the drawing is actually used to build that railway, like a blueprint? To mark the ground, like from a drone or something?

Please forgive me my ignorance, I just have no idea about railway things altogether

wapperdude

The problem is a real life problem and the lateral force generated when a train changes direction.  RailwayKen builds his model railroads to mimic real world.  It is a choice.  Most model railroad companies ignore this and provide fixed straight and curved track pieces.  Then, not that long ago, flex track was offered.  This allows, among other things, the ability to incorporate "properly" designed transitions.

The link to the article I provided does a good job discussing the history and development of transition spirals, as well as some alternatives to the common practice used today.

RailwayKen provides a working approach that he uses.  He was looking for a simpler technique to implement the specific curves used real world.

Hope I put correct words in his mouth!
Visio 2019 Pro

Browser ID: smf (possibly_robot)
Templates: 4: index (default), Display (default), GenericControls (default), GenericControls (default).
Sub templates: 6: init, html_above, body_above, main, body_below, html_below.
Language files: 4: index+Modifications.english (default), Post.english (default), Editor.english (default), Drafts.english (default).
Style sheets: 4: index.css, attachments.css, jquery.sceditor.css, responsive.css.
Hooks called: 410 (show)
Files included: 34 - 1306KB. (show)
Memory used: 1293KB.
Tokens: post-login.
Cache hits: 15: 0.00181s for 26,546 bytes (show)
Cache misses: 5: (show)
Queries used: 17.

[Show Queries]