How can the same calculation produce different results

Just spend two hours debugging, I think I know the cause of the problem, but I don’t understand how it can produce the results that it does.

I have a Swing based application where I override JPanel.paint (Graphics g) like this

public void paint(Graphics g) {
    <snipped code>

    Insets is = getInsets();
    Dimension sz = getSize();
    g2.setClip(is.left + 1, is.top + 1, sz.width - is.right - is.left - 2, sz.height - is.top - is.bottom - 2);

    int w = getWidth();
    int h = getHeight();
    double s = Math.min(sz.getWidth(), sz.getHeight());

    AffineTransform mc = g2.getTransform();

    AffineTransform m1 = new AffineTransform(mc);
    m1.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
    m1.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
    m1.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));

    AffineTransform m2 = new AffineTransform(mc);
    m2.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
    m2.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
    m2.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));

    try {
        m_InverseViewTransform = m1.createInverse();
    } catch (NoninvertibleTransformException e) {

        AffineTransform m3 = new AffineTransform(mc);
        m3.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
        m3.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
        m3.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));

        System.out.println("m1 = " + m1);
        System.out.println("m2 = " + m2);
        System.out.println("m3 = " + m3);

        AffineTransform m4 = new AffineTransform(mc);
        System.out.println("m4 = " + m4);
        m4.preConcatenate(AffineTransform.getTranslateInstance(-m_CenterX, -m_CenterY));
        System.out.println("m4 = " + m4);
        m4.preConcatenate(AffineTransform.getScaleInstance(m_ScaleX * s, -m_ScaleY * s));
        System.out.println("m4 = " + m4);
        m4.preConcatenate(AffineTransform.getTranslateInstance(w / 2, h / 2));
        System.out.println("m4 = " + m4);

        System.out.println(w); 
        System.out.println(h);
        System.out.println(s);
        System.out.println(m_CenterX);
        System.out.println(m_CenterY);
        System.out.println(m_ScaleX);
        System.out.println(m_ScaleY);

        e.printStackTrace();

Now the secret is, sometimes when I run the application, most often, say, three times out of four, a NoninvertibleTransformException is thrown.

As you can see, in order to debug, I output an offensive matrix and three other equally calculated matrices and variables that are used to form these matrices.

And this is where it gets interesting, see the conclusion below, all matrices do not have the same value!

m1 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m2 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m3 = AffineTransform[[0.0, 0.0, 400.0], [0.0, -0.0, 289.0]]
m4 = AffineTransform[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
m4 = AffineTransform[[1.0, 0.0, -49.5], [0.0, 1.0, -0.362762953421903]]
m4 = AffineTransform[[5.254545454545455, 0.0, -260.1], [0.0, -587.9922126928986, 213.3017916655554]]
m4 = AffineTransform[[5.254545454545455, 0.0, 139.89999999999998], [0.0, -587.9922126928986, 502.3017916655554]]
800
578
578.0
49.5
0.36276295342190257
0.009090909090909092
1.0172875652126274
java.awt.geom.NoninvertibleTransformException: Determinant is 0
at java.awt.geom.AffineTransform.createInverse(AffineTransform.java:2706)

, / , , .

JRE jdk1.8.0_25.jdk( Mac OS X 10.8.5), Java 1.6 1.6.

, , , JPanel Disportted Event, , , .

, , , , Java JVM 'rules', , AffineTransform , - ...

, .

, .

, - //, ...

+1
1

- , , . , , , . m_CenterX, m_CenterY, m_ScaleX m_ScaleY. , , , , , EDT. EDT , ( , ).

, , EDT, EDT , ( ).

+1

Source: https://habr.com/ru/post/1692177/


All Articles