Created as part of #30DayMapChallenge

**Behind the Scenes**

In this ‘Behind the Scenes’, I’ll cover drawing an arc in 3D. For the final animation, I built on these basic arc paths with objects moving on this path and creating a fire trail along the path. These two techniques will be covered in Space and Shipping Movements posts…

How hard can it be to draw an arc? Blender has a sphere object under ‘Add->Mesh->Ico Sphere’ and a point on the surface of the sphere has co-ordinates (x,y,z) defined by:

```
# R is the radius of the sphere. The earth's radius is 6,400km but we can scale this down to R=6.4 within Blender
def getXYZfromLatLonVector(R, lat, lon):
z = R * math.sin(math.radians(lat))
# the x,y radius changes with lat
r = R * math.cos(math.radians(lat))
x = r * math.sin(math.radians(lon)) * -1
y = r * math.cos(math.radians(lon))
return mathutils.Vector((x,y,z))
```

If we have two points defined by their latitudes and longitudes and a formula to create cartesian co-ordinates, can’t we just interpolate? Not quite it seems. I spent quite a while reading up on spherical co-ordinates, searching the web and reading math.stackexchange.com but, after implementing, none of the arcs looked quite right. I can’t remember how I ended up on the Blender documentation page, but I did and there’s a curiously named function slerp()

Function | Description |
---|---|

slerp(other, factor) | Returns the interpolation of two quaternions |

Seems it’s exactly what we need!

```
def testBlenderSlerp():
R = 6.4
# London
lat = 51.5072
lon = -0.1275
AVector = getXYZfromLatLonVector(R, lat, lon)
print(f"AVector: {AVector}")
# New York
lat = 40.7834
lon = -73.9662
BVector = getXYZfromLatLonVector(R, lat, lon)
print(f"BVector: {BVector}")
points = []
for step in range (-1, 12, 1):
increment = step / 10
newPoint = AVector.copy()
slerp = AVector.slerp(BVector, increment)
newPoint = scaleVector(slerp, getScale(R, increment))
points.append(newPoint)
addCurve(points)
```

As well as testBlenderSlerp(), there are a couple of other functions here… addCurve() creates a Blender curve object from a set of co-ordinates and getScale() adds elevation to the arc so it isn’t just on the surface of the sphere (earth in this case)

If only I’d read the Blender documentation earlier in the day!