Mi dispiace Salvio ma non ho del codice condivisibile.
Ciao Emilio!
certo che si riesce. Converti il polinomio in forma canonica,
calcoli derivata del polinomio e trovi gli zeri.
Sergio
ma quindi, questo tipo di problema non rientra nella soluzione nell’uso del codice sopra citato?
I “trucchi da strada” che faccio io sono accozzaglie di codice che imitano le cose imparate alle superiori… ma di fatto è tutto un po’ inventato alla fai-da-te …
Mi piacerebbe molto vedere un esempio minimale di quello che hai appena descritto…
… però le applichi bene.
Curva bezier grado 3 con i seguenti punti di controllo
P0=(0.0,0.0)
P1=(1.0,1.0)
P2=(2.0,-1.0)
P3=(3.0;0.0)
'La curva ha equazione:
C(x,y)=P0*(1-t)^3+3*P1*t*(1-t)^2+3*P2*t^2*(1-t)+P3*t^3
dC/dt = 3*[(P1-P0)*t^2+2*(P2-P1)*t*(1-t)+(P3-P2)*t^2]
' si considera la componente Y (la X è monotona crescente ...)
dCy/dt = 3*[(1)*t^2+2*(-2)*t*(1-t)+(1)*t^2]
dCy/dt = 0
'tolgo il 3 perché è una costante ... risulta:
6*t^2-6*t+1=0
'si applica la nota formula ...
t=[6 +/- (36-24)^0.5]/(2*6)
Così troviamo gli zeri, ovvero i punti con derivata nulla rispetto al sistema di riferimento di Rhino, la funzione che ha mostrato Ricc li trova rispetto a qualsiasi sistema di riferimento (lo chiamava vettore perpendicolare alla tangente).
Ciao Luca
questa è la soluzione per trovare i punti da snap quad.
Esiste la soluzione analitica anche per la condizione di perpendicolarità
punto - curva … ma anche curva - curva … anche tra superfici!
Le soluzioni sono analoghe.
Questa per me è materia studiata poco meno di trenta anni fa …
Lascio ai giovani come te di analisi I e II formulare la soluzione analitica.
Per concludere, non è detto che risolvere analiticamente il problema
sia la soluzione migliore. La soluzione brute di Emilio non è una cavolata, è di fatto
la più usata per molti problemi!
prima di postare una domanda, faccio sempre qualche ricerca, ed in questo caso sono riuscito a trovare poco e nulla, credevo che sbagliassi le parole chiavi, ma a come vedo la cosa è un bel pò complessa.
Sono riuscito a calcolare il punto di quadrante con il tuo metodo, matematicamente, con il metodo analitico come dicevi tu.
Ma non riesco comunque a capire questo passaggio:
Vedo che c’è la struttura del cubo di binomio (dove A=1-t e B=t):
A^3 + 3(A^2)B + 3A(B^2) + B^3
E la derivata:
3A^2 + 6AB + 3B^2
Ma non capisco il passaggio dai quattro punti P0,P1,P2,P3 ai 3 vettori(?) P1-P0,P2-P1,P3-P2 …
Però… funziona! … quindi ok.
Ma, potresti spiegarmi:
- qual’è la funzione di una nurbs a grado 3 con 5+ punti di controllo?
- pesi e knot? Immagino servirebbe integrarli per fare un lavoro completo…
La derivata di una bezier si calcola cosi:
grado che moltiplica la bezier di grado n -1 con punti di controllo Pi - Pi-1.
Se hai una spline la decomponi in bezier con l’algoritmo knot insertion.
Se poi è razionale calcoli la derivata.
C = N / D
dC = (N’D -ND’)/D^2

La derivata di una bezier si calcola cosi:
grado che moltiplica la bezier di grado n -1 con punti di controllo Pi - Pi-1.
Grazie per l’info.
Ma (suppongo ovviamente) se derivi il polinomio e poi raccogli viene fuori la stessa cosa.
A me pero’ il primo termine viene in (1-t)^2 … giusto ?
dC/dt = 3*[(P1-P0)*(1-t)^2+2*(P2-P1)*t*(1-t)+(P3-P2)*t^2]
Comunque derivando il polinomio il passaggio intermedio (se servisse) risulta …salvo errori :
dC/dt =
-3*P0*(1-t)^2+
+3*P1*(1-t)^2+
-3*2*P1*t*(1-t)+
+3*2*P2*t*(1-t)+
-3*P2*t^2+
+3*P3*t^2
Ciao a tutti cerco di dare un contributo per fare chiarezza sulla continuità interna delle curve. Essendo una nurbs composta da bezier concentro l’attenzione proprio sulle bezier. Anche una bezier di grado superiore ad 1 può non essere derivabile in un punto. Costruite una curva di grado 3 con punti di controllo alle coordinate: 0,0; 2,1; 0,1; 2,0 In mezzeria la curva ha continuità C0. E’ vero che le nurbs sono funzioni polimoniali, ma dobbiamo ricordare di aggiungere sempre il termine …
un 3d aperto tempo fa proprio sulle Curve Nurbs,
bella tutta la discussione con tanti post interessanti.

