Пример #1
0
        // In perspective mode, the warping functions are:
        //	x' = (a0 + a1 x + a2 y) / (c0 x + c1 y + 1)
        //	y' = (b0 + b1 x + b2 y) / (c0 x + c1 y + 1)
        //
        // The following calculates the factors a#, b# and c#.
        // We do this by creating a set of eight equations with a#, b# and c# as unknowns.
        // The equations are derived by:
        // 1. substituting the srcPoints for (x, y);
        // 2. substituting the corresponding destPoints for (x', y');
        // 3. solving the resulting set of equations, with the factors as unknowns.
        //
        // The equations are like these:
        //	a0	x a1	y a2	0		0		0		-xx'c0	-yx'c1	= x'
        //	0	0		0		b0		x b1	y b2	-xy'c0	-yy'c1  = y'
        // The known factors of left hand side ar put in the 8x8 matrix mxLeft for
        // all four point pairs, and the right hand side in the one column matrix mxRight.
        // After solving, m_mxWarpFactors contains a0, a1, a2, b0, b1, b2, c0, c1.
        private void PreCalc(PointD[] destPoints, PointD[] srcPoints)
        {
            var mxLeft  = new GeneralMatrix(8, 8);            //mxLeft.Null();
            var mxRight = new GeneralMatrix(8, 1);

            var row = 0;

            for (int i = 0; i < 4; i++)
            {
                mxLeft.Array[row][0] = 1.0;
                mxLeft.Array[row][1] = srcPoints[i].X;
                mxLeft.Array[row][2] = srcPoints[i].Y;

                mxLeft.Array[row][6] = -srcPoints[i].X * destPoints[i].X;
                mxLeft.Array[row][7] = -srcPoints[i].Y * destPoints[i].X;

                mxRight.Array[row][0] = destPoints[i].X;

                row++;

                mxLeft.Array[row][3] = 1.0f;
                mxLeft.Array[row][4] = srcPoints[i].X;
                mxLeft.Array[row][5] = srcPoints[i].Y;

                mxLeft.Array[row][6] = -srcPoints[i].X * destPoints[i].Y;
                mxLeft.Array[row][7] = -srcPoints[i].Y * destPoints[i].Y;

                mxRight.Array[row][0] = destPoints[i].Y;

                row++;
            }

            _mxWarpFactors = mxLeft.Solve(mxRight);
        }
Пример #2
0
        public void SolveLinear()
        {
            double[][]    subavals   = { new double[] { 5.0, 8.0, 11.0 }, new double[] { 6.0, 9.0, 12.0 } };
            double[][]    sqSolution = { new double[] { 13.0 }, new double[] { 15.0 } };
            GeneralMatrix sub        = new GeneralMatrix(subavals);
            GeneralMatrix o          = new GeneralMatrix(sub.RowDimension, 1, 1.0);
            GeneralMatrix sol        = new GeneralMatrix(sqSolution);
            GeneralMatrix sq         = sub.GetMatrix(0, sub.RowDimension - 1, 0, sub.RowDimension - 1);

            Assert.IsTrue(GeneralTests.Check(sq.Solve(sol), o));
        }
Пример #3
0
        // In bilinear mode, the warping functions are:
        //	x' = a0 + a1 x y + a2 x + a3 y
        //	y' = b0 + b1 x y + b2 x + b3 y
        //
        // Here, we have two sets of four equations. In the first set, the a# factors
        // are the unknowns, in the second set the b# factors.
        // The equations are of the form:
        //	a0		+ xy a1		+ x a2		+ y a3	= x'
        // The left hand side is identical for both sets. The right hand side differs.
        // Therefore, we can solve them in one operation.
        // The left hand side factors are put in the 4x4 matrix mxLeft, the right side
        // factors are put in the 4x2 matrix mxRight.
        // After solving, the first column of m_mxWarpFactors contains a0, a1, a2, a3; the
        // second columne contains b0, b1, b2, b3.
        private void PreCalc(PointD[] destPoints, PointD[] srcPoints)
        {
            var mxLeft  = new GeneralMatrix(4, 4);
            var mxRight = new GeneralMatrix(4, 2);

            for (int row = 0; row < 4; row++)
            {
                mxLeft.Array[row][0] = 1.0;
                mxLeft.Array[row][1] = srcPoints[row].X * srcPoints[row].Y;
                mxLeft.Array[row][2] = srcPoints[row].X;
                mxLeft.Array[row][3] = srcPoints[row].Y;

                mxRight.Array[row][0] = destPoints[row].X;
                mxRight.Array[row][1] = destPoints[row].Y;
            }

            _mxWarpFactors = mxLeft.Solve(mxRight);
        }
