@@ -46,7 +46,90 @@ function ClippingPolygon(options) {
4646 //>>includeEnd('debug');
4747
4848 this . _ellipsoid = options . ellipsoid ?? Ellipsoid . default ;
49- this . _positions = [ ...options . positions ] ;
49+ this . _positions = copyArrayCartesian3 ( options . positions ) ;
50+
51+ /**
52+ * A copy of the input positions.
53+ *
54+ * This is used to detect modifications of the positions in
55+ * <code>coputeRectangle</code>: The rectangle only has
56+ * to be re-computed when these positions have changed.
57+ *
58+ * @type {Cartesian3[]|undefined }
59+ * @private
60+ */
61+ this . _cachedPositions = undefined ;
62+
63+ /**
64+ * A cached version of the rectangle that is computed in
65+ * <code>computeRectangle</code>.
66+ *
67+ * This is only re-computed when the positions have changed, as
68+ * determined by comparing the <code>_positions</code> to the
69+ * <code>_cachedPositions</code>
70+ *
71+ * @type {Rectangle|undefined }
72+ * @private
73+ */
74+ this . _cachedRectangle = undefined ;
75+ }
76+
77+ /**
78+ * Returns a deep copy of the given array.
79+ *
80+ * If the input is undefined, then <code>undefined</code> is returned.
81+ *
82+ * Otherwise, the result will be a copy of the given array, where
83+ * each element is copied with <code>Cartesian3.clone</code>.
84+ *
85+ * @param {Cartesian3[]|undefined } input The input array
86+ * @returns {Cartesian3[]|undefined } The copy
87+ */
88+ function copyArrayCartesian3 ( input ) {
89+ if ( ! defined ( input ) ) {
90+ return undefined ;
91+ }
92+ const n = input . length ;
93+ const output = Array ( n ) ;
94+ for ( let i = 0 ; i < n ; i ++ ) {
95+ output [ i ] = Cartesian3 . clone ( input [ i ] ) ;
96+ }
97+ return output ;
98+ }
99+
100+ /**
101+ * Returns whether the given arrays are component-wise equal.
102+ *
103+ * When both arrays are undefined, then <code>true</code> is returned.
104+ * When only one array is defined, or they are both defined but have
105+ * different lengths, then <code>false</code> is returned.
106+ *
107+ * Otherwise, returns whether the corresponding elements of the arrays
108+ * are equal, as of <code>Cartesian3.equals</code>.
109+ *
110+ * @param {Cartesian3[]|undefined } a The first array
111+ * @param {Cartesian3[]|undefined } b The second array
112+ * @returns {boolean } Whether the arrays are equal
113+ */
114+ function equalsArrayCartesian3 ( a , b ) {
115+ if ( ! defined ( a ) && ! defined ( b ) ) {
116+ return true ;
117+ }
118+ if ( defined ( a ) !== defined ( b ) ) {
119+ return false ;
120+ }
121+ if ( a . length !== b . length ) {
122+ return false ;
123+ }
124+ const n = a . length ;
125+ for ( let i = 0 ; i < n ; i ++ ) {
126+ const ca = a [ i ] ;
127+ const cb = b [ i ] ;
128+ if ( ! Cartesian3 . equals ( ca , cb ) ) {
129+ return false ;
130+ }
131+ }
132+ return true ;
50133}
51134
52135Object . defineProperties ( ClippingPolygon . prototype , {
@@ -138,12 +221,18 @@ ClippingPolygon.equals = function (left, right) {
138221 * @returns {Rectangle } The result rectangle
139222 */
140223ClippingPolygon . prototype . computeRectangle = function ( result ) {
141- return PolygonGeometry . computeRectangleFromPositions (
224+ if ( equalsArrayCartesian3 ( this . _positions , this . _cachedPositions ) ) {
225+ return Rectangle . clone ( this . _cachedRectangle , result ) ;
226+ }
227+ const rectangle = PolygonGeometry . computeRectangleFromPositions (
142228 this . positions ,
143229 this . ellipsoid ,
144230 undefined ,
145231 result ,
146232 ) ;
233+ this . _cachedPositions = copyArrayCartesian3 ( this . _positions ) ;
234+ this . _cachedRectangle = Rectangle . clone ( rectangle ) ;
235+ return rectangle ;
147236} ;
148237
149238const scratchRectangle = new Rectangle ( ) ;
0 commit comments