This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 12705 - setTransform spec silent on what to do with singular matrices
Summary: setTransform spec silent on what to do with singular matrices
Status: CLOSED FIXED
Alias: None
Product: HTML WG
Classification: Unclassified
Component: LC1 HTML Canvas 2D Context (show other bugs)
Version: unspecified
Hardware: PC Linux
: P2 trivial
Target Milestone: ---
Assignee: contributor
QA Contact: HTML WG Bugzilla archive list
URL:
Whiteboard: canvas
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-19 15:10 UTC by Benjamin Peterson
Modified: 2011-12-10 00:05 UTC (History)
6 users (show)

See Also:


Attachments
singular and almost singular matrix example (858 bytes, text/html)
2011-05-20 20:29 UTC, Benjamin Peterson
Details

Description Benjamin Peterson 2011-05-19 15:10:37 UTC
The 2dcontext.setTransform method specification doesn't say how to react when passed a singular matrix.
Comment 1 Aryeh Gregor 2011-05-19 17:21:04 UTC
I'd expect that if the transformation matrix is singular, nothing that's affected by the transformation matrix should be displayed, since it would make everything zero pixels thick.  What do browsers do?
Comment 2 Benjamin Peterson 2011-05-19 17:44:26 UTC
WebKit apparently notes that it has a singular matrix and ignores every operation. Firefox doesn't handle it at all. Personally, I'd like to see it throw an error, since using a singular matrix as a transform doesn't make much sense.
Comment 3 Aryeh Gregor 2011-05-19 17:56:06 UTC
Yeah, it probably does make the most sense to ignore it or throw an exception or something.  Problem: how do you define "singular"?  The arguments are doubles.  Do you require that the determinant of {{a, c}, {b, d}} be within epsilon of 0 for some specific epsilon?  What happens if you call transform() when the existing matrix and the matrix you passed to transform() both have determinants greater than epsilon in absolute value, but their product has a determinant smaller than epsilon?
Comment 4 Benjamin Peterson 2011-05-19 18:04:20 UTC
Let
a b
c d
be a matrix where a, b, c, d are some floating point data type. We'll say it's singular iff a*d == c*b. This mostly defeats mistakes like passing the zero matrix or a simple non-invertible one. I'm not sure why we'd have to worry about them being close to equal. It should only arise with pathological matrices.
Comment 5 Aryeh Gregor 2011-05-19 22:16:38 UTC
You can *never* rely on equality for floating-point.  Rounding errors mean that basic mathematical identities don't hold, like (a*b)*c == a*(b*c) or (a/b)*b == a.  Having a determinant almost exactly zero wouldn't have to be pathological at all, it could be any matrix that went through some numeric operations.  For instance:

data:text/html,<!doctype html><script>alert((10/3000 - 2 + 2)*3000 == 10)</script>

alerts false in Firefox 4.0, Chrome 12 dev, and Opera 11.10.
Comment 6 Benjamin Peterson 2011-05-19 23:49:58 UTC
I realize floating comparisons are bad, but it's what browsers currently use afaict.
Comment 7 Aryeh Gregor 2011-05-20 18:48:46 UTC
Do you have a specific test-case?  I don't know enough about canvas to easily make one, but I'd be interested in fiddling and seeing how browsers behave here.  Your description in comment 2 makes it sound like WebKit doesn't handle singular matrices specially at all, it just draws everything with zero width.  If that's correct, presumably it behaves the same if the eigenvalues are both very small, not just if they're zero (since the width will round down to zero).
Comment 8 Benjamin Peterson 2011-05-20 20:29:25 UTC
Created attachment 989 [details]
singular and almost singular matrix example

Here is an example of a almost singular matrix and a singular matrix being used to transform.
Comment 9 Benjamin Peterson 2011-05-20 20:31:41 UTC
WebKit "handles" singular matrices by detecting when there are in effect and ignoring every operation on the canvas while they are.
Comment 10 Aryeh Gregor 2011-05-22 22:38:28 UTC
Your "almost singular" matrix isn't very close to singular at all.  It has a determinant of .00002.  That's quite a lot, since your lineWidth is 1999999.  Try something like this instead:

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/1002

If I set e to 0.0000001, Firefox draws the red square successfully.  If I add one more zero, so it's 0.00000001, Firefox doesn't draw anything, even though w(1 - e == 1) logs "false".  WebKit seems to have the same magic threshold, after which it just ignores the operation (even though the width variable is large enough that it should really draw the big black line).  So it doesn't seem to be just testing whether it's actually singular, it looks like they're testing that it's just "close" to singular.
Comment 11 Ian 'Hixie' Hickson 2011-06-21 06:14:13 UTC
Why can't implementations just do the maths as suggested by the spec? I don't understand why a special case is needed here.
Comment 12 Aryeh Gregor 2011-06-22 20:51:52 UTC
I don't understand why either, but it seems like implementations do have the special case.
Comment 13 Michael[tm] Smith 2011-08-04 05:04:14 UTC
mass-move component to LC1
Comment 14 Ian 'Hixie' Hickson 2011-08-11 05:49:15 UTC
This was also discussed on the WHATWG list:
   http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2011-June/thread.html#32229

Philip, any advice?
Comment 15 Ian 'Hixie' Hickson 2011-12-09 23:26:24 UTC
EDITOR'S RESPONSE: This is an Editor's Response to your comment. If you are satisfied with this response, please change the state of this bug to CLOSED. If you have additional information and would like the editor to reconsider, please reopen this bug. If you would like to escalate the issue to the full HTML Working Group, please add the TrackerRequest keyword to this bug, and suggest title and text for the tracker issue; or you may create a tracker issue yourself, if you are able to do so. For more details, see this document:
   http://dev.w3.org/html5/decision-policy/decision-policy.html

Status: Accepted
Change Description: see recent diffs (sorry I don't have a specific revision to point to at this time)
Rationale: Concurred with reporter's comments.