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); } }
static MagicDocument CreateDocumentFixture() { MagicDocument doc = new MagicDocument(); RigidBodyBase body; body = new EllipticalBody(); body.strokeid = 1; doc.Bodies.Add(body); body = new EllipticalBody(); body.strokeid = 2; doc.Bodies.Add(body); body = new PolygonalBody(); body.strokeid = 3; doc.Bodies.Add(body); ((PolygonalBody)body).Vertices = new Point[] { new Point(120, 340), new Point(560, 340), new Point(560, 780), new Point(120, 780) }; BindingMechanismBase mech; mech = new RodMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[0], Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[1], Point.Empty); doc.Mechanisms.Add(mech); mech = new RopeMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[1], Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[2], Point.Empty); doc.Mechanisms.Add(mech); mech = new SpringMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[2], Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[0], Point.Empty); doc.Mechanisms.Add(mech); return(doc); }
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; } }
static MagicDocument CreateDocumentFixture() { MagicDocument doc = new MagicDocument(); RigidBodyBase body; body = new EllipticalBody(); body.strokeid = 1; doc.Bodies.Add(body); body = new EllipticalBody(); body.strokeid = 2; doc.Bodies.Add(body); body = new PolygonalBody(); body.strokeid = 3; doc.Bodies.Add(body); ((PolygonalBody)body).Vertices = new Point[] { new Point(120,340), new Point(560,340), new Point(560,780), new Point(120,780) }; BindingMechanismBase mech; mech = new RodMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[0],Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[1],Point.Empty); doc.Mechanisms.Add(mech); mech = new RopeMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[1],Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[2],Point.Empty); doc.Mechanisms.Add(mech); mech = new SpringMech(); mech.EndpointA = BodyRef.For((RigidBodyBase)doc.Bodies[2],Point.Empty); mech.EndpointB = BodyRef.For((RigidBodyBase)doc.Bodies[0],Point.Empty); doc.Mechanisms.Add(mech); return doc; }