Bene, questa risulta essere un'estensione non banale della soluzione di Veldaeven.
Per ogni sequenza di 3 punti, calcola i 2 vettori tra di loro, come suggerito da Veldaeven.
Trova l'angolo tra i due vettori aggiungendo gli angoli dall'asse x - (nb non utilizzare il prodotto punto che restituisce sempre un angolo inferiore a pi e quindi è troppo simmetrico per il nostro problema).
Dimezza questo angolo. Questa è la bisettrice perpendicolare lungo la quale giace il vettore risultante.
Ora per calcolare quale quadrante disegnare il punto in (il problema "quale lato"). Trova la differenza tra i 2 vettori. Se il gradiente di questo (cioè la "derivata doppia") è positivo, il percorso ritorna su se stesso per un massimo: aggiungi pi / 2. Se il gradiente è negativo, il percorso passa attraverso un minimo: sottrarre pi / 2
innerWallClockwise :: Float -> V2 Float -> [Point V2 Float] -> [V2 Float]
innerWallClockwise w acc (p : p' : p'' : ps) =
let v = p' .-. p
v' = p'' .-. p'
d2v = v' .-. v
phi = atan2 (v ^. _y) (v ^. _x)
rho = atan2 (v' ^. _y) (v' ^. _x)
theta = phi + rho
d2vtheta = atan2 (d2v ^. _y) (d2v ^. _x)
theta' = theta / 2 + if d2vtheta > 0 then pi / 2 else (-1) * pi / 2
v''' = w *^ angle theta'
v'''' = acc .+^ v'''
in
if ps == [] then [v''''] else v'''' : (innerWallClockwise w (acc .+^ v') (p' : p'' : (head ps) : (tail ps)))
Diamo un semplice percorso rettangolare
let path=[P (V2 0 0), P(V2 0 5), P(V2 5 5), P (V2 5 (-5)), P (V2 0 (-5))]
Prova la nostra funzione:
innerWallClockwise 1 (V2 0 5) path
=> [V2 0.70710677 4.2928934,V2 4.2928934 4.2928934,V2 4.2928934 (-4.2928934)]
Sì, i punti sono tutti all'interno del percorso di input a una distanza di sqrt (2) dal vertice.
NB: tutti i metodi che utilizzano ad es. il prodotto incrociato dei due vettori è troppo simmetrico.
Speriamo che questo possa aiutare qualcuno in futuro.