]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/utils/geom/DirectionSet.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / utils / geom / DirectionSet.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.utils.geom;\r
13 \r
14 import java.awt.geom.Point2D;\r
15 import java.util.Collection;\r
16 import java.util.Collections;\r
17 import java.util.HashSet;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.g2d.utils.GeometryUtils;\r
21 \r
22 /**\r
23  * A set of compass [0..360) directions\r
24  */\r
25 public class DirectionSet extends HashSet<Double> {\r
26         \r
27         public static final DirectionSet NESW = new DirectionSet(0.0, 90.0, 180.0, 270.0);\r
28         \r
29         public static final DirectionSet N      = new DirectionSet(0.0);\r
30         public static final DirectionSet NE     = new DirectionSet(0.0, 90.0);\r
31         public static final DirectionSet E      = new DirectionSet(90.0);\r
32         public static final DirectionSet SE     = new DirectionSet(90.0,180.0);\r
33         public static final DirectionSet S      = new DirectionSet(180.0);\r
34         public static final DirectionSet SW     = new DirectionSet(180.0, 270.0);\r
35         public static final DirectionSet W      = new DirectionSet(270.0);\r
36         public static final DirectionSet NW     = new DirectionSet(270.0, 0.0);\r
37 \r
38         public static final DirectionSet NE2    = new DirectionSet(0.0, 90.0, 45.0);\r
39         public static final DirectionSet SE2    = new DirectionSet(90.0,180.0, 135.0);\r
40         public static final DirectionSet SW2    = new DirectionSet(180.0, 270.0, 225.0);\r
41         public static final DirectionSet NW2    = new DirectionSet(270.0, 0.0, 315.0);\r
42         \r
43         public static final DirectionSet HORIZ = new DirectionSet(90.0, 270.0);\r
44         public static final DirectionSet VERT = new DirectionSet(0.0, 180.0);\r
45         public static final DirectionSet ANY = \r
46                 new DirectionSet(\r
47                                 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180,\r
48                                 195, 210, 225, 240, 255, 270, 285, 300, 315, 330, 345);                         \r
49 \r
50         private Set<Point2D> unitVectors;\r
51         \r
52         public DirectionSet(double ... directions)\r
53         {\r
54                 for (double d : directions)\r
55                         add(d);\r
56         }\r
57         \r
58         private static final long serialVersionUID = 1L;\r
59         private boolean add(double e) {\r
60                 if (e<0 || e>=360.0) e = Math.IEEEremainder(e, 360.0);\r
61                 if (e<0) e = 360.0-e;\r
62                 return super.add(e);\r
63         }\r
64         @Override\r
65         public boolean add(Double e) {\r
66                 unitVectors = null;\r
67                 if (e==null) return false;\r
68                 return add((double)e);\r
69         }\r
70         @Override\r
71         public boolean addAll(Collection<? extends Double> c) {\r
72                 unitVectors = null;\r
73                 return super.addAll(c);\r
74         }\r
75         @Override\r
76         public boolean remove(Object o) {\r
77                 unitVectors = null;\r
78                 return super.remove(o);\r
79         }\r
80         @Override\r
81         public boolean removeAll(Collection<?> c) {\r
82                 unitVectors = null;\r
83                 return super.removeAll(c);\r
84         }\r
85         @Override\r
86         public void clear() {\r
87                 unitVectors = null;\r
88                 super.clear();\r
89         }\r
90         \r
91         public Double getClosestDirection(double d2)\r
92         {\r
93                 Double closest = null;\r
94                 for (Double d1 : this)\r
95                 {\r
96                         double diff = d1>180==d2>180 ? Math.abs(d1-d2) : d1<d2 ? d1-d2+360 : d2-d1+360;\r
97                         if (closest==null || closest<diff)\r
98                                 closest = diff;\r
99                 }\r
100                 return closest;\r
101         }\r
102         public Double getClosestDirection(double d2, double tolerance)\r
103         {\r
104                 Double closest = null;\r
105                 for (Double d1 : this)\r
106                 {\r
107                         double diff = d1>180==d2>180 ? Math.abs(d1-d2) : d1<d2 ? d1-d2+360 : d2-d1+360;\r
108                         if (diff>tolerance) continue;\r
109                         if (closest==null || closest<diff)\r
110                                 closest = diff;\r
111                 }\r
112                 return closest;\r
113         }       \r
114         \r
115         /**\r
116          * Create direction set of inverse directions\r
117          * @return\r
118          */\r
119         public DirectionSet createInverse() \r
120         {\r
121                 DirectionSet result = new DirectionSet();\r
122                 for (double dir : this)\r
123                 {\r
124                         dir = dir + 180.0;\r
125                         if (dir>360.0) dir-=360.0;\r
126                         result.add(dir);\r
127                 }\r
128                 return result;\r
129         }\r
130         \r
131         \r
132         /**\r
133          * Get directions as unit vectors\r
134          * @return collection where to add unit vectors\r
135          */\r
136         private Set<Point2D> createUnitVectors() {\r
137                 HashSet<Point2D> result = new HashSet<Point2D>(size());\r
138                 for (double d : this)\r
139                         result.add( GeometryUtils.toUnitVector(d, new Point2D.Double()) );\r
140                 return result;\r
141         }\r
142 \r
143         public Set<Point2D> getUnitVectors() {\r
144                 if (unitVectors==null) {\r
145                         unitVectors = createUnitVectors();\r
146                         unitVectors = Collections.unmodifiableSet(unitVectors);\r
147                 }\r
148                 return unitVectors;\r
149         }\r
150 \r
151         \r
152         \r
153 }