Skip to content

Instantly share code, notes, and snippets.

@Dan-Piker
Last active February 15, 2025 06:56
Show Gist options
  • Save Dan-Piker/f7d790b3967d41bff8b0291f4cf7bd9e to your computer and use it in GitHub Desktop.
Save Dan-Piker/f7d790b3967d41bff8b0291f4cf7bd9e to your computer and use it in GitHub Desktop.

Revisions

  1. Dan-Piker revised this gist Aug 10, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions Moebius3d
    Original file line number Diff line number Diff line change
    @@ -15,8 +15,8 @@ double xa = Pt.X;
    double ya = Pt.Y;
    double za = Pt.Z;

    double p = 1;
    double q = 0; //set to the same as q for isoclinic rotations
    double p = 0; //set to the same as q for isoclinic rotations
    double q = 1;

    //reverse stereographic projection to hypersphere
    double xb = 2 * xa / (1 + xa * xa + ya * ya + za * za);
  2. Dan-Piker created this gist Aug 9, 2020.
    43 changes: 43 additions & 0 deletions Moebius3d
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    //Moebius transformations in 3d, by reverse stereographic projection to the 3-sphere,
    //rotation in 4d space, and projection back.
    //by Daniel Piker 09/08/20
    //Feel free to use, adapt and reshare. I'd appreciate a mention if you post something using this.
    //You can also now find this transformation as a component in Grasshopper/Rhino
    //I first wrote about these transformations here:
    //https://spacesymmetrystructure.wordpress.com/2008/12/11/4-dimensional-rotations/

    //If you want to transform about a given circle. Points on the circle and its axis stay on those curves.
    //You can skip these 2 lines if you want to always use the origin centred unit circle.
    Pt.Transform(Transform.PlaneToPlane(circle.Plane, Plane.WorldXY));
    Pt /= circle.Radius;

    double xa = Pt.X;
    double ya = Pt.Y;
    double za = Pt.Z;

    double p = 1;
    double q = 0; //set to the same as q for isoclinic rotations

    //reverse stereographic projection to hypersphere
    double xb = 2 * xa / (1 + xa * xa + ya * ya + za * za);
    double yb = 2 * ya / (1 + xa * xa + ya * ya + za * za);
    double zb = 2 * za / (1 + xa * xa + ya * ya + za * za);
    double wb = (-1 + xa * xa + ya * ya + za * za) / (1 + xa * xa + ya * ya + za * za);

    //rotate hypersphere by amount t
    double xc = +(xb) * (Math.Cos((p) * (t))) + (yb) * (Math.Sin((p) * (t)));
    double yc = -(xb) * (Math.Sin((p) * (t))) + (yb) * (Math.Cos((p) * (t)));
    double zc = +(zb) * (Math.Cos((q) * (t))) - (wb) * (Math.Sin((q) * (t)));
    double wc = +(zb) * (Math.Sin((q) * (t))) + (wb) * (Math.Cos((q) * (t)));

    //project stereographically back to flat 3D
    double xd = xc / (1 - wc);
    double yd = yc / (1 - wc);
    double zd = zc / (1 - wc);

    //the transformed point
    Point3d P = new Point3d(xd, yd, zd);

    //transform back to our input circle (you can skip this part if always using the origin centred unit circle)
    P *= circle.Radius;
    P.Transform(Transform.PlaneToPlane(Plane.WorldXY, circle.Plane));