Пример #4
0
        public void TestSolve()
        {
            GeneralMatrix _ls = new GeneralMatrix(2, 2);

            _ls.SetElement(0, 0, 1);
            _ls.SetElement(0, 1, 2);
            _ls.SetElement(1, 0, 3);
            _ls.SetElement(1, 1, 4);

            GeneralMatrix _rs = new GeneralMatrix(2, 1);

            _rs.SetElement(0, 0, -3);
            _rs.SetElement(1, 0, -5);

            GeneralMatrix _solution = _ls.Solve(_rs);

            Assert.AreEqual(_solution.GetElement(0, 0), 1);
            Assert.AreEqual(_solution.GetElement(1, 0), -2);
        }
Пример #5
0
        private void computeaccCalButton_Click(object sender, EventArgs e)
        {
            int i, j;

            calStatusText.Text = "Computing Calibration...";

            // Construct D matrix
            // D = [x.^2, y.^2, z.^2, x.*y, x.*z, y.*z, x, y, z, ones(N,1)];
            for (i = 0; i < SAMPLES; i++)
            {
                // x^2 term
                D.SetElement(i, 0, loggedData[i, 0] * loggedData[i, 0]);

                // y^2 term
                D.SetElement(i, 1, loggedData[i, 1] * loggedData[i, 1]);

                // z^2 term
                D.SetElement(i, 2, loggedData[i, 2] * loggedData[i, 2]);

                // x*y term
                D.SetElement(i, 3, loggedData[i, 0] * loggedData[i, 1]);

                // x*z term
                D.SetElement(i, 4, loggedData[i, 0] * loggedData[i, 2]);

                // y*z term
                D.SetElement(i, 5, loggedData[i, 1] * loggedData[i, 2]);

                // x term
                D.SetElement(i, 6, loggedData[i, 0]);

                // y term
                D.SetElement(i, 7, loggedData[i, 1]);

                // z term
                D.SetElement(i, 8, loggedData[i, 2]);

                // Constant term
                D.SetElement(i, 9, 1);
            }

            // QR=triu(qr(D))
            QRDecomposition QR = new QRDecomposition(D);
            // [U,S,V] = svd(D)
            SingularValueDecomposition SVD = new SingularValueDecomposition(QR.R);
            GeneralMatrix V = SVD.GetV();

            GeneralMatrix A = new GeneralMatrix(3, 3);

            double[] p = new double[V.RowDimension];

            for (i = 0; i < V.RowDimension; i++)
            {
                p[i] = V.GetElement(i, V.ColumnDimension - 1);
            }

            /*
             * A = [p(1) p(4)/2 p(5)/2;
             * p(4)/2 p(2) p(6)/2;
             * p(5)/2 p(6)/2 p(3)];
             */

            if (p[0] < 0)
            {
                for (i = 0; i < V.RowDimension; i++)
                {
                    p[i] = -p[i];
                }
            }

            A.SetElement(0, 0, p[0]);
            A.SetElement(0, 1, p[3] / 2);
            A.SetElement(1, 2, p[4] / 2);

            A.SetElement(1, 0, p[3] / 2);
            A.SetElement(1, 1, p[1]);
            A.SetElement(1, 2, p[5] / 2);

            A.SetElement(2, 0, p[4] / 2);
            A.SetElement(2, 1, p[5] / 2);
            A.SetElement(2, 2, p[2]);

            CholeskyDecomposition Chol = new CholeskyDecomposition(A);
            GeneralMatrix         Ut   = Chol.GetL();
            GeneralMatrix         U    = Ut.Transpose();

            double[]      bvect = { p[6] / 2, p[7] / 2, p[8] / 2 };
            double        d     = p[9];
            GeneralMatrix b     = new GeneralMatrix(bvect, 3);

            GeneralMatrix v = Ut.Solve(b);

            double vnorm_sqrd = v.GetElement(0, 0) * v.GetElement(0, 0) + v.GetElement(1, 0) * v.GetElement(1, 0) + v.GetElement(2, 0) * v.GetElement(2, 0);
            double s          = 1 / Math.Sqrt(vnorm_sqrd - d);

            GeneralMatrix c = U.Solve(v);

            for (i = 0; i < 3; i++)
            {
                c.SetElement(i, 0, -c.GetElement(i, 0));
            }

            U = U.Multiply(s);

            for (i = 0; i < 3; i++)
            {
                for (j = 0; j < 3; j++)
                {
                    calMat[i, j] = U.GetElement(i, j);
                }
            }

            for (i = 0; i < 3; i++)
            {
                bias[i] = c.GetElement(i, 0);
            }

            accAlignment00.Text = calMat[0, 0].ToString();
            accAlignment01.Text = calMat[0, 1].ToString();
            accAlignment02.Text = calMat[0, 2].ToString();

            accAlignment10.Text = calMat[1, 0].ToString();
            accAlignment11.Text = calMat[1, 1].ToString();
            accAlignment12.Text = calMat[1, 2].ToString();

            accAlignment20.Text = calMat[2, 0].ToString();
            accAlignment21.Text = calMat[2, 1].ToString();
            accAlignment22.Text = calMat[2, 2].ToString();

            biasX.Text = bias[0].ToString();
            biasY.Text = bias[1].ToString();
            biasZ.Text = bias[2].ToString();

            calStatusText.Text               = "Done";
            flashCommitButton.Enabled        = true;
            accAlignmentCommitButton.Enabled = true;
        }
