-
Notifications
You must be signed in to change notification settings - Fork 83
/
GearsConfig.ts
149 lines (136 loc) · 5.37 KB
/
GearsConfig.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright 2016 Erik Neumann. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { ConcreteVertex } from '../../lab/engine2D/ConcreteVertex.js';
import { CoordType } from '../../lab/model/CoordType.js';
import { Polygon } from '../../lab/engine2D/Polygon.js';
import { RigidBody, Edge } from '../../lab/engine2D/RigidBody.js';
import { Shapes } from '../../lab/engine2D/Shapes.js';
import { Util } from '../../lab/util/Util.js';
import { Vector } from '../../lab/util/Vector.js';
/** Utility methods for making toothed gears, and setting forces on them.
**TO DO** add a DisplayObject for the turning force which is a big obvious arrow
*/
export class GearsConfig {
constructor() {
throw '';
};
/**
* @param radius
* @param startEdges adds to this array
* the starting edge of the gear
* @param opt_name name of the Polygon
* @param opt_localName localized name of the Polygon
*/
static makeGear(radius: number, startEdges: Edge[], opt_name?: string, opt_localName?: string): Polygon {
const p = new Polygon(opt_name, opt_localName);
GearsConfig.addGear(p, radius, 0.3, 36, 30, 30, startEdges);
p.finish();
p.setMomentAboutCM(radius*radius/2);
return p;
};
/** Adds a gear shape set of edges to the given Polygon.
The shape of a tooth is determined as follows. A tooth has 4 edges, which we call:
up-slope, out-edge, down-slope, and in-edge.
<pre>
___
/ \
/ \___
</pre>
Let the horizontal span be 100%, then each of the 4 tooth edges has a percentage. For
example in the above diagram, the percentages are roughly 25% each. The percentages
for the out-edge and in-edge are supplied as parameters. The remainder is split evenly
between the up-slope and down-slope.
@param p the Polygon to add the gear to
@param r1 the inside radius of the gear
@param depth the depth (or length) of the teeth
@param numTeeth number of teeth
@param outPercent the percentage of tooth that is extended (the out-edge)
@param inPercent the percentage of tooth that is not extended (the in-edge)
@param startEdges adds to this array the starting edge of the gear
*/
static addGear(p: Polygon, r1: number, depth: number, numTeeth: number, outPercent: number, inPercent: number, startEdges: Edge[]) {
// calculate the small angle fraction corresponding to each of the 4 tooth edges
const wholeTooth = 2 * Math.PI / numTeeth;
const upSlope = wholeTooth * (100.0 - outPercent - inPercent) / 200.0;
const downSlope = upSlope;
const outEdge = wholeTooth * outPercent/100.0;
const inEdge = wholeTooth * inPercent/100.0;
// the original inside and outside points are in_0 and out_0
const in_0 = new Vector(r1, 0);
const out_0 = new Vector(r1+depth, 0);
// The current inside & outside points are in and out.
// We rotate in_0 and out_0 to produce in and out.
let in1 = in_0;
p.startPath(new ConcreteVertex(new Vector(in1.getX(), in1.getY())));
for (let i=0; i<numTeeth; i++) {
const toothAngle = i * wholeTooth;
// the up-slope edge, from in1 to out1
const out1 = out_0.rotate(toothAngle + upSlope);
let outsideIsUp;
if (Math.abs(in1.getX() - out1.getX()) < 1e-3)
outsideIsUp = out1.getY() > in1.getY();
else
outsideIsUp = in1.getX() > out1.getX();
const e = p.addStraightEdge(out1, outsideIsUp);
if (i==0) {
startEdges.push(e);
}
// the out-edge, from out1 to out2
const out2 = out_0.rotate(toothAngle + upSlope + outEdge);
if (Math.abs(out2.getX() - out1.getX()) < 1e-3)
outsideIsUp = out2.getY() > out1.getY();
else
outsideIsUp = out2.getX() < out1.getX();
p.addStraightEdge(out2, outsideIsUp);
// the down-slope edge, from out2 to in2
const in2 = in_0.rotate(toothAngle + upSlope + outEdge + downSlope);
if (Math.abs(out2.getX() - in2.getX()) < 1e-3)
outsideIsUp = out2.getY() > in2.getY() ? false : true;
else
outsideIsUp = in2.getX() < out2.getX();
p.addStraightEdge(in2, outsideIsUp);
// the in-edge, from in2 to in1
in1 = in_0.rotate(toothAngle + wholeTooth);
if (Math.abs(in1.getX() - in2.getX()) < 1e-3)
outsideIsUp = in1.getY() > in2.getY();
else
outsideIsUp = in1.getX() < in2.getX();
p.addStraightEdge(in1, outsideIsUp);
}
p.closePath();
};
static readonly en: i18n_strings = {
LEFT_GEAR: 'left gear',
RIGHT_GEAR: 'right gear',
PINNED_GEARS: 'pinned gears',
TURNING_FORCE: 'turning force',
TWO_GEARS: 'two gears'
};
static readonly de_strings: i18n_strings = {
LEFT_GEAR: 'linkes Zahnrad',
RIGHT_GEAR: 'rechtes Zahnrad',
PINNED_GEARS: 'verstiftet Zahnräder',
TURNING_FORCE: 'drehende Kraft',
TWO_GEARS: 'zwei Zahnräder'
};
static readonly i18n = Util.LOCALE === 'de' ? GearsConfig.de_strings : GearsConfig.en;
} // end class
type i18n_strings = {
LEFT_GEAR: string,
RIGHT_GEAR: string,
PINNED_GEARS: string,
TURNING_FORCE: string,
TWO_GEARS: string
};
Util.defineGlobal('sims$engine2D$GearsConfig', GearsConfig);