Constraint.cs 10.8 KB
Newer Older
BlackAngle233's avatar
BlackAngle233 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum ConstraintType
{
    LineLength,
    LineEqual,
    LineNormal,
    LineNormalPlane,
    LineParallel,
    LineParallelPlane,
    LineCross,
    MidPoint,
    PointOnLine,
    PointInPlane,
    AngleEqual,
    PlaneParallelPlane,
BlackAngle233's avatar
5.31    
BlackAngle233 committed
19
20
    PlaneNormalPlane,
    PlaneArea
BlackAngle233's avatar
BlackAngle233 committed
21
22
23
24
25
26
}
public class Constraint
{
    public object Object1;
    public object Object2;

BlackAngle233's avatar
212    
BlackAngle233 committed
27
28
    public string name;

BlackAngle233's avatar
BlackAngle233 committed
29
30
31
32
33
34
35
36
37
38
    State state = State.unknown;

    ConstraintType constraintType;

    public Constraint(ConstraintType type, object obj1, object obj2)
    {
        Object1 = obj1;
        Object2 = obj2;
        constraintType = type;

BlackAngle233's avatar
5.31    
BlackAngle233 committed
39
        Point p = null;
BlackAngle233's avatar
BlackAngle233 committed
40
41
        Line l1 = null;
        Line l2 = null;
BlackAngle233's avatar
5.31    
BlackAngle233 committed
42
43
        Plane p1 = null;
        Plane p2 = null;
BlackAngle233's avatar
BlackAngle233 committed
44
45
        float length = 0;

BlackAngle233's avatar
BlackAngle233 committed
46
47
48
        switch (type)
        {
            case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
49
50
                l1 = (Line)obj1;
                length = (float)obj2;
BlackAngle233's avatar
BlackAngle233 committed
51

BlackAngle233's avatar
BlackAngle233 committed
52
53
                l1.setConstraint(this);
                name = l1.name + "=" + length.ToString();
BlackAngle233's avatar
BlackAngle233 committed
54
55
                break;
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
56
57
                l1 = (Line)obj1;
                l2 = (Line)obj2;
BlackAngle233's avatar
BlackAngle233 committed
58
59
60

                l1.setConstraint(this);
                l2.setConstraint(this);
BlackAngle233's avatar
212    
BlackAngle233 committed
61
                name = l1.name + "=" + l2.name;
BlackAngle233's avatar
BlackAngle233 committed
62
                break;
BlackAngle233's avatar
BlackAngle233 committed
63
64
65
66
67
68
69
70
            case ConstraintType.LineNormal:
                l1 = (Line)obj1;
                l2 = (Line)obj2;

                l1.setConstraint(this);
                l2.setConstraint(this);
                name = l1.name + "⊥" + l2.name;
                break;
BlackAngle233's avatar
5.31    
BlackAngle233 committed
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
            case ConstraintType.LineParallel:
                l1 = (Line)obj1;
                l2 = (Line)obj2;

                l1.setConstraint(this);
                l2.setConstraint(this);
                name = l1.name + "∥" + l2.name;
                break;
            case ConstraintType.LineParallelPlane:
                l1 = (Line)obj1;
                p1 = (Plane)obj2;

                l1.setConstraint(this);
                //p1.setConstraint(this);
                name = l1.name + "∥" + p1.name;
                break;
            case ConstraintType.LineCross:
                l1 = (Line)obj1;
                l2 = (Line)obj2;

                l1.setConstraint(this);
                l2.setConstraint(this);
                name = l1.name + "∩" + l2.name;
                break;
            case ConstraintType.MidPoint:
                l1 = (Line)obj1;
                p = (Point)obj2;

                l1.setConstraint(this);
                //p.setConstraint(this);
                name = l1.name + "中点" + p.name;
                break;
            case ConstraintType.PointOnLine:
                break;
            case ConstraintType.PointInPlane:
                break;
            case ConstraintType.AngleEqual:
                break;
            case ConstraintType.PlaneParallelPlane:
                p1 = (Plane)obj1;
                p2 = (Plane)obj2;

                //p1.setConstraint(this);
                //p2.setConstraint(this);
                name = p1.name + "∥" + p2.name;
                break;
            case ConstraintType.PlaneNormalPlane:
                p1 = (Plane)obj1;
                p2 = (Plane)obj2;

                //p1.setConstraint(this);
                //p2.setConstraint(this);
                name = p1.name + "⊥" + p2.name;
                break;
            case ConstraintType.PlaneArea:
                break;
BlackAngle233's avatar
BlackAngle233 committed
127
128
129
130
131
132
        }
    }

