00001
00002
00003
00004
00005
00006
00007 #include "mmsubs.h"
00008 #include <QImage>
00009 #include <QPointF>
00010 #include <qmath.h>
00011
00012 const double PI = 3.1415926535;
00013
00014 double angleBetweenVectors (const QPointF &v1,
00015 const QPointF &v2)
00016 {
00017 double v1Mag = qSqrt (v1.x() * v1.x() + v1.y() * v1.y());
00018 double v2Mag = qSqrt (v2.x() * v2.x() + v2.y() * v2.y());
00019
00020 double angle = 0;
00021 if ((v1Mag > 0) || (v2Mag > 0)) {
00022
00023 double cosArg = (v1.x() * v2.x() + v1.y() * v2.y()) / (v1Mag * v2Mag);
00024 cosArg = qMin (qMax (cosArg, -1.0), 1.0);
00025 angle = qAcos (cosArg);
00026 }
00027
00028 return angle;
00029 }
00030
00031 double angleFromVectorToVector (const QPointF &vFrom,
00032 const QPointF &vTo)
00033 {
00034 double angleFrom = qAtan2 (vFrom.y(), vFrom.x());
00035 double angleTo = qAtan2 (vTo.y() , vTo.x());
00036
00037
00038
00039 double angleSeparation = angleTo - angleFrom;
00040
00041 while (angleSeparation < -1.0 * PI) {
00042 angleSeparation += 2.0 * PI;
00043 }
00044 while (angleSeparation > PI) {
00045 angleSeparation -= 2.0 * PI;
00046 }
00047
00048 return angleSeparation;
00049 }
00050
00051 QRgb pixelRGB(const QImage &image, int x, int y)
00052 {
00053 switch (image.depth())
00054 {
00055 case 1:
00056 return pixelRGB1(image, x, y);
00057 case 8:
00058 return pixelRGB8(image, x, y);
00059 default:
00060 return pixelRGB32(image, x, y);
00061 }
00062 }
00063
00064 QRgb pixelRGB1(const QImage &image1Bit, int x, int y)
00065 {
00066 unsigned int bit;
00067 if (image1Bit.format () == QImage::Format_MonoLSB) {
00068 bit = *(image1Bit.scanLine (y) + (x >> 3)) & (1 << (x & 7));
00069 } else {
00070 bit = *(image1Bit.scanLine (y) + (x >> 3)) & (1 << (7 - (x & 7)));
00071 }
00072
00073 unsigned int tableIndex = ((bit == 0) ? 0 : 1);
00074 return image1Bit.color(tableIndex);
00075 }
00076
00077 QRgb pixelRGB8(const QImage &image8Bit, int x, int y)
00078 {
00079 unsigned int tableIndex = *(image8Bit.scanLine(y) + x);
00080 return image8Bit.color(tableIndex);
00081 }
00082
00083 QRgb pixelRGB32(const QImage &image32Bit, int x, int y)
00084 {
00085 unsigned int* p = (unsigned int *) image32Bit.scanLine(y) + x;
00086 return *p;
00087 }
00088
00089 void projectPointOntoLine(double xToProject,
00090 double yToProject,
00091 double xStart,
00092 double yStart,
00093 double xStop,
00094 double yStop,
00095 double *xProjection,
00096 double *yProjection,
00097 double *projectedDistanceOutsideLine,
00098 double *distanceToLine)
00099 {
00100 double s;
00101 if (qAbs (yStart - yStop) > qAbs (xStart - xStop)) {
00102
00103
00104 double slope = (xStop - xStart) / (yStart - yStop);
00105 double yintercept = yToProject - slope * xToProject;
00106
00107
00108 s = (slope * xStart + yintercept - yStart) /
00109 (yStop - yStart + slope * (xStart - xStop));
00110
00111 } else {
00112
00113
00114 double slope = (yStop - yStart) / (xStart - xStop);
00115 double xintercept = xToProject - slope * yToProject;
00116
00117
00118 s = (slope * yStart + xintercept - xStart) /
00119 (xStop - xStart + slope * (yStart - yStop));
00120
00121 }
00122
00123 *xProjection = (1.0 - s) * xStart + s * xStop;
00124 *yProjection = (1.0 - s) * yStart + s * yStop;
00125
00126 if (s < 0) {
00127
00128 *projectedDistanceOutsideLine = qSqrt ((*xProjection - xStart) * (*xProjection - xStart) +
00129 (*yProjection - yStart) * (*yProjection - yStart));
00130 *distanceToLine = qSqrt ((xToProject - xStart) * (xToProject - xStart) +
00131 (yToProject - yStart) * (yToProject - yStart));
00132
00133
00134 *xProjection = xStart;
00135 *yProjection = yStart;
00136
00137 } else if (s > 1) {
00138
00139 *projectedDistanceOutsideLine = qSqrt ((*xProjection - xStop) * (*xProjection - xStop) +
00140 (*yProjection - yStop) * (*yProjection - yStop));
00141 *distanceToLine = qSqrt ((xToProject - xStop) * (xToProject - xStop) +
00142 (yToProject - yStop) * (yToProject - yStop));
00143
00144
00145 *xProjection = xStop;
00146 *yProjection = yStop;
00147
00148 } else {
00149
00150 *distanceToLine = qSqrt ((xToProject - *xProjection) * (xToProject - *xProjection) +
00151 (yToProject - *yProjection) * (yToProject - *yProjection));
00152
00153
00154 *projectedDistanceOutsideLine = 0.0;
00155
00156 }
00157 }
00158
00159 void setPixelRGB(QImage &image, int x, int y, QRgb q)
00160 {
00161 switch (image.depth())
00162 {
00163 case 1:
00164 setPixelRGB1(image, x, y, q);
00165 return;
00166 case 8:
00167 setPixelRGB8(image, x, y, q);
00168 return;
00169 case 32:
00170 setPixelRGB32(image, x, y, q);
00171 return;
00172 }
00173 }
00174
00175 void setPixelRGB1(QImage &image1Bit, int x, int y, QRgb q)
00176 {
00177 for (int index = 0; index < image1Bit.colorCount(); index++) {
00178 if (q == image1Bit.color(index))
00179 {
00180 if (image1Bit.format () == QImage::Format_MonoLSB)
00181 {
00182 *(image1Bit.scanLine (y) + (x >> 3)) &= ~(1 << (x & 7));
00183 if (index > 0)
00184 *(image1Bit.scanLine (y) + (x >> 3)) |= index << (x & 7);
00185 }
00186 else
00187 {
00188 *(image1Bit.scanLine (y) + (x >> 3)) &= ~(1 << (7 - (x & 7)));
00189 if (index > 0)
00190 *(image1Bit.scanLine (y) + (x >> 3)) |= index << (7 - (x & 7));
00191 }
00192 return;
00193 }
00194 }
00195 }
00196
00197 void setPixelRGB8(QImage &image8Bit, int x, int y, QRgb q)
00198 {
00199 for (int index = 0; index < image8Bit.colorCount(); index++) {
00200 if (q == image8Bit.color(index))
00201 {
00202 *(image8Bit.scanLine(y) + x) = index;
00203 return;
00204 }
00205 }
00206 }
00207
00208 void setPixelRGB32(QImage &image32Bit, int x, int y, QRgb q)
00209 {
00210 int* p = (int *)image32Bit.scanLine(y) + x;
00211 *p = q;
00212 }