Search code examples
javascripthtmljsxgraph

A bug about curvedifference in JsxGraph


I write code about Venn diagram to draw the specific area with yellow. (Literarlly, we can represent the part as "A∩B-A")

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>curvedifference Demo</title>
  <script type="text/javascript" src="https://jsxgraph.uni-bayreuth.de/distrib/jsxgraphcore.js"></script>
</head>
<body>
  <div id="jxgbox" style="width:400px;height:400px;"></div>
  <script type="text/javascript">
    var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-3, 3, 3, -3], axis:true});

    
    var circle1 = board.create('circle', [[-1, 0], 2], {strokeWidth:2, strokeColor:'blue', fillOpacity:0.3});
    var circle2 = board.create('circle', [ [0, Math.sqrt(3)], 2], {strokeWidth:2, strokeColor:'red', fillOpacity:0.3});
    var circle3 = board.create('circle', [[1, 0], 2], {strokeWidth:2, strokeColor:'brown', fillOpacity:0.3});

    let temp = board.create("curveunion", [circle1,circle2],{
        fillColor: "blue",
        fillOpacity: 0
    } )

    board.create("curvedifference", [temp,circle1],{
        fillColor: "yellow",
        fillOpacity: 1
    } )
    board.update();
  </script>
</body>
</html>

Actual output: enter image description here

Expected output:enter image description here

May I ask is there any solution to fix this bug?

I tried many ways, but it does not help.


Solution

  • Thanks for pointing this problem out and sorry for this bug. It stems from certain numerical problems in the clipping algorithm. In the source code we already adapted the internal precision which makes the problem much more rare, but there are still cases which cause problems.

    From a practical point of view it suffices to slightly change the position of circle1 from [-1,0] to [-1.01,0] to make the construction work:

    var circle1 = board.create('circle', [[-1.01, 0], 2], {strokeWidth:2, strokeColor:'blue', fillOpacity:0.3});
    var circle2 = board.create('circle', [ [0, Math.sqrt(3)], 2], {strokeWidth:2, strokeColor:'red', fillOpacity:0.3});
    var circle3 = board.create('circle', [[1, 0], 2], {strokeWidth:2, strokeColor:'brown', fillOpacity:0.3});
    
    let temp = board.create("curveunion", [circle1,circle2],{
            fillColor: "blue",
            fillOpacity: 0
        } )
    
    board.create("curvedifference", [temp,circle1],{
            fillColor: "yellow",
            fillOpacity: 1
        } )
    
    

    See it live at https://jsfiddle.net/4xvf5uj3/.