    public float getConstraintValue()
    {
        float result = 0;
BlackAngle233's avatar
BlackAngle233 committed
133
134
135
136
137
138

        Line l1 = null;
        Line l2 = null;

        float length = 0;

BlackAngle233's avatar
BlackAngle233 committed
139
140
141
        switch (constraintType)
        {
             case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
142
143
                l1 = (Line)Object1;
                length = (float)Object2;
BlackAngle233's avatar
BlackAngle233 committed
144

BlackAngle233's avatar
BlackAngle233 committed
145
                result = l1.getLength() - length;
BlackAngle233's avatar
BlackAngle233 committed
146
147
                break;
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
148
149
                l1 = (Line)Object1;
                l2 = (Line)Object2;
BlackAngle233's avatar
BlackAngle233 committed
150
151
152
153
154
155
156
157
158
159
                
                if (l1.lineState > l2.lineState)
                {
                    result = l1.getLength() - l2.getLength();
                }
                else
                {
                    result = l2.getLength() - l1.getLength();
                }
                break;
BlackAngle233's avatar
BlackAngle233 committed
160
161
162
163
164
165
            case ConstraintType.LineNormal:
                l1 = (Line)Object1;
                l2 = (Line)Object2;
                
                result = Vector3.Dot(l1.direction, l2.direction);
                break;
BlackAngle233's avatar
BlackAngle233 committed
166
167
168
169
170
171
172
        }

        return result;
    }

    public Gradient getGradient()
    {
BlackAngle233's avatar
BlackAngle233 committed
173
174
175
176
177
        Line l1 = null;
        Line l2 = null;

        float length = 0;

BlackAngle233's avatar
BlackAngle233 committed
178
179
180
        switch (constraintType)
        {
            case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
181
182
                l1 = (Line)Object1;
                length = (float)Object2;
BlackAngle233's avatar
BlackAngle233 committed
183

BlackAngle233's avatar
BlackAngle233 committed
184
                return l1.getGradient();
BlackAngle233's avatar
BlackAngle233 committed
185
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
186
187
                l1 = (Line)Object1;
                l2 = (Line)Object2;
BlackAngle233's avatar
BlackAngle233 committed
188
189
190
191
192
193
194
195
                if(l1.lineState > l2.lineState)
                {
                    return l1.getGradient();
                }
                else
                {
                    return l2.getGradient();
                }
BlackAngle233's avatar
BlackAngle233 committed
196
197
198
199
200
201
202
203
204
205
206
            case ConstraintType.LineNormal:
                l1 = (Line)Object1;
                l2 = (Line)Object2;
                if(l1.lineState > l2.lineState)
                {
                    return new Gradient(l2.getUnknownPoint() ,l1.direction);
                }
                else
                {
                    return new Gradient(l1.getUnknownPoint() ,l2.direction);
                }
BlackAngle233's avatar
BlackAngle233 committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
        }
        return null;
    }

    public void setState(State s)
    {
        state = s;
    }

    public State getState()
    {
        return state;
    }

    public void checkState()
    {
BlackAngle233's avatar
BlackAngle233 committed
223
224
225
226
227
        Line l1 = null;
        Line l2 = null;

        float length = 0;

BlackAngle233's avatar
BlackAngle233 committed
228
229
230
        switch (constraintType)
        {
            case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
231
232
                l1 = (Line)Object1;
                length = (float)Object2;
BlackAngle233's avatar
BlackAngle233 committed
233
                
BlackAngle233's avatar
BlackAngle233 committed
234
                setState(l1.lineState);
BlackAngle233's avatar
BlackAngle233 committed
235
236
                break;
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
237
238
239
            case ConstraintType.LineNormal:
                l1 = (Line)Object1;
                l2 = (Line)Object2;
BlackAngle233's avatar
BlackAngle233 committed
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
                
                if(l1.lineState == State.confirm && l2.lineState == State.confirm)
                {
                    setState(State.confirm);
                } 
                else if((l1.lineState == State.confirm && l2.lineState == State.halfconfirm) || (l2.lineState == State.confirm && l1.lineState == State.halfconfirm))
                {
                    setState(State.halfconfirm);
                }
                else
                {
                    setState(State.unknown);
                }
                break;
        }
    }

