I'm trying to fill get a circle shaped area filled with rectangles (to be precise, Raster width dimensions 12x20).
After some research and experiments, I found one solution. To draw a circle, get its bounding box and iterate through every pixel to found that distance is smaller or equal to circle R.
Some code sample here, I'm using three.js
let shapeSize = [12, 20];
let circleR = R / 2;
let circle = new Circle(position, circleR);
let bounds = circle.bounds;
for (let i = bounds.x; i <= bounds.x + bounds.width; i += 1) {
for (let j = bounds.y; j <= bounds.y + bounds.height; j += 20) {
let center = new Point(i, j);
if (center.getDistance(position) <= circleR) {
center = new Point(i, j);
let shape = new Shape({center, alpha: 0.7, scale: 0.8});
j += shapeSize[1] - 1; // this part smells
}
}
}
Shape is square with a rester - size 12x20.
But with this code sample, it's impossible to get a circle filled with squares. If I increment i+=12 and y+=20, I get too much space around, and if by one every square is over another and it generates too many squares.
Any idea how to do it nice and elegant?
As JJ23 said, you can use the circle as a clip mask for a group containing your rasters grid.
Here is a Sketch demonstrating how to do it with Paper.js.
// constants
var RADIUS = 200;
var IMAGE = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAUCAIAAAA2kktGAAAACXBIWXMAAAsTAAALEwEAmpwYAAAE82lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE4LTA5LTI2VDA5OjE0OjQ5KzAyOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE4LTA5LTI2VDA5OjE0OjQ5KzAyOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOC0wOS0yNlQwOToxNDo0OSswMjowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTYwZDg3MWYtZmFjOS0wYTRjLThmOGQtYjdmNDdhMGRiYzBlIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjU2MGQ4NzFmLWZhYzktMGE0Yy04ZjhkLWI3ZjQ3YTBkYmMwZSIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjU2MGQ4NzFmLWZhYzktMGE0Yy04ZjhkLWI3ZjQ3YTBkYmMwZSIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyI+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NTYwZDg3MWYtZmFjOS0wYTRjLThmOGQtYjdmNDdhMGRiYzBlIiBzdEV2dDp3aGVuPSIyMDE4LTA5LTI2VDA5OjE0OjQ5KzAyOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+tv5OvAAAAiRJREFUKJFdks9qKjEUxs9JJk5GHdFBqEVBEAa6UHwA22codNeVWze+WR9CXHbRhZsqtP7BjjAYGWWs4+gkuYvI5XKzCt/5nZzvnBMkhCilAAAAOOe2bedyOUppkiRxHCulKKWWIRDR87xOp9NoNCilQRB8f3+fz+c0TSuVimXeKBQK/X7/9fU1CIK3t7fZbBaG4eVyQcTL5WIY8H3//f396+trOBzWajXHccrlsm3biEgIIQayLAsAFovFeDwWQriu2263Pc8DAK31rZwQYjKZMMbiONZaSylXq9XxeDQQJYRora/X63a73Ww28/k8TdM0TU+nU5qmt7bu7+/DMFRKMcYYY1mWcc5rtVqxWFwul1EUaa3J4+Mj5xwAsixLkoQx1m63X15eer2e0QGADgaDz89Pk4GIACCl/Pn5mUwmQgillNbauru7q1QqiKi1Nv6CIAiCQCll27bZh7Xf77MsAwBKKSJyzi3LklIqpZRSt1C9Xv/4+EiSpFgsIuL1epVSaq2zLCOE5HI5AEDf91erFWOsVCoBgFkF59x13Uaj4XnedDq11uu1ydvtdlprxpjrus1m8+npqdvtRlFEKUXbtvP5/OFwcBzH87zT6fT7++s4ju/71Wp1vV5HUYQPDw/7/V4I0Wq1np+fN5vNaDQKw9C0opSSUlpCiOPxiIjlcvl8PsdxLKU00zIX89sQAAghjDFjzgwQ/j0G+k8hhPzVOed/AJQ+QEC6tzaSAAAAAElFTkSuQmCC';
var IMAGE_WIDTH = 12;
var IMAGE_HEIGHT = 20;
// create image
var raster = new Raster(IMAGE);
// wait for image loading
raster.onLoad = function ()
{
// draw raster grid as a group
var group = new Group();
var stepsX = Math.ceil(RADIUS * 2 / IMAGE_WIDTH);
var stepsY = Math.ceil(RADIUS * 2 / IMAGE_HEIGHT);
for (var i = 0; i < stepsX; i++)
{
for (var j = 0; j < stepsY; j++)
{
// calculate grid point
var point = new Point(i * IMAGE_WIDTH, j * IMAGE_HEIGHT);
// clone original raster
var rasterClone = raster.clone();
// position it at grid point
rasterClone.position = point;
// add it to the group
group.addChild(rasterClone);
}
}
// draw circle
var circle = new Path.Circle(group.position, RADIUS);
// add it to the group as first child
group.insertChild(0, circle);
// enable clipping
group.clipped = true;
// position group at view center
group.position = view.center;
// delete original raster
raster.remove();
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With