A me pero’ il primo termine viene in (1-t)^2 … giusto ?
È giusto Emilio! Anche il passaggio intermedio.
Condivido una soluzione in rhinoscript. Non l’ho testato molto. La precisione sembra buona
ma potrei sbagliarmi … Genera un errore con curve chiuse: vedrò con calma. Qui i limiti del
linguaggio iniziano a farsi sentire ciò nonostante non è lentissimo …
MinMaxCrv.rvb (5,4 KB)
Option Explicit
'Script written by Ing. Alessi Sergio
'Script copyrighted by Ing. Alessi Sergio
'Script version Alfa 0 date 02.10.2022
Call Main()
Sub Main()
Dim crv:crv = rhino.getobject("Select a planar curve ...", 4)
Dim g:g = rhino.CurveDegree(crv)
Dim nK:nK = rhino.CurveKnotCount(crv)
Dim K:K = rhino.CurveKnots(crv)
Dim CPts():ReDim CPts((nk-g)*g*2)'Points coord.
Dim PPts():ReDim PPts((nk-g)*g*2)'Points param.
Dim Npts
Dim d0, d1, i, j, h, par
d0 = K(0)
Cpts(0) = rhino.EvaluateCurve(crv, d0)
Ppts(0) = d0
h = 1
i = g - 1
While i < nk - 1
d1 = K(i + 1)
If d1 <> d0 Then
For j=1 To 2 * g - 1
par = d0 + (d1 - d0) * j / 2 / g
PPts(h) = par
CPts(h) = rhino.EvaluateCurve(crv, par)
h = h + 1
Next
PPts(h) = d1
CPts(h) = rhino.EvaluateCurve(crv, d1)
d0 = d1
h = h + 1
End If
i = i + 1
Wend
Npts = h
Dim dd,ud, Iter,z
Dim mMx():ReDim mMx(Npts)
Dim mMy():ReDim mMy(Npts)
Dim mME():ReDim mME(Npts)
Dim ix
Dim iy
Dim aTol:aTol = 0.0001
ix = 0
iy = 0
par = k(0)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(0)) < aTol Then
mMx(ix) = par
ix = ix + 1
End If
If abs(ud(1)) < aTol Then
mMy(iy) = par
iy = iy + 1
End If
For i=1 To Npts - 2
'********************************************************************************
'MINMAX X
'********************************************************************************
If (CPts(i)(0) - CPts(i - 1)(0)) >= 0 And (CPts(i + 1)(0) - CPts(i)(0)) =< 0 Then
par = PPts(i)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(0)) > aTol Then
If ud(0) > 0 Then
d0 = PPts(i)
d1 = PPts(i + 1)
Else
d0 = PPts(i - 1)
d1 = PPts(i)
End If
Iter = 0
While abs(ud(0)) > aTol And Iter < 50
par = (d0 + d1) / 2
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If ud(0) > 0 Then
d0 = Par
Else
d1 = Par
End If
iter = iter + 1
Wend
If iter >= 50 Then
Call rhino.Print("Errore imprevisto param = " & par)
Else
mMx(ix) = par
ix = ix + 1
End If
Else
mMx(ix) = par
ix = ix + 1
End If
End If
If ((CPts(i)(0) - CPts(i - 1)(0)) < 0 And (CPts(i + 1)(0) - CPts(i)(0)) > 0) Then
par = PPts(i)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(0)) > aTol Then
If ud(0) < 0 Then
d0 = PPts(i)
d1 = PPts(i + 1)
Else
d0 = PPts(i - 1)
d1 = PPts(i)
End If
Iter = 0
While abs(ud(0)) > aTol And Iter < 50
par = (d0 + d1) / 2
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If ud(0) < 0 Then
d0 = Par
Else
d1 = Par
End If
iter = iter + 1
Wend
If iter >= 50 Then
Call rhino.Print("Errore imprevisto param = " & par)
Else
mMx(ix) = par
ix = ix + 1
End If
Else
mMx(ix) = par
ix = ix + 1
End If
End If
'********************************************************************************
'MINMAX Y
'********************************************************************************
If (CPts(i)(1) - CPts(i - 1)(1)) >= 0 And (CPts(i + 1)(1) - CPts(i)(1)) =< 0 Then
par = PPts(i)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(1)) > aTol Then
If ud(1) > 0 Then
d0 = PPts(i)
d1 = PPts(i + 1)
Else
d0 = PPts(i - 1)
d1 = PPts(i)
End If
Iter = 0
While abs(ud(1)) > aTol And Iter < 50
par = (d0 + d1) / 2
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If ud(1) > 0 Then
d0 = Par
Else
d1 = Par
End If
iter = iter + 1
Wend
If iter >= 50 Then
Call rhino.Print("Errore imprevisto param = " & par)
Else
mMy(iy) = par
iy = iy + 1
End If
Else
mMy(iy) = par
iy = iy + 1
End If
End If
If ((CPts(i)(1) - CPts(i - 1)(1)) < 0 And (CPts(i + 1)(1) - CPts(i)(1)) > 0) Then
par = PPts(i)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(1)) > aTol Then
If ud(1) < 0 Then
d0 = PPts(i)
d1 = PPts(i + 1)
Else
d0 = PPts(i - 1)
d1 = PPts(i)
End If
Iter = 0
While abs(ud(1)) > aTol And Iter < 50
par = (d0 + d1) / 2
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If ud(1) < 0 Then
d0 = Par
Else
d1 = Par
End If
iter = iter + 1
Wend
If iter >= 50 Then
Call rhino.Print("Errore imprevisto param = " & par)
Else
mMy(iy) = par
iy = iy + 1
End If
Else
mMy(iy) = par
iy = iy + 1
End If
End If
Next
par = k(nk - 1)
dd = rhino.CurveEvaluate(crv, par, 1)
ud = rhino.VectorUnitize(dd(1))
If abs(ud(0)) < aTol Then
mMx(ix) = par
ix = ix + 1
End If
If abs(ud(1)) < aTol Then
mMy(iy) = par
iy = iy + 1
End If
rhino.EnableRedraw False
For i=0 To ix - 1
par = rhino.AddPoint(rhino.EvaluateCurve(crv, mMx(i)))
Next
For i=0 To iy - 1
par = rhino.AddPoint(rhino.EvaluateCurve(crv, mMy(i)))
Next
rhino.EnableRedraw True
End Sub
Curva grado 7 con 275 punti di controllo.
Ciao Sergio

