Need help with z values being off

function addPlottingSpan(viewer: CesiumViewer, currentPole: any, pole: any, firstPole: boolean) {
	if (currentPole.id === pole.id) return;
  let pole1Position = currentPole.position.getValue();
  let pole2Position = pole.position.getValue();

  let cart1 = new Cartesian3(pole1Position.x, pole1Position.y, pole1Position.z);
  let cart2 = new Cartesian3(pole2Position.x, pole2Position.y, pole2Position.z);

	const ellipsoid = Ellipsoid.WGS84;

	const cartographic1 = ellipsoid.cartesianToCartographic(cart1);
	const cartographic2 = ellipsoid.cartesianToCartographic(cart2);

	cartographic1.height += 5;
	cartographic2.height += 5;

	const pole1 = ellipsoid.cartographicToCartesian(cartographic1);
	const pole2 = ellipsoid.cartographicToCartesian(cartographic2);

  let offsetX = Math.abs(pole1.x - pole2.x);
  let offsetY = Math.abs(pole1.y - pole2.y);

  let distance = Math.sqrt((offsetX * offsetX) + (offsetY + offsetY));
  let angle1 = Math.cos(offsetX/distance) * 57.295779513;

  angle1 = 90

  let crossarm = 8;
  let crossarmRadius = crossarm / 2;

  let x = crossarmRadius * Math.cos(angle1)
  let y = crossarmRadius * Math.sin(angle1)

  let pole1WireAttachment1 = new Cartesian3(pole1.x + x, pole1.y + y, pole1.z)
  let pole1WireAttachment2 = new Cartesian3(pole1.x - x, pole1.y - y, pole1.z);

  let pole2WireAttachment1 = new Cartesian3(pole2.x + x, pole2.y + y, pole2.z)
  let pole2WireAttachment2 = new Cartesian3(pole2.x - x, pole2.y - y, pole2.z);


  let midspan = viewer?.entities.add({
    polyline: {

      positions: [pole1, pole2],
      width: 3,
      material: new PolylineOutlineMaterialProperty({
        color: Color.BLACK,
        outlineWidth: 2
      }),
    },
  });

  viewer?.entities.add({
    polyline: {
      positions: [pole1WireAttachment1, pole2WireAttachment1],
      width: 3,
      material: new PolylineOutlineMaterialProperty({
        color: Color.BLACK,
        outlineWidth: 2
      }),
    },
  });

  viewer?.entities.add({
    polyline: {
      positions: [pole1WireAttachment2, pole2WireAttachment2],
      width: 3,
      material: new PolylineOutlineMaterialProperty({
        color: Color.BLACK,
        outlineWidth: 2
      }),
    },
  });
  return midspan;
}

I am trying to figure out why the z values for each wire would be at different heights even though I give them the same z value. Do I have to normalize the coordinates or something to that degree?

The wire on the top of the pole is in the correct position. However when I add the offsets to the 2nd and 3rd polylines, the polylines are in the right location but at different heights.

For better help sooner, it would be great to have that function inside of a https://sandcastle.cesium.com/ , to see how you are calling the function, and examine the behavior directly.

sandbox

Thank you for the response.

A few additional words about what you are trying to achieve could also be helpful :slight_smile: I tried to understand the code, but since the code apparently is not doing what you want it to do, I have to make some guesses.

It looks like you are trying to model some sort of electricity poles, and connect them with wires. What’s not entirely clear to me is where these wires should be. It looks like there is some angle involved, which I imagine should be the “angle of the ‘arms’ of the pole”.

Now, when you are performing computations in cartesian coordinates there, then you should be aware that … these poles are not really in cartesian coordinates. When you place them anywhere on the globe, then their orientation will depend on where on the globe they are.

For example, referring to your screenshot: It looks like the poles themself are “upright” - and one might think that “up” means “to add something to the z-component of some vector”. But in fact, the z-component alone is not enough:

Cesium What is Z

In contrast to that, if you placed your poles at the equator, the height would be right:

Cesium Forum Pole Wires Z

(But other components would be wrong, so… that won’t help you either way)


