Re: Disegnare archi su una sfera e marcare i punti

#98196
Liverpool
Partecipante
    Up
    0
    Down
    ::

    OldClaudio” post=98957Visto che l’appetito vie mangiando, saresti anche capace di disegnare una lossodromia fra due punti dati?

    Forse siamo un po’ OT e per questo chiedo scusa a @Squall. Questo regalo è tutto per @OldClaudio.
    Allo stesso modo dell’ortodromia ho definito un pic [tt]lossodromia[/tt] che genera la curva lossodromica tra due punti assegnati sulla sfera. Il codice usa solo i comandi di TikZ, ma per disegnare la sfera mi sono appoggiato a pgfplots, che non è necessario. Il pic utilizza l’istruzione [tt]plot[/tt] di TikZ con i valori di default (25 campioni), ma è possibile passare al comando le opzioni [tt]smooth[/tt], [tt]hobby[/tt] oppure [tt]samples=[/tt] per migliorare le caratteristiche del tratto. Non l’ho fatto a priori per non appesantire il risultato quando non è necessario.
    Il cuore è il comando:
    `\pic [partenza={latitudine A}{longitudine A}, arrivo={latitudine B}{longitudine B}] {lossodromia};`
    nel quale, come di consueto, la latitudine 0 corrisponde al piano [xy] e la longitudine 0 al semipiano [xz] di ascisse positive. La latitudine va da -90 al polo sud a 90 al polo nord; la longitudine va da -180 (ovest) a 180 (est). Non è possibile scegliere come punto di partenza o di arrivo uno dei due poli, ma è possibile prendere un punto di latitudine molto vicina (ad esempio 89.99°). Non è nemmeno possibile prendere due punti sullo stesso meridiano, ma in tal caso la lossodromia coincide con l’ortodromia e si può usare quel codice. Volendo si può pensare di affinare il codice per includere questi casi particolari.
    Anche qui è possibile utilizzare la chiave [tt]raggio[/tt] che è un alias per la chiave [tt]scale[/tt] e accetta solo numeri adimensionali che vengono interpretati come fattore di scala della lunghezza del versore dell’asse delle ascisse.
    Se le coordinate vengono inserite correttamente, il codice disegna il più breve tra tutti i tratti possibili. In alternativa, si può usare l’opzione [tt]demo[/tt]: in tal caso il codice disegna la curva che passa per i due punti e per tutti i punti di longitudine intermedia. Per fare un esempio: se la longitudine del punto di partenza è -178 e quella del punto di arrivo è 178, di default il codice disegna la curva che si estende su soli 4° di longitudine, mentre con l’opzione [tt]demo[/tt] disegna la curva che si estende su 356° di longitudine, passando per il meridiano di Greenwich.

    `\documentclass

    {standalone}
    \usepackage{pgfplots}
    \pgfplotsset{compat=1.11}

    % componenti dei versori degli assi coordinati
    % rispetto alla base della tela
    \pgfmathsetlengthmacro{\xx}{-2cm*sqrt(3)/2}
    \pgfmathsetlengthmacro{\xy}{-1cm}
    \pgfmathsetlengthmacro{\yx}{2cm*sqrt(3)/2}
    \pgfmathsetlengthmacro{\yy}{-1cm}
    \pgfmathsetlengthmacro{\zx}{0cm}
    \pgfmathsetlengthmacro{\zy}{2cm}

    \tikzset{
    latA/.initial=0,
    lonA/.initial=0,
    latB/.initial=0,
    lonB/.initial=0,
    partenza/.style 2 args={latA=#1, lonA=#2},
    arrivo/.style 2 args={latB=#1, lonB=#2},
    posizione/.style 2 args={latA=#1, lonA=#2},
    raggio/.initial=1,
    raggio/.code={\tikzset{/tikz/scale=#1}},
    /lossodromia/esteso/.initial=1,
    demo/.code={\tikzset{/lossodromia/esteso=0}},
    declare function={
    s(\x) = ln( (sin(\x)+1)/cos(\x) );
    S(\x) = \m*(\x-\lonA) + s(\latA);
    % s e S sono due espressioni della stessa funzione
    },
    lossodromia/.pic={
    % riferimento http://homepages-fb.thm.de/boergens/marken/marke062/marke062_loxo.pdf
    \pgfmathsetmacro{\latA}{\pgfkeysvalueof{/tikz/latA}}
    \pgfmathsetmacro{\lonA}{\pgfkeysvalueof{/tikz/lonA}}
    \pgfmathsetmacro{\latB}{\pgfkeysvalueof{/tikz/latB}}
    \pgfmathsetmacro{\lonB}{\pgfkeysvalueof{/tikz/lonB}}
    \pgfmathparse{\lonB-\lonA>180 && \pgfkeysvalueof{/lossodromia/esteso}==1 ? 360 : 0}
    \pgfmathsetmacro{\lonB}{\lonB – \pgfmathresult}
    \pgfmathparse{\lonA-\lonB>180 && \pgfkeysvalueof{/lossodromia/esteso}==1 ? 360 : 0}
    \pgfmathsetmacro{\lonA}{\lonA – \pgfmathresult}
    \pgfmathsetmacro{\m}{(s(\latB)-s(\latA)) / (\lonB-\lonA)}
    \draw [variable=\t, domain=\lonA:\lonB, pic actions]
    plot ({cos(\t)/cosh(S(\t))}, {sin(\t)/cosh(S(\t))}, {tanh(S(\t))});
    },
    coordinata/.pic={
    \pgftransformshift{
    \pgfpointspherical{90-\pgfkeysvalueof{/tikz/lonA}}{\pgfkeysvalueof{/tikz/latA}}{1}
    }
    \pgfnode{coordinate}{center}{}{#1}{}
    }
    }

    \begin{document}
    \begin{tikzpicture}
    \begin{axis} [x={(\xx,\xy)}, y={(\yx,\yy)}, z={(\zx,\zy)},
    anchor=origin, at={(0,0)}, disabledatascaling, hide axis]
    % disegna i meridiani e i paralleli
    \addplot3 [surf, z buffer=sort, fill opacity=0.6, white, faceted color=blue!40,
    samples=19, samples y=37, variable=\u, variable y=\v,
    domain=0:180, y domain=0:360]
    ({cos(u)*sin(v)}, {sin(u)*sin(v)}, {cos(v)});
    % disegna il contorno della sfera
    \draw [blue!40] (0,0,0) circle ({2cm*sqrt(3/2)});
    % disegna la lossodromia
    \pic [partenza={-10}{20}, arrivo={89.99}{360}, smooth, samples=50, demo, red] {lossodromia};
    % definisce le coordinate dei punti di partenza e arrivo
    \pic [posizione={-10}{20}] {coordinata=A};
    \pic [posizione={89.99}{360}] {coordinata=B};
    % traccia i pallini in corrispondenza degli estremi della curva
    \fill (A) circle (1pt)
    (B) circle (1pt);
    % disegna gli assi coordinati
    \draw [-latex] (1,0,0) — (1.5,0,0);
    \draw [-latex] (0,1,0) — (0,1.5,0);
    \draw [-latex] (0,0,1) — (0,0,1.5);
    \end{axis}
    \end{tikzpicture}
    \end{document}`

    [attachment=1239]lossodromia.jpg[/attachment]

    Il codice, come anche quello dell’ortodromia, al momento presenta un bug: quando usato all’interno dell’ambiente [tt]axis[/tt] di pgfplots per disegnare la sfera passando come opzioni i versori degli assi coordinati, i pallini (e nel caso dell’ortodromia la curva) potrebbero essere tracciati fuori asse per alcune combinazioni di assi coordinati. Il problema nasce dal fatto che il sistema di riferimento viene specificato due volte: una per l’ambiente [tt]axis[/tt] e l’altra per i pic. Se qualcuno mi aiuta a risolverlo, gli sono grato.

    Ciao

    Edit: bug risolto con la chiave [tt]disabledatascaling[/tt]. Ho aggiornato conseguentemente il codice.

    Attachments:
    You must be logged in to view attached files.

    Go to top