第 1 步:规范化方向。例如,假设所有曲线都从具有最低词典顺序的端点开始。
def inCanonicalOrientation(path):
return path if path[0]<path[-1] else reversed(path)
第 2 步:您可以大致准确,也可以非常准确。如果您希望非常准确,请计算样条曲线,或将两条曲线拟合到适当次数的多项式,然后比较系数。如果您只想粗略估计,请执行以下操作:
def resample(path, numPoints)
pathLength = pathLength(path) #write this function
segments = generateSegments(path)
currentSegment = next(segments)
segmentsSoFar = [currentSegment]
for i in range(numPoints):
samplePosition = i/(numPoints-1)*pathLength
while samplePosition > pathLength(segmentsSoFar)+currentSegment.length:
currentSegment = next(segments)
segmentsSoFar.insert(currentSegment)
difference = samplePosition - pathLength(segmentsSoFar)
howFar = difference/currentSegment.length
yield Point((1-howFar)*currentSegment.start + (howFar)*currentSegment.end)
这可以从线性重采样修改为更好的东西。
def error(pathA, pathB):
pathA = inCanonicalOrientation(pathA)
pathB = inCanonicalOrientation(pathB)
higherResolution = max([len(pathA), len(pathB)])
resampledA = resample(pathA, higherResolution)
resampledB = resample(pathA, higherResolution)
error = sum(
abs(pointInA-pointInB)
for pointInA,pointInB in zip(pathA,pathB)
)
averageError = error / len(pathAorB)
normalizedError = error / Z(AorB)
return normalizedError
其中 Z 类似于路径的“直径”,可能是路径中任意两点之间的最大欧几里得距离。