I am working on implementing Alchemy AO and reading through their paper and they mention to sample each point by: considering a
Disk of radius r and center C that is parallel to the image plane,
select a screen-space point Q uniformly at random on it's project, and
then read a depth or position buffer to find the camera-space scene
point P = (xp, yp, z(Q)) on that ray.
I am wondering how you would go about selecting a screen-space point in the manor? I have made an attempt below but since my result appears quite incorrect, I think it's the wrong approach.
vec3 Position = depthToPosition(uvCoords);
int turns = 16;
float screen_radius = (sampleRadius * 100.0 / Position.z); //ball around the point
const float disk = (2.0 * PI) / turns;
ivec2 px = ivec2(gl_FragCoord.xy);
float phi = (30u * px.x ^ px.y + 10u * px.x * px.y); //per pixel hash for randdom rotation angle at a pixel
for (int i = 0; i < samples; ++i)
{
float theta = disk * float(i+1) + phi;
vec2 samplepoint = vec2(cos(theta), sin(theta));
}
Anyone knows if I am able to user Google Maps Circle, Rectangle and Polygon classes in Node JS? In the frontend is easy with Google Maps Javascript SDK, but I can't figure out how to get a hold of this library within Node JS.
I need to be able to check if points are with bounds, something in the lines of:
const location = google.maps.LatLng(lat, lng);
const circle = new google.maps.Circle({
center: area.center,
radius: area.radius,
});
const doesContain = circle.getBounds().contains(location);
Thanks ahead!
Alright boys, after giving some thought I realized it's easier to create my own code for checking if a geometry contains a point than depend on Google Maps library to do so.
Although this does not offer and the functionality Google Maps SDK offers, it does solve the geometry problem.
For anyone else looking for other Google Maps SDK functionalities, checkout this Node.js Client for Google Maps Services. Though it does not include the geometry functions I was looking for.
Solution
Without further ado here is my code:
class Circle {
/**
* Circle constructor
* #param {array} center Center coordinate [lat, lng]
* #param {number} radius Radius of the circle in meters
*/
constructor(center, radius) {
this.name = "Circle";
this.center = center;
this.radius = radius;
}
/**
* Checks if a point is within the circle
* #param {array} point Coordinates of a point [lat,lng]
* #returns true if point is within, false otherwhise
*/
contains(point) {
const { center, radius } = this;
const distance = this.distance(center, point);
if (distance > radius) return false;
return true;
}
/**
* Calculate the distance between two points (in meters)
* #param {array} p1 [lat,lng] point 1
* #param {array} p2 p1 [lat,lng] point 2
* #returns Distance between the points in meters
*/
distance(p1, p2) {
var R = 6378.137; // Radius of earth in KM
var dLat = (p2[0] * Math.PI) / 180 - (p1[0] * Math.PI) / 180;
var dLon = (p2[1] * Math.PI) / 180 - (p1[1] * Math.PI) / 180;
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((p1[0] * Math.PI) / 180) *
Math.cos((p2[0] * Math.PI) / 180) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d * 1000; // meters
}
}
class Rectangle {
/**
* Rectangle constructor
* #param {arrar} sw South-west coorodinate of the rectangle [lat,lng]
* #param {array} ne North-east coordinate of the rectangle [lat, lng]
*/
constructor(sw, ne) {
this.name = "Rectangle";
this.sw = sw;
this.ne = ne;
}
/**
* Checks if a point is within the reactangle
* #param {array} point Coordinates of a point [lat,lng]
* #returns true if point is within, false otherwhise
*/
contains(point) {
const { sw, ne } = this;
const x = point[0];
const y = point[1];
if (x < sw[0] || x > ne[0] || y < sw[1] || y > ne[1]) return false;
return true;
}
}
class Polygon {
/**
* Polygon constructor
* #param {array} points Array of vertices/points of the polygon [lat,lng]
*/
constructor(points) {
this.name = "Polygon";
this.points = points;
}
/**
*
* #returns {obj} Returns the coordinate of the min/max bounds that surounds the polygon
* (south-west coordinate, north-east coordinage as in [lat,lng] format)
*/
getBounds() {
const { points } = this;
let arrX = [];
let arrY = [];
for (let i in points) {
arrX.push(points[i][0]);
arrY.push(points[i][1]);
}
return {
sw: [Math.min.apply(null, arrX), Math.min.apply(null, arrY)],
ne: [Math.max.apply(null, arrX), Math.max.apply(null, arrY)],
};
}
/**
* Checks if a point is within the polygon
* #param {array} point Coordinates of a point [lat,lng]
* #returns true if point is within, false otherwhise
*/
contains(point) {
const x = point[0];
const y = point[1];
const bounds = this.getBounds();
// Check if point P lies within the min/max boundary of our polygon
if (x < bounds.sw[0] || x > bounds.ne[0] || y < bounds.sw[1] || y > bounds.ne[1])
return false;
let intersect = 0;
const { points } = this;
// Geofencing method (aka Even–odd rule)
// See more at: https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
// Now for each path of our polygon we'll count how many times our imaginary
// line crosses our paths, if it crosses even number of times, our point P is
// outside of our polygon, odd number our point is within our polygon
for (let i = 0; i < points.length; i++) {
// Check if pont P lies on a vertices of our polygon
if (x === points[i][0] && y === points[i][1]) return true;
let j = i !== points.length - 1 ? i + 1 : 0;
// Check if Py (y-component of our point P) is with the y-boundary of our path
if (
(points[i][1] < points[j][1] && y >= points[i][1] && y <= points[j][1]) ||
(points[i][1] > points[j][1] && y >= points[j][1] && y <= points[i][1])
) {
// Check if Px (x-componet of our point P) crosses our path
let sx =
points[i][0] +
((points[j][0] - points[i][0]) * (y - points[i][1])) /
(points[j][1] - points[i][1]);
if (sx >= x) intersect += 1;
}
}
return intersect % 2 === 0 ? false : true;
}
}
module.exports = { Circle, Rectangle, Polygon };
Explanation
The Circle and Rectangle class is pretty straight forward, it's trivial to determine if a point lies within a boundary. The Polygon class is a bit more complicated because of obvious reasons.
The method used here to determine if a point P is within a polygon is called Geofencing (aka Even–odd rule), a common method in geospacial analysis.
Step 1
First we check if the point P falls within the max/min boundaries of the polygon (image 1), if it doesn't, we return false, problem solved.
Image 1 -- Polygon boundaries, P1 is within the polygon boundaries, P2 is not.
Step 2
Then we check if the point lies on a vertices (points) of the polygon, if it does, we return true, problem solved. (Image 2)
Image 2 -- Polygon boundaries, point P is on a vertices, return true.
Step 3
This next step is the most gratifying one, by now we know the point is with the polygon boundaries (from step 1) but we don't know if it's within it or not. The way to solve this we cast an imaginary line departing from the point to any direction, if it crosses the path of polygon even number of times, the point is outside of the polygon, if it crosses an odd number of times, the point is within the polygon. Like so:
Image 3 -- An imaginary line from P1 crosses the polygon paths an odd number of times (3 times), it's within the polygon boundaries. A imaginary line from P2 crosses an even number of times (4 times), it lies outside of the polygon.
Since we can pick any direction we want to cast the imaginary line from, we'll pick along the x-axis to simplify things, like so:
Image 4 -- Casting the imaginary line from point P parallel to the x-axis t0 simplify determining how many times it intersects our polygon.
To determine how many times the imaginary line intersects our polygon, we have to check each path of the polygon at a time. To do this, we break it down into two steps (see image 5 for references):
For each segment/path of the polygon we check if our point Py (y-component of our point P) is within the the boundaries of the path in question (Y1 and Y2). If it is not, we know our point is does not intersects that specific path and we can move on to the next one. If it is within the path's y-boundaries, then we have to check if it crosses our path in the x-direction (next step).
Assuming the step before is true, to check intersection in the x-direction we have calculate the equation for the path (using line equation: y2 - y1 = m(x2 - x1)) and plug in our Py component to solve for our intersection (in my code I call this Sx). Then we check if Sx is greater than Px, if so, then our imaginary line intersects the path in the x positive direction.
It's important to note that the imaginary line starts at our point P and we only count intersections in that direction we originally picked, in this case x-axis+. This is why Sx has to be grater than or equal to Px, otherwise the test fails.
Image 5 -- We break down each path of the polygon to determine the number of intersections.
Once this path is done we move to the next one and so on. In this case the line crosses 3 times our paths, and therefore we know it's within our polygon.
This is a very clever and simple way if you think about it, it works for any shape, it's truly amazing.
Read more
https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
Examples
Example 1 - Simple shapes
const p = new Polygon([
[-3, 3],
[-4, 1],
[-3, 0],
[-2, -1],
[0, 0],
[3, 2],
[0, 1],
[-1, 4],
]);
console.log("Contains: ", p.contains([-1, 1])); // returns true
JSFiddle 1
Example 2 - Complex shapes (overlapping areas)
This method works for more complex shapes, when the polygon coordinates creates overlappping areas and they cancel each other out.
const p = new Polygon([
[-2, 0],
[2, 0],
[2, 4],
[-2, 4],
[-2, 0],
[0, 2],
[2, 0],
[0, -2],
[-2, 0],
]);
console.log("Contains: ", p.contains([0, 1])); // returns false
JSFiddle 2
Side note
If you need to quickly plot points just to get a view of a shape/grid, this plotting tool helped a lot to get a visual of what's going on. Very often I thought my code had a bug when in fact my coordinates was skewed and code was correct.
https://www.desmos.com/calculator
I only wish it let you draw lines between points. Either way I found it helpful.
I'm not sure what to search for or how to ask the question as I can't draw. Please bear with me.
If I have a rectangle with circular end caps. I want to remove some of the edges of the rectangle so there is a smooth path all round. Kinda like of you were to stretch the ends, the middle gets thinner.
I was trying to work out the chord of a larger, outer circle until I got stuck trying to work out where the circles should touch.
I can see some relationships for trigonometry, but my brain just won't go the extra mile.
Can anyone please help point me in the right direction.
Thanks.
Here is the answer:
// Small value for CSG
Delta = 0.01;
2Delta = 2 * Delta;
$fa=1; $fs=$fa;
module roudedArm(xl=50, yt=10, zh=5, in=2, bh=0.8) {
EndRadius = yt/2; // size of outer ends
EndSpacing = xl-yt; // distance between end point radii
ArmConcavity = in; // how much in does it go in on each side
ArmThickness = zh; // height in z
// Negative curve to narrow the Arm (calculated by pythagoras)
ArmCurveRadius = (pow((EndSpacing / 2), 2) - 2 * EndRadius * ArmConcavity + pow(ArmConcavity, 2)) / (2 * ArmConcavity);
// The orthogonal distance between the middle of the Arm the point it touches the round pillar sections
ArmSectionLength = (EndSpacing / 2) * ArmCurveRadius / (ArmCurveRadius + EndRadius);
// end points
lbxcylinder(r=EndRadius, h=ArmThickness);
translate([EndSpacing, 0, 0]) lbxcylinder(r=EndRadius, h=ArmThickness);
// inner curve
difference()
{
translate([EndSpacing / 2 - ArmSectionLength, -EndRadius -ArmThickness, 0])
translate([ArmSectionLength, (EndRadius + ArmThickness),0])
lbxcube([ArmSectionLength * 2, 2 * (EndRadius + ArmThickness), ArmThickness], bh=bh);
// Cut out Arm curve
translate([EndSpacing / 2, ArmCurveRadius + EndRadius - ArmConcavity, -Delta])
lbxcylinder(r = ArmCurveRadius, h = ArmThickness + 2Delta, bh=-bh);
translate([EndSpacing / 2, -(ArmCurveRadius + EndRadius - ArmConcavity), -Delta])
lbxcylinder(r = ArmCurveRadius, h = ArmThickness + 2Delta, bh=-bh);
}
}
module lbxcube(size, bh=0.8) {
// don't support bevelling in demo
translate([-size[0]/2, -size[1]/2, 0]) cube(size);
}
module lbxcylinder(r, h, bh=0.8) {
// don't support bevelling in demo
cylinder(r=r, h=h);
}
roudedArm(xl=50, yt=10, zh=5, in=2, bh=0.8);
Thanks to Rupert and his Curvy Door Handle on Thingiverse.
Is there a way to fill a closed drawn path in easeljs? I have along string of mt(x_t,y_t).lt(x_(t+1),y_(t+1)) that draws a wacky shape. the shape closes off, but I can't find a way to have it actually fill in the closed area. Any ideas?
T is how many coordinates there are to connect, [round.X, round.Y] is the Tx2 array of coordinate pairs, ghf is the graphics object. xline.y is just a the lowest y value.
for(var i=0;i<T;i++){
x0 = round.X[i];
y0 = round.Y[i];
// scale for drawing
px0 = Math.round(xscale * x0);
py0 = Math.round(yscale * y0) + xline.y;
if(x0>gp.xmin){ // if not first point ...
ghf.mt(prevx,prevy).lt(px0,py0); // draw line from prev point to this point
}
// set this point as prev point
prevx = px0;
prevy = py0;
}
// fill out thing
ghf.mt(prevx,prevy).lt(px0,xline.y);
ghf.mt(px0,xline.y).lt(0,xline.y);
x0 = round.X[0];
y0 = round.Y[0];
px0 = Math.round(xscale * x0);
py0 = Math.round(yscale * y0) + xline.y;
ghf.mt(0,xline.y).lt(px0,py0);
ghf.f('red');
Your code is not very helpful, but I think what you need is the beginFill method. See link.
You can use it like this:
var ball = new createjs.Shape();
ball.graphics.setStrokeStyle(5, 'round', 'round');
ball.graphics.beginStroke(('#000000'));
ball.graphics.beginFill("#FF0000").drawCircle(0,0,50);
ball.graphics.endStroke();
ball.graphics.endFill();
ball.graphics.setStrokeStyle(1, 'round', 'round');
ball.graphics.beginStroke(('#000000'));
ball.graphics.moveTo(0,0);
ball.graphics.lineTo(0,50);
I am looking for an algorithm or help developing one for creating a tie-dye pattern in a 2-dimensional canvas. I will be using HTML Canvas (via fabric.js) or SVG and JavaScript, but I'm open to examples in any 2D graphics package, like Processing.
I would draw concentric rings of different colors, and then go around radially and offset them. Here's some pseudo-code for drawing concentric rings:
const kRingWidth = 10;
const centerX = maxX / 2;
const centerY = maxY / 2;
for (y = 0; y < maxY; y++)
{
for (x = 0; x < maxX; x++)
{
// Get the color of a concentric ring - assume rings are 10 pixels wide
deltaX = x - centerX;
deltaY = y - centerY;
distance = sqrt (deltaX * deltaX + deltaY * deltaY);
whichRing = int(distance / kRingWidth);
setPixel(x, y, myColorTable [ whichRing ]); // set the pixel based on a color look-up table
}
}
Now, to get the offsets, you can perturb the distance based on the angle of (x, y) to the x axis. I'd generate a random noise table with, say 360 entries (one per degree - you could try more or fewer to see how it looks). So after calculating the distance, try something like this:
angle = atan2(y, x); // This is arctangent of y/x - be careful when x == 0
if (angle < 0) angle += 2.0 * PI; // Make it always positive
angle = int(angle * 180 / PI); // This converts from radians to degrees and to an integer
distance += noiseTable [ angle ]; // Every pixel at this angle will get offset by the same amount.