1 /*
2 * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty.  In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 
19 #ifndef GEARS_H
20 #define GEARS_H
21 
22 class Gears : public Test
23 {
24 public:
Gears()25     Gears()
26     {
27         b2Body* ground = NULL;
28         {
29             b2BodyDef bd;
30             ground = m_world->CreateBody(&bd);
31 
32             b2EdgeShape shape;
33             shape.Set(b2Vec2(50.0f, 0.0f), b2Vec2(-50.0f, 0.0f));
34             ground->CreateFixture(&shape, 0.0f);
35         }
36 
37         // Gears co
38         {
39             b2CircleShape circle1;
40             circle1.m_radius = 1.0f;
41 
42             b2PolygonShape box;
43             box.SetAsBox(0.5f, 5.0f);
44 
45             b2CircleShape circle2;
46             circle2.m_radius = 2.0f;
47 
48             b2BodyDef bd1;
49             bd1.type = b2_staticBody;
50             bd1.position.Set(10.0f, 9.0f);
51             b2Body* body1 = m_world->CreateBody(&bd1);
52             body1->CreateFixture(&circle1, 0.0f);
53 
54             b2BodyDef bd2;
55             bd2.type = b2_dynamicBody;
56             bd2.position.Set(10.0f, 8.0f);
57             b2Body* body2 = m_world->CreateBody(&bd2);
58             body2->CreateFixture(&box, 5.0f);
59 
60             b2BodyDef bd3;
61             bd3.type = b2_dynamicBody;
62             bd3.position.Set(10.0f, 6.0f);
63             b2Body* body3 = m_world->CreateBody(&bd3);
64             body3->CreateFixture(&circle2, 5.0f);
65 
66             b2RevoluteJointDef jd1;
67             jd1.Initialize(body2, body1, bd1.position);
68             b2Joint* joint1 = m_world->CreateJoint(&jd1);
69 
70             b2RevoluteJointDef jd2;
71             jd2.Initialize(body2, body3, bd3.position);
72             b2Joint* joint2 = m_world->CreateJoint(&jd2);
73 
74             b2GearJointDef jd4;
75             jd4.bodyA = body1;
76             jd4.bodyB = body3;
77             jd4.joint1 = joint1;
78             jd4.joint2 = joint2;
79             jd4.ratio = circle2.m_radius / circle1.m_radius;
80             m_world->CreateJoint(&jd4);
81         }
82 
83         {
84             b2CircleShape circle1;
85             circle1.m_radius = 1.0f;
86 
87             b2CircleShape circle2;
88             circle2.m_radius = 2.0f;
89 
90             b2PolygonShape box;
91             box.SetAsBox(0.5f, 5.0f);
92 
93             b2BodyDef bd1;
94             bd1.type = b2_dynamicBody;
95             bd1.position.Set(-3.0f, 12.0f);
96             b2Body* body1 = m_world->CreateBody(&bd1);
97             body1->CreateFixture(&circle1, 5.0f);
98 
99             b2RevoluteJointDef jd1;
100             jd1.bodyA = ground;
101             jd1.bodyB = body1;
102             jd1.localAnchorA = ground->GetLocalPoint(bd1.position);
103             jd1.localAnchorB = body1->GetLocalPoint(bd1.position);
104             jd1.referenceAngle = body1->GetAngle() - ground->GetAngle();
105             m_joint1 = (b2RevoluteJoint*)m_world->CreateJoint(&jd1);
106 
107             b2BodyDef bd2;
108             bd2.type = b2_dynamicBody;
109             bd2.position.Set(0.0f, 12.0f);
110             b2Body* body2 = m_world->CreateBody(&bd2);
111             body2->CreateFixture(&circle2, 5.0f);
112 
113             b2RevoluteJointDef jd2;
114             jd2.Initialize(ground, body2, bd2.position);
115             m_joint2 = (b2RevoluteJoint*)m_world->CreateJoint(&jd2);
116 
117             b2BodyDef bd3;
118             bd3.type = b2_dynamicBody;
119             bd3.position.Set(2.5f, 12.0f);
120             b2Body* body3 = m_world->CreateBody(&bd3);
121             body3->CreateFixture(&box, 5.0f);
122 
123             b2PrismaticJointDef jd3;
124             jd3.Initialize(ground, body3, bd3.position, b2Vec2(0.0f, 1.0f));
125             jd3.lowerTranslation = -5.0f;
126             jd3.upperTranslation = 5.0f;
127             jd3.enableLimit = true;
128 
129             m_joint3 = (b2PrismaticJoint*)m_world->CreateJoint(&jd3);
130 
131             b2GearJointDef jd4;
132             jd4.bodyA = body1;
133             jd4.bodyB = body2;
134             jd4.joint1 = m_joint1;
135             jd4.joint2 = m_joint2;
136             jd4.ratio = circle2.m_radius / circle1.m_radius;
137             m_joint4 = (b2GearJoint*)m_world->CreateJoint(&jd4);
138 
139             b2GearJointDef jd5;
140             jd5.bodyA = body2;
141             jd5.bodyB = body3;
142             jd5.joint1 = m_joint2;
143             jd5.joint2 = m_joint3;
144             jd5.ratio = -1.0f / circle2.m_radius;
145             m_joint5 = (b2GearJoint*)m_world->CreateJoint(&jd5);
146         }
147     }
148 
Keyboard(unsigned char key)149     void Keyboard(unsigned char key)
150     {
151         switch (key)
152         {
153         case 0:
154             break;
155         }
156     }
157 
Step(Settings * settings)158     void Step(Settings* settings)
159     {
160         Test::Step(settings);
161 
162         float32 ratio, value;
163 
164         ratio = m_joint4->GetRatio();
165         value = m_joint1->GetJointAngle() + ratio * m_joint2->GetJointAngle();
166         m_debugDraw.DrawString(5, m_textLine, "theta1 + %4.2f * theta2 = %4.2f", (float) ratio, (float) value);
167         m_textLine += 15;
168 
169         ratio = m_joint5->GetRatio();
170         value = m_joint2->GetJointAngle() + ratio * m_joint3->GetJointTranslation();
171         m_debugDraw.DrawString(5, m_textLine, "theta2 + %4.2f * delta = %4.2f", (float) ratio, (float) value);
172         m_textLine += 15;
173     }
174 
Create()175     static Test* Create()
176     {
177         return new Gears;
178     }
179 
180     b2RevoluteJoint* m_joint1;
181     b2RevoluteJoint* m_joint2;
182     b2PrismaticJoint* m_joint3;
183     b2GearJoint* m_joint4;
184     b2GearJoint* m_joint5;
185 };
186 
187 #endif
188