    public void calculateConstraint(Point target)
    {
BlackAngle233's avatar
BlackAngle233 committed
259
        Vector3 normal;
BlackAngle233's avatar
BlackAngle233 committed
260
261
262
        Vector3 direction;
        Point tmp;

BlackAngle233's avatar
BlackAngle233 committed
263
264
265
266
267
268
269
        Line l1 = null;
        Line l2 = null;

        float length = 0;
        float cos = 0;
        float sin = 0;

BlackAngle233's avatar
BlackAngle233 committed
270
271
272
        switch (constraintType)
        {
            case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
273
274
                l1 = (Line)Object1;
                length = (float)Object2;
BlackAngle233's avatar
BlackAngle233 committed
275

BlackAngle233's avatar
BlackAngle233 committed
276
                tmp = l1.getAnotherPoint(target);
BlackAngle233's avatar
BlackAngle233 committed
277
                
BlackAngle233's avatar
BlackAngle233 committed
278
                direction = l1.getDirection(target);
BlackAngle233's avatar
BlackAngle233 committed
279
280
281
282
283
                target.setPoint(tmp.add(direction * length));

                target.setState(State.confirm);
                break;
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
284
285
                l1 = (Line)Object1;
                l2 = (Line)Object2;
BlackAngle233's avatar
BlackAngle233 committed
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301

                if(l1.lineState == State.confirm)
                {
                    tmp = l2.getAnotherPoint(target);

                    direction = l2.getDirection(target);
                    target.setPoint(tmp.add(direction * l1.getLength()));
                }
                else if(l2.lineState == State.confirm)
                {
                    tmp = l1.getAnotherPoint(target);

                    direction = l1.getDirection(target);
                    target.setPoint(tmp.add(direction * l2.getLength()));
                }

BlackAngle233's avatar
BlackAngle233 committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
                target.setState(State.confirm);
                break;
            case ConstraintType.LineNormal:
                l1 = (Line)Object1;
                l2 = (Line)Object2;

                if(l1.lineState == State.confirm)
                {
                    normal = l1.direction.normalized;

                    tmp = l2.getAnotherPoint(target);
                    direction = new Vector3(target.x - tmp.x, target.y - tmp.y, target.z - tmp.z);

                    sin = Vector3.Dot(l1.getVector3(), l2.getVector3()) / l1.getLength() / l2.getLength();
                    cos = Mathf.Sqrt(1 - cos * cos);

                    direction = direction * cos + Vector3.Cross(normal, direction) * sin + normal * Vector3.Dot(normal, direction) * (1 - cos);

                    target.setPoint(direction.x - tmp.x, direction.y - tmp.y, direction.z - tmp.z);
                }
                else if(l2.lineState == State.confirm)
                {
                    normal = l2.direction.normalized;

                    tmp = l1.getAnotherPoint(target);
                    direction = new Vector3(target.x - tmp.x, target.y - tmp.y, target.z - tmp.z);

                    sin = Vector3.Dot(l2.getVector3(), l1.getVector3()) / l2.getLength() / l1.getLength();
                    cos = Mathf.Sqrt(1 - cos * cos);

                    direction = direction * cos + Vector3.Cross(normal, direction) * sin + normal * Vector3.Dot(normal, direction) * (1 - cos);

                    target.setPoint(direction.x - tmp.x, direction.y - tmp.y, direction.z - tmp.z);
                }

BlackAngle233's avatar
BlackAngle233 committed
337
338
339
340
341
342
343
344
345
346
                target.setState(State.confirm);
                break;
        }
    }

    public void tryCalculateConstraint(Point target)
    {
        Gradient tmp;
        float value = 0;

BlackAngle233's avatar
BlackAngle233 committed
347
348
349
350
351
        Line l1 = null;
        Line l2 = null;

        float length = 0;

BlackAngle233's avatar
BlackAngle233 committed
352
353
354
        switch (constraintType)
        {
            case ConstraintType.LineLength:
BlackAngle233's avatar
BlackAngle233 committed
355
356
                l1 = (Line)Object1;
                length = (float)Object2;
BlackAngle233's avatar
BlackAngle233 committed
357
358
359
360
361
362
363
364

                tmp = getGradient();
                value = getConstraintValue();

                target += tmp.calculateGradient(value);

                break;
            case ConstraintType.LineEqual:
BlackAngle233's avatar
BlackAngle233 committed
365
366
                l1 = (Line)Object1;
                l2 = (Line)Object2;
BlackAngle233's avatar
BlackAngle233 committed
367
368
369
370
371
372
373

                tmp = getGradient();
                value = getConstraintValue();

                target += tmp.calculateGradient(value);

                break;
BlackAngle233's avatar
BlackAngle233 committed
374
375
376
377
378
379
380
381
382
383
384
            case ConstraintType.LineNormal:
                l1 = (Line)Object1;
                l2 = (Line)Object2;

                tmp = getGradient();
                value = getConstraintValue();

                target += tmp.calculateGradient(value);

                break;

BlackAngle233's avatar
BlackAngle233 committed
385
386
387
        }
    }
}