how to use IntersectWithLine function in vtk? - vtk

So I have a point, and create a line in the z axis to see the point of intersection with a certain mesh (to project the point on the mesh on the z axis).
So I create a vtkCellLocator, but what are each of the paramter of the function? It is not described at all in the documentation :
int vtkCellLocator::IntersectWithLine(double a0[3], double a1[3], double tol,
double& t, double x[3], double pcoords[3],
int &subId, vtkIdType &cellId,
vtkGenericCell *cell);
I've tested a bit, and it seems that a0 and a1 are the endpoints of our line, and x is the found intersection point values and cellid the cellid of the intersection point.
What does the rest means? What happens if I have multiple points of intersection? How does it choose the "best" cell of intersection from all the points of intersection?

The parameters for the IntersectWithLine are derived from vtkCell class. It is a bit buried you can see the detailed description here for the parameters. The implementation in vtkCellLocator uses this call to vtkCell::IntersectWithLine to define the parameters.
virtual int vtkCell::IntersectWithLine ( const double p1[3],
const double p2[3], double tol, double & t, double
x[3], double pcoords[3], int & subId )
Intersect with a ray.
Return parametric coordinates (both line and cell) and global
intersection coordinates, given ray definition p1[3], p2[3] and
tolerance tol. The method returns non-zero value if intersection
occurs. A parametric distance t between 0 and 1 along the ray
representing the intersection point, the point coordinates x[3] in
data coordinates and also pcoords[3] in parametric coordinates. subId
is the index within the cell if a composed cell like a triangle strip.
The cellId that is returned is based on the parametric distance to the intersecting cell. So the returned cellId is the cell that minimizes the member function vtkCell::GetParametricDistance
virtual double vtkCell::GetParametricDistance ( const double pcoords[3] )
Return the distance of the parametric coordinate provided to the
cell.
If inside the cell, a distance of zero is returned. This is used
during picking to get the correct cell picked. (The tolerance will
occasionally allow cells to be picked who are not really intersected
"inside" the cell.)
Therefore it should be the cell that intersects the line within the tolerance that is closest to p1

Sorry, I don't have a direct answer (well...the &t is probably the parameter of the line where the intersection happens, the cellId is the id of the found cell and the cell is a pointer to the found cell (but you can just use the cellId to get it)). But I do have an advice as someone who works with VTK often: use the fact that it is open source - just download the VTK sources and look directly into them to find your answers. Trust me that especially if you plan to work with VTK regularly, this will save you a lot of time in the end. The documentation is sadly sometimes a bit vague :(

Related

Custom smoothing kernel

