コード例 #1
0
        public static Direction GetNormal(PointUV uv, double p, double q, double circleAngle, Vector inverseOffset, bool isInverted)
        {
            double delta  = 0.001;
            var    deltaU = VectorUV.Create(delta, 0);
            var    deltaV = VectorUV.Create(0, delta);

            PointUV uv00 = uv - deltaU;
            PointUV uv01 = uv + deltaU;
            PointUV uv10 = uv - deltaV;
            PointUV uv11 = uv + deltaV;

            Point pCenter = Lawson.Evaluate(uv, p, q, circleAngle, inverseOffset, isInverted);

            var pxxs = new Point[] {
                Lawson.Evaluate(uv00, p, q, circleAngle, inverseOffset, isInverted),
                Lawson.Evaluate(uv01, p, q, circleAngle, inverseOffset, isInverted),
                Lawson.Evaluate(uv10, p, q, circleAngle, inverseOffset, isInverted),
                Lawson.Evaluate(uv11, p, q, circleAngle, inverseOffset, isInverted)
            };

            var sum = Vector.Zero;

            foreach (Point pxx in pxxs)
            {
                sum += pxx - pCenter;
            }

            if (sum != Vector.Zero)
            {
                return(sum.Direction);
            }

            return(Vector.Cross(pxxs[1] - pxxs[0], pxxs[1] - pxxs[2]).Direction);
        }
コード例 #2
0
        // static Create method follows the API convention and parent should be first argument
        public static LawsonRelaxGraphics Create(Lawson lawson)
        {
            var widget = new LawsonRelaxGraphics(lawson);

            widget.Initialize();
            return(widget);
        }
コード例 #3
0
        protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect)
        {
            base.OnExecute(command, context, buttonRect);
            lawson = new Lawson(angleForce, vForce, uAngleForce, uTouchForce, averageVForce, averageTabAngleForce);
            Window window = Window.ActiveWindow;

            window.SetTool(new LawsonRelax(lawson, this));
        }
コード例 #4
0
        public static Graphic GetGraphic(double p, double q, double circleAngle, Vector inverseOffset)
        {
            var graphics = new List <Graphic>();

            int    bandCount = 2;
            int    iSteps = bandCount * 32; //32
            int    jSteps = 34;             //34
            double uStep = 2 * Math.PI / iSteps;
            double vStep = 2 * Math.PI / jSteps;
            bool   uSwap = false, vSwap = false;

            for (int j = 0; j < jSteps; j++)
            {
                double v = 2 * Math.PI * j / jSteps;

                for (int i = 0; i < iSteps; i++)
                {
                    double u = 2 * Math.PI * i / iSteps;

                    Direction n00, n10, n11, n01;
                    Point     p00 = Lawson.Evaluate(PointUV.Create(u, v), p, q, circleAngle, inverseOffset, true, out n00);
                    Point     p10 = Lawson.Evaluate(PointUV.Create(u + uStep, v), p, q, circleAngle, inverseOffset, true, out n10);
                    Point     p11 = Lawson.Evaluate(PointUV.Create(u + uStep, v + vStep), p, q, circleAngle, inverseOffset, true, out n11);
                    Point     p01 = Lawson.Evaluate(PointUV.Create(u, v + vStep), p, q, circleAngle, inverseOffset, true, out n01);

                    var facetVertices = new List <FacetVertex>();
                    facetVertices.Add(new FacetVertex(p00, n00));
                    facetVertices.Add(new FacetVertex(p10, n10));
                    facetVertices.Add(new FacetVertex(p11, n11));
                    facetVertices.Add(new FacetVertex(p01, n01));

                    var facets = new List <Facet>();
                    facets.Add(new Facet(0, 1, 2));
                    facets.Add(new Facet(0, 2, 3));

                    HSBColor hsbFill = new HSBColor(Window.ActiveWindow.ActiveLayer.GetColor(null));
                    hsbFill.H = (float)(u / 2 / Math.PI * 360);
                    hsbFill.A = vSwap ? 127 : 255;

                    HSBColor hsbLine = new HSBColor(System.Drawing.Color.MidnightBlue);
                    hsbLine.H = (float)(u / 2 / Math.PI * 360);

                    var style = new GraphicStyle {
                        EnableDepthBuffer = true,
                        LineColor         = hsbLine.Color,
                        LineWidth         = 1,
                        FillColor         = hsbFill.Color
                    };

                    graphics.Add(Graphic.Create(style, MeshPrimitive.Create(facetVertices, facets)));

                    uSwap = !uSwap;
                }
                vSwap = !vSwap;
            }

            return(Graphic.Create(null, null, graphics));
        }
