object instances created on xformed and rotated grids - processing

In the fiddle below, I've drawn circles at certain points along a recursive tree structure.
https://jsfiddle.net/ypbprzzv/4/
The tree structure itself is a simplified version of the one found here:
https://processing.org/examples/tree.html
What if instead of drawing circles at (0, -h) on transformed and rotated grids, which is where they're being drawn in the fiddle, I wanted to hang pendulums which would hang in the unrotated y direction (down). If the pendulums were instances of an object class, it would be easy to add a new instance instead of (or in addition to) drawing the circle.
void branch(float h) {
h *= 0.6;
if (h > 10) {
pushMatrix();
rotate(a);
line(0, 0, 0, -h);
fill(0, 175, 0, 100);
if (h < 50) {
// I could add a new pendulum here, at (0, -h)
ellipse(0, -h, 5, 5);
}
translate(0, -h);
branch(h);
popMatrix();
} // closing the if statement
} // closing branch function
I have already tried this but because I wanted to keep the code very brief, I have not included it. The pendulums do indeed hang, but in wacky directions, since when I create these instances, the whole grid is xformed and rotated (which needs to be the case to simplify the drawing the tree or other interesting structures).
And suppose I want to make these pendulums sensitive to user interactions. The objects' frames of reference are different from the users'.
So I'll try to summarize the question:
Is it possible to create instances of objects on a transformed and rotated grid, but have that object behave in a prescribed way in relation to the unrotated grid?
Would it be helpful to provide a fiddle including the pendulums?

It's a little bit hard to help with general "how do I do this" or "is it possible" questions like this. The reason that it's hard to answer "is it possible" questions is the answer is almost always yes, it's possible. Similarly, "how do I do this" questions always have about a million possible answers, and there isn't any single best way to approach a problem. The "right" answer is really more dependent on how you think about the problem than anything else. But I'll try to help in a general sense.
Is it possible to create instances of objects on a transformed and rotated grid, but have that object behave in a prescribed way in relation to the unrotated grid?
Yes, it's possible.
There are a number of ways you might approach this:
You might keep track of the current state (current rotation) and then undo that when you draw the pendulum. For example, if you're rotated to 90 degrees, you'd simply rotate by -90 degrees before drawing the pendulum.
You could maybe use the screenX() and screenY() functions to get the screen location of a transformed point. More info can be found in the reference.
You could store positions as you recursively draw the tree, and then after the tree is drawn, you could loop over those points to draw the pendulums.
These are just what I could think of right now, and there are probably more ways to approach it. Again, which approach you choose really depends on how this stuff fits into your brain, which is pretty hard to help you with.
But if you want my two cents: I personally find it hard to "think in transformations" to do stuff like what you're describing. Instead, if I were you, I would refactor the code so it no longer relies on translations and rotations. I'd use basic trig (the sin() and cos() functions) to draw everything. Then you'd already be in screen coordinates, so drawing your pendulums would be much easier.
But again, which approach you take really depends on how you think about things.

Related

Organic shape that fills up space with Paper.js

I'm aware my question is maybe somewhat lazy. But I hope someone could maybe give me head start with my idea, or can provide me with an existing code example that points me in the right direction.
I want to create an organic shape/blob that more or less fills up existing space, but wraps around typographical elements. Whenever these elements move around, the shape should adjust itself accordingly. I was looking at Paper.js where examples like http://paperjs.org/examples/candy-crash/ and http://paperjs.org/examples/voronoi/ make it seem like this should be possible.
You can use the path.subtract() boolean operation, along with the path.smooth() function to smooth your shape with the type of smoothing of your choice.
Here is a demo sketch. You can also try to smooth the rectangles ; and maybe randomly add points on your curves or randomly displace all segment handles.

How do I synchronize scale and position of map and point layers in d3.js?

