# orientation?

**URL:** <https://community.cesium.com/t/orientation/2377>\
**Category:** CesiumJS\
**Created:** [April 20, 2015, 3:46pm UTC](https://community.cesium.com/t/orientation/2377 "2015-04-20T15:46:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sai\_Asuka](https://avatars.discourse-cdn.com/v4/letter/s/b5e925/32.png) [@Sai\_Asuka](https://community.cesium.com/u/Sai_Asuka)\
**Post date:** [April 20, 2015, 3:46pm UTC](https://community.cesium.com/t/orientation/2377/1 "2015-04-20T15:46:50Z")

</div>

I have an array of “orientations” in a variable “orient” [, 120], [, 130], [, 150]

How can I set this array or transform to so that I can set the “orientation” property of an entity such that it knows what orientation is at any given point in time when I use the timeslider?

---

<div class="post-metadata">

**Author:** ![Sai\_Asuka](https://avatars.discourse-cdn.com/v4/letter/s/b5e925/32.png) [@Sai\_Asuka](https://community.cesium.com/u/Sai_Asuka)\
**Post date:** [April 20, 2015, 8:30pm UTC](https://community.cesium.com/t/orientation/2377/2 "2015-04-20T20:30:41Z")

</div>

The following does not work:  
var prop = new Cesium.SampledProperty(Number);

var mytimes = ;

var myheads = ;

// loop thorough each item in “orient” and do the following:

for(var i = 0; i \< orient.length; i++) {

var mytime = Cesium.JulianDate.fromDate(orient[i][0]);

var heading = Cesium.Math.toRadians(orient[i][1]);

mytimes.push(mytime);

myheads.push(heading);

}

prop.addSamples(mytimes, myheads)

In my entity I set:

orientation: prop

I keep geting a “RangeError: Invalid array length”, what is the right way to do this?

---

<div class="post-metadata">

**Author:** ![Matt\_Amato](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/matt_amato/32/1993_2.png) [@Matt\_Amato](https://community.cesium.com/u/Matt_Amato)\
**Post date:** [April 20, 2015, 8:48pm UTC](https://community.cesium.com/t/orientation/2377/3 "2015-04-20T20:48:51Z")

</div>

Orientation is not a number, it is a Quaternion. If you’d like to orient a model with heading only, you need to compute a Quaternion from it. You need the position at the time of the heading for the computation (and you can just use 0 for pitch and roll). If your positions and orientation times don’t line up, then you can create a position property first and use getValue(time) to get the position for each heading time. I wrote up an issue for us to add HeadingOrientationProperty to handle this use case directly (similar to what VelocityOrientationProperty already does).

Here’s some pseudo-code mirrors from your own code.

var myPositions = //parallel with orient array

var prop = new Cesium.SampledProperty(Quaternion);

var mytimes = ;

var myheads = ;

// loop thorough each item in “orient” and do the following:

for(var i = 0; i \< orient.length; i++) {

var mytime = Cesium.JulianDate.fromDate(orient[i][0]);

var heading = Cesium.Math.toRadians(orient[i][1]);

mytimes.push(mytime);

myheads.push(Transforms.headingPitchRollQuaternion(myPositions[i], heading, 0, 0));

}

prop.addSamples(mytimes, myheads)

---

<div class="post-metadata">

**Author:** ![Kevin\_Ten\_Eyck](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/kevin_ten_eyck/32/27541_2.png) [@Kevin\_Ten\_Eyck](https://community.cesium.com/u/Kevin_Ten_Eyck)\
**Post date:** [April 20, 2015, 8:49pm UTC](https://community.cesium.com/t/orientation/2377/4 "2015-04-20T20:49:33Z")

</div>

You need to create a new Cesium.SampledProperty of type quaternion

Ex: var orientation = new Cesium.SampledProperty(Cesium.Quaternion);

Then push quaternions to an array:

quaternionArray = ;

var quaternion = new Cesium.Quaternion();

quaternionArray.push(quaternion);

Finally add the times and quaternions to the sampled property:

orientation.addSamples(times, quaternionArray);

Note: You aren’t able to define an orientation with just a heading angle, instead try using this to create quaternions from a heading, pitch and roll

[https://github.com/AnalyticalGraphicsInc/cesium/blob/1.8/Source/Core/Transforms.js#L408](https://github.com/AnalyticalGraphicsInc/cesium/blob/1.8/Source/Core/Transforms.js#L408)

---

<div class="post-metadata">

**Author:** ![Sai\_Asuka](https://avatars.discourse-cdn.com/v4/letter/s/b5e925/32.png) [@Sai\_Asuka](https://community.cesium.com/u/Sai_Asuka)\
**Post date:** [April 20, 2015, 9:16pm UTC](https://community.cesium.com/t/orientation/2377/5 "2015-04-20T21:16:41Z")

</div>

Thank you both. Is there a method/way to get the “number of samples” in a SampledProperty? Also, is there a way to get the “current sample index” that the entity is currently on after load?

---

<div class="post-metadata">

**Author:** ![Florent\_DURU](https://avatars.discourse-cdn.com/v4/letter/f/b782af/32.png) [@Florent\_DURU](https://community.cesium.com/u/Florent_DURU)\
**Post date:** [April 27, 2017, 1:08pm UTC](https://community.cesium.com/t/orientation/2377/6 "2017-04-27T13:08:28Z")

</div>

Hello everyone,

thank you for your solution. I worked like a charm !! It is a pity that there is no documentation on SampledProperty used with Cesium.Quaternion in the official website. Also there is no example with in the sandCastle.

I modified a few lines of one code example to illustrate orientation possibilities in cesium (copy/paste the code in HTML and JAVASCRIPT tabs in Cesium sandCastle :

HTML CODE :  
\<style\>  
&nbsp;&nbsp;&nbsp;&nbsp;@import url(../templates/bucket.css);  
\</style\>  
\<div id="cesiumContainer" class="fullSize"\>\</div\>  
\<div id="loadingOverlay"\>\<h1\>Loading...\</h1\>\</div\>  
\<div id="toolbar"\>  
&nbsp;&nbsp;&nbsp;&nbsp;\<div id="interpolationMenu"\>\</div\>  
\</div\>

JAVASCRIPT CODE :  
var viewer = new Cesium.Viewer('cesiumContainer', {  
&nbsp;&nbsp;&nbsp;&nbsp;terrainProviderViewModels : , //Disable terrain changing  
&nbsp;&nbsp;&nbsp;&nbsp;infoBox : false, //Disable InfoBox widget  
&nbsp;&nbsp;&nbsp;&nbsp;selectionIndicator : false //Disable selection indicator  
});

//Enable lighting based on sun/moon positions  
viewer.scene.globe.enableLighting = true;

//Use STK World Terrain  
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({  
&nbsp;&nbsp;&nbsp;&nbsp;url : ‘[https://assets.agi.com/stk-terrain/world](https://assets.agi.com/stk-terrain/world)’,  
&nbsp;&nbsp;&nbsp;&nbsp;requestWaterMask : true,  
&nbsp;&nbsp;&nbsp;&nbsp;requestVertexNormals : true  
});

//Enable depth testing so things behind the terrain disappear.  
viewer.scene.globe.depthTestAgainstTerrain = true;

//Set the random number seed for consistent results.  
Cesium.Math.setRandomNumberSeed(3);

//Set bounds of our simulation time  
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));  
var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());

//Make sure viewer is at the desired time.  
viewer.clock.startTime = start.clone();  
viewer.clock.stopTime = stop.clone();  
viewer.clock.currentTime = start.clone();  
viewer.clock.clockRange = Cesium.ClockRange.LOOP\_STOP; //Loop at the end  
viewer.clock.multiplier = 10;

//Set timeline to simulation bounds  
viewer.timeline.zoomTo(start, stop);

var lon = 0;  
var lat = 45;  
var radius = 0.03;

//Generate a random circular pattern with varying heights.

&nbsp;&nbsp;&nbsp;&nbsp;var positionProperty = new Cesium.SampledPositionProperty();  
&nbsp;&nbsp;&nbsp;&nbsp;var orientationProperty = new Cesium.SampledProperty(Cesium.Quaternion);  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;for (var i = 0; i \<= 360; i += 45) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var radians = Cesium.Math.toRadians(i);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// compute positions  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var position = Cesium.Cartesian3.fromDegrees(lon + (radius \* 1.5 \* Math.cos(radians)), lat + (radius \* Math.sin(radians)), Cesium.Math.nextRandomNumber() \* 500 + 1750);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;positionProperty.addSample(time, position);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// compute orientations  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var heading = Cesium.Math.toRadians(90+i);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var pitch = Cesium.Math.toRadians(20);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var roll = Cesium.Math.toRadians(0);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var hpRoll = new Cesium.HeadingPitchRoll(heading,pitch,roll);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var orientation = Cesium.Transforms.headingPitchRollQuaternion(position,hpRoll);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orientationProperty.addSample(time, orientation);  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Also create a point for each sample we generate.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;viewer.entities.add({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;position : position,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point : {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixelSize : 8,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color : Cesium.Color.TRANSPARENT,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outlineColor : Cesium.Color.YELLOW,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outlineWidth : 3  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});  
&nbsp;&nbsp;&nbsp;&nbsp;}

//Actually create the entity  
var entity = viewer.entities.add({

&nbsp;&nbsp;&nbsp;&nbsp;//Set the entity availability to the same interval as the simulation time.  
&nbsp;&nbsp;&nbsp;&nbsp;availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start : start,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stop : stop  
&nbsp;&nbsp;&nbsp;&nbsp;})]),

&nbsp;&nbsp;&nbsp;&nbsp;//Use our computed positions  
&nbsp;&nbsp;&nbsp;&nbsp;position : positionProperty,

&nbsp;&nbsp;&nbsp;&nbsp;//Automatically compute orientation based on position movement.  
&nbsp;&nbsp;&nbsp;&nbsp;orientation : orientationProperty,

&nbsp;&nbsp;&nbsp;&nbsp;//Load the Cesium plane model to represent the entity  
&nbsp;&nbsp;&nbsp;&nbsp;model : {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uri : '../../SampleData/models/CesiumAir/Cesium\_Air.gltf',  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;minimumPixelSize : 64  
&nbsp;&nbsp;&nbsp;&nbsp;},

&nbsp;&nbsp;&nbsp;&nbsp;//Show the path as a pink line sampled in 1 second increments.  
&nbsp;&nbsp;&nbsp;&nbsp;path : {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resolution : 1,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;material : new Cesium.PolylineGlowMaterialProperty({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glowPower : 0.1,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color : Cesium.Color.YELLOW  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}),  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width : 10  
&nbsp;&nbsp;&nbsp;&nbsp;}  
});

//Add button to view the path from the top down  
Sandcastle.addDefaultToolbarButton('View Top Down', function() {  
&nbsp;&nbsp;&nbsp;&nbsp;viewer.trackedEntity = undefined;  
&nbsp;&nbsp;&nbsp;&nbsp;viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90)));  
});

//Add button to view the path from the side  
Sandcastle.addToolbarButton('View Side', function() {  
&nbsp;&nbsp;&nbsp;&nbsp;viewer.trackedEntity = undefined;  
&nbsp;&nbsp;&nbsp;&nbsp;viewer.zoomTo(viewer.entities, new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-90), Cesium.Math.toRadians(-15), 7500));  
});

//Add button to track the entity as it moves  
Sandcastle.addToolbarButton('View Aircraft', function() {  
&nbsp;&nbsp;&nbsp;&nbsp;viewer.trackedEntity = entity;  
});

//Add a combo box for selecting each interpolation mode.  
Sandcastle.addToolbarMenu([{  
&nbsp;&nbsp;&nbsp;&nbsp;text : 'Interpolation: Linear Approximation',  
&nbsp;&nbsp;&nbsp;&nbsp;onselect : function() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entity.position.setInterpolationOptions({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationDegree : 1,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationAlgorithm : Cesium.LinearApproximation  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}, {  
&nbsp;&nbsp;&nbsp;&nbsp;text : 'Interpolation: Lagrange Polynomial Approximation',  
&nbsp;&nbsp;&nbsp;&nbsp;onselect : function() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entity.position.setInterpolationOptions({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationDegree : 5,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationAlgorithm : Cesium.LagrangePolynomialApproximation  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}, {  
&nbsp;&nbsp;&nbsp;&nbsp;text : 'Interpolation: Hermite Polynomial Approximation',  
&nbsp;&nbsp;&nbsp;&nbsp;onselect : function() {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;entity.position.setInterpolationOptions({  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationDegree : 2,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interpolationAlgorithm : Cesium.HermitePolynomialApproximation  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}], 'interpolationMenu');

---

<div class="post-metadata">

**Author:** ![Rachel\_Hwang](https://avatars.discourse-cdn.com/v4/letter/r/d78d45/32.png) [@Rachel\_Hwang](https://community.cesium.com/u/Rachel_Hwang)\
**Post date:** [May 1, 2017, 5:53pm UTC](https://community.cesium.com/t/orientation/2377/7 "2017-05-01T17:53:51Z")

</div>

Hi Florent,

Glad you worked it out and thanks for your examples! We’re always trying to extend our collection of learning materials and there’s definitely plenty of room for improvement. I’ve added this idea to our Cesium Learning Materials update thread here: [https://github.com/AnalyticalGraphicsInc/cesium/issues/5207](https://github.com/AnalyticalGraphicsInc/cesium/issues/5207)

Please feel free to contribute if you have any other thoughts on what would make Cesium easier to learn!

Cheers,

- Rachel
