|
degate 0.1.1
|
00001 /* 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 #include "Line.h" 00023 #include "globals.h" 00024 #include <math.h> 00025 #include <stdlib.h> 00026 00027 using namespace degate; 00028 00029 Line::Line() : 00030 from_x(0), 00031 from_y(0), 00032 to_x(0), 00033 to_y(0), 00034 diameter(0), 00035 d_x(0), 00036 d_y(0) { 00037 calculate_bounding_box(); 00038 } 00039 00040 Line::Line(int _from_x, int _from_y, int _to_x, int _to_y, unsigned int _diameter) : 00041 from_x(_from_x), 00042 from_y(_from_y), 00043 to_x(_to_x), 00044 to_y(_to_y), 00045 diameter(_diameter), 00046 d_x(_to_x - _from_x), 00047 d_y(_to_y - _from_y) { 00048 calculate_bounding_box(); 00049 } 00050 00051 bool Line::in_shape(int x, int y, int max_distance) const { 00052 00053 /* 00054 How to check if a point is on a line: 00055 y = m*x + n 00056 m = dy / dx 00057 n = y0 - m*x0 00058 y' = m*x' + n 00059 00060 |y' - y| < epsilon? 00061 */ 00062 00063 /* 00064 Check if it is a vertical line (dy ~~ 0). If it is true, the bounding box 00065 describes the line. The same applies to horiontal lines. 00066 */ 00067 00068 if(is_vertical() || is_horizontal()) { 00069 return bounding_box.in_shape(x, y, max_distance); 00070 } 00071 else { 00072 00073 // check if x is outside the x-range 00074 if(x < std::min(from_x,to_x) || 00075 x > std::max(from_x, to_x)) 00076 return false; 00077 00078 double m = d_y / d_x; 00079 double n = (double)from_y - m * (double)from_x; 00080 double y_dash = m * (double) x + n; 00081 00082 if(fabs(y_dash - y) <= diameter / 2 + max_distance) 00083 return true; 00084 else 00085 return false; 00086 } 00087 } 00088 00089 bool Line::in_bounding_box(BoundingBox const& bbox) const { 00090 return bounding_box.in_bounding_box(bbox); 00091 } 00092 00093 00094 BoundingBox const& Line::get_bounding_box() const { 00095 return bounding_box; 00096 } 00097 00098 bool Line::is_vertical() const { 00099 return to_x - from_x == 0; 00100 } 00101 00102 bool Line::is_horizontal() const { 00103 return to_y - from_y == 0; 00104 } 00105 00106 void Line::set_diameter(unsigned int diameter) { 00107 this->diameter = diameter; 00108 calculate_bounding_box(); 00109 } 00110 00111 unsigned int Line::get_diameter() const { 00112 return diameter; 00113 } 00114 00115 int Line::get_from_x() const { 00116 return from_x; 00117 } 00118 00119 int Line::get_from_y() const { 00120 return from_y; 00121 } 00122 00123 int Line::get_to_x() const { 00124 return to_x; 00125 } 00126 00127 int Line::get_to_y() const { 00128 return to_y; 00129 } 00130 00131 void Line::set_from_x(int from_x) { 00132 this->from_x = from_x; 00133 d_x = to_x - from_x; 00134 calculate_bounding_box(); 00135 } 00136 00137 void Line::set_to_x(int to_x) { 00138 this->to_x = to_x; 00139 d_x = to_x - from_x; 00140 calculate_bounding_box(); 00141 } 00142 00143 void Line::set_from_y(int from_y) { 00144 this->from_y = from_y; 00145 d_y = to_y - from_y; 00146 calculate_bounding_box(); 00147 } 00148 00149 void Line::set_to_y(int to_y) { 00150 this->to_y = to_y; 00151 d_y = to_y - from_y; 00152 calculate_bounding_box(); 00153 } 00154 00155 void Line::shift_y(int delta_y) { 00156 from_y += delta_y; 00157 to_y += delta_y; 00158 calculate_bounding_box(); 00159 } 00160 00161 void Line::shift_x(int delta_x) { 00162 from_x += delta_x; 00163 to_x += delta_x; 00164 calculate_bounding_box(); 00165 } 00166 00167 00168 void Line::calculate_bounding_box() { 00169 int radius = diameter >> 1; 00170 00171 if(is_vertical()) 00172 bounding_box = BoundingBox(std::max(from_x - radius, 0), 00173 std::max(to_x + radius, 0), from_y, to_y); 00174 else if(is_horizontal()) 00175 bounding_box = BoundingBox(from_x, to_x, 00176 std::max(from_y - radius, 0), 00177 std::max(to_y + radius, 0)); 00178 else 00179 bounding_box = BoundingBox(from_x, to_x, from_y, to_y); 00180 } 00181 00182 00183 unsigned int Line::get_length() const { 00184 return ((labs(from_x - to_x) << 1) + (labs(from_y - to_y) << 1)) >> 1; 00185 } 00186 00187 Point Line::get_p1() const { 00188 return Point(from_x, from_y); 00189 } 00190 00191 Point Line::get_p2() const { 00192 return Point(to_x, to_y); 00193 } 00194 00195 void Line::set_p1(Point const& p) { 00196 set_from_x(p.get_x()); 00197 set_from_y(p.get_y()); 00198 } 00199 00200 void Line::set_p2(Point const& p) { 00201 set_to_x(p.get_x()); 00202 set_to_y(p.get_y()); 00203 }
1.7.4