private Tuple <Term, Term[]> TwoSilhouettesSingleFeature(TSnapped snappedPrimitive, ISet <FeatureCurve> annotated) { var sil0 = SegmentApproximator.ApproximateSegment(snappedPrimitive.LeftSilhouette.Points); var sil1 = SegmentApproximator.ApproximateSegment(snappedPrimitive.RightSilhouette.Points); var axis2d = Get2DVector(snappedPrimitive.AxisResult); var isTopSnapped = snappedPrimitive.TopFeatureCurve.SnappedTo != null; var isBottomSnapped = snappedPrimitive.BottomFeatureCurve.SnappedTo != null; var snappedFeatureCurve = isTopSnapped ? snappedPrimitive.TopFeatureCurve : snappedPrimitive.BottomFeatureCurve; var unsnappedFeatureCurve = isTopSnapped ? snappedPrimitive.BottomFeatureCurve : snappedPrimitive.TopFeatureCurve; var sil0Top = GetForwardPoint(sil0, axis2d); var sil0Bot = GetForwardPoint(sil0, -axis2d); var sil1Top = GetForwardPoint(sil1, axis2d); var sil1Bot = GetForwardPoint(sil1, -axis2d); var sil0Far = isTopSnapped ? sil0Bot : sil0Top; var sil1Far = isTopSnapped ? sil1Bot : sil1Top; var featureProj = ProjectionFit.Compute(snappedFeatureCurve); var farProj = Enumerable.Repeat(EndpointsProjectionFit(unsnappedFeatureCurve, sil0Far, sil1Far), 1); var objective = TermUtils.SafeSum(new Term[] { TermUtils.SafeAvg(featureProj), TermUtils.SafeAvg(farProj) }); var constraints = new Term[] { snappedPrimitive.Axis.NormSquared - 1 }; return(Tuple.Create(objective, constraints)); }
private Term FeaturesTerm(IEnumerable <CircleFeatureCurve> iEnumerable) { var terms = from item in iEnumerable from term in ProjectionFit.Compute(item) select term; var objective = TermUtils.SafeAvg(terms); return(objective); }
private Tuple <Term, Term[]> FullInfo(TSnapped snappedPrimitive) { var terms = from item in snappedPrimitive.FeatureCurves.Cast <CircleFeatureCurve>() from term in ProjectionFit.Compute(item) select term; var objective = TermUtils.SafeAvg(terms); var constraints = new Term[] { snappedPrimitive.Axis.NormSquared - 1 }; return(Tuple.Create(objective, constraints)); }
private static Tuple <Term, Term[]> CreateSGCTerms(SnappedStraightGenCylinder snappedPrimitive, double[] radii, Point spineStart, Point spineEnd) { var constraints = new Term[] { snappedPrimitive.Axis.NormSquared - 1 }; if (radii.Length > 0) { var featureCurveTerms = from item in snappedPrimitive.FeatureCurves.Cast <CircleFeatureCurve>() where item != null where item.SnappedTo != null from term in ProjectionFit.Compute(item) select term; var featureCurvesTerm = 0.1 * TermUtils.SafeAvg(featureCurveTerms); // the difference between the primitive's radii and the computed radii is minimized var radiiApproxTerm = TermUtils.SafeAvg( from i in Enumerable.Range(0, snappedPrimitive.Components.Length) let component = snappedPrimitive.Components[i] let radius = radii[i] select TermBuilder.Power(component.Radius - radius, 2)); // the smoothness of the primitive's radii (laplacian norm) is minimized var radiiSmoothTerm = TermUtils.SafeAvg( from pair in snappedPrimitive.Components.SeqTripples() let r1 = pair.Item1.Radius let r2 = pair.Item2.Radius let r3 = pair.Item3.Radius select TermBuilder.Power(r2 - 0.5 * (r1 + r3), 2)); // how far is r2 from the avg of r1 and r3 // we specifically wish to give higher weight to first and last radii, so we have // an additional first/last radii term. var endpointsRadiiTerm = TermBuilder.Power(radii[0] - snappedPrimitive.Components.First().Radius, 2) + TermBuilder.Power(radii.Last() - snappedPrimitive.Components.Last().Radius, 2); // objective - weighed average of all terms var objective = radiiApproxTerm + radiiSmoothTerm + featureCurvesTerm + endpointsRadiiTerm; return(Tuple.Create(objective, constraints)); } else { return(Tuple.Create((Term)0, constraints)); // if we can't extract radii approximation, we don't do any snapping } }
private static Tuple <Term, Term[]> CreateBGCTerms(SnappedBendedGenCylinder snappedPrimitive, double[] radii, Point[] medial_axis) { var terms = from item in snappedPrimitive.FeatureCurves.Cast <CircleFeatureCurve>() where item.SnappedTo != null from term in ProjectionFit.Compute(item) select term; var featureCurvesTerm = TermUtils.SafeAvg(terms); var radiiApproxTerm = TermUtils.SafeAvg( from i in Enumerable.Range(0, snappedPrimitive.Components.Length) let component = snappedPrimitive.Components[i] let radius = radii[i] select TermBuilder.Power(component.Radius - radius, 2)); // the smoothness of the primitive's radii (laplacian norm) is minimized var radiiSmoothTerm = TermUtils.SafeAvg( from pair in snappedPrimitive.Components.SeqTripples() let r1 = pair.Item1.Radius let r2 = pair.Item2.Radius let r3 = pair.Item3.Radius select TermBuilder.Power(r2 - 0.5 * (r1 + r3), 2)); // how far is r2 from the avg of r1 and r3 var positionSmoothnessTerm = TermUtils.SafeAvg( from triple in snappedPrimitive.Components.SeqTripples() let p1 = new TVec(triple.Item1.vS, triple.Item1.vT) let p2 = new TVec(triple.Item2.vS, triple.Item2.vT) let p3 = new TVec(triple.Item3.vS, triple.Item3.vT) let laplacian = p2 - 0.5 * (p1 + p3) select laplacian.NormSquared); Term[] TermArray = new Term[medial_axis.Length]; for (int i = 0; i < medial_axis.Length; i++) { TVec PointOnSpine = snappedPrimitive.BottomCenter + snappedPrimitive.Components[i].vS * snappedPrimitive.U + snappedPrimitive.Components[i].vT * snappedPrimitive.V; TermArray[i] = TermBuilder.Power(PointOnSpine.X - medial_axis[i].X, 2) + TermBuilder.Power(PointOnSpine.Y + medial_axis[i].Y, 2); } var spinePointTerm = TermUtils.SafeAvg(TermArray); // we specifically wish to give higher weight to first and last radii, so we have // an additional first/last radii term. var endpointsRadiiTerm = TermBuilder.Power(radii[0] - snappedPrimitive.Components.First().Radius, 2) + TermBuilder.Power(radii.Last() - snappedPrimitive.Components.Last().Radius, 2); // objective - weighed average of all terms var objective = 0.1 * featureCurvesTerm + radiiApproxTerm + radiiSmoothTerm + positionSmoothnessTerm + spinePointTerm + endpointsRadiiTerm; var sB = snappedPrimitive.NPbot.X; var tB = snappedPrimitive.NPbot.Y; var s0 = snappedPrimitive.Components[0].vS; var t0 = snappedPrimitive.Components[0].vT; var s1 = snappedPrimitive.Components[1].vS; var t1 = snappedPrimitive.Components[1].vT; var botNormalParallelism = tB * (s1 - s0) - sB * (t1 - t0); var sT = snappedPrimitive.NPtop.X; var tT = snappedPrimitive.NPtop.Y; var sLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 1].vS; var tLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 1].vT; var sBeforeLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 2].vS; var tBeforeLast = snappedPrimitive.Components[snappedPrimitive.Components.Length - 2].vT; var topNormalParallelism = tT * (sLast - sBeforeLast) - sT * (tLast - tBeforeLast); var topNormalized = snappedPrimitive.NPtop.NormSquared - 1; var botNormalized = snappedPrimitive.NPbot.NormSquared - 1; var uNormalized = snappedPrimitive.U.NormSquared - 1; var vNormalized = snappedPrimitive.V.NormSquared - 1; var uvOrthogonal = TVec.InnerProduct(snappedPrimitive.U, snappedPrimitive.V); var firstComponentBottomS = snappedPrimitive.Components[0].vS; var firstComponentBottomT = snappedPrimitive.Components[0].vT; var constraints = new List <Term> { topNormalized, botNormalized, uNormalized, vNormalized, uvOrthogonal, firstComponentBottomS, firstComponentBottomT, botNormalParallelism, topNormalParallelism }; var meanRadius = radii.Sum() / radii.Length; var stdDevRadius = Math.Sqrt(radii.Select(r => r * r).Sum() / radii.Length - meanRadius * meanRadius); Debug.WriteLine("ALEXALEX Mean radius is {0}, stddev is {1}", meanRadius, stdDevRadius); if (stdDevRadius <= 0.3 * meanRadius) { foreach (var pair in snappedPrimitive.Components.SeqPairs()) { var ra = pair.Item1.Radius; var rb = pair.Item2.Radius; constraints.Add(ra - rb); } } return(Tuple.Create(objective, constraints.ToArray())); }