I would like to use Smooth.ppp in spatstat to calculate a sort of "moving average" according to a specific function. The specific distance-dependent weights I would like to use are given by a function wt; for simplicity
wt=function(x,y) exp(-1e5*(x-y)^2)
In the extreme case where wt=kernel, I'd expect no smoothing (ie input marks = smoothed estimates). I'm wondering what I am mis-understanding here about the kernel and how it is applied?
remotes::install_github("spatstat/spatstat.core")
n=4; PPP=ppp(rep(1:n,each=n),rep(1:n,n), c(1,n),c(1,n), marks=1:n^2);
smo=Smooth.ppp(PPP,cutoff=2,kernel=wt,at="points")
rbind(marks(PPP),smo)
(I'm using the latest spatstat build to allow estimates at points using a custom kernel)
This example may have been misinterpreted.
The kernel should be a function(x, y) in the R language which gives the value, at a spatial location (x,y), of the kernel centred at the origin (0,0). Generally the kernel takes its largest values when (x,y) is close to (0,0), and drops to zero when (x,y) is far from (0,0).
The function wt defined in your example has values close to 1 along the diagonal line x = y, and drops to zero rapidly away from the diagonal.
That is unusual. It means that a data point at location (a,b) will be 'smoothed' along the infinite line through the data point with unit slope, with equation y = x + b-a, rather than being smoothed over a region close to (a,b) as it normally would.
The example point pattern PPP consists of points along the diagonal y=x.
The smoothed value at a data point is the weighted average of the mark values at all data points, with weights proportional to the kernel value. In your example, the kernel value for each pair of data points, wt(x1-x2, y1-y2), is equal to 1 because all the data and query points lie on the same line with slope 1.
The kernel weights are all equal in this example, so the smoothed values should all be equal to the average mark value, if leaveoneout=FALSE, and if leaveoneout=TRUE then the smoothed value at data point i is the average of the mark values at the data points excluding point i.

Computing the area filled by matplotlib.pyplot.fill(...)

I'd like to compute the area inside of a curve defined by two vectors a and b. For your reference the curve looks something like this (pyplot.plot(a,b)):
I saw matplotlib has a fill functionality that let you fill the area enclosed by the curve:
I'm wondering, there's any way to obtain the area filled using that same function? It would be very useful as the other way I'm thinking of computing that area is through numerical integration, much more cumbersome.
Thank you for your time.
If you really want to find the area that was filled by matplotlib.pyplot.fill(a, b), you can use its output as follows:
def computeArea(pos):
x, y = (zip(*pos))
return 0.5 * numpy.abs(numpy.dot(x, numpy.roll(y, 1)) - numpy.dot(y, numpy.roll(x, 1)))
# pyplot.fill(a, b) will return a list of matplotlib.patches.Polygon.
polygon = matplotlib.pyplot.fill(a, b)
# The area of the polygon can be computed as follows:
# (you could also sum the areas of all polygons in the list).
print(computeArea(polygon[0].xy))
This method is based on this answer,
and it is not the most efficient one.

how to calculate anti/clockwise angle in direction of lines?

I need to offset a curve, which by the simplest way is just shifting the points perpendicularly. I can access each point to calculate angle of each line along given path, for now I use atan2. Then I take those two angle and make average of it. It returns the shortest angle, not what I need in this case.
How can I calculate angle of each connection? Concerning that I am not interested in the shortest angle but the one that would create parallel offset curve.
Assuming 2D case...
So do a cross product of direction vectors of 2 neighboring lines the sign of z coordinate of the result will tell you if the lines are CW/CCW
So if you got 3 consequent control points on the polyline: p0,p1,p2 then:
d1 = p1-p0
d2 = p2-p1
if you use some 3D vector math then convert them to 3D by setting:
d1.z=0;
d2.z=0;
now compute 3D cross:
n = cross(d1,d2)
which returns vector perpendicular to both vectors of size equals to the area of quad (parallelogram) constructed with d1,d2 as base vectors. The direction (from the 2 possible) is determined by the winding rule of the p0,p1,p2 so inspecting z of the result is enough.
The n.x,n.y are not needed so you can compute directly without doing full cross product:
n.z=(d1.x*d2.y)-(d1.y*d2.x)
if (n.z>0) case1
if (n.z<0) case2
if the case1 is CW or CCW depends on your coordinate system properties (left/right handness). This approach is very commonly used in CG fur back face culling of polygons ...
if n.z is zero it means that your vectors/lines are either parallel or at lest one of them is zero.
I think these might interest you:
draw outline for some connected lines
How can I create an internal spiral for a polygon?
Also in 2D you do not need atan2 to get perpendicular vector... You can do instead this:
u = (x,y)
v = (-y,x)
w = (x,-y)
so u is any 2D vector and v,w are the 2 possible perpendicular vectors to u in 2D. they are the result of:
cross((x,y,0),(0,0,1))
cross((0,0,1),(x,y,0))

How can I detect and remove unneeded points in cubic bezier

Here is example image of what I want to do:
I want to calculate Path 1 from Path 2.
Screenshot made from Inkscape, where I'm, at first, create Path 1, then add p3 to the original path. This is didn't change the original path at all, because new point actually unneeded. So, how can I detect this point(p3) using Path 2 SVG path representation and calculate Path 1 from Path 2?
Basically, I search for the math formulas, which can help me to convert(also checking that whether it is possible):
C 200,300 300,250 400,250 C 500,250 600,300 600,400
to
C 200,200 600,200 600,400
You're solving a constraint problem. Taking your first compound curve, and using four explicit coordinates for each subcurve, we have:
points1 = point[8];
points2 = point[4];
with the following correspondences:
points1[0] == points2[0];
points1[7] == points2[3];
direction(points1[0],points1[1]) == direction(points2[0], points2[1]);
direction(points1[6],points1[7]) == direction(points2[2], points2[3]);
we also have a constraint on the relative placement for points2[1] and points2[2] due to the tangent of the center point in your compound curve:
direction(points1[2],points[4]) == direction(points2[1],points2[2]);
and lastly, we have a general constraint on where on- and off-curve points can be for cubic curves if we want the curve to pass through a point, which is described over at http://pomax.github.io/bezierinfo/#moulding
Taking the "abc" ratio from that section, we can check whether your compound curve parameters fit a cubic curve: if we construct a new cubic curve with points
A = points1[0];
B = points1[3];
C = points1[7];
with B at t=0.5 (in this case), then we can verify whether the resulting curve fits the constraints that must hold for this to be a legal simplification.
The main problem here is that we, in general, don't know whether the "in between start and end" point should fall on t=0.5, or whether it's a different t value. The easiest solution is to see how far that point is along the total curve (using arc length: distance = arclength(c1) / arclength(c1)+arclength(c2) will tell us) and use that as initial guess for t, iterating outward on either side for a few values.
The second option is to solve a generic cubic equation for the tangent vector at your "in between" point. We form a cubic curve with points
points3 = [ points1[0], points1[1], points1[6], points1[7] ];
and then solve its derivative equations to find one or more t values that have the same tangent direction (but not magnitude!) as our in-between point. Once we have those (and we might have more than 2), we evaluate whether we can create a curve through our three points of interest with the middle point set to each of those found t values. Either one or zero of the found t values will yield a legal curve. If we have one: perfect, we found a simplification. If we find none, then the compound curve cannot be simplified into a single cubic curve.

Finding most distant point in circle from point

I'm trying to find the best way to get the most distant point of a circle from a specified point in 2D space. What I have found so far, is how to get the distance between the point and the circle position, but I'm not entirely sure how to expand this to find the most distant point of the circle.
The known variables are:
Point a
Point b (circle position)
Radius r (circle radius)
To find the distance between the point and the circle position, I have found this:
xd = x2 - x1
yd = y2 - y1
Distance = SquareRoot(xd * xd + yd * yd)
It seems to me, this is part of the solution. How would this be expanded to get the position of Point x in the below image?
As an additional but optional part of the question: I have read in some places that it would be possible to get the distance portion without using the Square Root, which is very performance intensive and should be avoided if fast code is necessary. In my case, I would be doing this calculation quite often; Any comments on this within the context of the main question would be welcome too.
What about this?
Calculate A-B.
We now have a vector pointing from the center of the circle towards A (if B is the origin, skip this and just consider point A a vector).
Normalize.
Now we have a well defined length (the length is 1)
If the circle is not of unit radius, multiply by radius. If it is unit radius, skip this.
Now we have the correct length.
Invert sign (can be done in one step with 3., just multiply with the negative radius)
Now our vector points in the correct direction.
Add B (if B is the origin, skip this).
Now our vector is offset correctly so its endpoint is the point we want.
(Alternatively, you could calculate B-A to save the negation, but then you have to do one more operation to offset the origin correctly.)
By the way, it works the same in 3D, except the circle would be a sphere, and the vectors would have 3 components (or 4, if you use homogenous coords, in this case remember -- for correctness -- setting w to 0 when "turning points into vectors" and to 1 at the end when making a point from the vector).
EDIT:
(in reply of pseudocode)
Assuming you have a vec2 class which is a struct of two float numbers with operators for vector subtraction and scalar multiplicaion (pretty trivial, around a dozen lines of code) and a function normalize which needs to be no more than a shorthand for multiplying with inv_sqrt(x*x+y*y), the pseudocode (my pseudocode here is something like a C++/GLSL mix) could look something like this:
vec2 most_distant_on_circle(vec2 const& B, float r, vec2 const& A)
{
vec2 P(A - B);
normalize(P);
return -r * P + B;
}
Most math libraries that you'd use should have all of these functions and types built-in. HLSL and GLSL have them as first type primitives and intrinsic functions. Some GPUs even have a dedicated normalize instruction.

Resources