0

There's a line between these paths; why?

(On my machine it looks like this: enter image description here )

path.myshape {
  stroke: gray;
  fill: gray;
  stroke-opacity:0.5;
  fill-opacity:0.5;
}
<svg width="120px" height="120px" viewBox="0 0 120 120">
  <path class="myshape" d="M0 0 L100 100 L100 0" />
  <path class="myshape" d="M0 0 L100 100 L0 100" />
</svg>

A similar issue happens even without the stroke (it's harder to see but it's still there). I am confused why this is happening; if I have two triangles that are halves of a square, why don't I just see a square? Is there a way to prevent this?

(On my machine it looks like this: enter image description here )

path.myshape {
  stroke: none;
  fill: gray;
  fill-opacity:0.5;
}
<svg width="120px" height="120px" viewBox="0 0 120 120">
  <path class="myshape" d="M0 0 L100 100 L100 0" />
  <path class="myshape" d="M0 0 L100 100 L0 100" />
</svg>

More realistic example (where I'm trying to get rid of the lines between triangles that have nearly the same fill/stroke attributes):

var margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = 500 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
    
// add the graph canvas to the body of the webpage
var svg = d3.select("div#plot1").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);
var axis = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
var xsc = d3.scaleLinear()
          .domain([-2, 2])  // the range of the values to plot
          .range([ 0, width ]);        // the pixel range of the x-axis

var ysc = d3.scaleLinear()
          .domain([-2, 2])
          .range([ height, 0 ]);
var closedLine = d3.line()
   .x(function(d){ return xsc(d[0]); })
   .y(function(d){ return ysc(d[1]); })
   .curve(d3.curveLinearClosed);

function attrfunc(f,attr) {
  return function(d) {
    return f(d[attr]);
  };
}


function doit(data)
{
  var items = axis.selectAll("path.item")
    .data(data);
  items.enter()
      .append("path")
        .attr("class", "item")
      .merge(items)
        .attr("d", attrfunc(closedLine, "xy"))
        .attr("stroke", "gray")
        .attr("stroke-width", 1)
        .attr("stroke-opacity", function(d) { return 1-d.age;})
        .attr("fill", "gray")
        .attr("fill-opacity", function(d) {return 1-d.age;});
  items.exit().remove();
}

var state = {
  t: 0,
  theta: 0,
  omega: 0.5,
  A: 1.0,
  N: 60,
  history: []
}
d3.timer(function(elapsed)
{
  var S = state;
  if (S.history.length > S.N)
    S.history.shift();
  var dt = Math.min(0.1, elapsed*1e-3);
  S.t += dt;
  S.theta += S.omega * dt;
  var sample = {
    t: S.t,
    x: S.A*(Math.cos(S.theta)+0.1*Math.cos(6*S.theta)),
    y: S.A*(Math.sin(S.theta)+0.1*Math.sin(6*S.theta))
  }
  S.history.push(sample);

  // Create triangular regions
  var data = [];
  for (var k = 0; k < S.history.length-1; ++k)
  {
     var pt1 = S.history[k];
     var pt2 = S.history[k+1];
   data.push({age: (S.history.length-1-k)/S.N,
                xy:
                 [[0,0],
                  [pt1.x,pt1.y],
                  [pt2.x,pt2.y]]
               });
  }
  doit(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.min.js"></script>
<div id="plot1">
</div>
Jason S
  • 184,598
  • 164
  • 608
  • 970
  • 1
    [antialiasing](https://en.wikipedia.org/wiki/Spatial_anti-aliasing) – Robert Longson Apr 23 '17 at 21:54
  • Doesn't really answer the question; if two logical triangles join together to form a square, why don't I just see a square? I get the same effect if I set `stroke: none`; – Jason S Apr 24 '17 at 02:17
  • Did you read the linked wikipedia's article ? Antialiasing will try its best to make the pixels that fit on floating coordinates to look as smooth as possible. To do so, it will convert some normally opaque pixels to semi-transparent ones. Then, when you draw an oblique line, a lot of the pixels on this oblique will be made semi-transparent. Apply this process on both of your triangles and you'll get a semi-transparent line where shape should be linked. Algorithms are not smart enough to deduce that it should compose a single full opaque square with same fill color. So workarounds are : – Kaiido Apr 24 '17 at 02:37
  • change your shape to a rect. Set the `shape-rendering` property to `crispEdges` which workaround have caveats, since you won't enjoy the smoothness of antialiasing when needed. So for both workarounds, it's best to use it only when needed (when shapes are colliding). – Kaiido Apr 24 '17 at 02:38
  • @Kalido you are, in effect, asserting that SVG rendering tries to draw the individual `path` elements separately, in which case, yes, I agree that antialiasing concerns apply. But I don't understand why it doesn't try to coalesce vector graphics first before rasterizing. (This is only a simple example; in my real example I have triangles that are adjacent but do not form a rectangle.) – Jason S Apr 24 '17 at 02:42
  • See my related question http://stackoverflow.com/questions/43576863/using-adjacent-data-values-in-d3 -- I want to get rid of those annoying lines. – Jason S Apr 24 '17 at 02:44
  • You want it to do so on every possible complex shapes too ? It would kill performances. – Kaiido Apr 24 '17 at 02:44
  • For such an animation, I think I would first construct the flower shape, as a single path, and then animate a mask over it. – Kaiido Apr 24 '17 at 02:53
  • it's not a fixed shape, that post was just a simpler approximation. I have essentially a queue of triangles and want to shade them so that the opacity fades from 1 to 0. The triangles are always adjacent to each other but they have vertices that derive from random variables. – Jason S Apr 24 '17 at 02:58
  • Still, if you keep your shapes as always opaque, with the stroke the same color, and only apply a rotating gradient over it, you'd get rid of these gaps : https://jsfiddle.net/bkyhvm9f/ – Kaiido Apr 24 '17 at 03:05
  • Yes, I understand that, but the gradient I want is not rotating, it's based on the triangles themselves which are moving in odd patterns. (in my real code) – Jason S Apr 24 '17 at 03:33

0 Answers0