Пример #6
0
        internal void FillInFendu(SaveFileDialog saveFileDialog1)
        {
            bool    docopen = false;
            Input   askdlg  = new Input();
            decimal t_start;
            decimal t_end;

            Dictionary <Decimal, Decimal> points = new Dictionary <Decimal, Decimal>();

            /*points[-55] = 78.2953M;
             * points[-40] = 84.2496M;
             * points[-20] = 92.1416M;
             * points[0] = 99.9841M;
             * points[50] = 119.4089M;
             * points[100] = 138.5204M;
             * points[125] = 147.9672M;
             */
            #region input

            askdlg.Message = "请输入铂电阻的出厂编号";
            if (askdlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }


            string ccbh   = askdlg.result;
            string ibcid  = "";
            string pageid = "";
            //search the corresponding page id and ibc ids
            for (int ibc = 0; ibc < 12; ibc++)
            {
                pageid = "abcdef"[ibc / 4].ToString();
                if (!IsValueAvailable(new string[] { "m_" + (ibc + 1).ToString() + "_ccbh" }))
                {
                    continue;
                }
                if (StrValue("m_" + (ibc + 1).ToString() + "_ccbh") == ccbh)
                {
                    ibcid = (ibc + 1).ToString();
                    for (int iwd = 1; iwd <= 3; iwd++)
                    {
                        if (!IsValueAvailable(new string[] { "m_" + pageid + "_" + iwd.ToString() + "jddwd",
                                                             "c_" + (ibc + 1).ToString() + "_" + iwd.ToString() + "bc" }))
                        {
                            continue;
                        }
                        string wdd = StrValue("m_" + pageid + "_" + iwd.ToString() + "jddwd").Trim();

                        if (wdd == "")
                        {
                            continue;
                        }
                        string sjz = FormatValue(data_record.Property("c_" + (ibc + 1).ToString() + "_" + iwd.ToString() + "sjzbc"), false);
                        points[Decimal.Parse(wdd)] = Decimal.Parse(sjz);
                    }
                }
            }
            if (points.Count <= 0)
            {
                MessageBox.Show("未找到出厂编号为" + ccbh + "的铂电阻,请检查后再试");
                return;
            }
            #endregion
            double r0 = 999;
            if (points.ContainsKey(0))
            {
                r0 = Convert.ToDouble(points[0]);
            }
            else
            {
                MessageBox.Show("未发现0℃温度点实际值,无法计算分度表");
                return;
            }
            double[][] mn = new double[3][];
            double[]   yn = new double[3];
            decimal    ptn1, ptn2, ptn3;
            ptn1  = 1000;
            ptn2  = 0;
            ptn3  = -1000;
            mn[0] = new double[3];
            mn[1] = new double[3];
            mn[2] = new double[3];

            decimal ptp1, ptp2;
            ptp1 = 1000;
            ptp2 = -1000;
            double[][] mp = new double[2][];
            mp[0] = new double[2];
            mp[1] = new double[2];

            double[] yp = new double[2];

            //count points for range
            int np = 0;
            int nn = 0;
            foreach (Decimal d in points.Keys)
            {
                double dv;
                if ((d < 0) && (d >= -200))
                {
                    if (d < ptn1)
                    {
                        ptn2 = ptn1;
                        ptn1 = d;
                    }
                    if (d > ptn3)
                    {
                        ptn2 = ptn3;
                        ptn3 = d;
                    }
                    if (points.ContainsKey(ptn1))
                    {
                        dv       = Convert.ToDouble(ptn1);
                        mn[0][0] = dv; mn[0][1] = dv * dv; mn[0][2] = (dv - 100) * dv * dv * dv;
                        yn[0]    = Convert.ToDouble(points[ptn1]) / r0 - 1;
                    }
                    if (points.ContainsKey(ptn2))
                    {
                        dv       = Convert.ToDouble(ptn2);
                        mn[1][0] = dv; mn[1][1] = dv * dv; mn[1][2] = (dv - 100) * dv * dv * dv;
                        yn[1]    = Convert.ToDouble(points[ptn2]) / r0 - 1;
                    }
                    if (points.ContainsKey(ptn3))
                    {
                        dv       = Convert.ToDouble(ptn3);
                        mn[2][0] = dv; mn[2][1] = dv * dv; mn[2][2] = (dv - 100) * dv * dv * dv;
                        yn[2]    = Convert.ToDouble(points[ptn3]) / r0 - 1;
                    }

                    nn++;
                }
                if ((d > 0) && (d <= 850))
                {
                    if (d < ptp1)
                    {
                        ptp1     = d;
                        dv       = Convert.ToDouble(ptp1);
                        mp[0][0] = dv; mp[0][1] = dv * dv;
                        yp[0]    = Convert.ToDouble(points[ptp1]) / r0 - 1;
                    }
                    if (d > ptp2)
                    {
                        ptp2     = d;
                        dv       = Convert.ToDouble(ptp2);
                        mp[1][0] = dv; mp[1][1] = dv * dv;
                        yp[1]    = Convert.ToDouble(points[ptp2]) / r0 - 1;
                    }
                    np++;
                }
            }
            if (ptn1 > 0)
            {
                ptn1 = 0;
            }
            if (ptp2 < 0)
            {
                ptp2 = 0;
            }

            askdlg.Message = "请输入分度表起始温度";
            if (askdlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            if (!Decimal.TryParse(askdlg.result, out t_start) || (t_start < ptn1))
            {
                MessageBox.Show("无效的起始温度,分度表不能外插");
                return;
            }

            askdlg.Message = "请输入分度表结束温度";
            if (askdlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            if (!Decimal.TryParse(askdlg.result, out t_end) || (t_end > ptp2))
            {
                MessageBox.Show("无效的结束温度,分度表不能外插");
                return;
            }

            Decimal s = t_start;
            Decimal e = t_end;

            if ((s < 0) && (nn < 3))
            {
                MessageBox.Show("检定点不足。-200℃ ~ 0 ℃的分度表计算至少有需要3个检定点.");
                return;
            }
            if ((e > 0) && (np < 2))
            {
                MessageBox.Show("检定点不足。0℃ ~ 850 ℃的分度表计算至少有需要2个检定点.");
                return;
            }

            double[]      xn = new double[3]; //A,B,C
            double[]      xp = new double[2]; //A,B
            GeneralMatrix gxn;
            GeneralMatrix gxp;
            if (nn >= 3)
            {
                GeneralMatrix gm = new GeneralMatrix(mn);
                gxn   = gm.Solve(new GeneralMatrix(yn, yn.Length));
                xn[0] = gxn.GetElement(0, 0);
                xn[1] = gxn.GetElement(1, 0);
                xn[2] = gxn.GetElement(2, 0);
            }
            if (np >= 2)
            {
                GeneralMatrix gm = new GeneralMatrix(mp);
                gxp   = gm.Solve(new GeneralMatrix(yp, yp.Length));
                xp[0] = gxp.GetElement(0, 0);
                xp[1] = gxp.GetElement(1, 0);
            }

            List <string> rows = new List <string>();
            while (s <= e)
            {
                double sv = Convert.ToDouble(s);
                if (s < 0)
                {
                    rows.Add(String.Format("{0}\t{1:F4}", s.ToString(), r0 * (1 + xn[0] * sv + xn[1] * sv * sv + xn[2] * (sv - 100) * sv * sv * sv)));
                }
                else
                {
                    rows.Add(String.Format("{0}\t{1:F4}", s.ToString(), r0 * (1 + xp[0] * sv + xp[1] * sv * sv)));
                }
                s = s + 1;
            }
            saveFileDialog1.DefaultExt = ".doc";
            saveFileDialog1.Filter     = "DOC File(*.doc)|*.doc|All Files(*.*)|*.*";


            saveFileDialog1.FileName = DateTime.Now.ToString("yyyy-MM-dd") + "分度表证书.doc";
            if (saveFileDialog1.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            string tofile = saveFileDialog1.FileName;

            try
            {
                string tmpl = "分度表";
                string src  = Path.Combine(Util.basedir, "报告模板\\" + tmpl + ".doc");
                File.Copy(src, tofile, true);
                doctool.PrepareWord(tofile);
                docopen = true;

                doctool.FillInTableByBookMarks("ITEMS", rows);

                doctool.FillInHeader(tofile, data_record.Properties(), ibcid, Microsoft.Office.Interop.Word.WdSeekView.wdSeekCurrentPageHeader);
                doctool.FillInHeader(tofile, data_record.Properties(), ibcid, Microsoft.Office.Interop.Word.WdSeekView.wdSeekPrimaryHeader);

                doctool.SaveWord(tofile);
                MessageBox.Show("导出" + tmpl + "成功");
                docopen = false;
                return;
            }
            catch (Exception ex)
            {
                MessageBox.Show("导出报告失败: " + ex.Message);
                if (docopen)
                {
                    doctool.SaveWord(tofile);
                }
                docopen = false;
            }
        }