Reputation: 533
I have a circle and simple function Math.cos(x)
I want the circle to be filled when it intersects with that function (fill only the upper side). But it's not working.
Script:
// circle
var point1 = app.board.create('point', [0,0], {size: 2, strokeWidth:2 })
var point2 = app.board.create('point', [6,0], {size: 2, strokeWidth:2 })
var circle = app.board.create('circle', [point1,point2], {strokeColor: "#f00", strokeWidth: 2 })
// function
var func = app.board.create('functiongraph',[function(x){ return Math.cos(x)}]);
// intersection
var curve = app.board.create('curve', [[], []], {strokeWidth: 0, fillColor: "#09f", fillOpacity: 0.8})
curve.updateDataArray = function() {
var a = JXG.Math.Clip.intersection(circle, func, this.board);
this.dataX = a[0];
this.dataY = a[1]
};
app.board.update()
Output
Expected output (I did it on Paint)
Thank you in advance :)
Upvotes: 2
Views: 429
Reputation: 2323
This can easily realized with the next version of JSXGraph which will be released next week: With the inequality
element the area above the cosine curve can be marked. The inequality element is a closed curve and can be intersected with a circle. In v1.2.3, the intersection does not work because of a small bug.
For the clipping, the next version contains new elements curveintersection
, curveunion
, curvedifference
which make it easier to use the methods of JXG.Math.Clip, but of course your approach with JXG.Math.Clip
will still work.
Here is the code:
var f = board.create('functiongraph', ['cos(x)']);
var ineq = board.create('inequality', [f], {
inverse: true, fillOpacity: 0.1
});
var circ = board.create('circle', [[0,0], 4]);
var clip = board.create('curveintersection', [ineq, circ], {
fillColor: 'yellow', fillOpacity: 0.6
});
Actually, the inequality element does the same as enxaneta does "by hand".
Upvotes: 2
Reputation: 33044
In the next example I'm building the d attribute for the path using Math.cos(). I suppose your function may be different. Please observe that at the end at the d attribute the path is closing the upper part of the svg canvas. I'm using the pth inside a clipPath and I'm clipping the circle with it.
let d ="M";
for(let x = -50; x<=50; x+=1){
d+=`${x}, ${5*Math.cos(x/5)} `
}
d+="L50,-50L-50,-50z"
pth.setAttribute("d",d);
<svg viewBox="-50 -50 100 100" width="200">
<clipPath id="clip">
<path id="pth"/>
</clipPath>
<circle r="45" clip-path="url(#clip)" fill="blue"/>
</svg>
In order to better understand how I'm building the path please take a look at the next example:
let d ="M";
for(let x = -50; x<=50; x+=1){
d+=`${x}, ${5*Math.cos(x/5)} `
}
d+="L50,-50L-50,-50z"
pth.setAttribute("d",d);
<svg viewBox="-50 -50 100 100" width="200">
<circle r="45" fill="blue"/>
<path id="pth" fill="rgba(250,0,0,.4)"/>
</svg>
Upvotes: 2