Programatically creating a triangle grid from centerpoint on graph - javascript

Im going to try to explain this as best as I can.
I have a centerpoint defined on a canvas element where I am using Kinetic JS to draw triangles.
What I want to do, is create an array of coordinates based on the center point of the excircle radius of a triangle (Kinetic draws regular polygons by using the excircle radius) to see how many of the triangle center points will fit on the canvas in a grid structure. Think this but bigger:
Now Ive already done this with squares because they fall in the same interval from the centerpoint on both the X axis and the Y axis. However with triangles this ends up being different due to where the radius center point of the excircle on a triangle is. Here is a semi clear picture illustrating the interval difference:
Now these coordinates HAVE to be pushed into an array in a very specific way, or else the way I have planned for them to interact will not work correctly.
Ultimately I want to find the bottom most triangle coordinate possible. Find out if that triangle is flipped at 180 degrees or 0 degrees respectively while making sure the centerpoint of the entire canvas is touching the vertex of a triangle.
Sounds complicated? It is. Ive been trying several different methods and racking my brain for two weeks now, and I cant figure out an algorithm that will allow me to do this from any canvas size possible.

Related

Konva-JS: how do you get the updated vertices coordinates for custom shape after translation, scale or rotation?

I'm using React-Konva (React version of KonvaJS) to draw custom shapes, mostly irregular polygons, and apply transformations to it, like moving them around, scaling and rotating.
Now, once the polygons are in place I need the coordinate of the vertices for another feature, but even though I move it around and transform and whatnot, the shape appears correctly modified but the vertices coordinates are still the initial ones.
For instance if I have a triangle at (0,0), (1,0), (0.5,2) and then drag it all the way to the right, after the drag ended the triangle will appear in the new position on the canva, but when printing the vertices it still will output (0,0), (1,0), (0.5,2).
How do you get the updated coordinates of all the vertices? I'm using the Shape class for the polygons with draggable set to true for the translation, and the Transformer class for scaling and rotating.
Canvas, and therefore Konva which is a wrapper & enhancer of canvas functionality, uses vector graphics. An important part of vector graphics is the concept of 'transform'-ing your shapes when you rotate or scale them. Essentially, the shape will tell you its position is unchanged when rotated or scaled, but the important fact is it's transform which is what does the rotation and scaling.
Long story short, without needing to understand the matrix math, you can 'get' the transform that is applied to your shape and give it the x,y positions of your shape's vertices/corners, and it will return the x,y of that point with the transform applied.
Here is an earlier answer to the same question but regarding rectangles. https://stackoverflow.com/a/65645262/7073944
This is vanilla JS but hopefully you can react-ify it.
The critical functions are node.getTransform and its close relation node.getAbsoluteTransform methods will retrieve the transform applied to the node (shape).

How to fill the space between two cylinder meshes. Three.js

I have a code that generates cylinders based on an array of 3d vectors.
The problem is that they have those ugly spaces between them:
Does any one know how I can fill them in the newest version of three.js?
Thanks in advance!!
To fill the gaps, I'd suggest you just use a sphere with the same radius as the cylinders, centered at the point the two cylinders meet.
Set height & width segment counts to match the cylinders so it all looks consistent.
The parts that aren't filling the gap will just get hidden inside the cylinders, and won't be visible.
If you want to keep the vertex count down, you could use the theta parameters on the Sphere Geometry to only generate the parts that you actually need to fill the gap.
https://threejs.org/docs/?q=sphere#api/en/geometries/SphereGeometry
Alternatively, if what you are really trying to achieve is a curved object with a circular cross-section, you could drop the cylinders altogether, and extrude a circle along a curve to achieve the shape that you want.
https://threejs.org/docs/?q=extrude#api/en/geometries/ExtrudeGeometry
https://threejs.org/examples/webgl_geometry_extrude_shapes.html

I need to "redefine" Canvas coordinates, so the center is {0,0}

I have some coordinates which i want to display as points, but they are in the negative range. I need to redefine the center of the canvas, so it won't be {width/2, height/2}, but it will be truly the {0,0}, or origo of the canvas.
I tried flipping scales and translating coordinates so far, but it just skews the coordinates. If what I mentioned in the title cannot be done, i need some tips to overcome this problems, since im not that great with this kind of stuff.
Since it's coordinates of a game's map, i would like to see the exact copy of that.

Rotating a Rectangle from any point

