# Drawing torus points and arches with coordinates read from a file

I have a quite intricate question... I have to plot a torus of radii (r,R) with two set of points of different colour on it its surface. The points' coordinates are in two different files that must be properly «incorporated». Finally I have to connect with an arch first point of a type with the first point of the other type, the second point with the second one and so on (the order being determined by their positions in the respective files), the arch being the geodesic on the toroidal surface...

Any suggestion?

-
Does this help? – Philipp Jan 29 '14 at 12:44
@Philipp: The arches in that picture would be geodesic on the "flat" torus, but not on the torus embedded in R^3. – Charles Staats Jan 29 '14 at 16:04
A couple of comments. First, it would help to know how your coordinates are specified. Are they given as points in 3-space, or points in a rectangle (the domain of a parametrization), or some other format? Second, asking for a geodesic arc on a torus embedded in R^3 is a fairly complex mathematical question, and I doubt you will find any drawing-oriented program with a built-in method to compute this for you. Do you really need the arcs to be geodesic, or just "reasonable"? – Charles Staats Jan 29 '14 at 16:10
Hi guys. Firstly, thank you for your answers. @Philipp the code helps a lot for drawing the torus, but I am totally unfamiliar with Asymptote unfortunately and I have to import (a lot of) points. I think however that I will use it to draw the donut :) Thanks again. – user44990 Jan 30 '14 at 16:49
@CharlesStaats I need a sort of geodetic on the flat torus (sorry I write not clearly) and a reasonable solution is fine! The points are in the form x y where x and y are the coordinates in the rectangle, domain of parametrization. However I can clearly recompute their coordinates in another form, if necessary. – user44990 Jan 30 '14 at 16:50

Here is an Asymptote solution that first creates files containing the data (random points), then imports the data from those files, and then creates the desired image. Hopefully you can adapt it to your needs.

This version is rasterized; by adapting the code from my solution here, it may be possible to produce a vector graphic solution if you can avoid an out-of-memory error.

Note that the "geodesics" are geodesic on the flat torus, but not on the actual surface embedded in three-space.

``````/* Create two human-readable files, each containing 40 random numbers between 0 and 1. */
file fout1 = output("torus_points_type1.txt");
file fout2 = output("torus_points_type2.txt");
for (int i = 0; i < 20; ++i) {
write(fout1, " ", unitrand(), unitrand());
write(fout1, endl);

write(fout2, " ", unitrand(), unitrand());
write(fout2, endl);
}
close(fout1);
close(fout2);

/************************************/

/* Read the files into arrays of points. */

pair[] type1pts, type2pts;

file type1 = input("torus_points_type1.txt").line();
file type2 = input("torus_points_type2.txt").line();

real[] temp;
while(!eof(type1) && !eof(type2)) {
temp = type1;
type1pts.push((temp[0], temp[1]));
temp = type2;
type2pts.push((temp[0], temp[1]));
}
close(type1);
close(type2);

/**********************************/

/* Now, do the actual drawings. */

settings.outformat="png";
settings.render=8;

import graph3;

unitsize(3cm);
triple eye = (10,1,4);
//currentprojection=perspective(2*eye);
currentprojection=orthographic(eye);

int nu = 40, nv = 32;
surface torus = surface(Circle(c=2Y, r=0.6, normal=X, n=nv), c=O, axis=Z, n=nu);
torus.ucyclic(true);
torus.vcyclic(true);

/* The following line is irrelevant unless you want to embed
an interactive image in a pdf file. */
defaultrender=render(merge=true);

draw(torus, surfacepen=emissive(white + opacity(0.6)));

/* Reparametrize over [0,1] x [0,1] */
triple torusPoint(real u, real v) {
}
triple torusPoint(pair uv) {
}

pen gridpen = linewidth(0.3pt) + gray;

int n = 40;
for (int i = 0; i < n; ++i) {
real u = i/n;
triple f(real v) {
}
draw(graph(f, 0, 1, n=40, operator..) .. cycle, p=gridpen);
}

n = 20;
for (int i = 0; i < n; ++i) {
real v = i/n;
triple f(real u) {
}
draw(graph(f, 0, 1, n=16, operator..) .. cycle, p=gridpen);
}

/* Make parampath an alias for triple(real). */
typedef triple parampath(real);

parampath _torusGeodesic(pair a, pair b) {
return new triple(real t) {
};
}
path3 torusGeodesic(pair a, pair b) {
return graph(_torusGeodesic(a,b), 0, 1, n=40, operator..);
}

for (int i = 0; i < type1pts.length; ++i) {
pair a = type1pts[i];
dot(torusPoint(a), heavyblue);
pair b = type2pts[i];
for (int du = -1; du <= 1; ++du) {
for (int dv = -1; dv <= 1; ++dv) {
pair bprime = b + (du,dv);
if (length(bprime-a) < length(b-a)) b = bprime;
}
}
dot(torusPoint(b), heavyred);
draw(torusGeodesic(a,b), 0.1*red + 0.2*blue);
}
``````

The result:

-
Sorry. I forgot the link of your Asymptote tutorial, where is it? Thanks. :-) – kiss my armpit Jan 31 '14 at 8:03
@Code Mocker: The tutorial in question may be found, for now, at this website. Note that I found this address quickly by googling "Asymptote tutorial." – Charles Staats Jan 31 '14 at 13:12