public override Value Evaluate(FSharpList <Value> args) { var parameter = ((Value.Number)args[0]).Item; var thisCurve = ((Value.Container)args[1]).Item as Curve; var thisEdge = (thisCurve != null) ? null : (((Value.Container)args[1]).Item as Edge); if (thisCurve == null && thisEdge == null && ((Value.Container)args[1]).Item is Reference) { var r = (Reference)((Value.Container)args[1]).Item; if (r != null) { var refElem = dynRevitSettings.Doc.Document.GetElement(r.ElementId); if (refElem != null) { GeometryObject geob = refElem.GetGeometryObjectFromReference(r); thisEdge = geob as Edge; if (thisEdge == null) { thisCurve = geob as Curve; } } } } var result = (thisCurve != null) ? (!XyzOnCurveOrEdge.curveIsReallyUnbound(thisCurve) ? thisCurve.ComputeDerivatives(parameter, true) : thisCurve.ComputeDerivatives(parameter, false)) : (thisEdge == null ? null : thisEdge.ComputeDerivatives(parameter)); return(Value.NewContainer(result)); }
public override FScheme.Value Evaluate(FSharpList <FScheme.Value> args) { double xi; //, x0, xs; xi = ((FScheme.Value.Number)args[1]).Item; // Number xi = Math.Round(xi); if (xi < System.Double.Epsilon) { throw new Exception("The point count must be larger than 0."); } xi = xi - 1; //x0 = ((Value.Number)args[2]).Item;// Starting Coord //xs = ((Value.Number)args[3]).Item;// Spacing var result = FSharpList <FScheme.Value> .Empty; Curve crvRef = null; if (((FScheme.Value.Container)args[0]).Item is CurveElement) { var c = (CurveElement)((FScheme.Value.Container)args[0]).Item; // Curve crvRef = c.GeometryCurve; } else { crvRef = (Curve)((FScheme.Value.Container)args[0]).Item; // Curve } double t = 0; if (xi < System.Double.Epsilon) { var pt = !XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef) ? crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(pt), result); return(FScheme.Value.NewList( ListModule.Reverse(result) )); } for (int xCount = 0; xCount <= xi; xCount++) { t = xCount / xi; // create normalized curve param by dividing current number by total number var pt = !XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef) ? crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(pt), result); } return(FScheme.Value.NewList( ListModule.Reverse(result) )); }
public override Value Evaluate(FSharpList <Value> args) { Curve curve = (Curve)((Value.Container)args[0]).Item; XYZ newStart = (XYZ)((Value.Container)args[1]).Item; XYZ newEnd = (XYZ)((Value.Container)args[2]).Item; IntersectionResult projectStart = curve.Project(newStart); IntersectionResult projectEnd = curve.Project(newEnd); double sParam = projectStart.Parameter; double eParam = projectEnd.Parameter; bool closed = XyzOnCurveOrEdge.curveIsReallyUnbound(curve); if (closed) { double period = curve.Period; while (eParam < sParam) { eParam += period; } while (eParam >= sParam + period) { eParam -= period; } if (eParam < sParam + 0.000000001 || eParam > sParam + period - 0.000000001) { throw new Exception(" bounded curve results into curve of full period"); } } Curve result = curve.Clone(); result.MakeBound(sParam, eParam); return(Value.NewContainer(result)); }
public override FScheme.Value Evaluate(FSharpList <FScheme.Value> args) { double xi; //, x0, xs; xi = ((FScheme.Value.Number)args[1]).Item; // Number xi = Math.Round(xi); if (xi < System.Double.Epsilon) { throw new Exception("The point count must be larger than 0."); } //x0 = ((Value.Number)args[2]).Item;// Starting Coord //xs = ((Value.Number)args[3]).Item;// Spacing var result = FSharpList <FScheme.Value> .Empty; Curve crvRef = null; if (((FScheme.Value.Container)args[0]).Item is CurveElement) { var c = (CurveElement)((FScheme.Value.Container)args[0]).Item; // Curve crvRef = c.GeometryCurve; } else { crvRef = (Curve)((FScheme.Value.Container)args[0]).Item; // Curve } double t = 0.0; XYZ startPoint = !XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef) ? crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(startPoint), result); t = 1.0; XYZ endPoint = !XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef) ? crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); if (xi > 2.0 + System.Double.Epsilon) { int numParams = Convert.ToInt32(xi - 2.0); var curveParams = new List <double>(); for (int ii = 0; ii < numParams; ii++) { curveParams.Add((ii + 1.0) / (xi - 1.0)); } int maxIterNum = 15; bool bUnbound = XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef); int iterNum = 0; for (; iterNum < maxIterNum; iterNum++) { XYZ prevPoint = startPoint; XYZ thisXYZ = null; XYZ nextXYZ = null; Vector <double> distValues = DenseVector.Create(numParams, (c) => 0.0); Matrix <double> iterMat = DenseMatrix.Create(numParams, numParams, (r, c) => 0.0); double maxDistVal = -1.0; for (int iParam = 0; iParam < numParams; iParam++) { t = curveParams[iParam]; if (nextXYZ != null) { thisXYZ = nextXYZ; } else { thisXYZ = !bUnbound?crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); } double tNext = (iParam == numParams - 1) ? 1.0 : curveParams[iParam + 1]; nextXYZ = (iParam == numParams - 1) ? endPoint : !bUnbound?crvRef.Evaluate(tNext, true) : crvRef.Evaluate(tNext * crvRef.Period, false); distValues[iParam] = thisXYZ.DistanceTo(prevPoint) - thisXYZ.DistanceTo(nextXYZ); if (Math.Abs(distValues[iParam]) > maxDistVal) { maxDistVal = Math.Abs(distValues[iParam]); } Transform thisDerivTrf = !bUnbound?crvRef.ComputeDerivatives(t, true) : crvRef.ComputeDerivatives(t * crvRef.Period, false); XYZ derivThis = thisDerivTrf.BasisX; if (bUnbound) { derivThis = derivThis.Multiply(crvRef.Period); } double distPrev = thisXYZ.DistanceTo(prevPoint); if (distPrev > System.Double.Epsilon) { double valDeriv = (thisXYZ - prevPoint).DotProduct(derivThis) / distPrev; iterMat[iParam, iParam] += valDeriv; if (iParam > 0) { iterMat[iParam - 1, iParam] -= valDeriv; } } double distNext = thisXYZ.DistanceTo(nextXYZ); if (distNext > System.Double.Epsilon) { double valDeriv = (thisXYZ - nextXYZ).DotProduct(derivThis) / distNext; iterMat[iParam, iParam] -= valDeriv; if (iParam < numParams - 1) { iterMat[iParam + 1, iParam] += valDeriv; } } prevPoint = thisXYZ; } Matrix <double> iterMatInvert = iterMat.Inverse(); Vector <double> changeValues = iterMatInvert.Multiply(distValues); double dampingFactor = 1.0; for (int iParam = 0; iParam < numParams; iParam++) { curveParams[iParam] -= dampingFactor * changeValues[iParam]; if (iParam == 0 && curveParams[iParam] < 0.000000001) { double oldValue = dampingFactor * changeValues[iParam] + curveParams[iParam]; while (curveParams[iParam] < 0.000000001) { curveParams[iParam] = 0.5 * (dampingFactor * changeValues[iParam] + curveParams[iParam]); } changeValues[iParam] = (oldValue - curveParams[iParam]) / dampingFactor; } else if (iParam > 0 && curveParams[iParam] < 0.000000001 + curveParams[iParam - 1]) { for (; iParam > -1; iParam--) { curveParams[iParam] = dampingFactor * changeValues[iParam] + curveParams[iParam]; } dampingFactor *= 0.5; continue; } else if (iParam == numParams - 1 && curveParams[iParam] > 1.0 - 0.000000001) { double oldValue = dampingFactor * changeValues[iParam] + curveParams[iParam]; while (curveParams[iParam] > 1.0 - 0.000000001) { curveParams[iParam] = 0.5 * (1.0 + dampingFactor * changeValues[iParam] + curveParams[iParam]); } changeValues[iParam] = (oldValue - curveParams[iParam]) / dampingFactor; } } if (maxDistVal < 0.000000001) { for (int iParam = 0; iParam < numParams; iParam++) { t = curveParams[iParam]; thisXYZ = !XyzOnCurveOrEdge.curveIsReallyUnbound(crvRef) ? crvRef.Evaluate(t, true) : crvRef.Evaluate(t * crvRef.Period, false); result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(thisXYZ), result); } break; } } if (iterNum == maxIterNum) { throw new Exception("could not solve for equal distances"); } } if (xi > 1.0 + System.Double.Epsilon) { result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(endPoint), result); } return(FScheme.Value.NewList( ListModule.Reverse(result) )); }