4

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?

5
  • Does this help? Commented Jan 29, 2014 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. Commented Jan 29, 2014 at 16:04
  • 1
    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"? Commented Jan 29, 2014 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. Commented Jan 30, 2014 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. Commented Jan 30, 2014 at 16:50

1 Answer 1

7

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) { return torus.point(nu*u, nv*v); } triple torusPoint(pair uv) { return torusPoint(uv.x, uv.y); } pen gridpen = linewidth(0.3pt) + gray; int n = 40; for (int i = 0; i < n; ++i) { real u = i/n; triple f(real v) { return torusPoint(u,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) { return torusPoint(u,v); } 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) { return torusPoint((1-t)*a + t*b); }; } 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:

enter image description here

2
  • Sorry. I forgot the link of your Asymptote tutorial, where is it? Thanks. :-) Commented Jan 31, 2014 at 8:03
  • 1
    @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." Commented Jan 31, 2014 at 13:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.