Code doesn't animate as expected

Hi, I a have some code but doesn’t do what I expect it to do. The code is supposed to animate different shapes into each other. Here is my code:
(FYI: I describe each shape with curves going from the leading to the trailing of the frame. Then the code automatically closes the path.)

struct Curve {
    var destination: CGPoint
    var control1: CGPoint
    var control2: CGPoint
}

/// A landscape shape defined by a start y-coordinate and an array of curves describing the surface of the landscape
struct AnimatableLandscape: View {
    
    var startY: Double
    var curves: [Curve]
    
    init(startY: Double, curves: [Curve]) {
        self.startY = startY
        
        // Add lines to close the path of the shape
        var newCurves = curves
        // If the last destination isn't at the bottom of the frame, draw a line straight down
        if let last = newCurves.last, last.destination.y != 1 {
            newCurves.append(Curve(destination: CGPoint(x: last.destination.x, y: 1), control1: CGPoint(x: last.destination.x, y: (1+last.destination.y)/2), control2: CGPoint(x: last.destination.x, y: (1+last.destination.y)/2)))
        }
        // Draw a line to the bottom-leftcorner
        newCurves.append(Curve(destination: CGPoint(x: 0, y: 1), control1: CGPoint(x: 0.5, y: 1), control2: CGPoint(x: 0.5, y: 1)))
        // If needed, draw a straight line to the start y-coordinate of the first curve
        if startY != 1 {
            newCurves.append(Curve(destination: CGPoint(x: 0, y: startY), control1: CGPoint(x: 0, y: (1+startY)/2), control2: CGPoint(x: 0, y: (1+startY)/2)))
        }
        self.curves = newCurves
    }
    
    var body: some View {
        AnimatableBezier(
                    yStartPoint: startY,
                    xDestinations: curves.map {$0.destination.x},
                    yDestinations: curves.map {$0.destination.y},
                    xControl1: curves.map {$0.control1.x},
                    yControl1: curves.map {$0.control1.y},
                    xControl2: curves.map {$0.control2.x},
                    yControl2: curves.map {$0.control2.y}
        )
    }
}
/// An animatable bezier shape which is defined by a list of destinations and their control points with their x- and y-coordinates passed through in seperate arrays
struct AnimatableBezier: Shape {
    
    // Properties
    // Define only the y-coordinate of the start point as the bezier should always start at x zero
    var yStartPoint: Double
    
    // Define the x- and y-coordinates as different properties to calculate these values seperately using AnimatableValues
    var xDestinations: AnimatableValues
    var yDestinations: AnimatableValues
    
    var xControl1: AnimatableValues
    var yControl1: AnimatableValues
    
    var xControl2: AnimatableValues
    var yControl2: AnimatableValues
    
    init(yStartPoint: Double, xDestinations: [Double], yDestinations: [Double], xControl1: [Double], yControl1: [Double], xControl2: [Double], yControl2: [Double]) {
        self.yStartPoint = yStartPoint
        self.xDestinations = AnimatableValues(xDestinations)
        self.yDestinations = AnimatableValues(yDestinations)
        self.xControl1 = AnimatableValues(xControl1)
        self.yControl1 = AnimatableValues(yControl1)
        self.xControl2 = AnimatableValues(xControl2)
        self.yControl2 = AnimatableValues(yControl2)
    }
    
    // Declare the animatable data
    typealias Points = AnimatablePair<AnimatableValues, AnimatableValues>
    typealias Curves = AnimatablePair<Points, AnimatablePair<Points, Points>>
    
    var animatableData: AnimatablePair<Double, Curves> {
        get {
            let destinationPoints = Points(xDestinations, yDestinations)
            let control1Points = Points(xControl1, yControl1)
            let control2Points = Points(xControl2, yControl2)
            let curves = Curves(destinationPoints, AnimatablePair(control1Points, control2Points))
            
            return AnimatablePair(yStartPoint, curves)
        }
        
        set {
            yStartPoint = newValue.first

            let curves: Curves = newValue.second
            let destinationPoints: Points = curves.first
            xDestinations = destinationPoints.first
            yDestinations = destinationPoints.second

            let control1Points: Points = curves.second.first
            xControl1 = control1Points.first
            yControl1 = control1Points.second

            let control2Points: Points = curves.second.second
            xControl2 = control2Points.first
            yControl2 = control2Points.second
        }
    }
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let width = rect.size.width
        let height = rect.size.height
        
        // Move the the start point
        let startPoint = CGPoint(x: 0, y: yStartPoint*height)
        path.move(to: startPoint)
        
