1 | /************************************************************************
|
---|
2 |
|
---|
3 | 2D Quadric Error Metric
|
---|
4 |
|
---|
5 | Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details.
|
---|
6 |
|
---|
7 | $Id: MxQMetric2.cxx,v 1.1 2002/09/24 16:53:54 wimmer Exp $
|
---|
8 |
|
---|
9 | ************************************************************************/
|
---|
10 |
|
---|
11 | #include "stdmix.h"
|
---|
12 | #include "MxQMetric2.h"
|
---|
13 |
|
---|
14 |
|
---|
15 | void MxQuadric2::init(double a, double b, double c, double len)
|
---|
16 | {
|
---|
17 | a2 = a*a; ab = a*b; ac = a*c;
|
---|
18 | b2 = b*b; bc = b*c;
|
---|
19 | c2 = c*c;
|
---|
20 |
|
---|
21 | r = len;
|
---|
22 | }
|
---|
23 |
|
---|
24 | Mat2 MxQuadric2::tensor() const
|
---|
25 | {
|
---|
26 | return Mat2(a2, ab, ab, b2);
|
---|
27 | }
|
---|
28 |
|
---|
29 | Mat3 MxQuadric2::homogeneous() const
|
---|
30 | {
|
---|
31 | return Mat3(Vec3(a2, ab, ac),
|
---|
32 | Vec3(ab, b2, bc),
|
---|
33 | Vec3(ac, bc, c2));
|
---|
34 | }
|
---|
35 |
|
---|
36 | MxQuadric2& MxQuadric2::operator=(const MxQuadric2& Q)
|
---|
37 | {
|
---|
38 | r = Q.r;
|
---|
39 |
|
---|
40 | a2 = Q.a2; ab = Q.ab; ac = Q.ac;
|
---|
41 | b2 = Q.b2; bc = Q.bc;
|
---|
42 | c2 = Q.c2;
|
---|
43 |
|
---|
44 | return *this;
|
---|
45 | }
|
---|
46 |
|
---|
47 | MxQuadric2& MxQuadric2::operator+=(const MxQuadric2& Q)
|
---|
48 | {
|
---|
49 | r += Q.r;
|
---|
50 |
|
---|
51 | a2 += Q.a2; ab += Q.ab; ac += Q.ac;
|
---|
52 | b2 += Q.b2; bc += Q.bc;
|
---|
53 | c2 += Q.c2;
|
---|
54 |
|
---|
55 | return *this;
|
---|
56 | }
|
---|
57 |
|
---|
58 | MxQuadric2& MxQuadric2::operator-=(const MxQuadric2& Q)
|
---|
59 | {
|
---|
60 | r -= Q.r;
|
---|
61 |
|
---|
62 | a2 -= Q.a2; ab -= Q.ab; ac -= Q.ac;
|
---|
63 | b2 -= Q.b2; bc -= Q.bc;
|
---|
64 | c2 -= Q.c2;
|
---|
65 |
|
---|
66 | return *this;
|
---|
67 | }
|
---|
68 |
|
---|
69 | MxQuadric2& MxQuadric2::operator*=(double s)
|
---|
70 | {
|
---|
71 | // Don't scale area
|
---|
72 |
|
---|
73 | a2 *= s; ab *= s; ac *= s;
|
---|
74 | b2 *= s; bc *= s;
|
---|
75 | c2 *= s;
|
---|
76 |
|
---|
77 | return *this;
|
---|
78 | }
|
---|
79 |
|
---|
80 | double MxQuadric2::evaluate(double x, double y) const
|
---|
81 | {
|
---|
82 | // Evaluate vAv + 2bv + c
|
---|
83 |
|
---|
84 | return x*x*a2 + 2*x*y*ab + 2*x*ac
|
---|
85 | + y*y*b2 + 2*y*bc
|
---|
86 | + c2;
|
---|
87 | }
|
---|
88 |
|
---|
89 | bool MxQuadric2::optimize(Vec2& v) const
|
---|
90 | {
|
---|
91 | Mat2 Ainv;
|
---|
92 | double det = tensor().invert(Ainv);
|
---|
93 | if( FEQ(det, 0.0, 1e-12) )
|
---|
94 | return false;
|
---|
95 |
|
---|
96 | v = -(Ainv*vector());
|
---|
97 |
|
---|
98 | return true;
|
---|
99 | }
|
---|
100 |
|
---|
101 | bool MxQuadric2::optimize(float *x, float *y) const
|
---|
102 | {
|
---|
103 | Vec2 v;
|
---|
104 |
|
---|
105 | bool success = optimize(v);
|
---|
106 | if( success )
|
---|
107 | {
|
---|
108 | *x = (float)v[X];
|
---|
109 | *y = (float)v[Y];
|
---|
110 | }
|
---|
111 | return success;
|
---|
112 | }
|
---|