I tried to implement what you probably wanted to accomplish:

Cesium Poles Z

There are many guesses involved, and it’s probably not the most elegant way of implementing it, but it contains some inlined comments, maybe that helps:


(Yes, I assume that you’ll want to connect the wires sooner or later. But that can be a challenge, independent of the question about the z-value…)


An aside: Calling a variable “cart” is probably not ideal :slight_smile: First of all, because it doesn’t tell you what that variable is. But more importantly, because it could be “…esian” or “…ographic”, and that’s valuable information.

Sorry about the random variables. I should have cleared that up before making the sandcastle.

The main problem I was having is the polylines not being at the same height, but it appears I was misunderstanding the z axis. I thought that if I don’t change the z-axis then the height of the polylines would not change. As I understand from your code, I need to compute the new location by a model matrix?

The idea of this program is to plot out telephone poles and wires with the wires being at the same height and the angles being connected. I will have to add a catenary curve to the polylines (wires) to resemble real wires. I assume I would also have to use a model matrix to compute x, y, z with the catmullrom spline object.

The main problem I was having is the polylines not being at the same height, but it appears I was misunderstanding the z axis. I thought that if I don’t change the z-axis then the height of the polylines would not change. As I understand from your code, I need to compute the new location by a model matrix?

Again: The given code may not be the most elegant way of writing it. Some details depend on which information you have to begin with (e.g. do you have the length of the ‘arms’ and some angles, or some offsets (delta X/Y from the top of the pole)…?).

But generally speaking: The way how the poles are usually displayed when you zoom closely to them may give the impression that “adding something to the z-value of a cartesian” will move that cartesian “up” - but that’s not necessarily the case (as I tried to illustrate in that drawing - it was only a quick drawing, but maybe brings the idea across).

When you imagine that “pole” as something like this

A---T---B
    | 
    | 
    |

(with T being the “top”), and you want to compute position B, then you cannot just move the top along the positive X-axis, because you don’t know the orientation of that pole. It might actually be located at the equator (which would mean that it would be “rotated by 90 degrees” in terms of cartesian coordinates).

The most important part of that sandcastle might therefore be the line that calls Cesium.Transforms.eastNorthUpToFixedFrame: For a given position on the globe (i.e. for the position of the pole), this computes the matrix that transforms coordinates from the local space of the pole into the “global” (cartesian) coordinates.

This means that when you have the pole, as drafted above, and you see
“When I start at ‘T’, and want to move to ‘B’, then I have to move about (1, 0, 0)”
then you can transform the vector (1, 0, 0) with that matrix, so that you know the movement that you have to make in cartesian coordinates.

I will have to add a catenary curve to the polylines (wires) to resemble real wires. I assume I would also have to use a model matrix to compute x, y, z with the catmullrom spline object.

Computing this can actually be quite tricky. Bot only because of the 3D part, and the cartesian-vs-cartographic conversions, but in general - even in the (“simple”) 2D case. The question is: When you want these wires to take a turn, how exactly will that be structured? You’ll probably have to address some questions about the “join type” (round, miter, or bevel), similar to what is shown (and computed under the hood) for the Corridors sandcastle…

1 Like

The most important part of that sandcastle might therefore be the line that calls Cesium.Transforms.eastNorthUpToFixedFrame: For a given position on the globe (i.e. for the position of the pole), this computes the matrix that transforms coordinates from the local space of the pole into the “global” (cartesian) coordinates.

Okay this makes sense now.

When you want these wires to take a turn, how exactly will that be structured?

Ideally the polylines should be rounded an joined at the pole to form a continuous polyline so I will have to compute each wire dynamically based off of the angle of the pole.

Is there an example of a line curve be implemented in 3d?

There are many examples for different types of interpolations. One that is relevant (or might at least be interesting) here is the Interpolation example Sandcastle that shows how to create polylines with different interpolation types (Lagrange, Hermite…).

The somewhat broader questions are still

  • what the orientation of the pole should be (i.e. its rotation when viewn from the top)
  • depending on that: what the “shape” of the wires should be