コード例 #5
0
        public LawsonPropertiesButtonCapsule(string name, string text, System.Drawing.Image image, string hint, RibbonCollectionCapsule parent, ButtonSize buttonSize)
            : base(name, text, image, hint, parent, buttonSize)
        {
            Values[Resources.LawsonTabAngleForce]        = new RibbonCommandValue(angleForce);
            Values[Resources.LawsonVAlignmentForce]      = new RibbonCommandValue(vForce);
            Values[Resources.LawsonUAngleForce]          = new RibbonCommandValue(uAngleForce);
            Values[Resources.LawsonUTouchForce]          = new RibbonCommandValue(uTouchForce);
            Values[Resources.LawsonVAverageForce]        = new RibbonCommandValue(averageVForce);
            Values[Resources.LawsonTabAngleAverageForce] = new RibbonCommandValue(averageTabAngleForce);

            if (lawson == null)
            {
                lawson = new Lawson(angleForce, vForce, uAngleForce, uTouchForce, averageVForce, averageTabAngleForce);
            }
        }
コード例 #6
0
        protected override void OnExecute(Command command, ExecutionContext context, System.Drawing.Rectangle buttonRect)
        {
            const int count = 24;

            double p             = 0.5;
            double q             = 1;
            double circleAngle   = Math.PI / 2;
            Vector inverseOffset = Vector.Create(0.5, 0, 0);

            Part mainPart = Window.ActiveWindow.Scene as Part;

            Point[] baseCirclePoints = new Point[count];
            for (int i = 0; i < count; i++)
            {
                double  u       = (double)i / count * 2 * Math.PI;
                Point[] vPoints = new Point[3];
                for (int j = 0; j < 3; j++)
                {
                    vPoints[j] = Lawson.Evaluate(PointUV.Create((double)j / 3 * 2 * Math.PI, u), p, q, circleAngle, inverseOffset, true);
                    if (j == 0)
                    {
                        baseCirclePoints[i] = vPoints[j];
                    }
                }

                Circle circle = Circle.CreateThroughPoints(
                    Plane.Create(Frame.Create(vPoints[0], Vector.Cross(vPoints[1] - vPoints[0], vPoints[2] - vPoints[0]).Direction)),
                    vPoints[0], vPoints[1], vPoints[2]
                    );

                DesignCurve.Create(mainPart, CurveSegment.Create(circle));

                //ShapeHelper.CreateTorus(circle.Frame.Origin, circle.Frame.DirZ, circle.Radius * 2,
            }

            Circle baseCircle = Circle.CreateThroughPoints(
                Plane.Create(Frame.Create(baseCirclePoints[0], Vector.Cross(baseCirclePoints[1] - baseCirclePoints[0], baseCirclePoints[2] - baseCirclePoints[0]).Direction)),
                baseCirclePoints[0], baseCirclePoints[1], baseCirclePoints[2]
                );

            DesignCurve.Create(mainPart, CurveSegment.Create(baseCircle));
        }
コード例 #7
0
        public static Direction GetNormal(PointUV uv, double p, double q, double circleAngle, Vector inverseOffset, bool isInverted)
        {
            double delta  = 0.001;
            var    deltaU = VectorUV.Create(delta, 0);
            var    deltaV = VectorUV.Create(0, delta);

            PointUV uv00 = uv - deltaU;
            PointUV uv01 = uv + deltaU;
            PointUV uv10 = uv - deltaV;
            PointUV uv11 = uv + deltaV;

            Vector du =
                Lawson.Evaluate(uv00, p, q, circleAngle, inverseOffset, isInverted) -
                Lawson.Evaluate(uv01, p, q, circleAngle, inverseOffset, isInverted)
            ;

            Vector dv =
                Lawson.Evaluate(uv10, p, q, circleAngle, inverseOffset, isInverted) -
                Lawson.Evaluate(uv11, p, q, circleAngle, inverseOffset, isInverted)
            ;

            return(Vector.Cross(du, dv).Direction);
        }
