001:
002: /*
003: * The JTS Topology Suite is a collection of Java classes that
004: * implement the fundamental operations required to validate a given
005: * geo-spatial data set to a known topological specification.
006: *
007: * Copyright (C) 2001 Vivid Solutions
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022: *
023: * For more information, contact:
024: *
025: * Vivid Solutions
026: * Suite #1A
027: * 2328 Government Street
028: * Victoria BC V8T 5G5
029: * Canada
030: *
031: * (250)385-6040
032: * www.vividsolutions.com
033: */
034: package com.vividsolutions.jts.geom;
035:
036: /**
037: * A Dimensionally Extended Nine-Intersection Model (DE-9IM) matrix. This class
038: * can used to represent both computed DE-9IM's (like 212FF1FF2) as well as
039: * patterns for matching them (like T*T******). <P>
040: *
041: * Methods are provided to:
042: * <UL>
043: * <LI> set and query the elements of the matrix in a convenient fashion
044: * <LI> convert to and from the standard string representation (specified in
045: * SFS Section 2.1.13.2).
046: * <LI> test to see if a matrix matches a given pattern string.
047: * </UL>
048: * <P>
049: *
050: * For a description of the DE-9IM, see the <A
051: * HREF="http://www.opengis.org/techno/specs.htm">OpenGIS Simple Features
052: * Specification for SQL</A> .
053: *
054: *@version 1.7
055: */
056: public class IntersectionMatrix implements Cloneable {
057: /**
058: * Internal representation of this <code>IntersectionMatrix</code>.
059: */
060: private int[][] matrix;
061:
062: /**
063: * Creates an <code>IntersectionMatrix</code> with <code>FALSE</code>
064: * dimension values.
065: */
066: public IntersectionMatrix() {
067: matrix = new int[3][3];
068: setAll(Dimension.FALSE);
069: }
070:
071: /**
072: * Creates an <code>IntersectionMatrix</code> with the given dimension
073: * symbols.
074: *
075: *@param elements a String of nine dimension symbols in row major order
076: */
077: public IntersectionMatrix(String elements) {
078: this ();
079: set(elements);
080: }
081:
082: /**
083: * Creates an <code>IntersectionMatrix</code> with the same elements as
084: * <code>other</code>.
085: *
086: *@param other an <code>IntersectionMatrix</code> to copy
087: */
088: public IntersectionMatrix(IntersectionMatrix other) {
089: this ();
090: matrix[Location.INTERIOR][Location.INTERIOR] = other.matrix[Location.INTERIOR][Location.INTERIOR];
091: matrix[Location.INTERIOR][Location.BOUNDARY] = other.matrix[Location.INTERIOR][Location.BOUNDARY];
092: matrix[Location.INTERIOR][Location.EXTERIOR] = other.matrix[Location.INTERIOR][Location.EXTERIOR];
093: matrix[Location.BOUNDARY][Location.INTERIOR] = other.matrix[Location.BOUNDARY][Location.INTERIOR];
094: matrix[Location.BOUNDARY][Location.BOUNDARY] = other.matrix[Location.BOUNDARY][Location.BOUNDARY];
095: matrix[Location.BOUNDARY][Location.EXTERIOR] = other.matrix[Location.BOUNDARY][Location.EXTERIOR];
096: matrix[Location.EXTERIOR][Location.INTERIOR] = other.matrix[Location.EXTERIOR][Location.INTERIOR];
097: matrix[Location.EXTERIOR][Location.BOUNDARY] = other.matrix[Location.EXTERIOR][Location.BOUNDARY];
098: matrix[Location.EXTERIOR][Location.EXTERIOR] = other.matrix[Location.EXTERIOR][Location.EXTERIOR];
099: }
100:
101: /**
102: * Adds one matrix to another.
103: * Addition is defined by taking the maximum dimension value of each position
104: * in the summand matrices.
105: *
106: * @param im the matrix to add
107: */
108: public void add(IntersectionMatrix im) {
109: for (int i = 0; i < 3; i++) {
110: for (int j = 0; j < 3; j++) {
111: setAtLeast(i, j, im.get(i, j));
112: }
113: }
114: }
115:
116: /**
117: * Returns true if the dimension value satisfies the dimension symbol.
118: *
119: *@param actualDimensionValue a number that can be stored in the <code>IntersectionMatrix</code>
120: * . Possible values are <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>.
121: *@param requiredDimensionSymbol a character used in the string
122: * representation of an <code>IntersectionMatrix</code>. Possible values
123: * are <code>{T, F, * , 0, 1, 2}</code>.
124: *@return true if the dimension symbol encompasses
125: * the dimension value
126: */
127: public static boolean matches(int actualDimensionValue,
128: char requiredDimensionSymbol) {
129: if (requiredDimensionSymbol == '*') {
130: return true;
131: }
132: if (requiredDimensionSymbol == 'T'
133: && (actualDimensionValue >= 0 || actualDimensionValue == Dimension.TRUE)) {
134: return true;
135: }
136: if (requiredDimensionSymbol == 'F'
137: && actualDimensionValue == Dimension.FALSE) {
138: return true;
139: }
140: if (requiredDimensionSymbol == '0'
141: && actualDimensionValue == Dimension.P) {
142: return true;
143: }
144: if (requiredDimensionSymbol == '1'
145: && actualDimensionValue == Dimension.L) {
146: return true;
147: }
148: if (requiredDimensionSymbol == '2'
149: && actualDimensionValue == Dimension.A) {
150: return true;
151: }
152: return false;
153: }
154:
155: /**
156: * Returns true if each of the actual dimension symbols satisfies the
157: * corresponding required dimension symbol.
158: *
159: *@param actualDimensionSymbols nine dimension symbols to validate.
160: * Possible values are <code>{T, F, * , 0, 1, 2}</code>.
161: *@param requiredDimensionSymbols nine dimension symbols to validate
162: * against. Possible values are <code>{T, F, * , 0, 1, 2}</code>.
163: *@return true if each of the required dimension
164: * symbols encompass the corresponding actual dimension symbol
165: */
166: public static boolean matches(String actualDimensionSymbols,
167: String requiredDimensionSymbols) {
168: IntersectionMatrix m = new IntersectionMatrix(
169: actualDimensionSymbols);
170: return m.matches(requiredDimensionSymbols);
171: }
172:
173: /**
174: * Changes the value of one of this <code>IntersectionMatrix</code>s
175: * elements.
176: *
177: *@param row the row of this <code>IntersectionMatrix</code>,
178: * indicating the interior, boundary or exterior of the first <code>Geometry</code>
179: *@param column the column of this <code>IntersectionMatrix</code>,
180: * indicating the interior, boundary or exterior of the second <code>Geometry</code>
181: *@param dimensionValue the new value of the element
182: */
183: public void set(int row, int column, int dimensionValue) {
184: matrix[row][column] = dimensionValue;
185: }
186:
187: /**
188: * Changes the elements of this <code>IntersectionMatrix</code> to the
189: * dimension symbols in <code>dimensionSymbols</code>.
190: *
191: *@param dimensionSymbols nine dimension symbols to which to set this <code>IntersectionMatrix</code>
192: * s elements. Possible values are <code>{T, F, * , 0, 1, 2}</code>
193: */
194: public void set(String dimensionSymbols) {
195: for (int i = 0; i < dimensionSymbols.length(); i++) {
196: int row = i / 3;
197: int col = i % 3;
198: matrix[row][col] = Dimension
199: .toDimensionValue(dimensionSymbols.charAt(i));
200: }
201: }
202:
203: /**
204: * Changes the specified element to <code>minimumDimensionValue</code> if the
205: * element is less.
206: *
207: *@param row the row of this <code>IntersectionMatrix</code>
208: * , indicating the interior, boundary or exterior of the first <code>Geometry</code>
209: *@param column the column of this <code>IntersectionMatrix</code>
210: * , indicating the interior, boundary or exterior of the second <code>Geometry</code>
211: *@param minimumDimensionValue the dimension value with which to compare the
212: * element. The order of dimension values from least to greatest is
213: * <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>.
214: */
215: public void setAtLeast(int row, int column,
216: int minimumDimensionValue) {
217: if (matrix[row][column] < minimumDimensionValue) {
218: matrix[row][column] = minimumDimensionValue;
219: }
220: }
221:
222: /**
223: * If row >= 0 and column >= 0, changes the specified element to <code>minimumDimensionValue</code>
224: * if the element is less. Does nothing if row <0 or column < 0.
225: *
226: *@param row the row of this <code>IntersectionMatrix</code>
227: * , indicating the interior, boundary or exterior of the first <code>Geometry</code>
228: *@param column the column of this <code>IntersectionMatrix</code>
229: * , indicating the interior, boundary or exterior of the second <code>Geometry</code>
230: *@param minimumDimensionValue the dimension value with which to compare the
231: * element. The order of dimension values from least to greatest is
232: * <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>.
233: */
234: public void setAtLeastIfValid(int row, int column,
235: int minimumDimensionValue) {
236: if (row >= 0 && column >= 0) {
237: setAtLeast(row, column, minimumDimensionValue);
238: }
239: }
240:
241: /**
242: * For each element in this <code>IntersectionMatrix</code>, changes the
243: * element to the corresponding minimum dimension symbol if the element is
244: * less.
245: *
246: *@param minimumDimensionSymbols nine dimension symbols with which to
247: * compare the elements of this <code>IntersectionMatrix</code>. The
248: * order of dimension values from least to greatest is <code>{DONTCARE, TRUE, FALSE, 0, 1, 2}</code>
249: * .
250: */
251: public void setAtLeast(String minimumDimensionSymbols) {
252: for (int i = 0; i < minimumDimensionSymbols.length(); i++) {
253: int row = i / 3;
254: int col = i % 3;
255: setAtLeast(row, col,
256: Dimension.toDimensionValue(minimumDimensionSymbols
257: .charAt(i)));
258: }
259: }
260:
261: /**
262: * Changes the elements of this <code>IntersectionMatrix</code> to <code>dimensionValue</code>
263: * .
264: *
265: *@param dimensionValue the dimension value to which to set this <code>IntersectionMatrix</code>
266: * s elements. Possible values <code>{TRUE, FALSE, DONTCARE, 0, 1, 2}</code>
267: * .
268: */
269: public void setAll(int dimensionValue) {
270: for (int ai = 0; ai < 3; ai++) {
271: for (int bi = 0; bi < 3; bi++) {
272: matrix[ai][bi] = dimensionValue;
273: }
274: }
275: }
276:
277: /**
278: * Returns the value of one of this <code>IntersectionMatrix</code>s
279: * elements.
280: *
281: *@param row the row of this <code>IntersectionMatrix</code>, indicating
282: * the interior, boundary or exterior of the first <code>Geometry</code>
283: *@param column the column of this <code>IntersectionMatrix</code>,
284: * indicating the interior, boundary or exterior of the second <code>Geometry</code>
285: *@return the dimension value at the given matrix position.
286: */
287: public int get(int row, int column) {
288: return matrix[row][column];
289: }
290:
291: /**
292: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
293: * FF*FF****.
294: *
295: *@return <code>true</code> if the two <code>Geometry</code>s related by
296: * this <code>IntersectionMatrix</code> are disjoint
297: */
298: public boolean isDisjoint() {
299: return matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE
300: && matrix[Location.INTERIOR][Location.BOUNDARY] == Dimension.FALSE
301: && matrix[Location.BOUNDARY][Location.INTERIOR] == Dimension.FALSE
302: && matrix[Location.BOUNDARY][Location.BOUNDARY] == Dimension.FALSE;
303: }
304:
305: /**
306: * Returns <code>true</code> if <code>isDisjoint</code> returns false.
307: *
308: *@return <code>true</code> if the two <code>Geometry</code>s related by
309: * this <code>IntersectionMatrix</code> intersect
310: */
311: public boolean isIntersects() {
312: return !isDisjoint();
313: }
314:
315: /**
316: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
317: * FT*******, F**T***** or F***T****.
318: *
319: *@param dimensionOfGeometryA the dimension of the first <code>Geometry</code>
320: *@param dimensionOfGeometryB the dimension of the second <code>Geometry</code>
321: *@return <code>true</code> if the two <code>Geometry</code>
322: * s related by this <code>IntersectionMatrix</code> touch; Returns false
323: * if both <code>Geometry</code>s are points.
324: */
325: public boolean isTouches(int dimensionOfGeometryA,
326: int dimensionOfGeometryB) {
327: if (dimensionOfGeometryA > dimensionOfGeometryB) {
328: //no need to get transpose because pattern matrix is symmetrical
329: return isTouches(dimensionOfGeometryB, dimensionOfGeometryA);
330: }
331: if ((dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A)
332: || (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.L)
333: || (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A)
334: || (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A)
335: || (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L)) {
336: return matrix[Location.INTERIOR][Location.INTERIOR] == Dimension.FALSE
337: && (matches(
338: matrix[Location.INTERIOR][Location.BOUNDARY],
339: 'T')
340: || matches(
341: matrix[Location.BOUNDARY][Location.INTERIOR],
342: 'T') || matches(
343: matrix[Location.BOUNDARY][Location.BOUNDARY],
344: 'T'));
345: }
346: return false;
347: }
348:
349: /**
350: * Returns <code>true</code> if this geometry crosses the
351: * specified geometry.
352: * <p>
353: * The <code>crosses</code> predicate has the following equivalent definitions:
354: * <ul>
355: * <li>The geometries have some but not all interior points in common.
356: * <li>The DE-9IM Intersection Matrix for the two geometries is
357: * <ul>
358: * <li>T*T****** (for P/L, P/A, and L/A situations)
359: * <li>T*****T** (for L/P, L/A, and A/L situations)
360: * <li>0******** (for L/L situations)
361: * </ul>
362: * </ul>
363: * For any other combination of dimensions this predicate returns <code>false</code>.
364: * <p>
365: * The SFS defined this predicate only for P/L, P/A, L/L, and L/A situations.
366: * JTS extends the definition to apply to L/P, A/P and A/L situations as well.
367: * This makes the relation symmetric.
368: *
369: *@param dimensionOfGeometryA the dimension of the first <code>Geometry</code>
370: *@param dimensionOfGeometryB the dimension of the second <code>Geometry</code>
371: *@return <code>true</code> if the two <code>Geometry</code>s
372: * related by this <code>IntersectionMatrix</code> cross.
373: */
374: public boolean isCrosses(int dimensionOfGeometryA,
375: int dimensionOfGeometryB) {
376: if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.L)
377: || (dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.A)
378: || (dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.A)) {
379: return matches(
380: matrix[Location.INTERIOR][Location.INTERIOR], 'T')
381: && matches(
382: matrix[Location.INTERIOR][Location.EXTERIOR],
383: 'T');
384: }
385: if ((dimensionOfGeometryA == Dimension.L && dimensionOfGeometryB == Dimension.P)
386: || (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.P)
387: || (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.L)) {
388: return matches(
389: matrix[Location.INTERIOR][Location.INTERIOR], 'T')
390: && matches(
391: matrix[Location.EXTERIOR][Location.INTERIOR],
392: 'T');
393: }
394: if (dimensionOfGeometryA == Dimension.L
395: && dimensionOfGeometryB == Dimension.L) {
396: return matrix[Location.INTERIOR][Location.INTERIOR] == 0;
397: }
398: return false;
399: }
400:
401: /**
402: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
403: * T*F**F***.
404: *
405: *@return <code>true</code> if the first <code>Geometry</code> is within
406: * the second
407: */
408: public boolean isWithin() {
409: return matches(matrix[Location.INTERIOR][Location.INTERIOR],
410: 'T')
411: && matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE
412: && matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
413: }
414:
415: /**
416: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
417: * T*****FF*.
418: *
419: *@return <code>true</code> if the first <code>Geometry</code> contains the
420: * second
421: */
422: public boolean isContains() {
423: return matches(matrix[Location.INTERIOR][Location.INTERIOR],
424: 'T')
425: && matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE
426: && matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
427: }
428:
429: /**
430: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
431: * <code>T*****FF*</code>
432: * or <code>*T****FF*</code>
433: * or <code>***T**FF*</code>
434: * or <code>****T*FF*</code>
435: *
436: *@return <code>true</code> if the first <code>Geometry</code> covers the
437: * second
438: */
439: public boolean isCovers() {
440: boolean hasPointInCommon = matches(
441: matrix[Location.INTERIOR][Location.INTERIOR], 'T')
442: || matches(
443: matrix[Location.INTERIOR][Location.BOUNDARY],
444: 'T')
445: || matches(
446: matrix[Location.BOUNDARY][Location.INTERIOR],
447: 'T')
448: || matches(
449: matrix[Location.BOUNDARY][Location.BOUNDARY],
450: 'T');
451:
452: return hasPointInCommon
453: && matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE
454: && matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE;
455: }
456:
457: /**
458: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
459: * <code>T*F**F***</code>
460: * or <code>*TF**F***</code>
461: * or <code>**FT*F***</code>
462: * or <code>**F*TF***</code>
463: *
464: *@return <code>true</code> if the first <code>Geometry</code>
465: * is covered by the second
466: */
467: public boolean isCoveredBy() {
468: boolean hasPointInCommon = matches(
469: matrix[Location.INTERIOR][Location.INTERIOR], 'T')
470: || matches(
471: matrix[Location.INTERIOR][Location.BOUNDARY],
472: 'T')
473: || matches(
474: matrix[Location.BOUNDARY][Location.INTERIOR],
475: 'T')
476: || matches(
477: matrix[Location.BOUNDARY][Location.BOUNDARY],
478: 'T');
479:
480: return hasPointInCommon
481: && matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE
482: && matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
483: }
484:
485: /**
486: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
487: * T*F**FFF*.
488: *
489: *@param dimensionOfGeometryA the dimension of the first <code>Geometry</code>
490: *@param dimensionOfGeometryB the dimension of the second <code>Geometry</code>
491: *@return <code>true</code> if the two <code>Geometry</code>
492: * s related by this <code>IntersectionMatrix</code> are equal; the
493: * <code>Geometry</code>s must have the same dimension for this function
494: * to return <code>true</code>
495: */
496: public boolean isEquals(int dimensionOfGeometryA,
497: int dimensionOfGeometryB) {
498: if (dimensionOfGeometryA != dimensionOfGeometryB) {
499: return false;
500: }
501: return matches(matrix[Location.INTERIOR][Location.INTERIOR],
502: 'T')
503: && matrix[Location.EXTERIOR][Location.INTERIOR] == Dimension.FALSE
504: && matrix[Location.INTERIOR][Location.EXTERIOR] == Dimension.FALSE
505: && matrix[Location.EXTERIOR][Location.BOUNDARY] == Dimension.FALSE
506: && matrix[Location.BOUNDARY][Location.EXTERIOR] == Dimension.FALSE;
507: }
508:
509: /**
510: * Returns <code>true</code> if this <code>IntersectionMatrix</code> is
511: * <UL>
512: * <LI> T*T***T** (for two points or two surfaces)
513: * <LI> 1*T***T** (for two curves)
514: * </UL>
515: * .
516: *
517: *@param dimensionOfGeometryA the dimension of the first <code>Geometry</code>
518: *@param dimensionOfGeometryB the dimension of the second <code>Geometry</code>
519: *@return <code>true</code> if the two <code>Geometry</code>
520: * s related by this <code>IntersectionMatrix</code> overlap. For this
521: * function to return <code>true</code>, the <code>Geometry</code>s must
522: * be two points, two curves or two surfaces.
523: */
524: public boolean isOverlaps(int dimensionOfGeometryA,
525: int dimensionOfGeometryB) {
526: if ((dimensionOfGeometryA == Dimension.P && dimensionOfGeometryB == Dimension.P)
527: || (dimensionOfGeometryA == Dimension.A && dimensionOfGeometryB == Dimension.A)) {
528: return matches(
529: matrix[Location.INTERIOR][Location.INTERIOR], 'T')
530: && matches(
531: matrix[Location.INTERIOR][Location.EXTERIOR],
532: 'T')
533: && matches(
534: matrix[Location.EXTERIOR][Location.INTERIOR],
535: 'T');
536: }
537: if (dimensionOfGeometryA == Dimension.L
538: && dimensionOfGeometryB == Dimension.L) {
539: return matrix[Location.INTERIOR][Location.INTERIOR] == 1
540: && matches(
541: matrix[Location.INTERIOR][Location.EXTERIOR],
542: 'T')
543: && matches(
544: matrix[Location.EXTERIOR][Location.INTERIOR],
545: 'T');
546: }
547: return false;
548: }
549:
550: /**
551: * Returns whether the elements of this <code>IntersectionMatrix</code>
552: * satisfies the required dimension symbols.
553: *
554: *@param requiredDimensionSymbols nine dimension symbols with which to
555: * compare the elements of this <code>IntersectionMatrix</code>. Possible
556: * values are <code>{T, F, * , 0, 1, 2}</code>.
557: *@return <code>true</code> if this <code>IntersectionMatrix</code>
558: * matches the required dimension symbols
559: */
560: public boolean matches(String requiredDimensionSymbols) {
561: if (requiredDimensionSymbols.length() != 9) {
562: throw new IllegalArgumentException("Should be length 9: "
563: + requiredDimensionSymbols);
564: }
565: for (int ai = 0; ai < 3; ai++) {
566: for (int bi = 0; bi < 3; bi++) {
567: if (!matches(matrix[ai][bi], requiredDimensionSymbols
568: .charAt(3 * ai + bi))) {
569: return false;
570: }
571: }
572: }
573: return true;
574: }
575:
576: /**
577: * Transposes this IntersectionMatrix.
578: *
579: *@return this <code>IntersectionMatrix</code> as a convenience
580: */
581: public IntersectionMatrix transpose() {
582: int temp = matrix[1][0];
583: matrix[1][0] = matrix[0][1];
584: matrix[0][1] = temp;
585: temp = matrix[2][0];
586: matrix[2][0] = matrix[0][2];
587: matrix[0][2] = temp;
588: temp = matrix[2][1];
589: matrix[2][1] = matrix[1][2];
590: matrix[1][2] = temp;
591: return this ;
592: }
593:
594: /**
595: * Returns a nine-character <code>String</code> representation of this <code>IntersectionMatrix</code>
596: * .
597: *
598: *@return the nine dimension symbols of this <code>IntersectionMatrix</code>
599: * in row-major order.
600: */
601: public String toString() {
602: StringBuffer buf = new StringBuffer("123456789");
603: for (int ai = 0; ai < 3; ai++) {
604: for (int bi = 0; bi < 3; bi++) {
605: buf.setCharAt(3 * ai + bi, Dimension
606: .toDimensionSymbol(matrix[ai][bi]));
607: }
608: }
609: return buf.toString();
610: }
611: }
|