I have a code that lets users enter data and plots it with a tube geometry. The code seems to work fine most of the time, however, one of the test data sets is not coloring properly.
Here is an example page for a site that I am building that solves for the position and velocity of a bungee jumper. Scroll to the bottom of the page and you will see a three js environment with a sin wave and a plot of the position of the jumper. These two items are charted with separate color maps and you can see that the sin wave is colored properly but the data is not.
At first I thought that maybe the data was too sparsely populated, but that was not the problem.
The code for this is too long to really paste here, but the fact that it charts right for all other data sets makes me think that I am missing something inherent to the tubeGeometry function.
Any ideas as to why the one tube is miscolored?
UPDATE: When I add additional interpolated points between each existing point in the data set, the error lessons. The more the padding, the less the error. This leads me to think that the error is due to the difference between the interpolation of the spline function from Three.SplineCurve3 and the true data. This would also explain why my other examples work fine since they are all sinusoid data.
How can I prevent SplineCurve3 from doing this, or what else can I use to create the Tube geometry?
I guess it is the mesh length counting problem (three did not count length on vector+vector+vector but by mesh.position+bounding radius)
Maybe you can separate curve to parts and color each part independent on their lenght.
There are some working approaches:
https://stemkoski.github.io/Three.js/Graphulus-Curve.html
https://stemkoski.github.io/Three.js/Graphulus-Surface.html
https://stemkoski.github.io/Three.js/Graphulus-Function.html
Related
I have a GeoJSON file with small details and features that I want to render using D3. Unfortunately, important details are lost because D3
removes polygon coordinate pairs that are closely spaced.
I've set up a small example to show this. Both links use the exact same GeoJSON data, rendered with both D3-geo and mapbox through github.
Specifically, notice the two areas marked by the red circles.
https://bl.ocks.org/alvra/eebb06be793bc06ff3ae01e6945298b6
https://gist.github.com/alvra/eebb06be793bc06ff3ae01e6945298b6
The top one one marks a part of polygon that is rounded using many closely spaced coordinate pairs, but D3 removes most points and just draws a rough square end.
The lower red circle marks a tiny triangle that is removed altogether. The adjacent polygons should touch exactly, but are also affected by D3's loss of precision.
I haven't found any documentation about D3's coordinate precision or a (configurable) feature size limit.
I've tried decreasing D3-geo's EPSILON and related EPSILON2 values and that removes this problem (for me), although I'm sure even smaller features will still be affected.
Assuming this is related to the fact that D3 uses proper geodesics for polygon segments, while the other mapping libraries just draw straight lines (in the output coordinate space),
I was hoping that this process can only introduce new points.
I haven't been able to find other users experiencing similar problems with small features, although I'm surprised this has never come up before.
Does anyone have an idea about the proper way to deal with this?
Through epsilon, I've narrowed the problem down to this use of pointEqual(). This indicates the problem is with clipCircle considering closely spaced coordinates equal and removes them.
Indeed, if I disable circular clipping projection.clipAngle(null), the problem disappears.
I'd like to transition between curve types using D3.js.
Take a look at this block. The data stay the same but the curve type changes. I was expecting the paths to maintain their approximate positions on the plane -- the data stay the same, after all -- but they don't. The paths appear to be redrawn, although I don't understand why with basis to linear the paths seem to be redrawn from left to right whilst with linear to basis the paths seem to be redrawn from right to left.
I've read Mike Bostock's post on Path Transitions, but I think this is a slightly different problem. There, the data change but the curve type remains the same. Here, the data stay the same but the curve type changes.
Thanks in advance for any help!
To understand why you have such a strange transition, let's compare the d attribute of the paths using a curveBasis and a curveLinear.
First, a curveBasis:
d="M0,101.2061594964L45.48756294826797,89.52282837400001C90.97512589653594,77.83949725160001,181.95025179307189,54.47283500680002,271.46268884480395,84.08731623460001C360.975125896536,113.70179746240001,449.0248741034641,196.2974221628,538.5373111551961,222.09899531679994C628.0497482069281,247.90056847079998,719.0248741034642,216.90809007840002,764.512437051732,201.4118508822L810,185.915611686"
Now a curveLinear (same data):
d="M0,101.2061594964L272.92537768960784,31.10617276200003L537.0746223103922,278.89304686319997L810,185.915611686"
As you can see, the path is way simpler with curveLinear. So, the strange transition is the expected behaviour.
A possible solution is using a path interpolation, as proposed in this code from Mike Bostock.
Here is your bl.ocks with a path interpolation: http://blockbuilder.org/anonymous/02125b1fb145a979e53f369c4976a772
PS: If you want to avoid that strange transition when you load the page (all paths coming from the top left corner), draw them the first time using a regular attr method.
I got a data set that where each sample has a size (0-1000) and a value (grade 1-5). I want to visualise the data with circles of different sizes along a line (domain axis), much like:
http://www.nytimes.com/interactive/2013/05/25/sunday-review/corporate-taxes.html?_r=1&
(note that circles even with the same effective taxrate do not overlap)
Example data:
sample 1: size 300 value 3.2
sample 2: size 45 value 3.8
sample 3: size 4400 value 4.0
sample 5: size 233 value 0.2
sample 6: size 4000 value 4.2
How can the data above be visualised using circles on a line (size decides diameter, value decides approximate position on the line) so that circles do not overlap?
I've been looking at D3's packing layout, but from what I can tell it doesn't support this out of the box. Anyone got any ideas on how to approach this?
Oooh, this one was a puzzle...
If you look at the code for the NYTimes graphic, it uses pre-computed coordinates in the data file, so that's not much use.
However, there's an unused variable declaration at the top of the script that hints that the original version used d3.geom.quadtree to lay out the circles. The quadtree isn't actually a layout method; it is used to create a search tree of adjacent nodes, so that when you need to find a node in a given area you don't have to search through the whole set. Example here.
The quadtree can therefore be used to identify which of your datapoints might be overlapping each other on the x-axis. Then you have to figure out how much you need to offset them in order to avoid that overlap. The variable radii complicate both functions...
I've got a test case implemented here:
http://fiddle.jshell.net/6cW9u/5/
The packing algorithm isn't perfect: I always add new circles to the outside of existing circles, without testing whether they could possibly fit closer in, so sometimes you get significant extra whitespace when it is just the far edges of circles bumping into each other. (Run it a few times to get an idea of the possibilities -- note that I've got x-variables distributed as random normal and r-variables distributed as random uniform.) I also got a stack overflow on the recursive methods during one iteration with N=100 -- the random distribution clearly wasn't distributed well enough for the quadtree optimization.
But it's got the basic functionality. Leave a comment here if you can't follow the logic of my code comments.
--ABR
Update
New fiddle here: http://fiddle.jshell.net/6cW9u/8/
After a lot of re-arranging, I got the packing algorithm to search for gaps between existing bubbles. I've got the sort order switched (so that biggest circles get added first) to show off how little circles can get added in the gaps -- although as I mention in the code comments, this reduces the efficiency of the quadtree search.
Also added various decoration and transition so you can clearly see how the circles are being positioned, and set the r-scale to be square root, so the area (not radius) is proportional to the value in the data (which is more realistic, and what the O.P. asked for).
D3's packing layout is not the answer here. It places circles in a spiral fashion around the existing group. Here's me reverse-engineering the algorithm behind packing layout:
I would suggest a force layout-based approach. That way, you can give your nodes force towards a gravitational center, and then let gravity do its thing.
Force layouts (e.g. Clustered Force Layout I) are usually animations, so you'll want to apply a static force layout.
I've wrapped up this approach in an example block, which looks like this:
My need is to draw a basic x-axis, y-axis plot of several lines, with the lines becoming known in sequence as the user enters data. jqPlot appears to have the ability (unlike flot, at least as I understand it) to add to an existing plot. My experimentation thus far is:
$.jqplot('dpCum',[ld.fCumPairFwd[0]],{axes:{xaxis:{min:0,max:2500},yaxis:{min:0,max:200000}}});
$.jqplot('dpCum',[ld.fCumPairAft[0]],{axes:{xaxis:{min:0,max:2500},yaxis:{min:0,max:200000}}});
which produces two lines as I want them, except the background of the 2nd obscures the the 1st line. In practice, the data for the 2nd line won't be known until the user responds to the 1st line, and then they're going to want to see both at once.
I've made a couple of passes at the jqplot documentation (it's capabilities are obviously impressive) but how to keep existing lines visible as new lines are added escapes me. I'm thinking there may be some kind of z-axis opacity, but haven't been able to understand it yet.
The answer to your problem, I believe, is to use the replot() method and paint a new plot with the modified data set.
This approach is presented in the following sample. Please notice I made only the series with index 0 responsive to clicks. On click on the series' data points another is painted.
EDIT: The reason I went for replot() was that I couldn't figure out how to draw just a single series. I tried the approach presented by #Mark here with no success. He might know better though. I am rather fresh to jqPlot myself. Also taking into account that when we add a new series some points might reach outside the current scale, therefore, since redraw() doesn't rescale as mentioned here by the jqPlot author - though in my case it will work since we reinitialize the graph. Thus, I think if you also will not manage to apply single series draw you might try using the redraw() method instead, taking from the doc I think it is less expensive to call.
Maybe actually in this case you will not use replot() or redraw(), as in the sample I am making a new plot each time. Therefore, it seems to me to be more appropriate to call destroy() on the previous graph before we paint the new one. This is what currently is in the code sample.
To give you some background as to what I'm doing: I'm trying to quantitatively record variations in flow of a compressible fluid via image analysis. One way to do this is to exploit the fact that the index of refraction of the fluid is directly related to its density. If you set up some kind of image behind the flow, the distortion in the image due to refractive index changes throughout the fluid field leads you to a density gradient, which helps to characterize the flow pattern.
I have a set of routines that do this successfully with a regular 2D pattern of dots. The dot pattern is slightly distorted, and by comparing the position of the dots in the distorted image with that in the non-distorted image, I get a displacement field, which is exactly what I need. The problem with this method is resolution. The resolution is limited to the number of dots in the field, and I'm exploring methods that give me more data.
One idea I've had is to use a regular grid of horizontal and vertical lines. This image will distort the same way, but instead of getting only the displacement of a dot, I'll have the continuous distortion of a grid. It seems like there must be some standard algorithm or procedure to compare one geometric grid to another and infer some kind of displacement field. Nonetheless, I haven't found anything like this in my research.
Does anyone have some ideas that might point me in the right direction? FYI, I am not a computer scientist -- I'm an engineer. I say that only because there may be some obvious approach I'm neglecting due to coming from a different field. But I can program. I'm using MATLAB, but I can read Python, C/C++, etc.
Here are examples of the type of images I'm working with:
Regular: Distorted:
--------
I think you are looking for the Digital Image Correlation algorithm.
Here you can see a demo.
Here is a Matlab Implementation.
From Wikipedia:
Digital Image Correlation and Tracking (DIC/DDIT) is an optical method that employs tracking & image registration techniques for accurate 2D and 3D measurements of changes in images. This is often used to measure deformation (engineering), displacement, and strain, but it is widely applied in many areas of science and engineering.
Edit
Here I applied the DIC algorithm to your distorted image using Mathematica, showing the relative displacements.
Edit
You may also easily identify the maximum displacement zone:
Edit
After some work (quite a bit, frankly) you can come up to something like this, representing the "displacement field", showing clearly that you are dealing with a vortex:
(Darker and bigger arrows means more displacement (velocity))
Post me a comment if you are interested in the Mathematica code for this one. I think my code is not going to help anybody else, so I omit posting it.
I would also suggest a line tracking algorithm would work well.
Simply start at the first pixel line of the image and start following each of the vertical lines downwards (You just need to start this at the first line to get the starting points. This can be done by a simple pattern that moves orthogonally to the gradient of that line, ergo follows a line. When you reach a crossing of a horizontal line you can measure that point (in x,y coordinates) and compare it to the corresponding crossing point in your distorted image.
Since your grid is regular you know that the n'th measured crossing point on the m'th vertical black line are corresponding in both images. Then you simply compare both points by computing their distance. Do this for each line on your grid and you will get, by how far each crossing point of the grid is distorted.
This following a line algorithm is also used in basic Edge linking algorithms or the Canny Edge detector.
(All this are just theoretic ideas and I cannot provide you with an algorithm to it. But I guess it should work easily on distorted images like you have there... but maybe it is helpful for you)