Example #1
0
    private MechanismBase MakeRodRopeOrSpring(Stroke stroke, RigidBodyBase headbody, RigidBodyBase tailbody)
    {
        // Rod, Rope, or Spring: we decide based on straightness, curvyness, and loopiness.
        int    np = stroke.PacketCount;
        Point  head = stroke.GetPoint(0), tail = stroke.GetPoint(np - 1);
        double distance = Geometry.DistanceBetween(head, tail);

        StrokeGeometry sg     = new StrokeGeometry(stroke);
        double         length = sg.IntegrateLength();

        // Consider spring: analyze total net curvature of the stroke, and call it a
        // spring if it makes at least 540 degrees (1.5 loops) in the same direction.
        double tt = StrokeAnalyzer.AnalyzeTotalCurvature(stroke, 100.0);

        if (Math.Abs(Geometry.Rad2Deg(tt)) > 540.0)
        {
            dbg.WriteLine("new SpringMech");

            SpringMech newmech = new SpringMech();
            newmech.EndpointA = BodyRef.For(headbody, head);
            newmech.EndpointB = BodyRef.For(tailbody, tail);
            newmech.extension = distance;
            newmech.stiffness = MathEx.Square(tt) / 100;           //Heuristic: th²/100 feels about right.

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return(newmech);
        }

        // Straight and narrow?
        double rodropethreshold = 1.1;         //heuristic

        if (length / distance < rodropethreshold)
        {
            dbg.WriteLine("new RodMech");

            RodMech newmech = new RodMech();
            newmech.EndpointA = BodyRef.For(headbody, head);
            newmech.EndpointB = BodyRef.For(tailbody, tail);
            newmech.length    = distance;

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return(newmech);
        }
        else
        {
            dbg.WriteLine("new RopeMech");

            RopeMech newmech = new RopeMech();
            newmech.EndpointA = BodyRef.For(headbody, head);
            newmech.EndpointB = BodyRef.For(tailbody, tail);
            newmech.length    = length;

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return(newmech);
        }
    }
