001: package org.drools.integrationtests.waltz;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: /**
020: * @author Alexander Bagerman
021: *
022: */
023: public class WaltzUtil {
024: private static double PI = 3.1415927;
025:
026: private static final int MOD_NUM = 10000;
027:
028: private static int get_y(final int val) {
029: return val % WaltzUtil.MOD_NUM;
030: }
031:
032: private static int get_x(final int val) {
033: return (val / WaltzUtil.MOD_NUM);
034: }
035:
036: /***************************************************************************
037: * This function is passed two points and calculates the angle between the
038: * line defined by these points and the x-axis.
039: **************************************************************************/
040: private static double get_angle(final int p1, final int p2) {
041: int delta_x, delta_y;
042: double ret = 0.0;
043: /*
044: * Calculate (x2 - x1) and (y2 - y1). The points are passed in the form
045: * x1y1 and x2y2. get_x() and get_y() are passed these points and return
046: * the x and y values respectively. For example, get_x(1020) returns 10.
047: */
048: delta_x = get_x(p2) - get_x(p1);
049: delta_y = get_y(p2) - get_y(p1);
050:
051: if (delta_x == 0) {
052: if (delta_y > 0) {
053: ret = WaltzUtil.PI / 2;
054: } else if (delta_y < 0) {
055: ret = -WaltzUtil.PI / 2;
056: }
057: } else if (delta_y == 0) {
058: if (delta_x > 0) {
059: ret = 0.0;
060: } else if (delta_x < 0) {
061: ret = WaltzUtil.PI;
062: }
063: } else {
064: ret = Math.atan2(delta_y, delta_x);
065: }
066: return ret;
067: }
068:
069: /***************************************************************************
070: * This procedure is passed the basepoint of the intersection of two lines
071: * as well as the other two endpoints of the lines and calculates the angle
072: * inscribed by these three points.
073: **************************************************************************/
074: private static double inscribed_angle(final int basepoint,
075: final int p1, final int p2) {
076: double angle1, angle2, temp;
077:
078: /*
079: * Get the angle between line #1 and the origin and the angle between
080: * line #2 and the origin, and then subtract these values.
081: */
082: angle1 = get_angle(basepoint, p1);
083: angle2 = get_angle(basepoint, p2);
084: temp = angle1 - angle2;
085: if (temp < 0.0) {
086: temp = -temp;
087: }
088:
089: /*
090: * We always want the smaller of the two angles inscribed, so if the
091: * answer is greater than 180 degrees, calculate the smaller angle and
092: * return it.
093: */
094: if (temp > WaltzUtil.PI) {
095: temp = 2 * WaltzUtil.PI - temp;
096: }
097: if (temp < 0.0) {
098: return (-temp);
099: }
100: return (temp);
101: }
102:
103: public static Junction make_3_junction(final int basepoint,
104: final int p1, final int p2, final int p3) {
105: int shaft, barb1, barb2;
106: double angle12, angle13, angle23;
107: double sum, sum1213, sum1223, sum1323;
108: double delta;
109: String j_type;
110:
111: angle12 = inscribed_angle(basepoint, p1, p2);
112: angle13 = inscribed_angle(basepoint, p1, p3);
113: angle23 = inscribed_angle(basepoint, p2, p3);
114:
115: sum1213 = angle12 + angle13;
116: sum1223 = angle12 + angle23;
117: sum1323 = angle13 + angle23;
118:
119: if (sum1213 < sum1223) {
120: if (sum1213 < sum1323) {
121: sum = sum1213;
122: shaft = p1;
123: barb1 = p2;
124: barb2 = p3;
125: } else {
126: sum = sum1323;
127: shaft = p3;
128: barb1 = p1;
129: barb2 = p2;
130: }
131: } else {
132: if (sum1223 < sum1323) {
133: sum = sum1223;
134: shaft = p2;
135: barb1 = p1;
136: barb2 = p3;
137: } else {
138: sum = sum1323;
139: shaft = p3;
140: barb1 = p1;
141: barb2 = p2;
142: }
143: }
144:
145: delta = sum - WaltzUtil.PI;
146: if (delta < 0.0) {
147: delta = -delta;
148: }
149:
150: if (delta < 0.001) {
151: j_type = Junction.TEE;
152: } else if (sum > WaltzUtil.PI) {
153: j_type = Junction.FORK;
154: } else {
155: j_type = Junction.ARROW;
156: }
157:
158: return new Junction(barb1, shaft, barb2, basepoint, j_type);
159:
160: }
161: }
|