Jordan Sitkin
Jordan Sitkin

Reputation: 2343

How can I turn this SVG triangle into a "wandering" path representation?

Please forgive my lack of familiarity with geometry/math terms. An image will better describe what I want to accomplish:

Triangle Example

I want to take a triangle such as the one on the left and generate a path from it such as the one on the right. Each triangle will be accompanied by a lightness value which can be used to determine the frequency of the shading lines.

The first two points on the path should represent one side of the triangle, but the last point doesn't necessarily need to be land on the 3rd point of the triangle (just as close as possible).

I'm trying to accomplish this in javascript but a framework or library specific solution is not important. I'm hoping that someone can point me towards some ideas / concepts that will help me grok the geometry and design an algorithm.

Thanks

Upvotes: 1

Views: 103

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101976

An interesting exercise. Here is my solution using pure Javascript.

Basically we calculate the two line equations (A->C and B->C). Then divide them up into an appropriate number of steps. Then draw a polyline back and forth as we step along those two lines.

// 'pts' is a 3x2 array ([3][2]) for the three triangle points
// 'step' is the approximate step distance between lines
function makeTriangle(pts, step)
{
    var  ax = pts[0][0];
    var  ay = pts[0][1];
    var  bx = pts[1][0];
    var  by = pts[1][1];
    var  cx = pts[2][0];
    var  cy = pts[2][1];

    // Get AC line length
    var  a_dx = cx - ax,
         a_dy = cy - ay;
    var  ac_len = Math.sqrt(a_dx * a_dx + a_dy * a_dy);
    // Get BC line length
    var  b_dx = cx - bx,
         b_dy = cy - by;
    bc_len = Math.sqrt(b_dx * b_dx + b_dy * b_dy);

    // Whichever line is shortest will determine the number of steps
    var  len = (ac_len < bc_len) ? ac_len : bc_len;

    // ac step amounts
    a_dx = step * a_dx / len;
    a_dy = step * a_dy / len;

    // bc step amounts
    b_dx = step * b_dx / len;
    b_dy = step * b_dy / len;

    var  poly = [];
     // first two points
    poly.push(ax);
    poly.push(ay);
    poly.push(bx);
    poly.push(by);
    while (len > step) {
        // step along the ac and bc lines
        ax += a_dx;
        ay += a_dy;
        bx += b_dx;
        by += b_dy;
        // add the line going from the bc line to the ac line
        poly.push(bx);
        poly.push(by);
        poly.push(ax);
        poly.push(ay);
        len -= step;
        if (len < step) break;
        // step again
        ax += a_dx;
        ay += a_dy;
        bx += b_dx;
        by += b_dy;
        // add line going back again
        poly.push(ax);
        poly.push(ay);
        poly.push(bx);
        poly.push(by);
        len -= step;
    }
    poly.push(cx);
    poly.push(cy);

    // Now we have all our points, build the SVG element
    var  svg = document.getElementById("mysvg");

    var  tri = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
    tri.setAttribute("fill", "none");
    tri.setAttribute("stroke", "black");
    tri.setAttribute("stroke-width", 4);
    tri.setAttribute("points", poly.join(","));
    svg.appendChild(tri);
}


makeTriangle([[117,0],[255,159],[2,279]], 15);

Demo here

Upvotes: 3

Related Questions