The point is: A single wire that connects two poles will usually not be “curved”. (Of course, it will be curved vertically, due to gravity - but it will not be curved when viewn from the top).

A quick draft again:

Cesium Wires Options

But I assume that you are aware of the these options in general, and are now tasked with finding a “good” solution that “always” works and “always” looks nice :no_mouth: (It’s difficult, but things like the ‘Interpolation’- and maybe ‘Corridors’ Sandcastle, and resources like the results of searching for keywords like line joins miter bevel round should provide plenty of information here)

You’re right. The wire will form a miter at the point of connection on the pole. In real life the angle will typically never be less than 130 degrees or so due to pole construction. The first illustration that you drew is a good example of what needs to happen.

Another interesting problem to solve is bounding the program to the laws of physics. Not allowing placements that could never be constructed in real life.

It’s an interesting topic, for sure. And depending on how “detailed” or “realistic” all that should be, it’s pretty much open-ended: You could eventually compute the shape of the wires as a real catenary (at least in theory), taking into account the distance between the poles, materials, and whatnot.

From the description so far, it sounds like the first goal(s) would be a mix of

  • coping with the clicks that the user makes
  • maybe: constraining what the user can do

The latter refers to the fact that the user should probably not place two poles that are 10km apart, or that are only 30cm apart (and even computing a “nice, somewhat-even spacing” for the poles could be an interesting sub task). The first one will depend on the degrees of freedom that the user has. And for the overall interaction, there will be additional questions. Imagine that the user is picking the positions of two poles (which are by definition a straight line), and then adds one that implies a 90° turn: Should the system automatically insert poles to cope with that sharp turn? Should the previous pole be rotated by 45° to “smooth out” the turn? …

OK, this is derailing a bit :slight_smile:

Coming back to the original topic: I could imagine that it might be easier to perform certain computations (like “the position of a wire, relative to a pole”) in a predefined “local” coordinate system, and then just transform everything into the global coordinate system at once (using the “eastNorthUpToFixedFrame” matrix).
But of course, these are higher-level engineering decisions that depend on the exact goals and requirements.

Should the system automatically insert poles to cope with that sharp turn? Should the previous pole be rotated by 45° to “smooth out” the turn? …

In my mind, it would be nice to have a color indicator for the user. Red being that you cannot place a pole at this location with the current configuration of the pole. Green being an acceptable location of the pole.

castle

Here is a example of what I am trying to do with the catenary curve. I have to solve the problem of whenever there is more sag in the polyline, I need to create a longer polyline to make up for the sag. Right now it’s just going higher up.

I could imagine that it might be easier to perform certain computations in a predefined “local” coordinate system, and then just transform everything into the global coordinate system at once

when you say local, do you mean the utm zone or the conversion matrix demonstrated in the latest example?

The sandcastle looks nice from a first test. But I cannot allocate toooo much more time to look into the details of the code right now.

This mainly refers to the fact that there are several conversions from ‘cartesian’ to ‘cartographic’ and back (!). For example, even for the basic definition of the poles: The user selected a cartesian position. And then you are

  1. converting that into a ‘cartographic’ (the “pole bottom”)
  2. adding a few meters to the height
  3. converting the result back into a ‘cartesian’ (the “pole top”)

Similarly, this is done for the points of the polyline that make up the “wire”.

I could imagine that it might be easier (technically, and in terms of the code) to just “pretend” that

  • the pole bottoms are are located at (0,0,0) and (100, 0, 0)
  • the pole tops are are located at (0,0,6) and (100, 0, 6)

and compute the “wire line” for these. (In this context, you can just use someCartesian.z += 1.5 to “move a point up”. So you don’t have to do that cartesian->cartographic->cartesian conversion each time…).

And then, eventually, you have a bunch of poles and wire polylines, and can just transform all these points, at once, with the east-nort-up-to-fixed-frame matrix for the desired target position.

But again: This is just a gut feeling! (Not a “recommendation”). You have to decide which approach makes most sense for you.

Okay that seems like a more reasonable approach. Thank you for you time! I really appreciate it.