Genera un errore con curve chiuse
Sembra che il problema siano le curve periodiche.
Vero Emilio
il vettore dei knot cambia … guarderò con molta calma.
Ciao!
Scusa Sergio …
Se capisco come funziona lo script, all’inizio su ogni span della curva ricavi dei punti e ci costruisci una polilinea con 2*grado segmenti.
Poi dove la polilinea presenta un massimo o un minimo (rispetto alla coordinata scelta) cerchi il massimo o il minimo della curva.
Se e’ cosi’ … La mia curiosita’ e’ questa:
Come hai ricavato il numero 2*grado per i segmenti della polilinea ?
Ciao Emilio
che domande mi fai in pubblico!!!
Il risultato è corretto?
Puoi tradurre il codice in py così mi fai sapere come gira? Con il poco tempo
a disposizione se lo scrivo in c++ ci metto un mese! … dimentico tutte le regole,
anche le basilari … . In VB scrivo di tutto …

che domande mi fai in pubblico!
Hahaha.

Puoi tradurre il codice in py così mi fai sapere come gira?
Ci provo .
( Se riesco a fare lo script lo posto cosi’ vedi tu come gira )
Come suggerisci di fare per le curve periodiche ?

se lo scrivo in c++ ci metto un mese!
Se e’ per GH puoi usare C#, per Rhino credo tocchi aspettare Rhino 8.

Come suggerisci di fare per le curve periodiche ?
Come faresti tu, vedo …
Il vettore dei knot cambia rispetto alle curve clamped.

Se e’ per GH puoi usare C#, per Rhino credo tocchi aspettare Rhino 8.
Intendevo che il codice è palesemente orientato verso la programmazione con puntatori di memoria. C# come tutti i linguaggi net mmm …