コード例 #8
0
        public void Iterate()
        {
            Iteration++;

            var newVParameters    = new CircularList <CircularList <double> >(iSteps * 2);
            var backupVParameters = new CircularList <CircularList <double> >(iSteps * 2);
            var newTabAngles      = new CircularList <CircularList <double> >(iSteps * 2);

            for (int i = 0; i < iSteps * 2; i++)
            {
                newVParameters.Add(new CircularList <double>(jSteps));
                backupVParameters.Add(new CircularList <double>(jSteps));
                newTabAngles.Add(new CircularList <double>(jSteps));
                for (int j = 0; j < jSteps; j++)
                {
                    newVParameters[i].Add(vParameters[i][j]);
                    backupVParameters[i].Add(vParameters[i][j]);
                    newTabAngles[i].Add(tabAngles[i][j]);
                }
            }

            double cumulativeErrorTally = 0;

            MaxError = 0;
            for (int i = 0; i < iSteps * 2; i++)
            {
                for (int j = 0; j < jSteps; j++)
                {
                    bool swap      = j % 2 == 0;
                    int  iOtherDir = swap ? -1 : 1;
                    int  iOther    = i + iOtherDir;

                    Circle baseCircle = GetTabFromPoints(true, i, j, iOther);
                    Circle circle0    = GetTabFromPoints(true, iOther, j - 1, i);
                    Circle circle1    = GetTabFromPoints(true, iOther, j + 1, i);

                    double distance0 = (baseCircle.Frame.Origin - circle0.Frame.Origin).Magnitude - baseCircle.Radius - circle0.Radius;
                    double distance1 = (baseCircle.Frame.Origin - circle1.Frame.Origin).Magnitude - baseCircle.Radius - circle1.Radius;
                    cumulativeErrorTally += distance0 * distance0 + distance1 * distance1;
                    MaxError              = Math.Max(Math.Abs(distance0), MaxError);
                    MaxError              = Math.Max(Math.Abs(distance1), MaxError);

                    double angleAdjust = (distance0 + distance1) / 2 * AngleForce / GetSpanAt(i, j) / baseCircle.Radius;                    // / GetSpanAt(i, j) / baseCircle.Radius; // / baseCircle.Radius;
                    newTabAngles[i][j] -= angleAdjust;

                    newTabAngles[i][j - 1] -= angleAdjust / 2;
                    newTabAngles[i][j + 1] -= angleAdjust / 2;

                    double iAngle = AddInHelper.AngleBetween(
                        circle0.Frame.Origin - baseCircle.Frame.Origin,
                        circle1.Frame.Origin - baseCircle.Frame.Origin
                        );

                    double vOffset = (distance1 - distance0) * VForce;
                    //double uAngleOffset = -(Math.PI / 2 - Math.Abs(iAngle)) * UAngleForce;
                    double uAngleOffset = -(Math.PI * 2 / 3 - Math.Abs(iAngle)) * UAngleForce;

                    Circle circleV      = GetTabFromPoints(true, iOther, j, i);
                    double distanceV    = (baseCircle.Frame.Origin - circleV.Frame.Origin).Magnitude - baseCircle.Radius - circleV.Radius;
                    double uTouchOffset = -distanceV * UTouchForce;

                    double averageOffset = 0;
                    double averageAngle  = 0;
                    double count         = 0;

#if false
                    for (int ii = i - 1; ii <= i + 1; ii++)
                    {
                        for (int jj = j - 2; jj <= j + 2; jj++)
                        {
                            if (i == ii && j == jj)
                            {
                                continue;
                            }

                            double weight = (double)1 / (Math.Pow(i - ii, 2) + Math.Pow(j - jj, 2));
                            averageOffset += GetSpanAt(ii, jj) * weight;
                            averageAngle  += GetTabFromPoints(true, i, j, j % 2 == 0 ? i - 1 : i + 1).Radius *weight;
                            count         += weight;
                        }
                    }

                    averageOffset  = averageOffset / count - GetSpanAt(i, j);
                    averageOffset *= -AverageVForce / 2;

                    averageAngle        = averageAngle / count - baseCircle.Radius;
                    newTabAngles[i][j] += averageAngle * AverageTabAngleForce;
#elif true
                    foreach (int ii in new int[] { i, iOther })
                    {
                        foreach (int jj in new int[] { j - 1, j + 1 })
                        {
                            averageAngle += GetTabFromPoints(true, ii, jj, ii == i ? iOther : i).Radius;
                            count++;
                        }
                    }

                    averageOffset += GetSpanAt(i - 1, j);
                    averageOffset += GetSpanAt(i + 1, j);
                    averageOffset += GetSpanAt(i, j - 1);
                    averageOffset += GetSpanAt(i, j + 1);
                    averageOffset /= 4;

                    averageOffset  = averageOffset / count - GetSpanAt(i, j);
                    averageOffset *= -AverageVForce / 2;

                    averageAngle        = averageAngle / count - baseCircle.Radius;
                    newTabAngles[i][j] -= averageAngle * AverageTabAngleForce;
#else
                    Point midpointV = GetFivePointNurbsAverage(new int[, ] {
                        { i, j - 2 },
                        { i, j - 1 },
                        { i, j },
                        { i, j + 1 },
                        { i, j + 2 }
                    });

                    Point midpointD0 = GetFivePointNurbsAverage(new int[, ] {
                        { i - iOtherDir, j - 2 },
                        { i, j - 1 },
                        { i, j },
                        { i + iOtherDir, j + 1 },
                        { i + 2 * iOtherDir, j + 2 }
                    });

                    Point midpointD1 = GetFivePointNurbsAverage(new int[, ] {
                        { i - iOtherDir, j + 2 },
                        { i, j + 1 },
                        { i, j },
                        { i + iOtherDir, j - 1 },
                        { i + 2 * iOtherDir, j - 2 }
                    });

                    Point midpointU = GetFivePointNurbsAverage(new int[, ] {
                        { i - 2 * iOtherDir, j },
                        { i - iOtherDir, j },
                        { i, j },
                        { i + iOtherDir, j },
                        { i + 2 * iOtherDir, j }
                    });

                    averageOffset  = (midpointV.Y + midpointU.Y) / 2 - GetSpanAt(i, j);
                    averageOffset *= -AverageVForce / 2;

                    averageAngle        = (midpointV.X + 2 * midpointD0.X + 2 * midpointD1.X) / 5 - tabAngles[i][j];
                    newTabAngles[i][j] += averageAngle * AverageTabAngleForce;
#endif

                    double size = 1;                    // (points[i][j + 1] - points[i][j]).Magnitude;
                    double slip = (uAngleOffset + averageOffset + uTouchOffset) * size;

                    newVParameters[i][j]     += vOffset + slip;
                    newVParameters[i][j + 1] += vOffset - slip;

                    newVParameters[i][j - 1] += (vOffset + slip) / 2;
                    newVParameters[i][j + 2] += (vOffset - slip) / 2;

                    //				double oldSpan = (points[i][j + 1] - points[i][j]).Magnitude;
                    //				double newSpan = (points[i][j + 1] - points[i][j]).Magnitude;


                    Trace.WriteIf(Iteration % 400 == 0, tabAngles[i][j] + " ");
                    //					Trace.WriteIf(Iteration % 400 == 0, iAngle + " ");
                    //					Trace.WriteIf(Iteration % 400 == 0, GetSpanAt(i,j) + " ");
                }
                Trace.WriteLineIf(Iteration % 400 == 0, "");
            }

            for (int i = 0; i < iSteps * 2; i++)
            {
                for (int j = 0; j < jSteps; j++)
                {
                    newTabAngles[i][j] = Math.Max(Math.PI / 2, newTabAngles[i][j]);
                    newTabAngles[i][j] = Math.Min(Math.PI * 3 / 4, newTabAngles[i][j]);

                    double l1 = backupVParameters[i][j + 1] - backupVParameters[i][j];
                    double l2 = newVParameters[i][j + 1] - newVParameters[i][j];
                    double b1 = Math.PI - tabAngles[i][j];

                    double a   = l1 / l2 / Math.Tan(b1 / 2) * (1 + 1 / Math.Cos(b1 / 2));
                    double phi = 2 * Math.Atan(1 / a);
                    tabAngles[i][j] = Math.PI - 2 * phi;

                    //double b2 = 2 * Math.Asin(l2 / l1 * Math.Sin(b1 / 2));
                    //tabAngles[i][j] = Math.PI - b2;
                }
            }

            for (int i = 0; i < iSteps * 2; i++)
            {
                // make intersecting tabs identical

                //double angle = (
                //    newTabAngles[i][0] +
                //    newTabAngles[i + iSteps][0] +
                //    newTabAngles[i + iSteps / 2][jSteps / 2] +
                //    newTabAngles[i + 3 * iSteps / 2][jSteps / 2]
                //) / 4;

                //newTabAngles[i][0] = angle;
                //newTabAngles[i + iSteps][0] = angle;
                //newTabAngles[i + iSteps / 2][jSteps / 2] = angle;
                //newTabAngles[i + 3 * iSteps / 2][jSteps / 2] = angle;

                double span = (
                    (newVParameters[i][1] - newVParameters[i][0]) +
                    (newVParameters[i + iSteps][1] - newVParameters[i + iSteps][0]) +
                    (newVParameters[i + iSteps / 2][jSteps / 2 + 1] - newVParameters[i + iSteps / 2][jSteps / 2]) +
                    (newVParameters[i + 3 * iSteps / 2][jSteps / 2 + 1] - newVParameters[i + 3 * iSteps / 2][jSteps / 2])
                    ) / 8;

                newVParameters[i][0]          = -span;
                newVParameters[i][1]          = span;
                newVParameters[i + iSteps][0] = -span;
                newVParameters[i + iSteps][1] = span;
                newVParameters[i + iSteps / 2][jSteps / 2]         = Math.PI - span;
                newVParameters[i + iSteps / 2][jSteps / 2 + 1]     = Math.PI + span;
                newVParameters[i + 3 * iSteps / 2][jSteps / 2]     = Math.PI - span;
                newVParameters[i + 3 * iSteps / 2][jSteps / 2 + 1] = Math.PI + span;
            }

            // Average antipodal points
            // for l(i, j),
            // l(i, j) == l(-i, pi+j)* == l(i+2pi, -j) == l(-i-2pi, pi-j)*
            // Where * means x=x, y=-y, z=-z
            for (int i = 0; i < iSteps * 2; i++)
            {
                for (int j = 0; j < jSteps / 2; j++)
                {
                    double average = (
                        newVParameters[i][j] +
                        newVParameters[-i][j + jSteps / 2] - Math.PI +
                        (j < 2 ? 0 : 2 * Math.PI) - newVParameters[i + iSteps][-j + 1] +
                        Math.PI - newVParameters[-i - iSteps][-j + jSteps / 2 + 1]
                        ) / 4;

                    newVParameters[i][j] = average;
                    newVParameters[-i][j + jSteps / 2] = average + Math.PI;
                    newVParameters[i + iSteps][-j + 1] = (j < 2 ? 0 : 2 * Math.PI) - average;
                    newVParameters[-i - iSteps][-j + jSteps / 2 + 1] = Math.PI - average;

                    average = (
                        tabAngles[i][j] +
                        tabAngles[-i][j + jSteps / 2 + 1] +
                        tabAngles[i + iSteps][-j] +
                        tabAngles[-i - iSteps][-j + jSteps / 2 + 1]
                        ) / 4;

                    tabAngles[i][j] = average;
                    tabAngles[-i][j + jSteps / 2 + 1]           = average;
                    tabAngles[i + iSteps][-j]                   = average;
                    tabAngles[-i - iSteps][-j + jSteps / 2 + 1] = average;
                }
            }

            CumulativeError = Math.Sqrt(cumulativeErrorTally / (iSteps * 2 * jSteps * 2));
            //	Trace.WriteLine(lastCumulativeError);

            // We're not calculating the points for the last iteration.  Whatevs.
            vParameters = newVParameters;
            tabAngles   = newTabAngles;

            for (int i = 0; i < iSteps * 2; i++)
            {
                double u = 2 * Math.PI * (double)i / iSteps;
                for (int j = 0; j < jSteps; j++)
                {
                    points[i][j] = Lawson.Evaluate(PointUV.Create(vParameters[i][j], u), p, q, circleAngle, inverseOffset, true) * scale;
                    //		Trace.WriteLine(string.Format("{0} {1} {2}", i, j, tabAngles[i][j]));
                }
            }
        }
コード例 #9
0
 public static Graphic GetGraphic(Lawson lawson)
 {
     return(lawson.GetGraphic());
 }
コード例 #10
0
 // creates a new custom object and a wrapper for it
 protected LawsonRelaxGraphics(Lawson lawson)
     : base(Window.ActiveWindow.Scene as Part)
 {
     this.lawson = lawson;
 }
コード例 #11
0
        //		double cursorScale = 0.01;

        public LawsonRelax(Lawson lawson, LawsonRelaxButtonCapsule buttonCapsule)
            : base(InteractionMode.Solid)
        {
            this.lawson        = lawson;
            this.buttonCapsule = buttonCapsule;
        }