I've seen many example maps in d3 where points added to a map automatically align as expected, but in code I've adapted from http://bl.ocks.org/bycoffe/3230965 the points I've added do not line up with the map below.
Example here: https://naltmann.github.io/d3-geo-collision/
(the points should match up with some major US cities)
I'm pretty sure the difference is due to the code around scale/range, but I don't know how to unify them between the map and points.
Aligning geographic features geographically with your example will be challenging - first you are projecting points and then scaling x,y:
node.cx = xScale(projection(node.coordinates)[0]);
node.cy = yScale(projection(node.coordinates)[1]);
The ranges for the scales is interesting in that both limits of both ranges are negatives, this might be an attempt to rectify the positioning of points due to the cumulative nature of forces on the points:
.on('tick', function(e) {
k = 10 * e.alpha;
for (i=0; i < nodes.length; i++) {
nodes[i].x += k * nodes[i].cx
nodes[i].y += k * nodes[i].cy
This is challenging as if we remove the scales, the points move farther and farther right and down. This cumulative nature means that with each tick the points drift further and further from recognizable geographic coordinates. This is fine when dealing with a set of geographic data that undergoes the same transformation, but when dealing with a background that doesn't undergo the same transformation, it's a bit hard.
I'll note that if you want a map width of 1800 and a height of 900, you should set the mercator projection's translate to [1800/2,900/2] and the scale to something like 1800/Math.PI/2
The disconnection between geographic coordinates and force coordinates appears to be very difficult to rectify. Any solution for this particular layout and dimensions is likely to fail on different layouts and dimensions.
Instead I'd suggest attempting to use only a projection to place coordinates and not cumulatively adding force changes to each point. This is the short answer to your question.
For a longer answer, my first thought was to get rid of the collision function and use an anchor point linked to a floating point for each city, only drawing the floating point (using link distance to keep them close). This is likely a cleaner solution, but one that is unfortunately completely different than what you've attempted.
However, my second thoughts were more towards keeping your example, but removing the scales (and the cumulative forces) and reducing the forces to zero so that the collision function can work without interference. Based on those thoughts, here's a demonstration of a possible solution.

Three js performance

Hy!
I am working with huge vertice objects, I am able to show lots of modells, because I have split them into smaller parts(Under 65K vertices). Also I am using three js cameras. I want to increase the performance by using a priority queue, and when the user moving the camera show only the top 10, then when the moving stop show the rest. This part is not that hard, but I dont want to put modells to render, when they are behind another object, maybe send out some Rays from the view of the camera(checking the bounding box hit) and according hit list i can build the prior queue.
What do you think?
Also how can I detect if I can load the next modell or not.(on the fly)
Option A: Occlusion culling, you will need to find a library for this.
Option B: Use a AABB Plane test with camera Frustum planes and object bounding box, this will tell you if an object is in cameras field of view. (not necessarily visible behind object, as such a operation is impossible, this mostly likely already done to a degree with webgl)
Implementation:
Google it, three js probably supports this
Option C: Use a max object render Limit, prioritized based on distance from camera and size of object. Eg Calculate which objects are visible(Option B), then prioritize the closest and biggest ones and disable the rest.
pseudo-code:
if(object is in frustum ){
var priority = (bounding.max - bounding.min) / distanceToCamera
}
Make sure your shaders are only doing one pass. As that will double the calculation time(roughly depending on situation)
Option D: raycast to eight corners of bounding box if they all fail don't render
the object. This is pretty accurate but by no means perfect.
Option A will be the best for sure, Using Option C is great if you don't care that small objects far away don't get rendered. Option D works well with objects that have a lot of verts, you may want to raycast more points of the object depending on the situation. Option B probably won't be useful for your scenario, but its a part of c, and other optimization methods. Over all there has never been an extremely reliable and optimal way to tell if something is behind something else.

Raytracing (LoS) on 3D hex-like tile maps

Greetings,
I'm working on a game project that uses a 3D variant of hexagonal tile maps. Tiles are actually cubes, not hexes, but are laid out just like hexes (because a square can be turned to a cube to extrapolate from 2D to 3D, but there is no 3D version of a hex). Rather than a verbose description, here goes an example of a 4x4x4 map:
(I have highlighted an arbitrary tile (green) and its adjacent tiles (yellow) to help describe how the whole thing is supposed to work; but the adjacency functions are not the issue, that's already solved.)
I have a struct type to represent tiles, and maps are represented as a 3D array of tiles (wrapped in a Map class to add some utility methods, but that's not very relevant).
Each tile is supposed to represent a perfectly cubic space, and they are all exactly the same size. Also, the offset between adjacent "rows" is exactly half the size of a tile.
That's enough context; my question is:
Given the coordinates of two points A and B, how can I generate a list of the tiles (or, rather, their coordinates) that a straight line between A and B would cross?
That would later be used for a variety of purposes, such as determining Line-of-sight, charge path legality, and so on.
BTW, this may be useful: my maps use the (0,0,0) as a reference position. The 'jagging' of the map can be defined as offsetting each tile ((y+z) mod 2) * tileSize/2.0 to the right from the position it'd have on a "sane" cartesian system. For the non-jagged rows, that yields 0; for rows where (y+z) mod 2 is 1, it yields 0.5 tiles.
I'm working on C#4 targeting the .Net Framework 4.0; but I don't really need specific code, just the algorithm to solve the weird geometric/mathematical problem. I have been trying for several days to solve this at no avail; and trying to draw the whole thing on paper to "visualize" it didn't help either :( .
Thanks in advance for any answer
Until one of the clever SOers turns up, here's my dumb solution. I'll explain it in 2D 'cos that makes it easier to explain, but it will generalise to 3D easily enough. I think any attempt to try to work this entirely in cell index space is doomed to failure (though I'll admit it's just what I think and I look forward to being proved wrong).
So you need to define a function to map from cartesian coordinates to cell indices. This is straightforward, if a little tricky. First, decide whether point(0,0) is the bottom left corner of cell(0,0) or the centre, or some other point. Since it makes the explanations easier, I'll go with bottom-left corner. Observe that any point(x,floor(y)==0) maps to cell(floor(x),0). Indeed, any point(x,even(floor(y))) maps to cell(floor(x),floor(y)).
Here, I invent the boolean function even which returns True if its argument is an even integer. I'll use odd next: any point point(x,odd(floor(y)) maps to cell(floor(x-0.5),floor(y)).
Now you have the basics of the recipe for determining lines-of-sight.
You will also need a function to map from cell(m,n) back to a point in cartesian space. That should be straightforward once you have decided where the origin lies.
Now, unless I've misplaced some brackets, I think you are on your way. You'll need to:
decide where in cell(0,0) you position point(0,0); and adjust the function accordingly;
decide where points along the cell boundaries fall; and
generalise this into 3 dimensions.
Depending on the size of the playing field you could store the cartesian coordinates of the cell boundaries in a lookup table (or other data structure), which would probably speed things up.
Perhaps you can avoid all the complex math if you look at your problem in another way:
I see that you only shift your blocks (alternating) along the first axis by half the blocksize. If you split up your blocks along this axis the above example will become (with shifts) an (9x4x4) simple cartesian coordinate system with regular stacked blocks. Now doing the raytracing becomes much more simple and less error prone.

How does the fill operation work in paint applications?

All paint programs, independent of how simple or complex they are, come with a fill tool. This basically replaces the color of a closed region with another color. I know that there are different APIs to do this, but I am interested in the algorithm. What would be an efficient algorithm to implement this tool?
A couple of things I can think of quickly are:
Convert image into a binary map, where pixels in the color to be replaced are 1 and all other colors are 0.
Find a closed region around the point you want to change such that all the pixels inside are 1 and all the neighbouring pixels are 0.
Sample Image
Many implementations are done as a recursive conquer and divide algorithm. If you do a quick google for "flood fill algorithm" you will find plenty of resources including the excellent wikipedia page on the topic.
The Flood Fill algorithm is what's most commonly used. The following is a naive version of it straight out of my old university textbook, "Computer Graphics with OpenGL" by Hearn Baker, 3rd ed:
void floodFill4 (int x, int y, int fillColor, int interiorColor)
{
int color;
/* Set current color to fillColor, then perform the following operations */
getPixel(x, y, color);
if (color == interiorColor)
{
setPixel(x,y); // Set color of pixel to fillColor.
floodFill4(x + 1, y, fillColor, interiorColor);
floodFill4(x - 1, y, fillColor, interiorColor);
floodFill4(x, y + 1, fillColor, interiorColor);
floodFill4(x, y - 1, fillColor, interiorColor);
}
}
For large images, however, the above will probably give you a stack-overflow error due to recursing for every pixel. Often, this algorithm is modified so that it uses iteration when filling a row of pixels, then recursively fills the rows above and below. As #kasperjj stated, wikipedia has a good article about this.
These kinds of algorithms are discussed in detail in Computer Graphics: Principles and Practice. I highly recommend this book if you're interested in understanding how to rasterize lines, fill polygons, writing 3d code without the benefit of using DirectX or OpenGL APIs. Of course, for real world applications, you'll probably want to use existing libraries, but if you're curious about how these libraries work, this is an awesome read.
If you want a time efficient algorithm that doesn't care very about memory efficiency, you can do it by:
1) keeping a boolean memory of which cells you have already visited: Vis[]
2) keeping a list of points you have already visited but have not yet marked the neighbours for: Busy[]
3) start both of those as empty
4) add your start point to Busy
5)
while you have a point P in Busy:
{
for each neighbour N of the point P for which Vis[N] is still false
{
if appropriate (not crossing the boundary of the fill region)
{
set Vis[N] to true
update the colour of N in the bitmap
add N to the end of Busy[]
}
remove P from Busy[]
}
}
Also read about connected component labelling. This is an efficent way to find connected pixels whilst only visiting every pixel twice.
Wikipedia article.
The advantage to this is that the pixel values don't have to necessarily be the same or the function that describes pixels as connected could be something other than raw value - gradient perhaps.
General idea is described as Flood Fill Algorithm and there are various modifications to it. A common one is scanline fill. See the related question How Scanline based 2d rendering engines works?

Resources