Example #2
0
        private void CreateLedGeometry()
        {
            switch (Led.RgbLed.Shape)
            {
            case Shape.Custom:
                if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
                {
                    CreateCustomGeometry(2.0);
                }
                else
                {
                    CreateCustomGeometry(1.0);
                }
                break;

            case Shape.Rectangle:
                if (Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keyboard || Led.RgbLed.Device.DeviceInfo.DeviceType == RGBDeviceType.Keypad)
                {
                    CreateKeyCapGeometry();
                }
                else
                {
                    CreateRectangleGeometry();
                }
                break;

            case Shape.Circle:
                CreateCircleGeometry();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Stroke geometry is the display geometry excluding the inner geometry
            StrokeGeometry = DisplayGeometry.GetWidenedPathGeometry(new Pen(null, 1.0), 0.1, ToleranceType.Absolute);
            DisplayGeometry.Freeze();
            StrokeGeometry.Freeze();
        }
Example #3
0
    public static void AnalyzeClosedness(Stroke stroke, double tolerance,
                                         out bool closed, out Point[] vertices) // out double tAB, out double tPQ)
    {
        closed   = false;
        vertices = null;

        // Formulate closure gap-tolerance, based on stroke length (but clipped to <= 500isu).
        double len = StrokeGeometry.IntegrateLength(stroke);

        double segtol = Math.Max(50, Math.Min(tolerance, len / 20.0));
        double gaptol = Math.Max(150, Math.Min(tolerance, len / 7.0));

        dbg.WriteLine(String.Format("length: {0}", len));
        dbg.WriteLine(String.Format("segtol: {0}", segtol));
        dbg.WriteLine(String.Format("gaptol: {0}", gaptol));

        // Break the stroke down into indices.
        int[] indices;
        vertices = SegmentizeStroke(stroke, segtol, out indices);
        int nv = vertices.Length;

        // Do the head/tail segments intersect?  Are they close?
        if (nv >= 4)
        {
            Point headA = (Point)vertices[0];
            Point headB = (Point)vertices[1];
            Point tailP = (Point)vertices[nv - 2];
            Point tailQ = (Point)vertices[nv - 1];

            double tAB, tPQ;
            SegmentCollision.HitTest(headA, headB, tailP, tailQ, out tAB, out tPQ);

            Point virtualIntersectH = Geometry.Interpolate(headA, headB, tAB);
            Point virtualIntersectT = Geometry.Interpolate(tailP, tailQ, tPQ);
            Point virtualIntersect  = Geometry.Interpolate(virtualIntersectH, virtualIntersectT, 0.5);

            double dh2i = Geometry.DistanceBetween(headA, virtualIntersect);
            double dt2i = Geometry.DistanceBetween(tailQ, virtualIntersect);

#if DEBUG
            dbg.WriteLine(String.Format("numV: {0}", nv));
            dbg.WriteLine(String.Format("tAB: {0}", tAB));
            dbg.WriteLine(String.Format("tPQ: {0}", tPQ));

            dbg.WriteLine(String.Format("isct: {0}", virtualIntersect));

            dbg.WriteLine(String.Format("dh2i: {0}", dh2i));
            dbg.WriteLine(String.Format("dt2i: {0}", dt2i));
#endif

            if (dh2i < gaptol && dt2i < gaptol)
            {
                closed = true;
                // Adjust the head point to the actual intersection.
                vertices[0] = virtualIntersect;
                dbg.WriteLine("Closed! Why? dh/t2i < gaptol");
            }
            else if ((-0.3 < tAB && tAB < 0.3) && (0.7 < tPQ && tPQ < 1.3))
            {
                closed = true;
                // Adjust the head point to the actual intersection.
                vertices[0] = virtualIntersect;
                dbg.WriteLine("Closed! Why? |t*| < 0.3");
            }
            else
            {
                // Last chance: measure nearest distance from head to tail segment.
                int closeI = StrokeGeometry.FindClosestPointTo(
                    stroke, headA, indices[nv - 2], indices[nv - 1]);
                Point  close = stroke.GetPoint(closeI);
                double d     = Geometry.DistanceBetween(headA, close);
                if (d < gaptol)
                {
                    closed = true;                     // Keep the head point; discard the tail point below.
                    dbg.WriteLine("Closed! Why? Last chance head/tail distance < gaptol");
                }
            }

            // Remove the last point as redundant if it's closed.
            if (closed)
            {
                Point[] verticesX = new Point[nv - 1];
                Array.Copy(vertices, verticesX, nv - 1);
                vertices = verticesX;
            }
        }
    }
 public static double IntegrateLengthApproximate(Stroke stroke, double tolerance)
 {
     StrokeGeometry sg = new StrokeGeometry(stroke);
     return sg.IntegrateLengthApproximate(tolerance);
 }
 public static double IntegrateLength(Stroke stroke)
 {
     StrokeGeometry sg = new StrokeGeometry(stroke);
     return sg.IntegrateLength();
 }
 public static int FindClosestPointTo(Stroke stroke, Point p, int start, int finish)
 {
     StrokeGeometry sg = new StrokeGeometry(stroke);
     return sg.FindClosestPointTo(p,start,finish);
 }
    private MechanismBase MakeRodRopeOrSpring(Stroke stroke, RigidBodyBase headbody, RigidBodyBase tailbody)
    {
        // Rod, Rope, or Spring: we decide based on straightness, curvyness, and loopiness.
        int np = stroke.PacketCount;
        Point head = stroke.GetPoint(0), tail = stroke.GetPoint(np-1);
        double distance = Geometry.DistanceBetween(head,tail);

        StrokeGeometry sg = new StrokeGeometry(stroke);
        double length = sg.IntegrateLength();

        // Consider spring: analyze total net curvature of the stroke, and call it a
        // spring if it makes at least 540 degrees (1.5 loops) in the same direction.
        double tt = StrokeAnalyzer.AnalyzeTotalCurvature(stroke,100.0);
        if (Math.Abs(Geometry.Rad2Deg(tt)) > 540.0)
        {
            dbg.WriteLine("new SpringMech");

            SpringMech newmech = new SpringMech();
            newmech.EndpointA = BodyRef.For(headbody,head);
            newmech.EndpointB = BodyRef.For(tailbody,tail);
            newmech.extension = distance;
            newmech.stiffness = MathEx.Square(tt)/100; //Heuristic: th²/100 feels about right.

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return newmech;
        }

        // Straight and narrow?
        double rodropethreshold = 1.1; //heuristic
        if (length/distance < rodropethreshold)
        {
            dbg.WriteLine("new RodMech");

            RodMech newmech = new RodMech();
            newmech.EndpointA = BodyRef.For(headbody,head);
            newmech.EndpointB = BodyRef.For(tailbody,tail);
            newmech.length = distance;

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return newmech;
        }
        else
        {
            dbg.WriteLine("new RopeMech");

            RopeMech newmech = new RopeMech();
            newmech.EndpointA = BodyRef.For(headbody,head);
            newmech.EndpointB = BodyRef.For(tailbody,tail);
            newmech.length = length;

            newmech.strokeid = stroke.Id;
            doc.Mechanisms.Add(newmech);
            return newmech;
        }
    }
Example #8
0
    public static double IntegrateLengthApproximate(Stroke stroke, double tolerance)
    {
        StrokeGeometry sg = new StrokeGeometry(stroke);

        return(sg.IntegrateLengthApproximate(tolerance));
    }
Example #9
0
    public static double IntegrateLength(Stroke stroke)
    {
        StrokeGeometry sg = new StrokeGeometry(stroke);

        return(sg.IntegrateLength());
    }
Example #10
0
    public static int FindClosestPointTo(Stroke stroke, Point p, int start, int finish)
    {
        StrokeGeometry sg = new StrokeGeometry(stroke);

        return(sg.FindClosestPointTo(p, start, finish));
    }