Trying to plant geographic coordinates (latitude/longitude) on a sphere

I’ll cut straight to the point, I’ve been trying to make an Earth like Rise Of Nations (they somehow planted cities on their globe, which is what I’m trying to replicate).

My current code looks like this:

function CityService:KnitInit()
    self.Earth = workspace:WaitForChild("Earth")
    self.Radius = 100

    self.TestCoordinate = {
        Latitude = 	50.716667,
        Longitude = -3.533333,
    }

    self.ORIGIN = Vector3.new()
end

function CityService:KnitStart()
    local function convertCoordinates(latitude, longitude)
        latitude = math.pi / 2 - latitude -- flips the y axis

        return Vector3.new(
            math.sin(latitude) * math.sin(longitude) * self.Radius,
            math.cos(latitude) * self.Radius,
            math.sin(latitude) * math.cos(longitude) * self.Radius
        )
    end

    local testAttachment = Instance.new("Attachment", self.Earth)
    testAttachment.Position = convertCoordinates(
        self.TestCoordinate.Latitude, 
        self.TestCoordinate.Longitude
    )
end

(The radius is 100. My latitude and longitude are 50.716667 and -3.533333)

This code produces this result:

Any ideas?

1 Like

You want to pass them to convertCoordinates in radians but I think that you defined them in degrees:

Are you sure Rise of Nations created cities using code? I feel like it would be a lot less labour intensive to manually place the cities in studio.

I’ve tried the following code (which I got from StackOverflow):

local function convertCoordinates(latitude, longitude, altitude)
        local lambda = math.atan((1 - self.Flattening) ^ 2 * math.tan(latitude))

        local x = math.cos(lambda)
            * math.cos(longitude) + altitude
            * math.cos(latitude)
            * math.cos(longitude)

        local y = math.cos(lambda)
            * math.sin(longitude) + altitude
            * math.cos(latitude)
            * math.sin(longitude)
        
        local z = math.sin(lambda) + altitude
            * math.sin(latitude)

        return Vector3.new(x, y, z)
    end

    local testAttachment = Instance.new("Part", workspace)
    testAttachment.Size = Vector3.new(1, 1, 1)
    testAttachment.Anchored = true
    testAttachment.Position = convertCoordinates(
        self.TestCoordinate.Latitude,
        self.TestCoordinate.Longitude,
        4 / 3 * math.pi * self.Radius ^ 3
    )

But this just produces the following result:

Any more ideas? Pretty stumped at the minute

I got this working!

Here’s my code:

local function convertCoordinates(latitude, longitude)
        local lon = math.rad(longitude)
        local lat = math.rad(latitude)

        local pos = self.Radius * Vector3.new(
            (math.cos(lon) * math.cos(lat)) + -math.pi / 2.5,
            math.sin(lat),
            math.sin(lon) * math.cos(lat)
        ) + self.ORIGIN

        return CFrame.new(pos)
    end

    local testpart = workspace:WaitForChild("Part")
    testpart.CFrame = convertCoordinates(50.716667, -3.533333)

(my radius is 50, and the origin is 0,0,0)
(ugh, nevermind, it only works on those coordinates)

1 Like

Well I’m now trying to figure out the following:
image
(all hail true mspaint)

Given I have point A, how would I calculate the opposite of it (not quite antipode, you’ll see what I mean in the image).