Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X
Hello Community,
I’m back after some time away from MathCAD due to other types of projects. This time, I need your expertise to help me resolve the following:
I have several 3D zones defined by two opposite diagonal points, as shown in the figure below. I have prepared the zones as an m × 6 matrix, where each row is [x1 y1 z1 x2 y2 z2]. Row 0 → Zone 1, Row 1 → Zone 2, etc.
I also prepared a list of points as an N × 3 matrix. Let PTS be N × 3 with columns [x y z]:
My inVolume formula is producing the correct Boolean answer (1 or 0) depending on whether a point lies inside the volume or not. However, my matrix implementation is not producing the expected result. I would like also to work with units of length.
Attached is the MathCAD Prime 7 worksheet. You can reply in either MathCAD Prime 7 or 11.
Solved! Go to Solution.
@Perez wrote:
Hello Werner,
I reviewed the real input data for the zones, and yes, the zones in the ZONES matrix are sorted by pressure. This means the last one corresponds to the highest pressure, and in those cases, higher pressure is associated with a larger y-coordinate. However, I also have a set of zones where the opposite occurs: the pressure is higher at the lower y-coordinate and decreases as the y-coordinate increases.
So for the one data set you can use the "last wins" approach, for the other the "first wins".
For a more general solution you would have to provide the pressure values for "classifyPoint" to decide which zone to return as explained in the answer above.
As for the 3D plot find attached one possible way to plot the boxes.
As you can see Primes 3D plot is missing a lot of features and achieving correct proportions involves some manual work and has its drawbacks.
You also have to manually turn the plot so that the y-axis is (approximately) vertical to duplicate the picture of plot you provided. Primes 3D plot provides no means to help you doing so and as you can see it does not adjust the orientation of the numbers on the scale.
EDIT: Also added a more generic classifyPoint function which does not rely on the zones list to be sorted in any way
The reason you get the zero vector unchanged back is because you assign the result of "classifyPoints" to the index "i" and not to the variable "ids". Note that the expression is still subscripted. So this line actually has no effect.
If we fix this wee see that the second point is classified to be in zone 1, not zone 2!
As your definition if "inside" includes the boundaries, I would say that point 2 lies within both zones and your function "inVolume" confirms that
The last but one line in your function "classifyPoint"
is confusing and wrong.
When j=0 variable "zone" is assigned the value 1 (because the point is inside the first zone).
When j=1 inside is correctly assigned the value 1, but zone remains at one because (zone=0) is wrong and so its value is zero and you add zero to the value 1 already in zone.
What did you intend with this line?
What should happen if a points lies within multiple zones?
Should the program return a list with all zones the point lies within? Or should the first zone "win", or the last one?
Your desired result "2" for the second point would mean that you want the last zone in the list where the point still lies within, should win.
If that's true you could apply the following modification:
I also added alternative shorter versions of your functions, using the very same data structure you provided
Also added variants where the first zone "wins" and also where all zones a point lies within are returned
Prime 11 sheet attached
Thank you, Werner,
I implemented your solutions, and they are working well.
We just need to account for the scenario where a point falls on the boundary between two zones. In that case, the zone with the higher pressure should be selected.
Also, in my real application, there will be no overlap between two zones—only shared boundaries—which should simplify the problem.
Could you also include a 3D plot with filtering by Zone?
Attached is the MathCAD Prime 7 file, version 2.
We just need to account for the scenario where a point falls on the boundary between two zones. In that case, the zone with the higher pressure should be selected.
So you would have to provide the pressure information as an additional argument for function "classifyPoint". Either a separate vector with an entry for every zone or you may also provide the pressure info as a seventh element in the "zone" row vector.
Also, in my real application, there will be no overlap between two zones—only shared boundaries—which should simplify the problem.
I don't think that this simplifies the task significally. It may do so
if we can rely on the zones always being arranged in such a way that shared areas can occur at best in two immediately consecutive zones.
However, I would still prefer to rely on a general approach. First collect all zones that contain the point and then select the one with the highest pressure.
However... what should be done if two zones containing the point have the same pressure? Which one should be returned?
Could you also include a 3D plot with filtering by Zone?
It might be possible to do a rudimentary 3D plot, but unfortunately Primes plot capabilities, especially when it comes to 3D plots, are very limited.
So its not possible to let Prime show the axis. Primes shows something which looks like axis, but aren't as they usually don't cross at the origin.
You would also have to decide if you are happy with showing the boxes as wire frames or if you need solid surfaces. The latter would be a bit more work and Prime is so limited than on contrary to real Mathcad it won't allow for transparency, so points inside or behind a box would not show.
Furthermore, if you need a different color for each box you would have to use a separate plot for each box and manually assign a color. This means that the plot will not automatically adjust if you add or delete zones in the ZONES matrix.
Hello Werner,
I reviewed the real input data for the zones, and yes, the zones in the ZONES matrix are sorted by pressure. This means the last one corresponds to the highest pressure, and in those cases, higher pressure is associated with a larger y-coordinate. However, I also have a set of zones where the opposite occurs: the pressure is higher at the lower y-coordinate and decreases as the y-coordinate increases.
@Perez wrote:
Hello Werner,
I reviewed the real input data for the zones, and yes, the zones in the ZONES matrix are sorted by pressure. This means the last one corresponds to the highest pressure, and in those cases, higher pressure is associated with a larger y-coordinate. However, I also have a set of zones where the opposite occurs: the pressure is higher at the lower y-coordinate and decreases as the y-coordinate increases.
So for the one data set you can use the "last wins" approach, for the other the "first wins".
For a more general solution you would have to provide the pressure values for "classifyPoint" to decide which zone to return as explained in the answer above.
As for the 3D plot find attached one possible way to plot the boxes.
As you can see Primes 3D plot is missing a lot of features and achieving correct proportions involves some manual work and has its drawbacks.
You also have to manually turn the plot so that the y-axis is (approximately) vertical to duplicate the picture of plot you provided. Primes 3D plot provides no means to help you doing so and as you can see it does not adjust the orientation of the numbers on the scale.
EDIT: Also added a more generic classifyPoint function which does not rely on the zones list to be sorted in any way