Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
SawtoothStretchType.cpp
1#include "SawtoothStretchType.h"
2
3#include <QVBoxLayout>
4#include <QLayout>
5#include <QLineEdit>
6#include <QLabel>
7#include <QTableWidget>
8
9#include "CubeViewport.h"
10#include "HistogramWidget.h"
11#include "Statistics.h"
12#include "Stretch.h"
13#include "CubeStretch.h"
14
15namespace Isis {
25 const Stretch &stretch, const QString &name, const QColor &color) :
26 StretchType(hist, stretch, name, color) {
27 p_offsetSlider = NULL;
28 p_widthSlider = NULL;
29 p_offsetEdit = NULL;
30 p_widthEdit = NULL;
31 p_sliderOverride = false;
32
33 QWidget *sliderWidget = new QWidget();
34 QGridLayout *sliderLayout = new QGridLayout();
35 sliderLayout->setColumnStretch(1, 10);
36
37 QLabel *startLabel = new QLabel("Offset");
38 p_offsetSlider = new QSlider(Qt::Horizontal);
39 p_offsetSlider->setTickPosition(QSlider::NoTicks);
40 p_offsetSlider->setMinimum(0);
41 p_offsetSlider->setMaximum(1000);
42 p_offsetSlider->setPageStep(50);
43 connect(p_offsetSlider, SIGNAL(valueChanged(int)),
44 this, SLOT(offsetSliderMoved(int)));
45 p_offsetEdit = new QLineEdit();
46 p_offsetEdit->setMaximumWidth(75);
47 p_offsetEdit->setText(QString::number(
48 p_cubeHist->Maximum() - p_cubeHist->Minimum()
49 ));
50 connect(p_offsetEdit, SIGNAL(textChanged(const QString &)),
51 this, SLOT(offsetEditChanged(const QString &)));
52 sliderLayout->addWidget(startLabel, 0, 0);
53 sliderLayout->addWidget(p_offsetSlider, 0, 1);
54 sliderLayout->addWidget(p_offsetEdit, 0, 2);
55
56 QLabel *widthLabel = new QLabel("Width");
57 p_widthSlider = new QSlider(Qt::Horizontal);
58 p_widthSlider->setTickPosition(QSlider::NoTicks);
59 p_widthSlider->setMinimum(0);
60 p_widthSlider->setMaximum(1000);
61 p_widthSlider->setPageStep(50);
62 connect(p_widthSlider, SIGNAL(valueChanged(int)),
63 this, SLOT(widthSliderMoved(int)));
64 p_widthEdit = new QLineEdit();
65 p_widthEdit->setMaximumWidth(75);
66 connect(p_widthEdit, SIGNAL(textChanged(const QString &)),
67 this, SLOT(widthEditChanged(const QString &)));
68 sliderLayout->addWidget(widthLabel, 1, 0);
69 sliderLayout->addWidget(p_widthSlider, 1, 1);
70 sliderLayout->addWidget(p_widthEdit, 1, 2);
71
72 sliderWidget->setLayout(sliderLayout);
73 p_mainLayout->addWidget(sliderWidget, 1, 0);
74
75 setLayout(p_mainLayout);
76
77 p_widthEdit->setText(QString::number(
78 p_cubeHist->Median() - p_cubeHist->Minimum()
79 ));
81 }
82
83
89
90
105 Stretch interpretted;
106 double offset = 0.0;
107 double width = 0.0;
108 bool changed = false;
109
110 // Too few pairs to do a saw tooth with
111 if(newStretch.Pairs() < 3) {
112 return;
113 }
114 else {
115 // find an offset... should be the second or third point
116 offset = newStretch.Input(1);
117
118 // offset should always be a low point
119 if(newStretch.Output(1) > 127)
120 offset = newStretch.Input(2);
121
122 width = (newStretch.Input(2) - newStretch.Input(0)) / 2;
123
124 interpretted.CopyPairs(calculateNewStretch(offset, width));
125
126 double deltaOffset = fabs(p_offsetEdit->text().toDouble() - offset);
127 changed = (changed || (deltaOffset > p_cubeHist->BinSize()));
128
129 double deltaWidth = fabs(p_widthEdit->text().toDouble() - width);
130 changed = (changed || (deltaWidth > p_cubeHist->BinSize()));
131 }
132
133 if(changed) {
134 p_stretch->CopyPairs(interpretted);
135 p_offsetEdit->setText(QString::number(offset));
136 p_widthEdit->setText(QString::number(width));
137 }
138
139 // regardless of it all, slider positions could need changed...
140 offsetEditChanged(QString());
141 widthEditChanged(QString());
142
143 if(changed) {
144 emit stretchChanged();
145 }
146 }
147
148
154 if(p_offsetSlider->value() >= p_widthSlider->value())
155 p_offsetSlider->setValue(p_widthSlider->value() - 1);
156
158 return;
159
160 double value = p_cubeHist->Minimum();
161 value += p_offsetSlider->value() * 2 *
162 (p_cubeHist->Maximum() - p_cubeHist->Minimum()) / 1000.0;
163 p_offsetEdit->setText(QString::number(value));
164 }
165
166
173 double value = p_offsetEdit->text().toDouble();
174
175 double percentage = value - p_cubeHist->Minimum();
176 percentage /= (p_cubeHist->Maximum() - p_cubeHist->Minimum()) * 2;
177 int valuePos = (int)(percentage * 1000.0);
178
179 p_sliderOverride = true;
180 p_offsetSlider->setValue(valuePos);
181 p_sliderOverride = false;
182
183 Stretch newStretch = calculateNewStretch();
184
185 if(newStretch.Text() != p_stretch->Text()) {
186 p_stretch->CopyPairs(newStretch);
187 emit stretchChanged();
188 }
189
190 }
191
192
198 if(p_widthSlider->value() <= p_offsetSlider->value())
199 p_widthSlider->setValue(p_offsetSlider->value() + 1);
200
202 return;
203
204 double highVal = p_cubeHist->Maximum() - p_cubeHist->Minimum();
205 double lowVal = p_cubeHist->BinSize();
206 double value = lowVal + p_widthSlider->value() *
207 (highVal - lowVal) / 1000.0;
208 p_widthEdit->setText(QString::number(value));
209 }
210
211
218 double value = p_widthEdit->text().toDouble();
219
220 double highVal = p_cubeHist->Maximum() - p_cubeHist->Minimum();
221 double lowVal = p_cubeHist->BinSize();
222
223 double percentage = value - lowVal;
224 percentage /= (highVal - lowVal);
225 int valuePos = (int)(percentage * 1000.0);
226
227 p_sliderOverride = true;
228 p_widthSlider->setValue(valuePos);
229 p_sliderOverride = false;
230
231 Stretch newStretch = calculateNewStretch();
232
233 if(newStretch.Text() != p_stretch->Text()) {
234 p_stretch->CopyPairs(newStretch);
235 emit stretchChanged();
236 }
237 }
238
239
252 double width) {
253 Stretch stretch;
254 width = fabs(width);
255
256 if(width < p_cubeHist->BinSize())
257 width = p_cubeHist->BinSize();
258
259 // Still can't do it? Give up
260 if(width <= 0) return Stretch();
261
262 bool high = false;
263
264 // We want leftPoint to be our starting point for the sawtooth, one left of
265 // the minimum
266 double leftPoint = offset;
267
268 // If leftPoint is too far left, move it right
269 while(leftPoint < p_cubeHist->Minimum() - width) {
270 leftPoint += width;
271 high = !high;
272 }
273
274 // If leftPoint is too far fight, move it left
275 while(leftPoint >= p_cubeHist->Minimum()) {
276 leftPoint -= width;
277 high = !high;
278 }
279
280 double currPoint = leftPoint;
281
282 bool terminated = false;
283 while(!terminated) {
284 int outValue = (high) ? 255 : 0;
285
286 // This conversion to a string & back prevents infinite loops due to
287 // rounding errors and disagreements betweeen double to string
288 // conversions later on (in setStretch)
289 stretch.AddPair(QString::number(currPoint).toDouble(), outValue);
290
291 if(currPoint > p_cubeHist->Maximum()) {
292 terminated = true;
293 }
294
295 high = !high;
296 currPoint += width;
297 }
298
299 return stretch;
300 }
301
302
309 return calculateNewStretch(p_offsetEdit->text().toDouble(),
310 p_widthEdit->text().toDouble());
311 }
312
313
320 CubeStretch cubeStretch(*p_stretch, "Sawtooth");
321 return cubeStretch;
322 }
323}
324
Stores stretch information for a cube.
Definition CubeStretch.h:27
Container of a cube histogram.
Definition Histogram.h:74
void widthSliderMoved(int)
This is called when the sawtooth width slider moves.
virtual void setStretch(Stretch)
Given an arbitrary stretch, this will re-interpret it, as best as possible, into a sawtooth stretch.
virtual CubeStretch getStretch()
Gets the CubeStretch for this Sawtooth Stretch.
QLineEdit * p_widthEdit
Width edit.
SawtoothStretchType(const Histogram &, const Stretch &, const QString &name, const QColor &color)
This initializes a sawtooth stretch type.
void offsetEditChanged(const QString &)
This is called when the the sawtooth offset edit changes.
void widthEditChanged(const QString &)
This is called when the the sawtooth width edit changes.
QLineEdit * p_offsetEdit
Offset edit.
Stretch calculateNewStretch()
This calculates a new stretch using the GUI edits.
void offsetSliderMoved(int)
This is called when the sawtooth offset slider moves.
bool p_sliderOverride
This is used to let the edits be changed to where sliders cant go.
QSlider * p_widthSlider
Width slider.
QSlider * p_offsetSlider
Offset slider.
Pixel value mapper.
Definition Stretch.h:58
void CopyPairs(const Stretch &other)
Copies the stretch pairs from another Stretch object, but maintains special pixel values.
Definition Stretch.cpp:392
void AddPair(const double input, const double output)
Adds a stretch pair to the list of pairs.
Definition Stretch.cpp:48
double Output(const int index) const
Returns the value of the output side of the stretch pair at the specified index.
Definition Stretch.cpp:302
double Input(const int index) const
Returns the value of the input side of the stretch pair at the specified index.
Definition Stretch.cpp:287
int Pairs() const
Returns the number of stretch pairs.
Definition Stretch.h:162
QString Text() const
Converts stretch pair to a string.
Definition Stretch.cpp:268
Stretch * p_stretch
Current stretch pairs stored here.
Definition StretchType.h:71
Histogram * p_cubeHist
Visible area histogram.
Definition StretchType.h:68
StretchType(const Histogram &hist, const Stretch &stretch, const QString &name, const QColor &color)
This constructs a stretch type.
QGridLayout * p_mainLayout
Main layout.
Definition StretchType.h:67
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition IString.cpp:149