I'm trying to write a script (javascript) in an API of a Virtual Table Top program so I can manipulate some tokens (Car Wars :)).
I'm sort of finding the answer, but it seems like I'm struggling and reinventing the wheel so I thought I'd ask for help. One reason I'm getting confused is the program returns results based on +y is down and Deg go clockwise which is different than what all the trig formulas want (counter clockwise and +y is up).
Here is what I have access to. Rectangle rotates around centre, Centre point(x,y), width, height, and rotation. I've got the code working for moving the rectangle in the direction of the rotation, side to side, up and down, etc. Now I need to be able to rotate it around any of the four corners or any point would be nice, but four corners are all thats needed.
It won't let me include an image since I'm new so I hope the description is good enough. I had an image all done up. :(
In the API I can't actually draw the rectangle, I can only set its rotation, and centre value. So my thought was if I can find the x,y of one corner currently, then rotate it the desired degs around the centre (I can do this easily by setting the rectangles rotation), find the new x,y of that same corner. Then I will know the offset and apply that to the centre (thats how the rectangle is moved as well).
So I need to be able to find the x,y of any corner of a rectangle at any given starting angle, then again at a new angle rotated at its centre. This offset would then be easily applied to the centre x,y and the rectangle would see to have rotated along one of its corners.
Thanks for any help you can give. I'm hoping I will eventually figure it out, just writing this description out actually has helped me think it through. But I'm currently stuck!
Konrad
The trick to rotating around an arbitrary point in 2d (eg, one of the four corners of the rectangle), is to first translate the vertices of the shape so that the point around which you want to rotate is in the origin (ie 0,0).
To achieve this:
1. Translate your rectangle by (-x, -y).
2. Rotate your rectangle by the desired angle.
3. Translate your rectangle by (x, y) to place it back where it originally was.
where (x,y) is the x/y coordinates of the point around which to rotate.
You can use negative angles to adjust for clockwise rotations.
There is a lot of info about this on the net, for example:
http://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/2drota.htm

How can I (somewhat) evenly distribute dynamically-sized SVG shapes within a canvas?

I'm looking for some high-level recommendations for how to implement a project I'm starting for a client.
This is a web page that will include an SVG canvas (sized 920px W x 450px H) containing 20-40 "circular" images (i.e., they may just be square images cropped with a circle). The size of the images will probably range from about 50px to about 200px diameter, each one set dynamically within that range based on data from an API. It's basically a dynamic data visualization, so pretty much every aspect of this needs to be configurable/dynamic.
I think the hardest problem to solve is how to distribute these images within the given canvas area, considering that they will vary in size, and should appear to be evenly/randomly distributed (i.e., they shouldn't line up to a grid, be clumped together, or be in groups of similar sizes). It's OK if they overlap slightly. Here's a quick sketch of how this should look, ideally (each gray circle represents an image):
https://skitch.com/troywarr/gwj14/adobe-fireworks-cs5
FWIW, I was planning to use Raphaƫl as an SVG library; I'll also have jQuery available and can probably use any other libraries as needed. This needs to be cross-browser compatible back to IE7.
Can anyone suggest a general approach to this problem, any specific libraries or algorithms to look into, or provide any other guidance or suggestions? Please let me know if this description isn't clear, or if you need any additional details.
Thanks in advance!
Here is how I would tackle it:
First decide on the percentage of the screen that will be filled in with circles and the number of circles that will be displayed. You can use that to determine the average radius of each circle using the area of a circle formula - e.g. given x circles what would the average radius of all the circles have to be to cover y% of my container. You can then decide how much you want the radius to vary, that is +/- 50%. Unless the number of circles is very small you should get a good result - statistically that is.
Then I would divide the screen in to a rectangular grid - I know that is not what you want just be patient :) The dimensions of the grid are calculable from the number of circles, e.g. 16 circles would fit nicely into a 4 X 4 grid. The number of circles can be less than the number of cells but not a lot less.
I would then select a random x,y co-ordinate inside each grid cell as my circle's center. I would also leave a padding of about 25% around the edges so that my circle is not centered too close to an edge.
You could then check for overlap - the ratio of (r1 + r2) / distance between the circle center points will equal 1 if the circles touch, be less than 1 if they don't and greater than 1 if they overlap. A ratio of 1.1 is a small overlap; careful of the limit here - exact same centers result in a distance of 0 and a division by 0 error.
One thing to worry about but should not happen unless you pick a very high initial coverage percentage or the number if circles is much smaller than the number of cells. If all the cells adjacent to a given cell have circles close to that cells edges, especially if they overlap the edge, there may not be enough room (even with circle overlap) for the current cell's circle. This can be checked for and handled by shrinking the radius or moving a circle away...
NOTE if the number of desired circle's does not exactly match your square (or rectangular) grid, just randomly leave some cells empty...
Here's a rough description of the approach I took after all. Sorry, pressed for time so this may be inexact.
I initially approached the problem similarly to #BigMac66's answer. I laid out a grid corresponding to the quantity of circles I had, drew a circle in each and then randomly shifted the circles from the center point of each grid cell.
I built in a variety of "fudge factors" - circle radius bounds, offset from center, maximum overlap with adjacent cells, etc. - but, no matter how I tweaked my settings, you could still always tell that a grid was behind the layout; the circles aligned just enough to look like a wonky polka dot pattern rather than a truly random collection of circles.
So, I changed to a more brute-force approach.
First, I set up configurable bounds for the radius of a circle, tweaking the upper bound until I found a maximum size that didn't make the canvas look crowded based on the total number of circles I had.
Then, I applied my math to size the circles as needed (in short, the largest circles represented a 100% value, and the smallest represented a 0% value; the rest were sized accordingly based on where they fell in the spectrum).
Then, I sorted the circles descending by size. I laid them out randomly on the canvas, using an algorithm roughly like so:
Place a circle at random coordinates.
Place the next circle at random coordinates.
If the latter circle overlaps the former by more than X pixels (configurable param), place it at a new set of random coordinates.
Continue step #3 for up to Y times (another configurable param) until you successfully place another circle.
If you can't place the circle in Y times, clear the canvas, drop the maximum circle radius by Z pixels (another configurable param) and start over.
This worked surprisingly well, and I tweaked the params until I could draw the entire canvas very quickly while requiring few maximum circle radius reductions.
You can actually see the finished product here:
http://www.eonline.com/news/2012_sag_awards/heatgauge
It's out of season, so click the "Overall View" tab at the top of the main box to see cumulative stats (and hence a full canvas of circles).

Categories

Resources