/// <summary> /// Calculate the parameter corresponding to our AlignFeature /// </summary> private void calculateParam(Shape s) { Featurefy.FeatureStroke fs = new Featurefy.FeatureStroke(_template); List <AlignFeature> keys = new List <AlignFeature>(_tf.Count); foreach (AlignFeature af in _tf.Keys) { keys.Add(af); } foreach (AlignFeature af in keys) { switch (af) { case AlignFeature.Curvature: _tf[af] = fs.Curvature.AverageCurvature; break; case AlignFeature.AngleTraveled: _tf[af] = fs.Curvature.TotalAngle; break; case AlignFeature.AngleTraveledRank: List <Substroke> ordered_substrokes = new List <Substroke>(s.SubstrokesL); ordered_substrokes.Sort(delegate(Substroke lhs, Substroke rhs) { Featurefy.FeatureStroke lfs = new Featurefy.FeatureStroke(lhs); Featurefy.FeatureStroke rfs = new Featurefy.FeatureStroke(rhs); return(rfs.Curvature.TotalAngle.CompareTo(lfs.Curvature.TotalAngle)); }); _tf[af] = ordered_substrokes.IndexOf(_template); break; case AlignFeature.Length: double len = 0.0; foreach (Substroke test in s.SubstrokesL) { len += test.SpatialLength; } _tf[af] = _template.SpatialLength / len; break; case AlignFeature.LengthRank: List <Substroke> lr_ordered_substrokes = new List <Substroke>(s.SubstrokesL); lr_ordered_substrokes.Sort(delegate(Substroke lhs, Substroke rhs) { return(rhs.SpatialLength.CompareTo(lhs.SpatialLength)); } ); _tf[af] = lr_ordered_substrokes.IndexOf(_template); break; } } }
/// <summary> /// Attempts to match a substroke with the current parameter. Returns /// some measure of dissimilarity (that is, smaller numbers are better) /// <remarks>Goodness measure is not comparable between AlignFeatures!</remarks> /// </summary> /// <param name="ss">The substroke to match</param> private double match(Substroke ss, Shape sp, AlignFeature af) { Featurefy.FeatureStroke fs = new Featurefy.FeatureStroke(ss); switch (af) { case AlignFeature.Curvature: return(Math.Abs(_tf[af] - fs.Curvature.AverageCurvature)); case AlignFeature.AngleTraveled: return(Math.Abs(_tf[af] - fs.Curvature.TotalAngle)); case AlignFeature.AngleTraveledRank: List <Substroke> ordered_substrokes = new List <Substroke>(sp.SubstrokesL); ordered_substrokes.Sort(delegate(Substroke lhs, Substroke rhs) { Featurefy.FeatureStroke lfs = new Featurefy.FeatureStroke(lhs); Featurefy.FeatureStroke rfs = new Featurefy.FeatureStroke(rhs); return(rfs.Curvature.TotalAngle.CompareTo(lfs.Curvature.TotalAngle)); }); return(Math.Abs(_tf[af] - ordered_substrokes.IndexOf(ss))); case AlignFeature.Length: double total_length = 0.0; foreach (Substroke test in sp.SubstrokesL) { total_length += test.SpatialLength; } return(Math.Abs(ss.SpatialLength / total_length - _tf[af])); case AlignFeature.LengthRank: List <Substroke> lr_ordered_substrokes = new List <Substroke>(sp.SubstrokesL); lr_ordered_substrokes.Sort(delegate(Substroke lhs, Substroke rhs) { return(rhs.SpatialLength.CompareTo(lhs.SpatialLength)); } ); return(Math.Abs(_tf[af] - lr_ordered_substrokes.IndexOf(ss))); } return(0.0); }