001/* 002 * Copyright (c) 1998-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.geon; 031 032import java.util.Vector; 033 034import nl.skybound.awt.DoublePolygon; 035import ptolemy.actor.TypedAtomicActor; 036import ptolemy.actor.TypedIOPort; 037import ptolemy.data.ArrayToken; 038import ptolemy.data.DoubleToken; 039import ptolemy.data.ObjectToken; 040import ptolemy.data.StringToken; 041import ptolemy.data.Token; 042import ptolemy.data.type.ArrayType; 043import ptolemy.data.type.BaseType; 044import ptolemy.kernel.CompositeEntity; 045import ptolemy.kernel.util.IllegalActionException; 046import ptolemy.kernel.util.NameDuplicationException; 047 048////////////////////////////////////////////////////////////////////////// 049//// PointInPolygonXY 050/** 051 * This actor receives an array of polygons and regions and a classification 052 * point. It returns an array of all the regions the point falls in. 053 * 054 * @author Efrat Jaeger 055 * @version $Id: PointinPolygonXY.java 24234 2010-05-06 05:21:26Z welker $ 056 * @since Ptolemy II 3.0.2 057 */ 058public class PointinPolygonXY extends TypedAtomicActor { 059 060 /** 061 * Construct an actor with the given container and name. 062 * 063 * @param container 064 * The container. 065 * @param name 066 * The name of this actor. 067 * @exception IllegalActionException 068 * If the actor cannot be contained by the proposed 069 * container. 070 * @exception NameDuplicationException 071 * If the container already has an actor with this name. 072 */ 073 public PointinPolygonXY(CompositeEntity container, String name) 074 throws NameDuplicationException, IllegalActionException { 075 076 super(container, name); 077 078 // Set the type constraint. 079 region = new TypedIOPort(this, "region", false, true); 080 region.setTypeEquals(new ArrayType(BaseType.STRING)); 081 point = new TypedIOPort(this, "point", true, false); // input point 082 point.setTypeEquals(new ArrayType(BaseType.DOUBLE)); 083 polygonRegions = new TypedIOPort(this, "polygonRegions", true, false); // Polygon 084 // coordinates 085 // and 086 // regions 087 polygonRegions.setTypeEquals(BaseType.GENERAL); 088 089 _attachText("_iconDescription", "<svg>\n" 090 + "<polygon points=\"-15,-2 0,-15 15,-2 11,15 -11,15\" " 091 + "style=\"fill:white\"/>\n" 092 + "<circle cx=\"3\" cy=\"4\" r=\"1\"" 093 + "style=\"fill:black\"/>\n" + "</svg>\n"); 094 095 } 096 097 // ///////////////////////////////////////////////////////////////// 098 // // ports and parameters //// 099 100 /** 101 * A classification point. 102 */ 103 public TypedIOPort point; 104 105 /** 106 * A set of polygons and their region names. 107 */ 108 public TypedIOPort polygonRegions; 109 110 /** 111 * The point's region. 112 */ 113 public TypedIOPort region; 114 115 // ///////////////////////////////////////////////////////////////// 116 // // public methods //// 117 118 /** 119 * Receive a set of polygons and a classification point and returns the 120 * point region along with a URL for browser display of the point in the 121 * polygon. 122 * 123 * @exception IllegalActionException 124 * If there's no director. 125 */ 126 public void fire() throws IllegalActionException { 127 if (polygonRegions.hasToken(0) && point.hasToken(0)) { 128 ObjectToken obj1 = (ObjectToken) polygonRegions.get(0); 129 PolygonUtil polygons[] = (PolygonUtil[]) obj1.getValue(); 130 ArrayToken arrayToken = (ArrayToken) point.get(0); 131 double x = ((DoubleToken) arrayToken.getElement(0)).doubleValue(); 132 double y = ((DoubleToken) arrayToken.getElement(1)).doubleValue(); 133 // Point2D.Double p = (Point2D.Double) obj2.getValue(); 134 // double x = p.getX(); 135 // double y = p.getY(); 136 Vector result = new Vector(); 137 for (int j = 0; j < polygons.length; j++) { 138 DoublePolygon P = polygons[j].getPolygon(); 139 arrayLen = P.npoints; 140 String _region = polygons[j].getRegion(); 141 if (_isPolygonVertex(P, x, y) || _onPolygonEdge(P, x, y) 142 || P.contains(x, y)) { 143 result.add(new StringToken(_region)); // FIX ME!!! TAKE CARE 144 // OF MULTIPLE 145 // REGIONS AND NO 146 // REGION!!! 147 } 148 } 149 Token[] regions = null; 150 if (result.size() > 0) { 151 regions = new Token[result.size()]; 152 result.toArray(regions); 153 } else { 154 regions = new Token[1]; 155 regions[0] = new StringToken(""); 156 } 157 region.broadcast(new ArrayToken(regions)); 158 } 159 } 160 161 // ///////////////////////////////////////////////////////////////// 162 // // private methods //// 163 164 /* 165 * Checking whether the given point is one of the polygon's vertices. 166 */ 167 private boolean _isPolygonVertex(DoublePolygon P, double x, double y) { 168 for (int i = 0; i < arrayLen; i++) { 169 if (P.xpoints[i] == x && P.ypoints[i] == y) 170 return true; 171 } 172 return false; 173 } 174 175 /* 176 * Checking whether the given point is one of the polygon's edges. 177 */ 178 private boolean _onPolygonEdge(DoublePolygon P, double x, double y) { 179 double x1, x2, y1, y2; 180 for (int i = 0; i < arrayLen; i++) { 181 x1 = P.xpoints[i]; 182 x2 = P.xpoints[(i + 1) % arrayLen]; 183 y1 = P.ypoints[i]; 184 y2 = P.ypoints[(i + 1) % arrayLen]; 185 if (((x1 <= x && x <= x2) || (x2 <= x && x <= x1)) && // x and y are 186 // between 187 // x1,x2 and 188 // y1,y2 189 ((y1 <= y && y <= y2) || (y2 <= y && y <= y1))) { 190 if (((y - y1) / (x - x1)) == ((y - y2) / (x - x2))) 191 return true; 192 } 193 } 194 return false; 195 } 196 197 /* 198 * Adding the classification point to the SVG file for display purposes. 199 */ 200 /* 201 * private void _addRegionToSVG(String svgFile, String region) { try { // 202 * System.out.println("SVG File: " + svgFile); File svg = new File(svgFile); 203 * BufferedReader br = new BufferedReader(new FileReader(svg)); String line; 204 * String toFile = ""; String extraLine; if (region.length() > 20) { int tmp 205 * = result.indexOf(" ",15); extraLine = 206 * "<text x= '315' y='70' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 207 * + region.substring(0,tmp) + "</text>"; extraLine += 208 * "<text x= '315' y='90' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 209 * + region.substring(tmp+1) + "</text>"; } else { extraLine = 210 * "<text x= '315' y='70' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 211 * + region + "</text>"; } // System.out.println("Extra line" + extraLine); 212 * while ( (line = br.readLine()) != null) { int ind = 213 * line.toLowerCase().indexOf("<text"); if (ind != -1) { // 214 * System.out.println("Inside extra line"); toFile += line.substring(0, ind) 215 * + "\n"; toFile += extraLine + "\n"; toFile += line.substring(ind) + "\n"; 216 * } else toFile += line + "\n"; } br.close(); 217 * 218 * // System.out.println(toFile); BufferedWriter out = new 219 * BufferedWriter(new FileWriter(svg)); out.write(toFile); out.close(); } 220 * catch (IOException e) { MessageHandler.error("Error opening file", e); } 221 * } 222 */ 223 // ///////////////////////////////////////////////////////////////// 224 // // private members //// 225 // private double x, y; 226 // private String id; 227 private int arrayLen; 228}