        // Draw the curves
        let count = min(xDestinations.values.count, yDestinations.values.count, xControl1.values.count, yControl1.values.count, xControl2.values.count, yControl2.values.count)
        for i in 0..<count {
            let destination = CGPoint(x: xDestinations.values[i], y: yDestinations.values[i])
            let control1 = CGPoint(x: xControl1.values[i], y: yControl1.values[i])
            let control2 = CGPoint(x: xControl2.values[i], y: yControl2.values[i])
            
            path.addCurve(to: CGPoint(x: destination.x*width, y: destination.y*height),
                          control1: CGPoint(x: control1.x*width, y: control1.y*height),
                          control2: CGPoint(x: control2.x*width, y: control2.y*height))
        }
        
        // Close the path
        path.closeSubpath()
        
        return path
    }
}
/// Uses the Accelerate framework to utilize its high-performance vector-based arithmetic for animating large arrays.
import enum Accelerate.vDSP

/// Holds an array of Doubles anc conforms to VectorArithmetic allowing it to be used as AnimatableValue
struct AnimatableValues: VectorArithmetic {
    init(_ values: [Double]) {
        self.values = values
    }
    
    var values: [Double]
    
    static var zero: AnimatableValues = AnimatableValues([0.0])
    
    var magnitudeSquared: Double {
        vDSP.sum(vDSP.multiply(values, values))
    }
    
    static func + (lhs: AnimatableValues, rhs: AnimatableValues) -> AnimatableValues {
        let count: Int = min(lhs.values.count, rhs.values.count)
        return AnimatableValues(vDSP.add(lhs.values[0..<count], rhs.values[0..<count]))
    }
    
    static func += (lhs: inout AnimatableValues, rhs: AnimatableValues) {
        let count: Int = min(lhs.values.count, rhs.values.count)
        vDSP.add(lhs.values[0..<count], rhs.values[0..<count], result: &lhs.values[0..<count])
    }
    
    static func - (lhs: AnimatableValues, rhs: AnimatableValues) -> AnimatableValues {
        let count: Int = min(lhs.values.count, rhs.values.count)
        return AnimatableValues(vDSP.subtract(lhs.values[0..<count], rhs.values[0..<count]))
    }
    
    static func -= (lhs: inout AnimatableValues, rhs: AnimatableValues) {
        let count: Int = min(lhs.values.count, rhs.values.count)
        vDSP.subtract(lhs.values[0..<count], rhs.values[0..<count], result: &lhs.values[0..<count])
    }
    
    mutating func scale(by rhs: Double) {
        values = vDSP.multiply(rhs, values)
    }
}

When I use this code to show a shape without animating it, it shows as expected, but when I change a shape into another shape, the other shape doesn’t look like it normally does when not animated.

Shape 1:

let firstStartY = 0.90164
let firstCurves = [
    Curve(destination: CGPoint(x: 0.48065, y: 0.53167),
          control1: CGPoint(x: 0.09511, y: 0.67288),
          control2: CGPoint(x: 0.25329, y: 0.48162)),
    Curve(destination: CGPoint(x: 0.92773, y: 0.13855),
          control1: CGPoint(x: 0.79214, y: 0.60023),
          control2: CGPoint(x: 0.87503, y: 0.318)),
    Curve(destination: CGPoint(x: 1, y: 0.0002),
          control1: CGPoint(x: 0.95181, y: 0.05655),
          control2: CGPoint(x: 0.9696, y: -0.00398))
]

Shape 2:

let secondStartY = 0.03728
let secondCurves = [
    Curve(destination: CGPoint(x: 0.69054, y: 0.20178),
          control1: CGPoint(x: 0, y: 0.03728),
          control2: CGPoint(x: 0.45736, y: -0.11688)),
    Curve(destination: CGPoint(x: 1, y: 1),
          control1: CGPoint(x: 0.82381, y: 0.38388),
          control2: CGPoint(x: 0.94161, y: 0.78003))
]

Animating Shape 1 into Shape 2:
(See file”Animating Shape1 into Shape2.mov” for visual):
https://drive.google.com/file/d/12dR4U8JQZl-fySI7Vtk7H_Q-u6msXLFc/view?usp=share_link

struct ContentView: View {
    
    @State var startPointY = 0.0
    @State var curves = [Curve]()
    
    var body: some View {
        
        GeometryReader { geo in
            AnimatableLandscape(startY: startPointY, curves: curves)
                .frame(height: geo.size.width * 0.5)
        }
        .onAppear {
            self.startPointY = firstStartY
            self.curves = firstCurves
        }
        .onTapGesture {
            withAnimation {
                if startPointY == firstStartY {
                    self.startPointY = secondStartY
                    self.curves = secondCurves
                } else {
                    self.startPointY = firstStartY
                    self.curves = firstCurves
                }
            }
        }
        
    }
}

As you can see, when I animate shape 1 into shape 2, the result doesn’t look like the original shape 2 at all. I can’t figure out why this happens, if anyone could help me with this that’d be great!