jlouthan / perspective-transform

A small JavaScript library for creating and applying perspective transforms
MIT License
182 stars 29 forks source link

Destination quadrilateral of width 0 throws error #3

Open rynobax opened 7 years ago

rynobax commented 7 years ago
var PerspT = require('perspective-transform');
const src = [ 0, 0, 0, 1024, 1024, 0, 1024, 1024 ];
const dest = [ 512, 171, 512, 853, 512, 0, 512, 1024 ];
var perspT = PerspT(src, dest);

When I try to map to a quadrilateral where all the x coordinates are the same, I get the following error:

TypeError: Cannot read property '3' of undefined
    at Object.inv (C:\Users\Ryan\Documents\Code\js_playground\node_modules\perspective-transform\dist\perspective-transform.js:98:17)
    at getNormalizationCoefficients (C:\Users\Ryan\Documents\Code\js_playground\node_modules\perspective-transform\dist\perspective-transform.js:224:22)
    at PerspT (C:\Users\Ryan\Documents\Code\js_playground\node_modules\perspective-transform\dist\perspective-transform.js:248:20)
    at PerspT (C:\Users\Ryan\Documents\Code\js_playground\node_modules\perspective-transform\dist\perspective-transform.js:242:11)
    at Object.<anonymous> (C:\Users\Ryan\Documents\Code\js_playground\js.js:5:14)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)

I poked around in the code a bit to try to come up with a nice solution, but the best I could get was throwing in a check like:

if(dstPts[0] === dstPts[2] && dstPts[0] === dstPts[4] && dstPts[0] === dstPts[6]){
    this.coeffs = [0, 0, dstPts[0], 0, 1, 0, 0, 0]
    this.coeffsInv = [0, 0, 1/dstPts[0], 0, 0, 0, 0, 0]
} else if(dstPts[1] === dstPts[3] && dstPts[1] === dstPts[5] && dstPts[1] === dstPts[7]){
    this.coeffs = [0, 1, 0, 0, 0, dstPts[0], 0, 0]
    this.coeffsInv = [0, 1, 0, 0, 0, 1/dstPts[0], 0, 0]
}else {
    this.coeffs = getNormalizationCoefficients(this.srcPts, this.dstPts, false);
    this.coeffsInv = getNormalizationCoefficients(this.srcPts, this.dstPts, true);
}

This just maps everything to a line that is the height of the source quadrilateral and on the x coordinate that all the x points of the destination quadrilateral are on, which is fine for my use case, but I feel like there could be a better solution.