Shapes3D is beyond Coool : But can I do dynamic textures

2»

Answers

  • edited January 2018 Answer ✓

    Some thoughts on this:

    You can use loadStrings() to load an array of lines from a text file that you save in your sketch folder. If you have one star per line in your text file, with x and y values separated by tabs and/or commas, like this:

    stars.txt

    9      198
    128    189
    176    191
    12     67
    126    136
    

    ...split the line on the delimiter with splitTokens() to access the x and y values, like this:

    StarLines.pde

    String[] starLines = loadStrings("stars.txt");
    println("Loaded " + starLines.length + " stars:");
    for (int i = 0 ; i < starLines.length; i++) {
      String[] star = splitTokens(starLines[i], ", ");
      float x = float(star[0]);
      float y = float(star[1]);
      println(i, ": ", x, y);
    }
    

    This produces the output:

    Loaded 5 stars:
    0 : 9.0 198.0
    1 : 128.0 189.0
    2 : 176.0 191.0
    3 : 12.0 67.0
    4 : 126.0 136.0

    You can use any number of variables (star names, etc.) in this way.

    If you want to get more complex, using different data types and filtering for special kinds of stars etc., then instead of splitting lines into tokens yourself you might instead load your data as a Table using loadTable().

  • @jeremydouglass, sir, thank you for that example. That's very simple and powerful. It also shows me that I don't need an array for the x and y values of point(x,y). Being kinda stubborn, I continued with the SQLite .db file and got that working to my surprise.

    Another surprise was that I don't have to do anything differently for E or W Ascension now. I don't understand that, but it draws correctly whether the angle is negative or positive and mapped from 0 to PI.

  • edited January 2018

    Here's the snippet of code that goes into addDiagonalLine().

     if ( db.connect() ) {
       String[] tableNames = db.getTableNames();
    
       db.query("SELECT * FROM %s"tableNames[0] );
       int i = 1;
       while (db.next()) {
         //i++;
         TableOne t = new TableOne();
    
         db.setFromRow( t );
         String  starName = t.one;
         float x = (float) t.two;
         float y = (float) t.three;
         //println( t.one, t.two, t.three );
         println(i,starName, x, y);
         //println(t);
         i++;
    
         texture.stroke(0,255,0);
         texture.strokeWeight(3);
         texture.strokeWeight(5);
         x = map(radians(x), radians(0), PI, texture.width / 2, texture.width - texture.width);
         y = map(radians(y), radians(0), radians(90), texture.height / 2, texture.height - texture.height);
         texture.point( x,y);
      }
    }
    

    I put this class definition at the end of the sketch:

    class TableOne {
      //  public String fieldOne;
      //  public int fieldTwo;
      public String one;
      public double two;
      public double three;
    
      public String toString () {
        //  return String.format("fieldOne: %s fieldTwo: %d", fieldOne, fieldTwo);
        return String.format("StarName: %s MeridianAngle: %f Declination: %f", one, two, three);
      }
    }
    

    To use a SQLite database, processing needs to import the library,
    import de.bezier.data.sql.*;

    This is definitely not as simple as @jeremydouglass example, the more I think about it, but it works.

  • edited January 2018

    If anyone wants to plot some stars using the @jeremydouglass text file example, I learned I can export a CSV format text file from the SQLite database. Here's the output, just copy into a text file.

    Dubhe,165.6620666,61.7516944
    Kochab,-137.3373345,74.0821666
    Merak,165.72974999,56.2836666
    Phecda,178.695,53.5933333
    Megrez,-175.92337505,56.948444443
    Alioth,-166.296250005,55.86183333
    Mizar,-158.83841667,54.81666666
    Alkaid,-152.837708333,49.22355554666
    Seginus,-141.79804167,47.22527777
    Rasalhague,-96.05475,12.55002777
    Vega,-80.6112916666,38.80380555
    Altair,-62.0817083333,8.9192166666
    Enif,-33.7294166666,9.9604166666
    Capella,79.510583333,46.0125555
    Mirfak,51.4099583333,49.92297222
    Pollux,116.6067916666,58.945
    Procyon,115.0637916666,5.1751666666
    Regulus,152.334875,11.87675
    Betelgeuse,89.039916666,7.407
    Shedar,10.3912916666,56.6368611111
    
  • Answer ✓

    (Harry, when posting code just paste the code, highlight it and press ctrl-o. That's all you need to do. no html tags, no nbsp, no backticks, nothing, just ctrl-o.)

    ((i was browsing the change log and there was an entire page of entries of you twiddling html when there's no need))

  • I got it, thanks. Can you change my name to HarryTwiddles? It's what I do best, fiddle and twiddle. :-??

  • edited January 2018

    @HarryCodes -- If you are excited about using SQLite with this project you may be interested in using @vesolba 's DB Manager for Processing:

  • I figured out that mapping right ascension from 0 to PI works fine because it isn't "clamped" to the range 0 to PI, so negative angles(0 to -PI) still get mapped. That's handy as I found.

    My database has progressed from 20 stars to 100,000+, but I just exported the ones with proper names. What I found is that the right ascension and declination is spot on compared to the NASA star image map. My conversions were maybe a bit sloppy and there was always a very slight shift between image and texture.point.

  • edited January 2018

    @jeremydouglass , Yup, I'm having fun refining my search of 100,000 stars down to something reasonable to display. This recent query results in 7500 stars based on constellation. I queried for Ursa Major, Ursa Minor, Cassaeiopea to try to show defined boundaries of constellations that don't touch each other.

  • Excellent -- beautiful work!

  • Thanks, glad you like it. I downloaded the constellation boundaries image and what you see in the image above is exactly within the boundaries of the NASA image.

    I went further and found a problem with the database I'm using and that was that I imported the .csv version and didn't specify the data type for every field by first creating a table and defining that, so every field was TEXT. For most queries, I got what I wanted but for some the results were strange. I realized I needed to define some fields as REAL. Its fixed now, I can query for a range and I get it without deadband or just nothing sometimes.

  • Now I'm just spinning my wheels. I need to add some kind of drop down controlP5 that can change what gets searched from the .db . I also want to be able to mouse over and select a star and display its data.

    I've been avoiding adding a curved horizon and getting back to using the IMU to measure Altitude(Hc/computed altitude) and Azimuth.

  • edited January 2018

    I finally can visualize correctly what the horizon represents and that is a plane that slices through the celestial sphere/star ball at an angle equal to latitude. If I add a rectangle as a plane, it blocks the stars so I added an ellipse with radius just shy of the radius of the sphere. Thanks @jeremydouglass again for that.

  • You are really polishing this! Is it something you are planning on using for work, or releasing to the public, or is it a hobby project?

  • @jeremydouglass, I'll give it all the polish it can take or that I can find a way to apply. Its definately a hobby project that I'm using to learn some things...Its not a straight line path that's for sure.

  • I'm back to using the ellipsoid in Shapes3D and testing the IMU by comparing with an ephemeris. This ellipsoid gives a different projection when inside. When I pull a star down to the horizon(this is kinda how a sextant works too), my results have been very good, within a 1/10 of a degree, now that I know where the mathematical horizon should be. I'm leaving the spherical trig to the ephemeris.

    One of many things I'd like to add is a crosshair that magnifies whatever is in it. I saw this somewhere in a Processing example but cant find it.

    One direction I'd like to go with this is as a digital planisphere/astrolabe. Observe the azimuth and altitude of a few stars, plot them on the image and then tweak the rotation and tilt of the sphere until everything lines up. This is how it could calculate latitude and longitude, graphically.

    One thing I need is a transparent blank image that I can overlay on the starmap image. Plot the observations on the transparency.

  • edited January 2018

    @jeremydouglass, sir, I used processing to make a transparent PNG and all by itself on a sphere it is indeed transparent. I can through the sphere. That's what I want but It isn't transparent the way I need. If I have two spheres with one just slightly bigger, there is no transparency. Why is that?

    What I tried to fix it is to make both spheres the same radius and that almost works. I can see both PNGs but its alternating stripes.

    Any ideas how to do this so I can manipulate one sphere's orientation relative to the other sphere and be able to see it?

    I just took another look, tried one sphere smaller than the other but viewed it all from outside and the inner sphere is visible. Is this a lighting issue?

  • If I have two spheres with one just slightly bigger, there is no transparency. Why is that?

    Can you make a very simple sketch with just two spheres that demonstrates the problem? What is going wrong when you add the second sphere?

  • edited January 2018

    Possibly relevant -- past sphere lighting, stroke, and opacity discussion

  • Awright, here we go with some code. First, this code is from the archives and is how I made a transparent png file.

    PGraphics alphaG;
    
    void setup() {
    size(2048,1024); 
    // create an extra pgraphics object for rendering on a transparent background 
    alphaG = createGraphics(width,height, JAVA2D);
    
    // background will be transparent in the png-file 
    background(0);
    }
    
    void draw() {
    
     // draw into the pgraphics object
     alphaG.beginDraw();
       alphaG.fill(255,100);
      // alphaG.rect(random(width), random(height), 30,30);
       alphaG.rect((width),(height), 2048,1024);
     alphaG.endDraw();
    
     // draw the second renderer into the window, so we can see something 
     image(alphaG, 0,0);
    }
    
    void keyPressed() {
      alphaG.save("alphatest.png"); 
      println("alphatest.png saved.");
    }
    

    Next, is the code that uses "alphatest.png" and shows the transparency goofiness.

    import shapes3d.utils.*;
    import shapes3d.animation.*;
    import shapes3d.*;
    
    
    import processing.opengl.*;
    
    
    
    PImage original;
    PImage original2;
    PGraphics texture;
    PGraphics texture2;
    Ellipsoid starBall;
    Ellipsoid starBall2;
    //float zoom = 0.5;  //outside the sphere
    float zoom = 1.5;  //inside the sphere
    
    public void setup() {
    
      size(1275, 750, P3D);
    
      original = loadImage("alphatest.png");
      original2 = loadImage("alphatest.png");
    
      texture = createGraphics(original.width, original.height);
      texture2 = createGraphics(original2.width, original2.height);
    
      initStars();
      addDiagonalLine(texture);
      addDiagonalLine(texture2);
      starBall = new Ellipsoid(this, 64, 64);
      starBall.setTexture(texture);
      starBall.setRadius(399);
      starBall.drawMode(Shape3D.TEXTURE); 
    
      starBall2 = new Ellipsoid(this, 64, 64);
      starBall2.setTexture(texture2);
      starBall2.setRadius(400);
      starBall2.drawMode(Shape3D.TEXTURE);
    
    }
    
    void initStars(){
      texture.beginDraw();
      texture.image(original,0,0);
      texture2.beginDraw();
      texture2.image(original2,0,0);
      texture2.endDraw();
      texture.endDraw();
    
    }
    
    void addDiagonalLine(PGraphics texture){
    
      texture.beginDraw();
    
      texture.stroke(255,0,0);
      texture.strokeWeight(1);
    
    
     //longitude lines
      texture.line(0,0,0, texture.height);
      texture.line(texture.width/12, 0,texture.width/12,texture.height);
      texture.line(texture.width/12*2, 0,texture.width/12*2,texture.height);
      texture.line(texture.width/12*3, 0,texture.width/12*3,texture.height);     
      texture.line(texture.width/12*4, 0,texture.width/12*4,texture.height);
      texture.line(texture.width/12*5, 0,texture.width/12*5,texture.height);
      texture.line(texture.width/12*6, 0,texture.width/12*6,texture.height);
      texture.line(texture.width/12*7, 0,texture.width/12*7,texture.height);
      texture.line(texture.width/12*8, 0,texture.width/12*8,texture.height);
      texture.line(texture.width/12*9, 0,texture.width/12*9,texture.height);
      texture.line(texture.width/12*10, 0,texture.width/12*10,texture.height);
      texture.line(texture.width/12*11, 0,texture.width/12*11,texture.height);
    /////  texture.line(texture.width/12 * 11 -texture.width/12/3, 0,texture.width/12 * 11 -texture.width/12/3,texture.height);
    
    
      texture.line(texture.width/12 -texture.width/12/2, 0,texture.width/12 -texture.width/12/2,texture.height);
      texture.line(texture.width/12+texture.width/12/2, 0,texture.width/12+texture.width/12/2,texture.height);
      texture.line(texture.width/12/2+texture.width/12/2, 0,texture.width/12/2+texture.width/12/2,texture.height);
      texture.line(texture.width/12 * 2+texture.width/12/2, 0,texture.width/12 * 2+texture.width/12/2,texture.height);
    
      texture.line((texture.width/12 * 3)+texture.width/12/2, 0,(texture.width/12 * 3)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 4)+texture.width/12/2, 0,(texture.width/12 * 4)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 5)+texture.width/12/2, 0,(texture.width/12 * 5)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 6)+texture.width/12/2, 0,(texture.width/12 * 6)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 7)+texture.width/12/2, 0,(texture.width/12 * 7)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 8)+texture.width/12/2, 0,(texture.width/12 * 8)+texture.width/12/2,texture.height);//////////////
      texture.line((texture.width/12 * 9)+texture.width/12/2, 0,(texture.width/12 * 9)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 10)+texture.width/12/2, 0,(texture.width/12 * 10)+texture.width/12/2,texture.height);
      texture.line((texture.width/12 * 11)+texture.width/12/2, 0,(texture.width/12 * 11)+texture.width/12/2,texture.height);
    
    
    //latitude lines  
      texture.line(0, texture.height/2,texture.width,texture.height/2);
      texture.line(0, texture.height/2/3,texture.width,texture.height/2/3);
      texture.line(0, texture.height/2/3 * 2,texture.width,texture.height/2/3 * 2);
      texture.line(0, texture.height/2/6,texture.width,texture.height/2/6 );
      texture.line(0, texture.height/2/3 + texture.height/2/6,texture.width,texture.height/2/3 + texture.height/2/6);
      texture.line(0, texture.height/2/3 * 2 + texture.height/2/6 ,texture.width,texture.height/2/3 * 2 + texture.height/2/6);
      texture.line(0, texture.height/2 + texture.height/2/3/2 ,texture.width,texture.height/2 + texture.height/2/3/2);
      texture.line(0, texture.height/2 -texture.height/2/3 ,texture.width,texture.height/2 -texture.height/2/3);
      texture.line(0, texture.height - texture.height/2/3 * 2,texture.width,texture.height -texture.height/2/3 * 2);
      texture.line(0, texture.height -texture.height/2/3,texture.width,texture.height -texture.height/2/3);
      texture.line(0, texture.height - texture.height/2/3 * 2 + texture.height/2/6,texture.width,texture.height -texture.height/2/3 * 2 + texture.height/2/6);
      texture.line(0, texture.height -texture.height/2/3 + texture.height/2/6,texture.width,texture.height -texture.height/2/3 + texture.height/2/6); 
    
      texture.endDraw();
    }
    
    public void draw() {
    
      background(0,0,0); 
      translate(width/2, height/2);
      float t = map(hour() + norm(minute(),0,60)+ norm(second(), 0, 3600),0,24,0,TWO_PI);
    
      scale(zoom, -zoom, zoom);
      starBall.rotateTo(0,t * 1000,0);
      starBall2.rotateTo(0,0,0);
      starBall.draw();  ///transparent
      starBall2.draw(); //transparent   
    
    }
    
  • Holy moly, If I change the order of ellipsoid size difference, I can make it transparent as I want it. What is goofy is that transparency seemingly depends on which sphere is bigger, which gets drawn first, and whether zoomed inside the sphere or outside.

    Note that line 59, strokeweight works better at texture.strokeWeight(2) .

  • What is goofy is that transparency seemingly depends on which sphere is bigger, which gets drawn first, and whether zoomed inside the sphere or outside.

    That sounds like it might be culling / depth-testing. Not my area of expertise, but you could also changing controlling hint(DISABLE_DEPTH_TEST) or hint(ENABLE_DEPTH_TEST) to see if that helps...?

  • @jeremydouglass, winner winner chicken dinner,disabling works. I tested by changing the zoom first, inside or outside the sphere both are visible. I then tested the ellipsoid size order and it still works.

  • Like I said back some posts, this development process is not linear. Early in I knew "star" time is not the same as terrestrial time, but I was unclear in how to calculate it or what effect it even had. The technical term for star time is Sidereal Time and it comes in a few variations. The most complicated form involves gravitational effects(precession and nutation) from the sun and moon on the earths orbit and rotation. The simplest form involves the number of days since 01/01/2000, the beginning of the J2000 epoch, and ignores the sun and the moon. It does account for the fact that a star day is a few minutes shorter than a 24 hour day. For my purposes, this should be fine. Here's how I am calculating Mean Sidereal Time. The code is mostly borrowed with the exception of dfrac from this link, www2.arnes.si/~gljsentvid10/sidereal.htm

    double dfrac = map(hour()+ 5 + norm(minute(),0,60)+ norm(second(), 0, 3600) ,0,24f,0,24);
     dfrac = dfrac/24;
     double dwhole = (367*year()-(int)(7*(year()+(int)((month()+9)/12))/4) + (int)(275*month()/9)+day()-730531.5);
    double JD = dwhole + dfrac;  //fractional plus whole days since 01/01/2000
       double LMST = 280.46061837 +( 360.98564746629 * (JD)) + (-West_Longitude);  //Local Mean Sidereal Time is Greenwich adjusted for Lon
    
  • edited February 2018

    Interesting. In practice how are you using Sidereal time -- are you converting solar time inputs into it to find the correct rotation of your skybox / skysphere? Are you doing everything internally in sidereal time, then converting to solar, or vice versa (or no solar at all)?

  • edited February 2018

    I'm using the local mean sidereal time to rotate it. In the link where I got the code, he uses ICE(interactive computer ephemeris) to check his accuracy. I'm not getting the results he claims. I'm about 30 seconds ahead of ICE. I have no idea why. I was using different code to calculate number of days from J2000 and compared it with the code I posted above and the results were identical to the last digit. To test it, I set ICE for a specific time and then stopped my sketch at that same time which was when the system clock turned. I might be off by a fraction of a second, but not 30 seconds. I'll keep trying.

    I just tested again and this time, its ahead by 18 seconds. I'll keep testing and see how the error varies.

  • One thing I have been assuming is that my system clock is correct, so I synchronized with NIST. I did the same test, setup ICE, get sidereal time for a specific UT time and stop the processing sketch at that same UT. This time the result was much better.

    My calculation: 23h 4m 41.08s ICE ephemeris: 23h 4m 37.64s

    My calculation of Julian Date agreed exactly with the ephemeris, so that part is good.

  • All this testing to .01 of a second is somewhat friviolous I'm finding. I found a freeware celestial navigation program at this link:

    onboardintelligence.com/

    ASNAv is what its called. Ive been using it to test my calculations by printing to the processing console my estimates for altitude(h). ASNAv only takes altitude input to .1 minute of angle. The results have been pretty good though. It uses statistical analysis of observations to determine probability of position. So far Ive been within 3 miles of the Assumed position I gave it.

    As for this project, I've managed to build a celestial observation simulator. I'm not sure if it can go much further.

  • Congratulations!

    If you are also willing to share it then I am sure that others would love to try it out -- and/or learn from your code.

  • I have to clean it up. I can only call it a "simulator".

    To call it complete, it would need an ephemeris(no idea how to add that), some navigational and positional fix formulae, nice ways to input data, statistical analysis routines, useable output. These are all things that ASNAv does. I'm only giving it an estimate of what a sextant might read at some time and place.

  • I haven't completely abandoned this project. I have some code that takes an assumed/selected latitude and longitude, and two stars as input, and computes the GHA, declination, altitude for each star. It then computes the latitude and longitude of the two intersections of the circles of equal altitude. Circles of equal altitude are the basis for a celestial fix. If the fix is based on two stars, then there are two locations where these circles intersect and one will be where the stars were observed, your location. Common sense is how you determine which point of intersection is your location.

    To run this code, pick from the top scrollable list a star which is West of your location. The top sliders are to change latitude and longitude Then, pick from the bottom scrollable list a star which is East of your location. The code doesn't consider every possible geometry, so if the first star is West and second East, it should work.

    Ideally, I'd like to compute GHA and declination and then input an observation for altitude.

    To keep with the initial topic, I might use this to draw the two intersections onto a sphere and then add arcs to visualize the triangles involved.

    Now some code:

    import de.bezier.data.sql.*;
    
    import java.lang.*;
    import java.util.*;
    import java.time.*;
    import controlP5.*;
    
    SQLite db;
    ControlP5 controlP5;
    ControlP5 cp5;
    int Latitude_1 = 64;
    int Lat_minutes = 8;
    int Lat_seconds = 51;
    int Longitude_1 = -21;
    int Lon_minutes = 56;
    int Lon_seconds = 3;
    int Zone = 4;  ////Time zone correction
    double GMST = 0;
    double LMST = 0;
    float Lon = 0;
    float Lat = 0;
    float ra = 0;
    float RA = 0;
    float dec = 0;
    float ma = 0; //Meridian angle
    String starName = " ";
    
    ScrollableList Name1;
    ScrollableList Name2;
    String Star1 = " ";
    String Star2 = " ";
    
     double GHAaries = 0;
     double GAST = 0;
     double GHA = 0;
     double SHA = 0;
    
    
    
     double GHA1 = 0;
     double GHA2 = 0;
     double dec1 = 0;
     double dec2 = 0;
     double alt1 = 0;
     double alt2 = 0;
     double t12 = 0;
     double alt12 = 0;
     double A = 0;
     double B = 0;
     double Par1 = 0;
     double Par2 = 0;
     double t1 = 0;
     double t2 = 0;
     double Lat1 = 0;
     double Lat2 = 0;
     double Lon1 = 0;
     double Lon2 = 0;
    
     double Az = 0;
     double Alt = 0;
     double[] Fix;
    
     PFont f; 
    
    void setup() {
    
      size(625, 750);
      f = createFont("Arial",16,true);
         db = new SQLite( this, "hygdata.db" );  // open database file
    
         controlP5 = new ControlP5(this);
          cp5 = new ControlP5(this);
                 List l = Arrays.asList("Procyon","Rasalhague","Dubhe", "Mirphak", "Alkaid","Altair", "Alioth", "Spica", "Betelgeuse", "Capella", "Vega","Polaris", "Menkalinan", "Pollux", "Regulus","Deneb", "Denebola");
      /* add a ScrollableList, by default it behaves like a DropdownList */
      Name1 = cp5.addScrollableList("StarName  1")
         .setPosition(20, 270)
         .setSize(200, 100)
         .setBarHeight(20)
         .setItemHeight(20)
         .addItems(l)
         // .setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST
         ;
    
    
         controlP5.addSlider("Latitude_1",0,90,Latitude_1,20,10,255,20);
         controlP5.addSlider("Lat_minutes",0,60,Lat_minutes,20,40,255,20);
         controlP5.addSlider("Lat_seconds",0,60,Lat_seconds,20,70,255,20);
    
         controlP5.addSlider("Longitude_1",-180,180,Longitude_1,20,110,255,20);
         controlP5.addSlider("Lon_minutes",0,60,Lon_minutes,20,140,255,20);
         controlP5.addSlider("Lon_seconds",0,60,Lon_seconds,20,170,255,20);
    
    
    
           Name2 = cp5.addScrollableList("StarName  2")
         .setPosition(20, 390)
         .setSize(200, 100)
         .setBarHeight(20)
         .setItemHeight(20)
         .addItems(l)
        ; 
    
    
    
    }
    
    void draw() {
      background(240);
        Lat = (float)Latitude_1 + (float)Lat_minutes/60 + (float)Lat_seconds/3600;  //Estimated Latitude
        Lon = (float)Longitude_1 - (float)Lon_minutes/60 - (float)Lon_seconds/3600; //Estimated Longitude
    
       if (Longitude_1 > 0) {
       Lon = (float)Longitude_1 + (float)Lon_minutes/60 + (float)Lon_seconds/3600; //East of Greenwich
       }
    
    
    
     SiderealTime();
     CalcAstro();
    
     t12 = GHA2 - GHA1;  //combined polar meridian angle
    
    alt12 = alt(t12,dec1,dec2);
    A = (azi(dec2,dec1,Math.toDegrees(alt12)));
    B = (azi(alt2,alt1,Math.toDegrees(alt12)));
    
    Par1 = A - B; 
    
    Par2 = A + B;
    
    Lat1 = alt(Math.toDegrees(Par1),dec1,alt1);
    Lat2 = alt(Math.toDegrees(Par2),dec1,alt1);
    t1 = azi(alt1,dec1,Math.toDegrees(Lat1));
    t2 = azi(alt1,dec1,Math.toDegrees(Lat2));
    Lon1 = GHA1 - Math.toDegrees(t1);
    Lon2 = GHA1 - Math.toDegrees(t2);
    
    println(Math.toDegrees(Lat1) + "  " + + Lon1); 
    println(Math.toDegrees(Lat2) + "  " + Lon2);
    String Position1Lat = new Double(Math.toDegrees(Lat1)).toString();
    String Position1Lon = new Double(-Lon1).toString();
    String Position2Lat = new Double(Math.toDegrees(Lat2)).toString();
    String Position2Lon = new Double(Lon2).toString();
      textFont(f);       
      fill(0);
    
      textAlign(LEFT);
      //text("This text is centered.",width/4,550);
     text("Pick Fix from these Possible Positions",width/8,530);
     text("Position1: "+"Latitude= " + Position1Lat + " Longitude= " + Position1Lon,width/8,550);
     text("Position2: "+"Latitude= " + Position2Lat + " Longitude= " + Position2Lon,width/8,570);
    
    }
    
    
    
    
    
    ArrayList CalcAstro() {
    
      ArrayList results = new ArrayList();
       double hour = (GMST)/15;
           if ( db.connect() )
        {
          String test = "SELECT ra,dec,proper,con FROM %s WHERE  proper > ' '";
    
            String[] tableNames = db.getTableNames();
                    db.query( test, tableNames[0] ); // AND dist <= '30.65' OR proper > ' ', tableNames[0] ); // AND mag >= '5.0' AND mag <= '5.05'", tableNames[0] );
    
      int i = 1;
            while (db.next())
            {
               TableOne t = new TableOne();
                db.setFromRow( t );
                ra = (float)(t.ra);
                RA = (float)(t.ra);
              dec = (float)(t.dec);
              starName = t.proper;
    if (ra > 12){
    ra = -(24 - ra); 
    }
               ra = ra * 15;
    
    
               for (int j = 1; j < i; j = i+1) {
    
    
      double deci = hour - (int)hour;
      double min = deci * 60;
      double sec = (min - (int)min) * 60;
    
      float h = sin(radians(Lat)) * sin(radians(dec)) + cos(radians(Lat)) * cos(radians(dec)) * cos(radians( ra - ((float)GMST)));
    
    h = asin(h);
    
    float Az = (sin(radians(dec)) - sin(h) * sin(radians(Lat)))/(cos(h) * cos(radians(Lat)));
    Az = acos(Az);
    
    
    
    
    ma = acos (sin((h)) - sin(radians(Lat)) * sin(radians(dec))/( cos(radians(Lat)) * cos(radians(dec))) );
    
    
    
    
    float H = degrees(h);
    H = H - (int)H;
    H = H * 60;
    
      SHA = 360 - ra;
    GHA = SHA + GHAaries;
    
    while(GHA > 360){
      GHA = GHA - 360;
    }
    Star1 = Name1.getCaptionLabel().getText();
    Star2 = Name2.getCaptionLabel().getText();
    if (Star1.equals(starName)){
    
    GHA1 = GHA; //Denebola
    dec1 = dec; 
    alt1 = Math.toDegrees(h); 
    println(i + " " + starName + ": " + GHA1 + " " + dec1 + " " + (alt1));
    
    
    
    
    }
    if (Star2.equals(starName)){
    
    GHA2 = GHA; 
    dec2 =  dec; 
    alt2 = Math.toDegrees(h); 
    println(i + " " + starName + ": " + GHA2 + " " + dec2 + " " + (alt2));
    
    }
    
    
    
    
    }
    
             //  println(i,t.con,t.proper, t.ra, t.dec);
                 i++;
            }
        }
    
    
    return results;
    
    
    }
    
    class TableOne
    {
      //  public String fieldOne;
      //  public int fieldTwo;
          public String one;
          public double two;
          public double three;
    
        /*  public double ra;
          public double dec;
          public double rarad;
          public double decrad;
          public String Name; */
    
          public String hip;
          public String con;
          public String proper;
          public double dec;
          public double ra;
        public String toString ()
        {
          //  return String.format("fieldOne: %s fieldTwo: %d", fieldOne, fieldTwo);
         //  return String.format("StarName: %s MeridianAngle: %f Declination: %f", one, two, three);
           //  return String.format("StarName: %s MeridianAngle: %f Declination: %f", Name, ra, dec);
                 return String.format("StarName: %s MeridianAngle: %d Declination: %d", proper, ra, dec);
    
    
      }
    }
    
    
    
    public double SiderealTime(){
    
      Date OldDate = new Date("01/01/2000");
      Date TodaysDate = new Date();
      long mills_per_day = 1000*60*60*24;
      long day_diff = (TodaysDate.getTime() - OldDate.getTime())/mills_per_day;
    
      double dfrac = map(hour()+ Zone + norm(minute(),0,60)+ norm(second(), 0, 3600) ,0,24f,0,24f);
    
      double UT = dfrac;
    
    // println(UT);
      dfrac = dfrac/24; // - (5/24);
    
      double JD = day_diff + dfrac - 0.5 +  2451545;
    
      double dwhole = (367*year()-(int)(7*(year()+(int)((month()+9)/12))/4) + (int)(275*month()/9)+day()-730531.5);
    
      double SD = dwhole + dfrac;
    
    
       GMST = 280.46061837 +( 360.98564746629 * (SD)) + Lon;
    
    
    double LMST = GMST - (-77.461f);
    
      GMST = (((GMST/360) - (int)GMST/360)*360);
      double T = 367 * year() - (int)(1.75 * (year() + (int)((month()+9)/12))) + (int)(275 * month()/9) + day() + UT/24 - 730531.5; 
      GHAaries = 0.9856474 * T + 15 * UT + 100.46062;
      GHAaries = (((GHAaries/360) - (int)GHAaries/360)*360);
      GAST = GHAaries/15f;
    
     return GMST;
    }
    
    public double azi(double x, double y, double z){
        x = Math.toRadians(x);
       y = Math.toRadians(y);
        z = Math.toRadians(z);
    
      Az = (Math.sin(x) - Math.sin(y) * Math.sin(z))/(Math.cos(y) * Math.cos(z));
      Az = Math.acos(Az);
      return Az;
    }
    
    public double alt(double a, double b, double c) {
      a = Math.toRadians(a);
       b = Math.toRadians(b);
        c = Math.toRadians(c);
    
      Alt = (Math.cos((a)) * Math.cos(b) * Math.cos(c)) + (Math.sin(b) * Math.sin(c));
      Alt = Math.asin(Alt);
    
      return Alt;
    }
    
    public double[] fix(double GHA1, double GHA2) {
     double t12 = 0;
    
    
     return Fix;
    } 
    
  • Add this code between line 143 and 144:

    String Altitude1 = new Double(alt1).toString();
    String Altitude2 = new Double(alt2).toString();
    

    Then this code after line 151:

     text("Star1 Altitude: " + Altitude1,250,290);
     text("Star2 Altitude: " + Altitude2,250,410);
    

    This shows the computed altitude. Play with the lat and lon sliders and see how altitude changes and how the intersection points for equal altitude change.

  • I got some more additions. Add this to variables before setup():

     double azi1 = 0;
     double azi2 = 0;
    

    Then add this to where the text gets written in draw():

    String Azimuth1 = new Double(azi1).toString();
    String Azimuth2 = new Double(azi2).toString();
    

    Last, add this to CalcAstro() right after line 234:

    azi1 = Math.toDegrees(Az);
    if (GHA1 < 180) {
    azi1 = 360 - azi1;
    } 
    

    This shows the azimuth of the selected star. For the first list, select a star with an azimuth greater than 180. Then, from the second list, select a star with an azimuth less than 180. This should help pick a star in the West and then a star in the East.

  • Heres a picture of the triangles used to compute a fix from two stars.

  • The red triangle is formed by the geographic positions of star1 and star2 and the celestial north pole. The green triangle is the "navigational triangle", with the upper intersection point of the circles of equal altitude. The blue is formed by the lower intersection point of the circles of equal altitude. Id like to draw those circles on the sphere but it doesn't work.

  • edited March 2018

    I figured out how to draw the circles of equal altitude, but I cant control them. I'm drawing them as lines of latitude on individual spheres using the texture technique @quark showed me. I then tilt and rotate that sphere to center on a star. With it drawn as transparency, the circles show like they should. In the "real" world, uh huh, these circles grow and shrink with the altitude angle.

    This is what I'm having trouble controlling. Right now, I use mouseX to change the altitude angle. It just keeps drawing a new line/circle until eventually the sphere is solid.

    This thread should be about Dynamic textures which I kinda have now but I want it to redraw so the old line disappears and only see one at a time. This would make it look like the circle of altitude is growing or shrinking with the variable that represents it.

    So, to make this truly dynamic, how would I do that?

    Heres a shot of the circles of equal altitude. The rings of Saturn looking thing is controlled by mouseX and is what I want to be able to draw and redraw somehow so that all you see is one ring, but it is Dynamic and can change with some variable.

  • Heres the code I'm working with that just adds another line. I tried initstars and adddiagonalline in draw, but as mentioned early into this by @jeremydouglass, that causes a memory leak. Before I ran out of memory, it did draw a single circle that I could manipulate size with mouseX.

    Its probably possible to do what I want with this, I just don't know enough. Heres the code, worts and all:

    import shapes3d.utils.*;
    import shapes3d.animation.*;
    import shapes3d.*;
    
    import controlP5.*;
    import processing.opengl.*;
    
    
    
    import java.awt.event.*;
    
    PImage original;
    PImage original2;
    PImage original3;
    PGraphics texture;
    PGraphics texture2;
    PGraphics texture3;
    Ellipsoid starBall;
    Ellipsoid starBall2;
    Ellipsoid starBall3;
    //float zoom = 0.5;
    float zoom = 0.8;
    //float zoom = 1.5;
    
    ControlP5 cp5;
    ControlGroup messageBox;
    int messageBoxResult = -1;
    String messageBoxString = "";
    float t;
    
    
    public void setup() {
    
      size(1275, 750, P3D);
       hint(DISABLE_DEPTH_TEST);
      //  hint(ENABLE_DEPTH_TEST);
    
    original = loadImage("alphatest.png");
    original2 = loadImage("alphatest.png");
    original3 = loadImage("alphatest.png");
    
      texture = createGraphics(original.width, original.height);
    
      texture2 = createGraphics(original2.width, original2.height);
    
      texture3 = createGraphics(original3.width, original3.height);
    
    
      frame.addMouseWheelListener(new MouseWheelInput());
    
      initStars();
      initStar3();
        addDiagonalLine(texture);
        addDiagonalLine2(texture2);
       addDiagonalLine2(texture3);
    
        starBall = new Ellipsoid(this, 64, 64);
      starBall.setTexture(texture);
      starBall.setRadius(399);
      starBall.drawMode(Shape3D.TEXTURE); 
    
      starBall2 = new Ellipsoid(this, 64, 64);
      starBall2.setTexture(texture2);
      starBall2.setRadius(400);
      starBall2.drawMode(Shape3D.TEXTURE);  
    
        starBall3 = new Ellipsoid(this, 64, 64);
      starBall3.setTexture(texture3);
      starBall3.setRadius(401);
      starBall3.drawMode(Shape3D.TEXTURE); 
    
    }
    
    void initStars(){
      texture.beginDraw();
      texture.image(original,0,0);
      texture2.beginDraw();
      texture2.image(original2,0,0);
      texture2.endDraw();
    
    
    
      texture.endDraw();
    
    
    }
    void initStar3(){
    
          texture3.beginDraw();
      texture3.image(original3,0,0);
      texture3.endDraw();
    
    }
    
    void addDiagonalLine(PGraphics texture){
    
    
      texture.beginDraw();
      float RAvalue = 165.8620666f; //Dubhe
      float DecValue = 61.75169444f;
    
    
    
      float x = map(radians(RAvalue), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y = map(radians(DecValue),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue2 = -137.3373345f; // //Kochab
      float  DecValue2 = 74.0821666f;
      float  X = map(radians(RAvalue2),radians(0),-PI ,texture.width/2,texture.width  );
      float Y = map(radians(DecValue2),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue3 = 165.7297499f; // //Merak
      float  DecValue3 = 56.283666f;
      float x1 = map(radians(RAvalue3), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y1 = map(radians(DecValue3),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
        float RAvalue4 = 178.695f; // //Phecda
      float  DecValue4 = 53.5933333f;
      float x2 = map(radians(RAvalue4), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y2 = map(radians(DecValue4),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue5 = -175.923375005f; // //Megrez
      float  DecValue5 = 56.94844444333f;
      float  x3 = map(radians(RAvalue5),radians(0),-PI ,texture.width/2,texture.width  );
      float y3 = map(radians(DecValue5),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
     float RAvalue6 = -166.296250005f; // //Alioth
      float  DecValue6 = 55.86183333f;
      float  x4 = map(radians(RAvalue6),radians(0),-PI ,texture.width/2,texture.width  );
      float y4 = map(radians(DecValue6),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
     float RAvalue7 = -158.83841667f; // //Mizar
      float  DecValue7 = 54.8166666f;
      float  x5 = map(radians(RAvalue7),radians(0),-PI ,texture.width/2,texture.width  );
      float y5 = map(radians(DecValue7),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue8 = -152.937708333f; // //Alkaid
      float  DecValue8 = 49.22355554666f;
      float  x6 = map(radians(RAvalue8),radians(0),-PI ,texture.width/2,texture.width  );
      float y6 = map(radians(DecValue8),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue9 = -141.79804167f; // //Seginus //-218.2019583333
      float  DecValue9 = 47.22527777f;
      float  x7 = map(radians(RAvalue9),radians(0),-PI ,texture.width/2,texture.width  );
      float y7 = map(radians(DecValue9),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue10 = -96.05475f; // //Rasalhague
      float  DecValue10 = 12.55002777f;
      float  x8 = map(radians(RAvalue10),radians(0),-PI ,texture.width/2,texture.width  );
      float y8 = map(radians(DecValue10),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue11 = -80.6112916666f; //Vega 
      float  DecValue11 = 38.80380555f;
      float  x9 = map(radians(RAvalue11),radians(0),-PI ,texture.width/2,texture.width  );
      float y9 = map(radians(DecValue11),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue12 = -62.0817083333f; //Altair 
      float  DecValue12 = 8.9192166666f;
      float  x10 = map(radians(RAvalue12),radians(0),-PI ,texture.width/2,texture.width  );
      float y10 = map(radians(DecValue12),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue13 = -33.7294166666f; //Enif 
      float  DecValue13 = 9.9604166666f;
      float  x11 = map(radians(RAvalue13),radians(0),-PI ,texture.width/2,texture.width  );
      float y11 = map(radians(DecValue13),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue14 = 79.510583333f; //Capella
      float DecValue14 = 46.01255555f; 
      float x12 = map(radians(RAvalue14), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y12 = map(radians(DecValue14),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue15 = 51.409958333f; //Mirfak
      float DecValue15 = 49.92297222f; 
      float x13 = map(radians(RAvalue15), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y13 = map(radians(DecValue15),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue16 = 116.6067916666f; //Pollux
      float DecValue16 = 58.945f; 
      float x14 = map(radians(RAvalue16), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y14 = map(radians(DecValue16),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue17 = 115.0637916666f; //Procyon
      float DecValue17 =  5.1751666666f; 
      float x15 = map(radians(RAvalue17), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y15 = map(radians(DecValue17),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
    
      float RAvalue18 = 152.334875f; //Regulus
      float DecValue18 = 11.87675f; 
      float x16 = map(radians(RAvalue18), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y16 = map(radians(DecValue18),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue19 =  89.039916666f; //Betelgeuse
      float DecValue19 = 7.407f; 
      float x17 = map(radians(RAvalue19), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y17 = map(radians(DecValue19),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue20 =  10.3912916666f; //Shedar
      float DecValue20 = 56.6368611111f; 
      float x18 = map(radians(RAvalue20), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y18 = map(radians(DecValue20),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue21 = -4.95816666f; //Errai 
      float  DecValue21 = 77.734f;
      float  x19 = map(radians(RAvalue21),radians(0),-PI ,texture.width/2,texture.width  );
      float y19 = map(radians(DecValue21),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue22 =  2.539583333f; //Caph
      float DecValue22 = 59.25442222f; 
      float x20 = map(radians(RAvalue22), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y20 = map(radians(DecValue22),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue23 =  14.459375f; //Navi
      float DecValue23 = 60.814694f; 
      float x21 = map(radians(RAvalue23), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y21 = map(radians(DecValue23),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue24 =  21.757083333f; //Ruchbah
      float DecValue24 = 60.330361111f; 
      float x22 = map(radians(RAvalue24), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y22 = map(radians(DecValue24),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue25 =  28.9352083333f; //Segin
      float DecValue25 = 63.7582222222f; 
      float x23 = map(radians(RAvalue25), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y23 = map(radians(DecValue25),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
      float RAvalue26 =  43.774625f; //Polaris
      float DecValue26 = 90f;//89.339777f; 
      float x24 = map(radians(RAvalue26), radians(0),PI,texture.width/2,texture.width - texture.width);
      float y24 = map(radians(DecValue26),radians(0),radians(90),texture.height/2,texture.height - texture.height);
    
    
      texture.stroke(0,255,0);
      texture.strokeWeight(3);
    
    
     texture.point( x,y);
     texture.point( x1,y1);
      texture.point( x2,y2);
       texture.point( x3,y3);
        texture.point( x4,y4);
        texture.point( x5,y5);
        texture.point( x6,y6);
        texture.point( x7,y7);
        texture.point( x8,y8);
        texture.point( x9,y9);
         texture.point( x10,y10);
         texture.point( x11,y11);
         texture.point( x12,y12);
         texture.point( x13,y13);
         texture.point( x14,y14);
         texture.point( x15,y15);
          texture.point( x16,y16);
          texture.point( x17,y17);
          texture.point( x18,y18);
           texture.point( x19,y19);
           texture.point( x20,y20);
           texture.point( x21,y21);
            texture.point( x22,y22);
             texture.point( x23,y23);
              texture.point( x24,y24);  //Polaris
     texture.strokeWeight(3);
       texture.point( X,Y);
       texture.strokeJoin(MITER);
       texture.beginShape();
       texture.vertex(x10,y10);
      // vert
       texture.vertex(x20,y20);
       texture.endShape();
      texture.stroke(255,0,0);
      texture.strokeWeight(2);
    
      //star location
    
    
            //longitude lines
            texture.line(0,0,0, texture.height);
    
            texture.line(texture.width/12, 0,texture.width/12,texture.height);
            texture.line(texture.width/12*2, 0,texture.width/12*2,texture.height);
            texture.line(texture.width/12*3, 0,texture.width/12*3,texture.height);
            texture.line(texture.width/12*4, 0,texture.width/12*4,texture.height);
            texture.line(texture.width/12*5, 0,texture.width/12*5,texture.height);
            texture.line(texture.width/12*6, 0,texture.width/12*6,texture.height);
            texture.line(texture.width/12*7, 0,texture.width/12*7,texture.height);
            texture.line(texture.width/12*8, 0,texture.width/12*8,texture.height);
            texture.line(texture.width/12*9, 0,texture.width/12*9,texture.height);
            texture.line(texture.width/12*10, 0,texture.width/12*10,texture.height);
            texture.line(texture.width/12*11, 0,texture.width/12*11,texture.height);
    /////  texture.line(texture.width/12 * 11 -texture.width/12/3, 0,texture.width/12 * 11 -texture.width/12/3,texture.height);
    
    
            texture.line(texture.width/12 -texture.width/12/2, 0,texture.width/12 -texture.width/12/2,texture.height);
            texture.line(texture.width/12+texture.width/12/2, 0,texture.width/12+texture.width/12/2,texture.height);
            texture.line(texture.width/12/2+texture.width/12/2, 0,texture.width/12/2+texture.width/12/2,texture.height);
            texture.line(texture.width/12 * 2+texture.width/12/2, 0,texture.width/12 * 2+texture.width/12/2,texture.height);
    
            texture.line((texture.width/12 * 3)+texture.width/12/2, 0,(texture.width/12 * 3)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 4)+texture.width/12/2, 0,(texture.width/12 * 4)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 5)+texture.width/12/2, 0,(texture.width/12 * 5)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 6)+texture.width/12/2, 0,(texture.width/12 * 6)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 7)+texture.width/12/2, 0,(texture.width/12 * 7)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 8)+texture.width/12/2, 0,(texture.width/12 * 8)+texture.width/12/2,texture.height);//////////////
            texture.line((texture.width/12 * 9)+texture.width/12/2, 0,(texture.width/12 * 9)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 10)+texture.width/12/2, 0,(texture.width/12 * 10)+texture.width/12/2,texture.height);
            texture.line((texture.width/12 * 11)+texture.width/12/2, 0,(texture.width/12 * 11)+texture.width/12/2,texture.height);
    
    
    
    
    //latitude lines
            texture.line(0, texture.height/2,texture.width,texture.height/2);
            texture.line(0, texture.height/2/3,texture.width,texture.height/2/3);
            texture.line(0, texture.height/2/3 * 2,texture.width,texture.height/2/3 * 2);
            texture.line(0, texture.height/2/6,texture.width,texture.height/2/6 );
            texture.line(0, texture.height/2/3 + texture.height/2/6,texture.width,texture.height/2/3 + texture.height/2/6);
            texture.line(0, texture.height/2/3 * 2 + texture.height/2/6 ,texture.width,texture.height/2/3 * 2 + texture.height/2/6);
            texture.line(0, texture.height/2 + texture.height/2/3/2 ,texture.width,texture.height/2 + texture.height/2/3/2);
            texture.line(0, texture.height/2 -texture.height/2/3 ,texture.width,texture.height/2 -texture.height/2/3);
            texture.line(0, texture.height - texture.height/2/3 * 2,texture.width,texture.height -texture.height/2/3 * 2);
            texture.line(0, texture.height -texture.height/2/3,texture.width,texture.height -texture.height/2/3);
            texture.line(0, texture.height - texture.height/2/3 * 2 + texture.height/2/6,texture.width,texture.height -texture.height/2/3 * 2 + texture.height/2/6);
            texture.line(0, texture.height -texture.height/2/3 + texture.height/2/6,texture.width,texture.height -texture.height/2/3 + texture.height/2/6);
    
      texture.endDraw();
    }
    
    void addDiagonalLine2(PGraphics texture){
    
    
      texture.beginDraw();
    
      texture.stroke(0,255,0);
      texture.strokeWeight(2);
    
    
     float y = map(radians(mouseX),radians(0),radians(texture.width),texture.height/2,texture.height - texture.height);
    
    
    //latitude lines
    
        texture.line(0, texture.height/2/3 + texture.height/2/6,texture.width,texture.height/2/3 + texture.height/2/6);
     texture.line(0,y,texture.width,y);
      texture.endDraw();
    }
    
    public void draw() {
    
    
    
      background(0,0,0);  
    
     translate(width/2, height/2); 
         stroke(0, 255, 0);
      strokeWeight(1);
     line(0,-500,0 , 0, 500, 0);
       stroke(255, 0, 0);
      strokeWeight(2);
    
    
      initStars();
      initStar3();
    
        addDiagonalLine(texture);
        addDiagonalLine2(texture2);
       addDiagonalLine2(texture3);
    
    
    
    
    rotateY(radians(-90f));
    float Lat = map(mouseX, 0, texture.height, -(180f), (180f));
    
    if (Lat > 90 + 90 - 50.575f){
    
    }
    println( Lat);
    
      rotateZ(radians(-180-(90 -39.425f))); //Lat))); 
      float s = map(second(), 0, 60, 0, TWO_PI);
      float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI); 
      float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2)- HALF_PI;
      float l = map(77.4105388888f/15, 0, 24,0, PI);
    
      float t = map(hour() + norm(minute(),0,60)+ norm(second(), 0, 3600) + norm(l,0,PI),0,24,0,TWO_PI) - PI + radians(15f/4f) - radians(60); // - radians(180 - 77.461f);// - radians(-77.461f) - radians(-180) - radians(-180); //-radians(-77.461f); // - radians(-75) -radians(-77.461f);
    
     scale(zoom, -zoom, zoom);
    rotateX(radians(Lat ));
    
       starBall.rotateTo(0,0, 0); //90 + 90 - 50.575f);
        starBall.draw();  ///star image
     rotateZ(radians(90-61.75f));
     rotateX(radians(11.17/2));
      starBall2.rotateTo(0,0,0);
    
      starBall2.draw(); 
    
       rotateZ(radians(90-53.5933333f));
     rotateX(radians(41.17/2));
      starBall3.draw();
    
    
      }           
    
    
    
    
    
    class MouseWheelInput implements MouseWheelListener{
      void mouseWheelMoved(MouseWheelEvent e) {
        zoom -= 0.15 * e.getWheelRotation();
    
      }
    }
    
  • Like most things in my life, this is and has been almost right, very close but not exactly. Picture this guyhttps://en.wikipedia.org/wiki/Bob_Uecker saying, "Just a bit outside" as a pitcher throws a pitch in the bleachers. Anyway, heres where things are with this star trek I'm on. Its almost correct. The 3 spheres intersect and indicate an unambiguous position, but they intersect on the opposite side of what I'm calling the primary sphere. Visually, you cant tell the difference but I know its wrong.

    Heres a shot of it.

  • @HarryCodes -- it has been a while, but I hope that if you carry on with this project (or even if you don't) you will continue on the new forum after this one shuts down.

    Your project is pretty mature, and I wanted to suggest two cleanup recommendations about your code.

    1. Renaming of all variables to conform to Java naming conventions. For example, variables are lowercase or lowerCamelCase, global constants are CAPS, class names are TitleCase.

    2. Either declare a local variable and return it, or else assign to a global variable -- don't assign to a global variable AND return it. For example, don't assign to the global Alt here and return Alt:

      public double alt(double a, double b, double c) {
        a = Math.toRadians(a);
        b = Math.toRadians(b);
        c = Math.toRadians(c);
        Alt = (Math.cos((a)) * Math.cos(b) * Math.cos(c)) + (Math.sin(b) * Math.sin(c));
        Alt = Math.asin(Alt);
        return Alt;
      }
      

      Instead, use a temp variable internally and assign where you returned it.

  • Thank You, sir. I know its sloppy and conventions are good. I'm at a slight impasse with this project. I found a genuine astronomy library, JPARSEC, and have been learning how to use it. I'd like to use it to do the ephemeris stuff and processing to do the graphic stuff.

Sign In or Register to comment.