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
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 ?
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 …
Di solito e’ piu’ un problema per GH (che ricalcola come un matto ) che per Rhino.
Comunque anche C#, dai … intanto puoi usare RhinoCommon e poi meglio che ReDim Preserve sara’, no ?
… Unica alternativa, almeno per ora, Python (sul 7 IronPython, per Rhino 8 CPython) … che pero’ credo ti dia una certa allergia …
Purtroppo per te e’ quello che piace in RMA … e riesce anche a connettersi in qualche modo col divino dotNET … tanto con Rhino sempre li’ si casca ormai.
Sto provando ‘accorciando’ il knot vector per calcolare la spezzata, cioe’ tengo solo i nodi nel dominio della curva …
Dice che potrebbe andare o ci vedi qualche cavolata galattica ?
Poi a essere pignoli dovrei evitare di cercare il quad a fine curva per le curve chiuse credo …
Ti rispondo come prima da cell… Non conosco come si trattino le curve chiuse periodiche in termini di punti e knot. Io le tratterei tutte come clamped … ma non sembra vada bene per gli standard prefissati …
Per ora non riesco a concentrarmi per capire come funziona la definizione, sorry, con GH fatico sempre … ma sembra che funzioni bene !
Pare che invece lo script VBS non trovi quel punto.
Direi che lo script in casi come questo puo’ mancare un punto.
@Sergio_Alessi , forse serve aggiungere un punto lungo la tangente a inizio/fine curva, per avere una ulteriore terna di punti da testare, credo che cosi’ dovrebbe trovarlo … che dici ?
ciao Leopoldo,
finalmente ho capito come funziona il tuo sistema, io creavo direttamente i rettangoli usando due punti
lo script finale mi è chiaro quello che invece non comprendo è il fatto che dopo esserti trovato i punti,
(a metà def) poi nella parte finale ti ritrovi con 3 punti da gestire con lo script? mi manca il motivo. . . .
ps
ma con “shatter” avresti ottenuto lo stesso risultato di “point trim curve” ma senza il dominio giusto?
la funzione “indexof” ho letto la descrizione ma mi sfugge il risultato che riporta da un testo a 6
edit:
a me con un paio di prove fatte tra “RhScript” e “Extreme Parameters” un punto non mi corrispondeva
mentre con l’ultima def di Leopoldo ho dovuto modificare i decimali da 3 a 4 per ritrovarmi tutti i punti
Lo “shatter” non divide la curva in segmenti.
Vediamo se riesco a spiegarmi, ho messo qualche didascalia nella definizione.
Tenete presente e che in queste definizioni non ho usato il componente “equality” ma il componente “similarity”, anche se con una tolleranza molto bassa. serg2 c.gh (31,3 KB)
Quest’altra definizione prevede la possibilità di modificare il piano di riferimento. quad points l.gh (22,2 KB)
ok Leopoldo grazie per la spiegazione ora è più chiaro
è normale che poi alla fine i punti finali del “list item 1 centrale” non combacino con quelli del cull pattern?
non mi sembra che ci sia qualcosa che cambi, a meno che non mi sfugge qualcosa verso il merge. . . .
strano perché così mi fu consigliato di usarlo, essendo che mi serviva propro dividere la curva in segmenti.