Riapro questa vecchia conversazione perché, approfittando delle festività, ho messo su una bozza di soluzione. Se non ricordo male il problema di tracciare l’arco di cerchio massimo tra due punti di una sfera era già stato sollevato come curiosità da @OldClaudio, perciò rispondo qui in una sola volta.
La soluzione sembra funzionare correttamente, ma non ci metterei le mani sul fuoco perché mi sembra “troppo semplice”, perciò se qualcuno fosse interessato a dargli un’occhiata, farebbe cosa gradita alla comunità.
Il cuore del codice è il pic [tt]ortodromia[/tt] che richiede almeno due opzioni: [tt]partenza[/tt] per le coordinate del punto di partenza e [tt]arrivo[/tt] per le coordinate del punto di arrivo. Le coordinate vanno espresse in gradi nella forma [tt]
Il codice non richiede alcuna libreria opzionale e può essere riassunto in questi passi:
1) trasformazione delle coordinate geografiche in coordinate cartesiane per i due punti che indichiamo con A e B
2) determinazione del vettore OP complanare con OA e OB e ortogonale a OA
3) determinazione del versore OC parallelo ed equiverso ad OP
4) tracciatura dell’arco sul piano cartesiano avente gli assi coordinati paralleli a OA e OC (l’asse z è ininfluente perché l’arco è sempre tracciato sul piano [xy]).
Se qualcuno trova degli errori oppure vuole semplicemente migliorare il codice, è il benvenuto.
P.S.: se si conoscono due punti non degeneri dello stesso cerchio, si può comunque costruire una semicirconferenza o una circonferenza spezzandola in due archi contigui.
`\documentclass{standalone}
\usepackage{tikz}
% componenti dei versori degli assi coordinati
% rispetto alla base della tela
\pgfmathsetlengthmacro{\xx}{-1cm*sqrt(3)/2}
\pgfmathsetlengthmacro{\xy}{-0.5cm}
\pgfmathsetlengthmacro{\yx}{1cm*sqrt(3)/2}
\pgfmathsetlengthmacro{\yy}{-0.5cm}
\pgfmathsetlengthmacro{\zx}{0cm}
\pgfmathsetlengthmacro{\zy}{1cm}
\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}},
lungo/.initial=0,
opposto/.code={\tikzset{/tikz/lungo=1}},
ortodromia/.pic={
% conversione delle coordinate geografiche in cartesiane
\pgfmathsetmacro{\Ax}{cos(\pgfkeysvalueof{/tikz/latA})*cos(\pgfkeysvalueof{/tikz/lonA})}
\pgfmathsetmacro{\Ay}{cos(\pgfkeysvalueof{/tikz/latA})*sin(\pgfkeysvalueof{/tikz/lonA})}
\pgfmathsetmacro{\Az}{sin(\pgfkeysvalueof{/tikz/latA})}
\pgfmathsetmacro{\Bx}{cos(\pgfkeysvalueof{/tikz/latB})*cos(\pgfkeysvalueof{/tikz/lonB})}
\pgfmathsetmacro{\By}{cos(\pgfkeysvalueof{/tikz/latB})*sin(\pgfkeysvalueof{/tikz/lonB})}
\pgfmathsetmacro{\Bz}{sin(\pgfkeysvalueof{/tikz/latB})}
% prodotto scalare (OA\cdot OB)
\pgfmathsetmacro{\ps}{\Ax*\Bx + \Ay*\By + \Az*\Bz}
% vettore OP complanare con OA e OB e ortogonale al primo
\pgfmathsetmacro{\Px}{-\Ax*\ps + \Bx}
\pgfmathsetmacro{\Py}{-\Ay*\ps + \By}
\pgfmathsetmacro{\Pz}{-\Az*\ps + \Bz}
% versore CP parallelo a OP
\pgfmathsetmacro{\Cx}{\Px/sqrt((\Px)^2 + (\Py)^2 + (\Pz)^2)}
\pgfmathsetmacro{\Cy}{\Py/sqrt((\Px)^2 + (\Py)^2 + (\Pz)^2)}
\pgfmathsetmacro{\Cz}{\Pz/sqrt((\Px)^2 + (\Py)^2 + (\Pz)^2)}
% angolo tra i due vettori OA e OB
\pgfmathsetmacro{\angolo}{acos(\ps)-360*\pgfkeysvalueof{/tikz/lungo}}
\draw [x={(\Ax*\xx+\Ay*\yx+\Az*\zx, \Ax*\xy+\Ay*\yy+\Az*\zy)},
y={(\Cx*\xx+\Cy*\yx+\Cz*\zx, \Cx*\xy+\Cy*\yy+\Cz*\zy)}, pic actions]
(1,0,0) arc (0:\angolo:1);
},
coordinata/.pic={
\pgftransformshift{
\pgfpointspherical{90-\pgfkeysvalueof{/tikz/lonA}}{\pgfkeysvalueof{/tikz/latA}}{1}
}
\pgfnode{coordinate}{center}{}{#1}{}
}
}
% stile usato per le linee dei meridiani e paralleli
\tikzset{griglia/.style={blue!40, very thin}}
\begin{document}
\begin{tikzpicture} [x={(\xx,\xy)}, y={(\yx,\yy)}, z={(\zx,\zy)}]
% disegna i meridiani e i paralleli
\foreach \i in {0,10,…,170}{
\pic [partenza={0}{\i}, arrivo={90}{\i}, griglia] {ortodromia};
\pic [partenza={0}{\i}, arrivo={90}{\i}, opposto, griglia] {ortodromia};
}
\foreach \i in {-80,-70,…,80}
\draw [griglia] (0,0,{sin(\i)}) circle ({cos(\i)});
% disegna l'arco
\pic [partenza={30}{-50}, arrivo={30}{90}, red] {ortodromia};
\pic [posizione={30}{-50}] {coordinata=A};
\pic [posizione={30}{90}] {coordinata=B};
% marca i due punti
\fill (A) circle (0.8pt)
(B) circle (0.8pt);
% assi coordinati
\draw [-latex] (1,0,0) — (2,0,0);
\draw [-latex] (0,1,0) — (0,2,0);
\draw [-latex] (0,0,1) — (0,0,2);
\end{tikzpicture}
\end{document}`
[attachment=1225]prova3_2014-12-29.png[/attachment]