AgetoAge Genealogy

For dem som er interessert i C# og DirectX vil jeg her dokumentere hvordan jeg finner lengde og breddegrad på det punktet på globen jeg klikker med musen. Siden det er ganske komplekst har jeg delt det inn i 4 funksjoner og den funksjonen jeg starter med å kalle opp er "GetEarthCoordinates" med parameter mesh som er de punkter som globen består av og p er det punktet jeg klikker med musen (vanlig x og y value) og co er det jeg får tilbake fra funksjonen og co inneholder da lengde og breddegrad. (co.X er lengdegrad og co.Y er breddegrad).

Dette virker meget bra og er nøyaktig nok, når man zoomer inn på globen kan man skille mellom 1/10 000 dels grader. Jeg har vært litt bekymret for at jeg ikke skulle klare å få en nøyaktig og god funksjon for å finne bredde og lengdegrad (ved museklikk) og at dette nå er løst er et stort fremskritt for utviklingen av Globen.

 

public bool GetEarthCoordinates(Mesh mesh, Point p, ref PointF co)
        {
                 Vector3 v = Vector3.Empty;
            if (GetPicked3DPoint(mesh, p, ref v))
            {
                double radius = Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
                double longitude = Math.Atan2(v.Y, v.X) * 180 / Math.PI;                 
                double latitude = 90 - Math.Acos(v.Z / radius) * 180 / Math.PI;                
                   co.X = -(float)longitude;
                   co.Y = (float)latitude;
                return true;
            }
            else
                return false;
        }

 

public bool GetPicked3DPoint(Mesh mesh, Point p, ref Vector3 v)
        {          
                 Vector3 rayOrigin = Vector3.Empty;
                 Vector3 rayDir = Vector3.Empty;
                 GetRay(p, ref rayOrigin, ref rayDir);
            Matrix m = Matrix.Invert(device.Transform.World);
                 rayOrigin.TransformNormal(m);
                 rayDir.TransformNormal(m);
                 IntersectInformation d;
            if (mesh.Intersect(rayOrigin, rayDir, out d))
            {
                v = rayOrigin + (rayDir * d.Dist);
                return true;
            }
            else
                return false;
        }


private void GetRay(Point p, ref Vector3 rayOrigin, ref Vector3 rayDir)
        {           
            Matrix m = Matrix.Invert(device.Transform.View);            
            // Transform the screen space pick ray into 3D space
                 Vector3 v = GetWorldPoint(p);
                 rayDir.X = v.X * m.M11 + v.Y * m.M21 + v.Z * m.M31;
                 rayDir.Y = v.X * m.M12 + v.Y * m.M22 + v.Z * m.M32;
                 rayDir.Z = v.X * m.M13 + v.Y * m.M23 + v.Z * m.M33;
                 rayOrigin.X = m.M41;
                 rayOrigin.Y = m.M42;
                 rayOrigin.Z = m.M43;
        }


private Vector3 GetWorldPoint(Point p)
        {
                 Vector3 v = new Vector3();
                 Viewport vp = device.Viewport;
            Matrix matProj = device.Transform.Projection;
                 int w = vp.Width;
                 int h = vp.Height;           
                 v.X = (((2.0f * p.X) / w) - 1) / matProj.M11;
                 v.Y = -(((2.0f * p.Y) / h) - 1) / matProj.M22;
                 v.Z = 1.0f;
            return v;
        }

 

 Oppdatert TextureGlobe er lastet opp. Videoen under viser også en demo på å vise strukturen i Globen (press W (wireframe) og S (solid).

 

 

21-10-2012 - Lastet opp ny Globe med forbedret triangulering og texturebehandler. Man kan nå også velge mellom flere formater på teksturene, ('*.bmp, *.png, *.jpg og *.gif). Avstandsmåler er også inkludert. Den virker slik at man får kalkulert avstand fra forrige punkt man klikket.

23-10-2012 - Ny versjon med test på flere texturer er lastet opp.

 

Legg til kommentar


Sikkerhetskode
Vis ny kode

Pics of the day
hands.bmp