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 12969 - bilinear interpolation
Summary: bilinear interpolation
Status: NEW
Alias: None
Product: SVG
Classification: Unclassified
Component: Gradients (show other bugs)
Version: SVG 2.0
Hardware: All All
: P2 enhancement
Target Milestone: Test Suite
Assignee: Doug Schepers
QA Contact: SVG Public List
URL: http://www.peepo.com
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-16 12:54 UTC by j.chetwynd
Modified: 2011-08-03 21:11 UTC (History)
3 users (show)

See Also:


Attachments
javascript patch (1.10 KB, application/x-javascript)
2011-06-16 12:59 UTC, j.chetwynd
Details
y and out.length correction (1.36 KB, application/x-javascript)
2011-06-16 21:37 UTC, j.chetwynd
Details
include border values (1.39 KB, application/x-javascript)
2011-06-18 13:35 UTC, j.chetwynd
Details
adjust out.length (1.39 KB, application/x-javascript)
2011-06-18 13:46 UTC, j.chetwynd
Details
visualisation (4.96 KB, image/svg+xml)
2011-06-18 15:07 UTC, j.chetwynd
Details

Description j.chetwynd 2011-06-16 12:54:27 UTC
SVG 1.1 & 1.2 provide linear colour gradients.

bilinear interpolation provides two dimensional gradients, frequently used in for instance mapping applications, these are not readily reproduced using SVG or lerp alone.

an array is input, and a larger one that contains the intermediate values is generated.
Comment 1 j.chetwynd 2011-06-16 12:58:35 UTC
    /**
    * linear interpolation
    * t value between 0 and 1, a = initial value, b = final value
    */

    function lerp(t, a, b) {
      return (+a+(b-a)*t);
    }

    /**
    * bilinear interpolation of intermediate values in two dimensions
    * tx = number of intermediate x values required + 1
    * ty= number of intermediate y values required + 1
    * x = width
    * y = height
    * arr = array of length x*y
	* out = array of length x*(tx-1)*y*(ty-1)
    */

    function blerp(tx, ty, arr, x, y){
      var out = [],
          outv = 0,
          k = 1,
          j = 0,
          i = 1;

      for(k; k<=ty; k++){
        for(j; j<x-1; j++){
          f = lerp(k/ty, arr[j], arr[x+j]);
          g = lerp(k/ty, arr[j+1], arr[x+j+1]);
          for(i; i<tx; i++){
            outv = lerp(i/tx, f, g);
            out.push(outv);
          }
          i = 1;
        }
        j=0;
      }
      return out;
    }

    var ex1 = blerp(10, 10, [0,10,100,110], 2, 2),
        ex2 = blerp(10, 10, [0,10,20,100,110,120], 3, 2);

    console.log(ex1.join(','));
    console.log("\n");
    console.log(ex2.join(','));
Comment 2 j.chetwynd 2011-06-16 12:59:31 UTC
Created attachment 1000 [details]
javascript patch
Comment 3 j.chetwynd 2011-06-16 21:37:32 UTC
Created attachment 1001 [details]
y and out.length correction
Comment 4 j.chetwynd 2011-06-16 21:38:45 UTC
see 'y and out.length correction' attachment
Comment 5 j.chetwynd 2011-06-18 13:35:00 UTC
Created attachment 1002 [details]
include border values
Comment 6 j.chetwynd 2011-06-18 13:46:36 UTC
Created attachment 1003 [details]
adjust out.length
Comment 7 j.chetwynd 2011-06-18 15:07:04 UTC
Created attachment 1004 [details]
visualisation
Comment 8 Cameron McCormack 2011-08-03 05:15:54 UTC
This sounds like something that could be added as a new image-rendering property value, if it is useful.
Comment 9 Tab Atkins Jr. 2011-08-03 15:23:58 UTC
Nah, this is actually a new kind of gradient.  It should be handled by the Coons Patch suggestion, though, since that usually does bilinear blending within each patch.  Just make a patch with straight sides.
Comment 10 j.chetwynd 2011-08-03 20:39:42 UTC
comments: 8/9

please open the visualisation attachment,

the bilinear extrapolation is one aspect, 
another is the matrix,

both are needed, not necessarily via this method,
but something as easily assimilated.
Comment 11 j.chetwynd 2011-08-03 20:43:26 UTC
comment 10 oops: interpolation, not extrapolation ~:"
Comment 12 Rik Cabanier 2011-08-03 21:11:49 UTC
Are you looking for something like PDF's function shading?
Look for the PDF reference manual, chapter 4.6.3 under 'Type1 (Function-Based) Shadings'
I've seen cases where this gradient is used with a sample function (chapter 3.9.1) as input. This seems to match what you're trying to accomplish:
set up a 2x2 domain of colors and interpolate between them.

You could approximate the same behavior with a grid of coons patches (= the matrix) but it would be very verbose.