I propose a solution using PyQGIS. It should work both for Linestring and MultiLineString layers.

This solution is based on the creation of semicircular rings, so you need to set a value for the diameter (i.e. the `step` variable in the code below). The step you choose won't be the real step used because it is *adjusted* on the basis of the line length (but it would be really similar to the value initially set). You need to do some attempts before finding the best value for the `step` variable.

The code also requires a second (optional) parameter (called `crv_angle`), which helps for decreasing or increasing the curvature for the rings (I performed a few tests for it, so I suggest leaving 45 degrees as default angle since it would lead to real circular rings).

You only need to run this code from the Python Console:

<!-- language-all: lang-py -->

    from math import sin, cos, radians
    
    step = 0.5 # they are meters in this case, but choose the correct value with reference to the CRS used
    crv_angle = 45 # degrees
    
    def segment(polyline):
        for x in range(0, len(polyline) - 1):
            first_point = polyline[x]
            second_point = polyline[x +1]
            seg = QgsGeometry.fromPolyline([first_point, second_point])
            tmp_azim = first_point.azimuth(second_point)
            len_feat = seg.length()
            print len_feat
            parts = int(len_feat/step)
            real_step = len_feat/parts # this is the real step applied
            
            current = 0
            points = []
            while current <= len_feat:
                first = seg.interpolate(current)
                p1=QgsPointV2(first.asPoint().x(), first.asPoint().y())
                angle_1 = radians(90 - (tmp_azim - crv_angle))
                dist_x, dist_y = ((real_step*sin(radians(crv_angle)))* cos(angle_1), (real_step*sin(radians(crv_angle))) * sin(angle_1))
                p2 = QgsPointV2(first.asPoint().x() + dist_x, first.asPoint().y() + dist_y)
                second = seg.interpolate(current + real_step)
                p3=QgsPointV2(second.asPoint().x(), second.asPoint().y())
                angle_2 = radians(90 - (tmp_azim + crv_angle))
                dist_x, dist_y = ((real_step*sin(radians(crv_angle)))* cos(angle_2), (real_step*sin(radians(crv_angle))) * sin(angle_2))
                p4 = QgsPointV2(second.asPoint().x() + dist_x, second.asPoint().y() + dist_y)
                points.extend([p1, p2, p3, p4])
                current += 2*real_step
    
            circularRing = QgsCircularStringV2()
            circularRing.setPoints(points) # set points for circular rings
            fet = QgsFeature()
            fet.setGeometry(QgsGeometry(circularRing))
            prov.addFeatures([fet])
    
    layer = iface.activeLayer() # load the input layer as you want
    crs = layer.crs().toWkt()
    
    # Create the output layer
    outLayer = QgsVectorLayer('Linestring?crs='+ crs, 'wiggly_line' , 'memory')
    prov = outLayer.dataProvider()
    fields = layer.pendingFields()
    prov.addAttributes(fields) # Add input layer fields to the outLayer
    outLayer.updateFields()
    
    for feat in layer.getFeatures():
        geom = feat.geometry()
        polyline = geom.asPolyline()
        segment(polyline)
        
    # Add the layer to the Layers panel
    QgsMapLayerRegistry.instance().addMapLayer(outLayer)

and it will create a new line memory layer with the expected result:

[![enter image description here][1]][1]







  [1]: https://i.sstatic.net/eisUP.png