void ResizeMap(FileMappingInfo* mapping_info, size_t minimum_size) { munmap(mapping_info->m_memory, mapping_info->m_memory_size); struct stat file_statbuf; fstat(mapping_info->m_file_handle, &file_statbuf); int file_size = file_statbuf.st_size; // I'm not sure this will ever happen. If years go by and this assert is // never hit then the fstat and the next tmax below can be removed. TAssert(file_size <= minimum_size); minimum_size = tmax(minimum_size, file_size); int page_size = sysconf(_SC_PAGESIZE); int remainder = stb_mod_eucl(minimum_size, page_size); int aligned_size; if (remainder) aligned_size = minimum_size - stb_mod_eucl(minimum_size, page_size) + page_size; else aligned_size = tmax(minimum_size, page_size); int truncated = ftruncate(mapping_info->m_file_handle, aligned_size); TAssert(truncated == 0); mapping_info->m_memory_size = aligned_size; mapping_info->m_memory = mmap(nullptr, aligned_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, mapping_info->m_file_handle, 0); }
double weightedScaling(const Eigen::VectorXf& virtualInput, Matrix* scaled, Vector* taui) { Eigen::VectorXf tauIdeal = BinvIdeal*virtualInput; Eigen::VectorXf tmax(tauIdeal.size()); for (int i=0; i<tmax.size(); ++i) { tmax(i) = ((tauIdeal(i)>=0)?posDir[i]:fabs(negDir[i])); } tmax=(tmax/(tmax.minCoeff())).cwiseInverse(); Eigen::MatrixXf W = tmax.asDiagonal(); Eigen::MatrixXf Winv = W.inverse(); Eigen::MatrixXf Binv = Winv*B.transpose()*(B*Winv*B.transpose()).inverse(); std::cout<<Binv<<std::endl; Eigen::VectorXf tdes = Binv*virtualInput; double scale_max = 1; for (size_t i=0; i<tdes.rows();++i) { double scale = fabs((tdes(i)>0)?tdes(i)/posDirC[i]:tdes(i)/negDirC[i]); if (scale>scale_max) scale_max=scale; } tdes = tdes/scale_max; (*taui) = tdes; (*scaled) = B*tdes; std::cout<<"Input:"<<virtualInput<<std::endl; std::cout<<"Output:"<<*scaled<<std::endl; return scale_max; }
TRectD SandorFxRenderData::getBBoxEnlargement(const TRectD &bbox) { switch (m_type) { case BlendTz: { //Nothing happen, unless we have color 0 among the blended ones. In such case, //we have to enlarge the bbox proportionally to the amount param. std::vector<std::string> items; std::string indexes = std::string(m_argv[0]); parseIndexes(indexes, items); PaletteFilterFxRenderData paletteFilterData; insertIndexes(items, &paletteFilterData); if (paletteFilterData.m_colors.size() > 0 && *paletteFilterData.m_colors.begin() == 0) return bbox.enlarge(m_blendParams.m_amount); return bbox; } case Calligraphic: case OutBorder: return bbox.enlarge(m_callParams.m_thickness); case ArtAtContour: return bbox.enlarge( tmax(tceil(m_controllerBBox.getLx()), tceil(m_controllerBBox.getLy())) * m_contourParams.m_maxSize); default: assert(false); return bbox; } }
inline static int getMotifLeftOffset (int motifLen, int seedLen) { const int leftPaddingLength = tmax ((motifLen - seedLen) / 2, 0); return leftPaddingLength; }
inline bool checkCircles(std::vector<double> &heights) { unsigned int i, j; double cos, sin, frac; TPointD vi, vj; //Execute test on angle-consecutive EnteringSequences couples for (j = 0, i = currEnterings->size() - 1; j < currEnterings->size(); i = j, ++j) { vi = (*currEnterings)[i].m_direction; vj = (*currEnterings)[j].m_direction; sin = cross(vi, vj); if (heights[i] == heights[j]) goto test_against_max_height; frac = heights[i] / heights[j]; if (sin < 0) return 0; cos = vi * vj; if (cos < 0 && (frac < -cos || frac > (-1 / cos))) return 0; test_against_max_height: //Reusing cos cos = (sin < 0.1) ? tmax(heights[i], heights[j]) : norm((vi * (heights[j] / sin)) + (vj * (heights[i] / sin))); if (cos < hMax) return 0; } return 1; }
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info) { //return -1; //Deactivated. This fx is currently very inefficient if subdivided! int shrink = (info.m_shrinkX + info.m_shrinkY) / 2; double scale = sqrt(fabs(info.m_affine.det())); double gridStep = 1.5 * m_gridStep->getValue(frame); WarpParams params; params.m_intensity = m_intensity->getValue(frame) / gridStep; params.m_warperScale = scale * gridStep; params.m_sharpen = m_sharpen->getValue(); params.m_shrink = shrink; double warperScaleFactor = 1.0 / params.m_warperScale; TRectD warpedBox, warpedComputeRect, tileComputeRect; m_warped->getBBox(frame, warpedBox, info); getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect, params); TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect); double warperEnlargement = getWarperEnlargement(params); warperComputeRect = warperComputeRect.enlarge(warperEnlargement); return tmax( TRasterFx::memorySize(warpedComputeRect, info.m_bpp), TRasterFx::memorySize(warperComputeRect, info.m_bpp)); }
void TColorValue::getHls(double &h, double &l, double &s) const { double max, min; double delta; max = tmax(m_r, m_g, m_b); min = tmin(m_r, m_g, m_b); l = (max + min) / 2; if (max == min) { s = 0; h = 0; } else { if (l <= 0.5) s = (max - min) / (max + min); else s = (max - min) / (2 - max - min); delta = max - min; if (m_r == max) h = (m_g - m_b) / delta; else if (m_g == max) h = 2 + (m_b - m_r) / delta; else if (m_b == max) h = 4 + (m_r - m_g) / delta; h = h * 60; if (h < 0) h += 360; } }
void RowArea::mousePressEvent(QMouseEvent *event) { m_viewer->setQtModifiers(event->modifiers()); if (event->button() == Qt::LeftButton) { bool playRangeModifierisClicked = false; TApp *app = TApp::instance(); TXsheet *xsh = app->getCurrentScene()->getScene()->getXsheet(); TPoint pos(event->pos().x(), event->pos().y()); int row = m_viewer->yToRow(pos.y); QRect visibleRect = visibleRegion().boundingRect(); int playR0, playR1, step; XsheetGUI::getPlayRange(playR0, playR1, step); bool playRangeEnabled = playR0 <= playR1; if (!playRangeEnabled) { TXsheet *xsh = m_viewer->getXsheet(); playR1 = xsh->getFrameCount() - 1; playR0 = 0; } if (playR1 == -1) { //getFrameCount = 0 i.e. xsheet is empty setDragTool(XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer)); } else if (m_xa <= pos.x && pos.x <= m_xa + 10 && (row == playR0 || row == playR1)) { if (!playRangeEnabled) XsheetGUI::setPlayRange(playR0, playR1, step); setDragTool(XsheetGUI::DragTool::makePlayRangeModifierTool(m_viewer)); playRangeModifierisClicked = true; } else setDragTool(XsheetGUI::DragTool::makeCurrentFrameModifierTool(m_viewer)); //when shift+click the row area, select a single row region in the cell area if (!playRangeModifierisClicked && 0 != (event->modifiers() & Qt::ShiftModifier)) { int filledCol; for (filledCol = xsh->getColumnCount() - 1; filledCol >= 0; filledCol--) { TXshColumn *currentColumn = xsh->getColumn(filledCol); if (!currentColumn) continue; if (!currentColumn->isEmpty()) break; } m_viewer->getCellSelection()->selectNone(); m_viewer->getCellSelection()->selectCells(row, 0, row, tmax(0, filledCol)); m_viewer->updateCellRowAree(); } m_viewer->dragToolClick(event); event->accept(); } // left-click // pan by middle-drag else if (event->button() == Qt::MidButton) { m_pos = event->pos(); m_isPanning = true; } }
inline unsigned char PixelEvaluator<TPixel32>::getBlackOrWhite(int x, int y) { //return ras->pixels(y)[x].r + 2 * ras->pixels(y)[x].g + ras->pixels(y)[x].b < // threshold * (ras->pixels(y)[x].m / 255.0); //NOTE: Green is considered twice brighter than red or blue channel. //Using Value of HSV color model return tmax(m_ras->pixels(y)[x].r, tmax(m_ras->pixels(y)[x].g, m_ras->pixels(y)[x].b)) < m_threshold * (m_ras->pixels(y)[x].m / 255.0); //Using Lightness of HSV color model //return (max(ras->pixels(y)[x].r, max(ras->pixels(y)[x].g, ras->pixels(y)[x].b)) + // min(ras->pixels(y)[x].r, min(ras->pixels(y)[x].g, ras->pixels(y)[x].b))) / 2.0 < // threshold * (ras->pixels(y)[x].m / 255.0); //Using (relative) Luminance //return 0.2126 * ras->pixels(y)[x].r + 0.7152 * ras->pixels(y)[x].g + 0.0722 * ras->pixels(y)[x].b < // threshold * (ras->pixels(y)[x].m / 255.0); }
TRectD getBBox() const { if (!m_isValidBBox) { m_bBox = TRectD(); for (UINT i = 0; i < m_edge.size(); i++) m_bBox += m_edge[i]->m_s->getBBox(tmin(m_edge[i]->m_w0, m_edge[i]->m_w1), tmax(m_edge[i]->m_w0, m_edge[i]->m_w1)); m_isValidBBox = true; } return m_bBox; }
inline bool JunctionArea::sequencesPullBack() { std::vector<EnteringSequence>::iterator a; double alongLinePosition, distanceFromLine; unsigned int i, iLink, tail; TPointD P; for (a = m_enteringSequences.begin(); a != m_enteringSequences.end(); ++a) { i = a->m_head; iLink = a->m_headLink; //NOTE: updated tails are stored this way, *DONT* look in a->m_tail //because these typically store old infos tail = currJSGraph->getNode(a->m_initialJoint).getLink(a->m_outerLink)->m_tail; P = planeProjection(*a->m_graphHolder->getNode(a->m_head)); while (i != tail) { alongLinePosition = a->m_direction * (m_newJointPosition - P); distanceFromLine = tdistance(m_newJointPosition, a->m_direction, P); if (alongLinePosition >= 0 && (distanceFromLine / alongLinePosition) <= 0.5) goto found_pull_back; //We then take the next arc and check it if (!a->m_graphHolder->getNode(i).getLink(iLink)->hasAttribute(SkeletonArc::ROAD)) return 0; //Pull back failed a->next(i, iLink); P = planeProjection(*a->m_graphHolder->getNode(i)); if (tdistance(P, a->m_direction, m_newJointPosition) > tmax(pullBackMul * a->m_height, 1.0)) return 0; //Pull back failed } //Now checking opposite sequence extremity if (alongLinePosition < 0 || (distanceFromLine / alongLinePosition) > 0.5) return 0; found_pull_back: a->m_head = i; a->m_headLink = iLink; } return 1; }
bool DateChooserWidget::GetDate(wxDateTime &date) { int ret = wxID_OK; date_control->SetDate(date); hour_control->SetValue(date.GetHour()); minute_control->SetValue(date.GetMinute()); current_minute = date.GetMinute(); current_second = date.GetSecond(); while( (ret = ShowModal()) == wxID_OK){ date = date_control->GetDate(); // ustawiamy godzine date.SetHour(hour_control->GetValue()); date.SetMinute(minute_control->GetValue()); if (second_control) date.SetSecond(second_control->GetValue()); wxDateTime tmin(time_t(0)); wxDateTime tmax(MAX_TIME_T_FOR_WX_DATE_TIME); if (date <= tmin || date >= tmax) { wxMessageBox(_("Invalid (too large/small) date"), _("Error!"), wxOK); return false; } if (min_date == -1 && max_date == -1) return true; if(date.GetTicks() >= min_date && date.GetTicks() <= max_date) return true; else { wxString buf; buf = _("Please choose the date from between: "); buf += wxDateTime(min_date).Format(_T("%Y-%m-%d %H:%M ")); buf += _("and"); buf += wxDateTime(max_date).Format(_T(" %Y-%m-%d %H:%M\n")); wxMessageDialog *mesg = new wxMessageDialog(this, buf, _("Incorrect date range"), wxOK); mesg->ShowModal(); delete mesg; } } return false; }
void TColorValue::getHsv(int &ih, int &is, int &iv) const { double max, min; double delta; double r, g, b; double v, s, h; r = m_r; g = m_g; b = m_b; assert(0 <= r && r <= 1); assert(0 <= g && g <= 1); assert(0 <= b && b <= 1); max = tmax(r, g, b); min = tmin(r, g, b); v = max; if (max != 0) s = (max - min) / max; else s = 0; if (s == 0) h = 0; else { delta = max - min; if (r == max) h = (g - b) / delta; else if (g == max) h = 2 + (b - r) / delta; else if (b == max) h = 4 + (r - g) / delta; h = h * 60; if (h < 0) h += 360; } assert(0 <= h && h <= 360); assert(0 <= s && s <= 1); assert(0 <= v && v <= 1); ih = (int)h; is = (int)(s * 100); iv = (int)(v * 100); }
void octave_print(std::ostream &ostr, const std::string &varname, const piecewise_curve_type &pc) { index_type i; data_type tmin(pc.get_parameter_min()), tmax(pc.get_parameter_max()); // initialize the t parameters std::vector<data_type> t(101); for (i=0; i<static_cast<index_type>(t.size()); ++i) { t[i]=tmin+(tmax-tmin)*static_cast<data_type>(i)/(t.size()-1); } std::vector<point_type, Eigen::aligned_allocator<point_type> > pts(t.size()); for (i=0; i<static_cast<index_type>(pts.size()); ++i) pts[i]=pc.f(t[i]); octave_print(ostr, varname, pts); }
void Iwa_TiledParticlesFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &info) { Iwa_ParticlesManager *pc = Iwa_ParticlesManager::instance(); unsigned long fxId = getIdentifier(); int inputPortCount = getInputPortCount(); int i, j, curr_frame = frame, /*- 現在のフレーム -*/ startframe = startpos_val->getValue(); /*- Particesの開始フレーム -*/ TRenderSettings infoOnInput(info); infoOnInput.m_affine = TAffine(); // Using the standard reference - indep. from cameras. infoOnInput.m_bpp = 64; // Control ports rendered at 32 bit - since not visible. for (i = startframe - 1; i <= curr_frame; ++i) { double frame = tmax(0, i); for (j = 0; j < inputPortCount; ++j) { TFxPort *port = getInputPort(j); std::string tmpName = getInputPortName(j); if (port->isConnected()) { TRasterFxP fx = port->getFx(); // Now, consider that source ports work different than control ones QString portName = QString::fromStdString(tmpName); if (portName.startsWith("C")) { // Control ports are calculated from start to current frame, since // particle mechanics at current frame is influenced by previous ones // (and therefore by all previous control images). TRectD bbox; fx->getBBox(frame, bbox, infoOnInput); if (bbox == TConsts::infiniteRectD) bbox = info.m_affine.inv() * rect; fx->dryCompute(bbox, frame, infoOnInput); } else if (portName.startsWith("T")) { // Particles handle source ports caching procedures on its own. } } } } }
bool Grid::initInfiniteRay (const Vec3r &orig, const Vec3r& dir, unsigned timestamp) { _ray_dir = dir; _t_end = FLT_MAX; _t = 0; _ray_dir.normalize(); _timestamp = timestamp; // check whether the origin is in or out the box: Vec3r boxMin(_orig); Vec3r boxMax(_orig+_size); BBox<Vec3r> box(boxMin, boxMax); if(box.inside(orig)){ for(unsigned i = 0; i < 3; i++) { _current_cell[i] = (unsigned)floor((orig[i] - _orig[i]) / _cell_size[i]); unsigned u = _current_cell[i]; _pt[i] = orig[i] - _orig[i] - _current_cell[i] * _cell_size[i]; } }else{ // is the ray intersecting the box? real tmin(-1.0), tmax(-1.0); if(GeomUtils::intersectRayBBox(orig, _ray_dir, boxMin, boxMax, 0, _t_end, tmin, tmax)){ assert(tmin != -1.0); Vec3r newOrig = orig + tmin*_ray_dir; for(unsigned i = 0; i < 3; i++) { _current_cell[i] = (unsigned)floor((newOrig[i] - _orig[i]) / _cell_size[i]); if(_current_cell[i] == _cells_nb[i]) _current_cell[i] = _cells_nb[i] - 1; unsigned u = _current_cell[i]; _pt[i] = newOrig[i] - _orig[i] - _current_cell[i] * _cell_size[i]; } }else{ return false; } } //_ray_occluders.clear(); return true; }
inline void tryConfiguration(const std::vector<unsigned int> &bounds) { std::vector<double> currHeights(currEnterings->size()); double mean, currMeanError = 0; unsigned int i, j, first, end; for (i = 0, first = 0; i <= bounds.size(); first = end, ++i) { end = i < bounds.size() ? end = bounds[i] + 1 : currEnterings->size(); //Calculate mean from first (included) to end (not included) for (j = first, mean = 0; j < end; ++j) mean += (*currEnterings)[(*heightIndicesPtr)[j]].m_height; mean /= end - first; //Check if the distance from extremities to mean is tolerable if (tmax((*currEnterings)[(*heightIndicesPtr)[end - 1]].m_height - mean, mean - (*currEnterings)[(*heightIndicesPtr)[first]].m_height) > hDiffMul * mean) return; //Calculate squared error to mean for (j = first; j < end; ++j) currMeanError += sq((*currEnterings)[(*heightIndicesPtr)[j]].m_height - mean); //Set calculated currHeights for (j = first; j < end; ++j) currHeights[(*heightIndicesPtr)[j]] = mean; } //Update current maximum height hMax = mean; //Global //If this configuration could be better than current, launch circle test if (optHeights->empty() || currMeanError < optMeanError) { if (checkCircles(currHeights)) { (*optHeights) = currHeights; optMeanError = currMeanError; } } }
int Client::calcCurrentObjLag() const { // get modifiying values double objLagModifier = configHandler.getDoubleValue("object_lag_modifier", OBJECT_LAG_MODIFIER_DEFAULT); int objLagAddTime = configHandler.getIntValue("object_lag_time", OBJECT_LAG_ADD_TIME_DEFAULT); int objLagAddTick = configHandler.getIntValue("object_lag_tick", OBJECT_LAG_ADD_TICK_DEFAULT); // get base objLag (can in some cases be negative if the result of syncronise of clocks wasn't perfect) double baseObjLagTime = static_cast<double>(link.getCurrentLag() - getTimeHandler()->getTick0Time()); // multiply depending on positive or negative if (baseObjLagTime > 0.0) baseObjLagTime *= objLagModifier; else baseObjLagTime /= objLagModifier; // add extra modifiers and change to "ticks" int currentObjLag = static_cast<int>(baseObjLagTime + objLagAddTime) / TimeHandler::TICK_DELTA_TIME + objLagAddTick; // do not allow negative objLag return tmax(currentObjLag, 0); }
void FullColorBrushTool::loadPreset() { const std::set<BrushData> &presets = m_presetsManager.presets(); std::set<BrushData>::const_iterator it; it = presets.find(BrushData(m_preset.getValue())); if (it == presets.end()) return; const BrushData &preset = *it; try //Don't bother with RangeErrors { m_thickness.setValue(TIntPairProperty::Value(tmax((int)preset.m_min, 1), preset.m_max)); m_brushPad = ToolUtils::getBrushPad(preset.m_max, preset.m_hardness * 0.01); m_hardness.setValue(preset.m_hardness, true); m_opacity.setValue(TDoublePairProperty::Value(preset.m_opacityMin, preset.m_opacityMax)); m_pressure.setValue(preset.m_pressure); } catch (...) { } }
HalfCord(int radius) { assert(radius >= 0); m_radius = radius; m_array = new int[m_radius + 1]; memset(m_array, 0, (m_radius + 1) * sizeof(int)); float dCircle = 1.25f - m_radius; // inizializza decision variable int y = m_radius; // inizializzazione indice scanline int x = 0; // inizializzazione indice colonna do { m_array[y] = tmax(x, m_array[y]); m_array[x] = y; if (dCircle <= 0) { dCircle = dCircle + 2 * x + 3; } else { y--; dCircle = dCircle + 2 * (x - y) + 5; } x++; } while (y >= x); }
void AdjustLevelsPopup::autoAdjust() { if (!m_inputRas) return; Histograms *histograms = m_histogram->getHistograms(); int channelIdx = histograms->currentIndex(); int inputBarIdx = (channelIdx << 1); EditableMarksBar *editableMarksBar = m_marksBar[inputBarIdx]; int min, max; //Clamp histogram const QVector<int> &values = histograms->getHistogramView(channelIdx)->values(); if (channelIdx == 0) { int minR, maxR, minG, maxG, minB, maxB; ::getRange(histograms->getHistogramView(1)->values(), m_threshold, minR, maxR); ::getRange(histograms->getHistogramView(2)->values(), m_threshold, minG, maxG); ::getRange(histograms->getHistogramView(3)->values(), m_threshold, minB, maxB); min = tmin(minR, minG, minB); max = tmax(maxR, maxG, maxB); } else ::getRange(values, m_threshold, min, max); QVector<int> &marks = editableMarksBar->marksBar()->values(); if (min < max) marks[0] = min, marks[1] = max + 1; else marks[0] = 0, marks[1] = 256; editableMarksBar->updateFields(); onParamsChanged(); update(); }
//--------------------------------------------------------------------------------------- BOOL CBigTerrain::Create(const BYTE* hmap, const V3& start, const V3& size, int xt, int yt) { Clear(1); p_dummyBrush = new Brush(); p_dummyBrush->MakeCube((V3&)size); p_dummyBrush->Recalc(); p_dummyBrush->_brushflags = BRSH_BIGTERRAIN|TERR_GOR|TERR_UTT0; p_dummyBrush->_pUsrData = this; p_dummyBrush->Reverse(); p_dummyBrush->_pUsrData=this; strcpy(p_dummyBrush->_name,"terrain"); n_xtiles = xt; n_ztiles = yt; b_box._min = start; b_box._max = start + size; BYTE* pwhmap = (BYTE*)hmap; int k=0; BYTE bmin=255; BYTE bmax=0; v_vxes.ObjReserve((n_xtiles+1)*(n_ztiles+1)); for(int x=0 ; x <= n_xtiles; x++) { for(int z=0 ; z <= n_ztiles; z++) { bmin = tmin(*pwhmap,bmin); bmax = tmax(*pwhmap,bmax); v_vxes[k++] = *pwhmap++; } } return 1; }
// // the 1st argument (in/out) provides the offset from this position // the 2nd argument (in/out) provides the length from the offset // // this method makes changes the offset (if necessary) so // that it is legal, decreasing the length in accordance. // also if the length is too large, it is decreased. void SeqPosition::getModifiedOffsets (int& offset, int& length) const { // // do not go past the beginning of the string int startIndex = _position + offset; if (startIndex < 0) { // // the string is truncated in the left, so return less bytes length += startIndex; // shorten length offset -= startIndex; // make offset less negative startIndex = 0; } // // do not go beyond the end of the string int endIndex = startIndex + length; if (endIndex > _sequence->length ()) { endIndex = _sequence->length (); } // // calculate length length = tmax (endIndex - startIndex, 0); }
// place a triangle into intesected cells void TXGrid3D::PlaceTriangle(TXTriangle *t) { // bounding box CVector3f tmin(FLT_MAX, FLT_MAX, FLT_MAX), tmax(-FLT_MAX, -DBL_MAX, -FLT_MAX); for (int v=0; v<3; v++) { tmin.Set( MIN(tmin.GetX(),t->m_v[v]->m_pos.GetX()), MIN(tmin.GetY(),t->m_v[v]->m_pos.GetY()), MIN(tmin.GetZ(),t->m_v[v]->m_pos.GetZ()) ); tmax.Set( MAX(tmax.GetX(),t->m_v[v]->m_pos.GetX()), MAX(tmax.GetY(),t->m_v[v]->m_pos.GetY()), MAX(tmax.GetZ(),t->m_v[v]->m_pos.GetZ()) ); } // starting and ending cells of the bounding box CVector3 start( MAX((int)floor((tmin.GetX() - m_min.GetX())/m_xstep), 0), MAX((int)floor((tmin.GetY() - m_min.GetY())/m_ystep), 0), MAX((int)floor((tmin.GetZ() - m_min.GetZ())/m_zstep), 0) ); CVector3 end( MIN((int)floor((tmax.GetX() - m_min.GetX())/m_xstep), m_size-1), MIN((int)floor((tmax.GetY() - m_min.GetY())/m_ystep), m_size-1), MIN((int)floor((tmax.GetZ() - m_min.GetZ())/m_zstep), m_size-1) ); TXGridTriangle* gt = new TXGridTriangle(t); bool sa = (gt->m_n.GetX() >= 0), sb = (gt->m_n.GetY() >= 0), sc = (gt->m_n.GetZ() >= 0); CVector3f p1, p2; bool sd1, sd2; // put triangle in the cells in its bounding box // still excessive, treat triangle as a plane to detect intersection for (int i=(int)start.GetX(); i<=(int)end.GetX(); i++) { p1.Set(m_min.GetX() + i*m_xstep,p1.GetY(),p2.GetZ()); p2.Set(p1.GetX() + m_xstep,p2.GetY(),p2.GetZ()); for (int j=(int)start.GetY(); j<=(int)end.GetY(); j++) { if (sb == sa) { p1.Set(p1.GetX(),m_min.GetY() + j*m_ystep,p1.GetZ()); p2.Set(p2.GetX(),p1.GetY()+ m_ystep,p2.GetZ()); } else { p2.Set(p2.GetX(), m_min.GetY() + j*m_ystep,p2.GetZ()); p1.Set(p1.GetX(),p2.GetY() + m_ystep,p1.GetZ()); } for (int k=start.GetZ(); k<=end.GetZ(); k++) { if (sc == sa) { p1.Set(p1.GetX(),p1.GetY(),m_min.GetZ() + k*m_zstep); p2.Set(p2.GetX(),p2.GetY(),p1.GetZ() + m_zstep); } else { p2.Set(p2.GetX(),p2.GetY(),m_min.GetZ() + k*m_zstep); p1.Set(p1.GetX(),p1.GetY(),p2.GetZ() + m_zstep); } CVector3f p1gt, p2gt; p1gt.Sub(p1,gt->m_t->m_v[0]->m_pos); p2gt.Sub(p2,gt->m_t->m_v[0]->m_pos); sd1 = gt->m_n.Dot(p1gt) >= 0; sd2 = gt->m_n.Dot(p2gt) >= 0; if (sd1 != sd2) m_grid[i][j][k].push_back(gt); } } } }
void bessjy(double x, double xnu, double *rj, double *ry, double *rjp, double *ryp) { int i, isign, l, nl; double a, b, br, bi, c, cr, ci, d, del, del1, den, di, dlr, dli, dr, e, f, fact, fact2, fact3, ff, gam, gam1, gam2, gammi, gampl, h, p, pimu, pimu2, q, r, rjl, rjl1, rjmu, rjp1, rjpl, rjtemp, ry1, rymu, rymup, rytemp, sum, sum1, temp, w, x2, xi, xi2, xmu, xmu2; if (x <= 0.0 || xnu < 0.0) throw; nl = (x < XMIN ? (int)(xnu + 0.5) : tmax(0, (int)(xnu - x + 1.5))); xmu = xnu - nl; xmu2 = xmu * xmu; xi = 1.0 / x; xi2 = 2.0 * xi; w = xi2 / PI; isign = 1; h = xnu * xi; if (h < FPMIN) h = FPMIN; b = xi2 * xnu; d = 0.0; c = h; for (i = 1; i <= MAXIT; i++) { b += xi2; d = b - d; if (fabs(d) < FPMIN) d = FPMIN; c = b - 1.0 / c; if (fabs(c) < FPMIN) c = FPMIN; d = 1.0 / d; del = c * d; h = del * h; if (d < 0.0) isign = -isign; if (fabs(del - 1.0) < EPS) break; } if (i > MAXIT) throw; rjl = isign * FPMIN; rjpl = h * rjl; rjl1 = rjl; rjp1 = rjpl; fact = xnu * xi; for (l = nl; l >= 1; l--) { rjtemp = fact * rjl + rjpl; fact -= xi; rjpl = fact * rjtemp - rjl; rjl = rjtemp; } if (rjl == 0.0) rjl = EPS; f = rjpl / rjl; if (x < XMIN) { x2 = 0.5 * x; pimu = PI * xmu; fact = (fabs(pimu) < EPS ? 1.0 : pimu / sin(pimu)); d = -log(x2); e = xmu * d; fact2 = (fabs(e) < EPS ? 1.0 : sinh(e) / e); beschb(xmu, &gam1, &gam2, &gampl, &gammi); ff = 2.0 / PI * fact * (gam1 * cosh(e) + gam2 * fact2 * d); e = exp(e); p = e / (gampl * PI); q = 1.0 / (e * PI * gammi); pimu2 = 0.5 * pimu; fact3 = (fabs(pimu2) < EPS ? 1.0 : sin(pimu2) / pimu2); r = PI * pimu2 * fact3 * fact3; c = 1.0; d = -x2 * x2; sum = ff + r * q; sum1 = p; for (i = 1; i <= MAXIT; i++) { ff = (i * ff + p + q) / (i * i - xmu2); c *= (d / i); p /= (i - xmu); q /= (i + xmu); del = c * (ff + r * q); sum += del; del1 = c * p - i * del; sum1 += del1; if (fabs(del) < (1.0 + fabs(sum))*EPS) break; } if (i > MAXIT) throw; rymu = -sum; ry1 = -sum1 * xi2; rymup = xmu * xi * rymu - ry1; rjmu = w / (rymup - f * rymu); } else { a = 0.25 - xmu2; p = -0.5 * xi; q = 1.0; br = 2.0 * x; bi = 2.0; fact = a * xi / (p * p + q * q); cr = br + q * fact; ci = bi + p * fact; den = br * br + bi * bi; dr = br / den; di = -bi / den; dlr = cr * dr - ci * di; dli = cr * di + ci * dr; temp = p * dlr - q * dli; q = p * dli + q * dlr; p = temp; for (i = 2; i <= MAXIT; i++) { a += 2 * (i - 1); bi += 2.0; dr = a * dr + br; di = a * di + bi; if (fabs(dr) + fabs(di) < FPMIN) dr = FPMIN; fact = a / (cr * cr + ci * ci); cr = br + cr * fact; ci = bi - ci * fact; if (fabs(cr) + fabs(ci) < FPMIN) cr = FPMIN; den = dr * dr + di * di; dr /= den; di /= -den; dlr = cr * dr - ci * di; dli = cr * di + ci * dr; temp = p * dlr - q * dli; q = p * dli + q * dlr; p = temp; if (fabs(dlr - 1.0) + fabs(dli) < EPS) break; } if (i > MAXIT) throw; gam = (p - f) / q; rjmu = sqrt(w / ((p - f) * gam + q)); rjmu = NRSIGN(rjmu, rjl); rymu = rjmu * gam; rymup = rymu * (p + q / gam); ry1 = xmu * xi * rymu - rymup; } fact = rjmu / rjl; *rj = rjl1 * fact; *rjp = rjp1 * fact; for (i = 1; i <= nl; i++) { rytemp = (xmu + i) * xi2 * ry1 - rymu; rymu = ry1; ry1 = rytemp; } *ry = rymu; *ryp = xnu * xi * rymu - ry1; }
void TRop::brush( TRaster32P ras, const TPoint &aa, const TPoint &bb, int radius, const TPixel32 &col) { TPoint a = aa; TPoint b = bb; if (a.y > b.y) tswap(a, b); // a e' piu' in basso di b int lx = ras->getLx(); int ly = ras->getLy(); ras->lock(); // ----- radius = 0 if (radius == 0) { // k = +1/-1 se il rettangolo e' inclinato positivamente (0<=m)/negativamente (m<0) // (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle // coordinate "di schermo") int k = 1; int dy = b.y - a.y; int dx = b.x - a.x; if (dx < 0) { dx = -dx; k = -1; } assert(dx >= 0); assert(dy >= 0); double m; // m sara' definita solo per dx!=0) if (dx > 0) { m = dy / (double)dx; } //double length = sqrt(dx*dx + dy*dy); const int alpha = dy, beta = -dx; const int incE = alpha; const int incNE = alpha + beta; const int incN = beta; // N.B. le coordinate sono relative ad un sist. di rif. con l'origine in a // l'eq. della retta e' alpha * x + beta * y = 0 int yMin = tmax(a.y, 0) - a.y; // clipping y + cambio riferimento int yMax = tmin(b.y, ly - 1) - a.y; // (trasporto dell'origine in a) if (dx > 0 && m <= 1) { // midpoint algorithm TPoint segm; if (dy == 0) // segmento orizzontale: inizializza segm { segm.x = 0; segm.y = yMin; } else // 0<m<=1 : inizializza segm { segm.x = tceil((yMin - 0.5) / m); segm.y = yMin; } int dSegm = tfloor(alpha * (segm.x + 1) + beta * (segm.y + 0.5)); while (segm.y <= yMax) { int count = 0; // i trati orizzontali di segm vengono disegnati in "blocco" while (dSegm < 0 && segm.x <= dx) // Est: segm.x<=dx evita il ciclo { // infinito quando m=0 (incE=0) dSegm = dSegm + incE; segm.x++; count++; } // NordEst int xMin, xMax; if (k > 0) { xMin = tmax(a.x + segm.x - count, a.x, 0); // clipping x + ritorno alle xMax = tmin(a.x + segm.x, b.x, lx - 1); // coordinate "di schermo" } else { xMin = tmax(a.x - segm.x, a.x - dx, 0); // clipping x + riflessione + ritorno xMax = tmin(a.x - segm.x + count, a.x, lx - 1); // alle coordinate "di schermo" } TPixel32 *p = ras->pixels(segm.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; dSegm = dSegm + incNE; segm.x++; segm.y++; } } else // m>1 oppure segmento verticale { // midpoint algorithm TPoint segm; if (dx == 0) // segmento verticale: inizializza segm { segm.x = 0; segm.y = yMin; } else // m>1 : inizializza segm { segm.x = tround(yMin / m); segm.y = yMin; } int dSegm = tfloor(alpha * (segm.x + 0.5) + beta * (segm.y + 1)); while (segm.y <= yMax) { int xMin, xMax; if (k > 0) { xMin = tmax(a.x + segm.x, 0); // clipping x + ritorno alle xMax = tmin(a.x + segm.x, lx - 1); // coordinate "di schermo" } else { xMin = tmax(a.x - segm.x, 0); // clipping x + riflessione + ritorno xMax = tmin(a.x - segm.x, lx - 1); // alle coordinate "di schermo" } TPixel32 *p = ras->pixels(segm.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; if (dSegm <= 0) // NordEst { dSegm = dSegm + incNE; segm.x++; } else // Nord { dSegm = dSegm + incN; } segm.y++; } } ras->unlock(); return; } HalfCord halfCord(radius); int x, y; // ----- punti iniziali coincidenti: disegna un cerchio if (a == b) { int yMin = tmax(a.y - radius, 0); // clipping y int yMax = tmin(a.y + radius, ly - 1); // clipping y for (y = yMin; y <= yMax; y++) { int deltay = abs(y - a.y); int xMin = tmax(a.x - halfCord.getCord(deltay), 0); // clipping x int xMax = tmin(a.x + halfCord.getCord(deltay), lx - 1); // clipping x TPixel32 *p = ras->pixels(y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; } ras->unlock(); return; } // ----- rettangolo orizzontale (a.y = b.y, a.x != b.x) if (a.y == b.y) { int yMin = tmax((a.y - radius), 0); // clipping y int yMax = tmin((a.y + radius), ly - 1); // clipping y int xLeft = tmin(a.x, b.x); int xRight = tmax(a.x, b.x); for (y = yMin; y <= yMax; y++) { int deltay = abs(y - a.y); int xMin = tmax(xLeft - halfCord.getCord(deltay), 0); // clipping x int xMax = tmin(xRight + halfCord.getCord(deltay), lx - 1); // clipping x TPixel32 *p = ras->pixels(y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; } ras->unlock(); return; } // ----- rettangolo verticale (a.x = b.x, a.y != b.y) if (a.x == b.x) { int xMin = tmax(a.x - radius, 0); // clipping x int xMax = tmin(a.x + radius, lx - 1); // clipping x for (x = xMin; x <= xMax; x++) { int deltax = abs(x - a.x); int yMin = tmax(a.y - halfCord.getCord(deltax), 0); // clipping y int yMax = tmin(b.y + halfCord.getCord(deltax), ly - 1); // clipping y if (yMin <= yMax) { TPixel32 *p = ras->pixels(yMin) + x; TPixel32 *q = ras->pixels(yMax) + x; int wrap = ras->getWrap(); while (p <= q) { *p = col; p += wrap; } } } ras->unlock(); return; } // ----- rettangolo inclinato // k = +1/-1 se il rettangolo e' inclinato positivamente/negativamente int k = 1; int dx = b.x - a.x; if (dx < 0) { dx = -dx; k = -1; } int dy = b.y - a.y; assert(dx > 0); assert(dy > 0); double length = sqrt((double)(dx * dx + dy * dy)); const double m = dy / (double)dx; //punto di tangenza superiore nel sistema di riferimento del cerchio TPointD up(-radius * dy / length, radius * dx / length); //semi-ampiezza orizzontale delle "calotte" circolari int halfAmplCap = tfloor(-up.x); // A meno di intersezioni relative tra le diverse zone: // le scanline della "calotta" circolare superiore sono (b.y+cutExt,b.y+radius] // le scanline del trapezoide circolare superiore sono [b.y-cutIn,b.y+cutExt] // le scanline del parallelogramma sono (a.y+cutIn,b.y-cutIn) // le scanline del trapezoide circolare inferiore sono [a.y-cutExt,a.y+cutIn] // le scanline della "calotta" circolare inferiore sono [a.y-radius,a.y-cutExt) int cutExt, cutIn; // vertici del parallelogramma TPointD rightUp; TPointD rightDown; TPointD leftUp; TPointD leftDown; double mParall; //coeff. angolare parallelogramma // NOTA BENE: halfAmplCap=0 <=> (radius=0 (caso a parte) , 1) if (radius > 1) { for (cutExt = radius; cutExt >= 0 && halfCord.getCord(cutExt) <= halfAmplCap; cutExt--) ; cutIn = cutExt; // vedi else successivo rightUp.x = dx + halfCord.getCord(cutIn); rightUp.y = dy - cutIn; rightDown.x = halfCord.getCord(cutIn); rightDown.y = -cutIn; leftUp.x = dx - halfCord.getCord(cutIn); leftUp.y = dy + cutIn; leftDown.x = -halfCord.getCord(cutIn); leftDown.y = cutIn; mParall = dy / (double)dx; } else // N.B. cutExt != cutIn solo quando radius=1 { cutExt = radius; // radius=1 => halfAmplCap=0 (non ci sono mai le "calotte" circolari) cutIn = 0; // anche per radius=1 il limite "interno" dei trapezoidi circolari e' < radius rightUp.x = dx - up.x; rightUp.y = dy - up.y; rightDown.x = -up.x; rightDown.y = -up.y; leftUp.x = dx + up.x; leftUp.y = dy + up.y; leftDown.x = up.x; leftDown.y = up.y; mParall = m; } // ----- riempie "calotte" circolari // ----- riempie "calotta" circolare inferiore int yMin = tmax(a.y - radius, 0); // clipping y int yMax = tmin(a.y - cutExt - 1, ly - 1); // clipping y for (y = yMin; y <= yMax; y++) { int r = halfCord.getCord(a.y - y); int xMin = tmax(a.x - r, 0); // clipping x int xMax = tmin(a.x + r, lx - 1); // clipping x TPixel32 *p = ras->pixels(y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; } // ----- riempie "calotta" circolare superiore yMin = tmax(b.y + cutExt + 1, 0); // clipping y yMax = tmin(b.y + radius, ly - 1); // clipping y for (y = yMin; y <= yMax; y++) { int r = halfCord.getCord(y - b.y); int xMin = tmax(b.x - r, 0); // clipping x int xMax = tmin(b.x + r, lx - 1); // clipping x TPixel32 *p = ras->pixels(y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; } // ----- riempie trapezoidi // (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle // coordinate "di schermo") // limite destro assoluto delle scanline trapezoide: int xSegmMax = tround(dx - up.x); // coordinata x del punto di tangenza inferiore sul cerchio superiore // limite sinistro assoluto delle scanline: int xSegmMin = tround(up.x); // coordinata x del punto di tangenza superiore sul cerchio inferiore // ----- riempie trapezoide inferiore // N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro // del cerchio inferiore yMin = tmax(a.y - cutExt, 0) - a.y; // clipping y yMax = tmin(a.y + cutIn, b.y - cutIn - 1, ly - 1) - a.y; // clipping y // l'eq. della retta e' alpha * x + beta * y + gammaRight = 0 const int alpha = dy, beta = -dx; const double gammaRight = rightDown.y * dx - rightDown.x * dy; const int incE = alpha; const int incNE = alpha + beta; const int incN = beta; if (m <= 1) { // midpoint algorithm; le scanline vengono disegnate solo // sul NordEst. L'ultima scanline non viene disegnata TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin); int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight); while (segmRight.y <= yMax) { if (dSegmRight < 0) // Est { dSegmRight = dSegmRight + incE; segmRight.x++; } else // NordEst { int xMin, xMax; if (k > 0) { xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); // clipping x xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); // clipping x } else { xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0); // clipping x + ritorno alle xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; dSegmRight = dSegmRight + incNE; segmRight.x++; segmRight.y++; } } } else // m>1 { // midpoint algorithm; le scanline vengono disegnate sempre TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin); int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight); while (segmRight.y <= yMax) { int xMin, xMax; if (k > 0) { xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); // clipping x xMax = tmin(a.x + segmRight.x, lx - 1); // clipping x } else { xMin = tmax(a.x - segmRight.x, 0); // clipping x + ritorno alle coordinate xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); // "di schermo" } TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; if (dSegmRight <= 0) // NordEst { dSegmRight = dSegmRight + incNE; segmRight.x++; } else // Nord { dSegmRight = dSegmRight + incN; } segmRight.y++; } } // ----- riempie trapezoide superiore // N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro // del cerchio superiore yMin = tmax(b.y - cutIn, a.y + cutIn + 1, 0) - b.y; // clipping y yMax = tmin(b.y + cutExt, ly - 1) - b.y; // clipping y // l'eq. della retta e' alpha * x + beta * y + gammaLeft = 0 const double gammaLeft = leftDown.y * dx - leftDown.x * dy; if (m <= 1) { // midpoint algorithm; le scanline vengono disegnate solo // sul NordEst. L'ultima scanline non viene disegnata TPoint segmLeft(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin); int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft); while (segmLeft.y <= yMax) { int xMin, xMax; if (k > 0) { xMin = tmax(b.x + tmax(segmLeft.x, xSegmMin - dx), 0); // clipping x xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); // clipping x } else { xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); // clipping x + ritorno alle xMax = tmin(b.x - tmax(segmLeft.x, xSegmMin - dx), lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; while (dSegmLeft < 0) { dSegmLeft = dSegmLeft + incE; segmLeft.x++; } dSegmLeft = dSegmLeft + incNE; segmLeft.x++; segmLeft.y++; } } else // m>1 { // midpoint algorithm; le scanline vengono disegnate sempre TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin); int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft); while (segmLeft.y <= yMax) { int xMin, xMax; if (k > 0) { xMin = tmax(b.x + segmLeft.x, 0); // clipping x xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); // clipping x } else { xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); // clipping x + ritorno alle xMax = tmin(b.x - segmLeft.x, lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; if (dSegmLeft <= 0) // NordEst { dSegmLeft = dSegmLeft + incNE; segmLeft.x++; } else // Nord { dSegmLeft = dSegmLeft + incN; } segmLeft.y++; } } // ----- parallelogramma (in alternativa a "parallelogrammoide circolare") // N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro // del cerchio inferiore // retta destra di equaz. alpha * x + beta * y + gammaRight = 0 // retta sinistra di equaz. alpha * x + beta * y + gammaLeft = 0 yMin = tmax(a.y + cutIn + 1, 0) - a.y; //clipping y yMax = tmin(b.y - cutIn - 1, ly - 1) - a.y; //clipping y if (m <= 1) { // midpoint algorithm; le scanline vengono disegnate solo // sul NordEst. L'ultima scanline non viene disegnata TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin); TPoint segmLeft = TPoint(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin); int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight); int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft); while (segmRight.y <= yMax) { if (dSegmRight < 0) // segmRight a Est { dSegmRight = dSegmRight + incE; segmRight.x++; } else // segmRight a NordEst { int xMin, xMax; if (k > 0) { xMin = tmax(a.x + tmax(segmLeft.x, xSegmMin), 0); // clipping x xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); // clipping x } else { xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0); // clipping x + ritorno alle xMax = tmin(a.x - tmax(segmLeft.x, xSegmMin), lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; dSegmRight = dSegmRight + incNE; segmRight.x++; segmRight.y++; while (dSegmLeft < 0) // segmLeft a Est { dSegmLeft = dSegmLeft + incE; segmLeft.x++; } // segmLeft a NordEst dSegmLeft = dSegmLeft + incNE; segmLeft.x++; segmLeft.y++; } } } else // m>1 { // midpoint algorithm; le scanline vengono disegnate sempre TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin); TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin); int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight); int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft); while (segmRight.y <= yMax) { int xMin, xMax; if (k > 0) { xMin = tmax(a.x + segmLeft.x, 0); // clipping x xMax = tmin(a.x + segmRight.x, lx - 1); // clipping x } else { xMin = tmax(a.x - segmRight.x, 0); // clipping x + ritorno alle xMax = tmin(a.x - segmLeft.x, lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; if (dSegmRight <= 0) // segmRight a NordEst { dSegmRight = dSegmRight + incNE; segmRight.x++; } else // segmRight a Nord { dSegmRight = dSegmRight + incN; } segmRight.y++; if (dSegmLeft <= 0) // segmLeft a NordEst { dSegmLeft = dSegmLeft + incNE; segmLeft.x++; } else // segmLeft a Nord { dSegmLeft = dSegmLeft + incN; } } } // ---- parallelogrammoide circolare (in alternativa a parallelogramma) // N.B. coordinate di schermo (riflessione per k<0 ) yMin = tmax(b.y - cutIn, 0); yMax = tmin(a.y + cutIn, ly - 1); for (y = yMin; y <= yMax; y++) { int xMin, xMax; if (k > 0) { xMin = tmax(a.x - halfCord.getCord(abs(y - a.y)), 0); // clipping x xMax = tmin(b.x + halfCord.getCord(abs(b.y - y)), lx - 1); // clipping x } else { xMin = tmax(b.x - halfCord.getCord(abs(b.y - y)), 0); // clipping x + ritorno alle xMax = tmin(a.x + halfCord.getCord(abs(y - a.y)), lx - 1); // coordinate "di schermo" } TPixel32 *p = ras->pixels(y) + xMin; TPixel32 *q = p + (xMax - xMin); while (p <= q) *p++ = col; } ras->unlock(); }
bool Convert2Tlv::init(std::string &errorMessage) { m_lastIndex = m_maxPaletteIndex = 0; m_colorMap.clear(); try { m_lr1 = TLevelReaderP(m_levelIn1); if (m_lr1) m_level1 = m_lr1->loadInfo(); } catch (...) { errorMessage = "Error: can't read level " + toString(m_levelIn1.getWideString()); return false; } if (m_level1->getFrameCount() == 0) { errorMessage = "Error: can't find level " + toString(m_levelIn1.getWideString()); return false; } TLevelP level2; if (m_levelIn2 != TFilePath()) { try { m_lr2 = TLevelReaderP(m_levelIn2); if (m_lr2) level2 = m_lr2->loadInfo(); } catch (...) { errorMessage = "Error: can't read level " + toString(m_levelIn2.getWideString()); return false; } if (level2->getFrameCount() == 0) { errorMessage = "Error: can't find level " + toString(m_levelIn2.getWideString()); return false; } if (m_level1->getFrameCount() != level2->getFrameCount()) { errorMessage = "Error: the two input levels must have same frame number"; return false; } } m_size = TDimension(); m_lw = TLevelWriterP(m_levelOut); m_it = m_level1->begin(); TLevel::Iterator it2; if (level2->getFrameCount() > 0) it2 = level2->begin(); for (; m_it != m_level1->end(); ++m_it) { TImageReaderP ir1 = m_lr1->getFrameReader(m_it->first); const TImageInfo *info1 = ir1->getImageInfo(); if (!info1) { errorMessage = "Error: can't read frame " + toString(m_it->first.getNumber()) + " of level " + toString(m_levelIn1.getWideString()); return false; } if (info1->m_bitsPerSample != 8) { errorMessage = "Error: all frames must have 8 bits per channel!\n"; return false; } m_size.lx = tmax(m_size.lx, info1->m_lx); m_size.ly = tmax(m_size.ly, info1->m_ly); if (m_lr2 != TLevelReaderP()) { TImageReaderP ir2 = m_lr2->getFrameReader(it2->first); if (ir2) { const TImageInfo *info2 = ir2->getImageInfo(); if (!info1) { errorMessage = "Error: can't read frame " + toString(it2->first.getNumber()) + " of level " + toString(m_levelIn2.getWideString()); ; return false; } if (info1->m_lx != info2->m_lx || info1->m_ly != info2->m_ly) { errorMessage = "Error: painted frames must have same resolution of matching unpainted frames!\n"; return false; } if (info2->m_bitsPerSample != 8) { errorMessage = "Error: all frames must have 8 bits per channel!\n"; return false; } } ++it2; } } m_palette = new TPalette(); if (m_palettePath != TFilePath()) { TIStream is(m_palettePath); is >> m_palette; if (m_palette->getStyleInPagesCount() == 0) { errorMessage = "Error: invalid palette!\n"; return false; } for (int i = 0; i < m_palette->getStyleCount(); i++) if (m_palette->getStylePage(i)) { m_colorMap[m_palette->getStyle(i)->getMainColor()] = i; if (i > m_lastIndex) m_lastIndex = i; } assert(m_colorMap.size() == m_palette->getStyleInPagesCount()); }
void build_lw_lut(float ref_lw[256], float lw[256], UCHAR lut[256]) { /* crea una lut tale che l'immagine con il profilo di linewidths lw venga mappata in un'immagine con il profilo di riferimento ref_lw. Le lw sono non decrescenti e delimitate da 0.0 li' dove non sono valide */ int i, j; float bot_ref_lw, top_ref_lw, bot_lw, top_lw; int bot_ref_gr, top_ref_gr, bot_gr, top_gr; float min_lw, max_lw; int min_ref_gr, max_ref_gr, min_gr, max_gr; float fac; for (i = 0; !ref_lw[i]; i++) { } bot_ref_lw = ref_lw[i]; bot_ref_gr = i; for (i = 255; !ref_lw[i]; i--) { } top_ref_lw = ref_lw[i]; top_ref_gr = i; for (i = 0; !lw[i]; i++) { } bot_lw = lw[i]; bot_gr = i; for (i = 255; !lw[i]; i--) { } top_lw = lw[i]; top_gr = i; min_lw = tmax(bot_ref_lw, bot_lw); max_lw = tmin(top_ref_lw, top_lw); if (min_lw >= max_lw) { for (i = 0; i < 256; i++) lut[i] = i; return; } for (i = bot_ref_gr; ref_lw[i] < min_lw; i++) { } min_ref_gr = i; for (i = top_ref_gr; ref_lw[i] > max_lw; i--) { } max_ref_gr = i; for (i = bot_gr; lw[i] < min_lw; i++) { } min_gr = i; for (i = top_gr; lw[i] > max_lw; i--) { } max_gr = i; j = min_ref_gr; for (i = min_gr; i <= max_gr; i++) { while (ref_lw[j] < lw[i] && j < max_ref_gr) j++; lut[i] = j; } fac = (float)min_ref_gr / (float)min_gr; for (i = 0; i < min_gr; i++) lut[i] = troundp(i * fac); fac = (float)(255 - max_ref_gr) / (float)(255 - max_gr); for (i = 255; i > max_gr; i--) lut[i] = 255 - troundp((255 - i) * fac); /*** printf ("-----\n\lut:\n\n"); for (i = 255; i >= 0; i--) printf ("%4d :%4u\n", i, lut[i]); printf ("\n"); ***/ }
/***********************************************************************//** * @brief Test observations optimizer. * * @param[in] mode Testing mode. * * This method supports two testing modes: 0 = unbinned and 1 = binned. ***************************************************************************/ void TestOpenMP::test_observations_optimizer(const int& mode) { // Create Test Model GTestModelData model; // Create Models conteners GModels models; models.append(model); // Time iterval GTime tmin(0.0); GTime tmax(1800.0); // Rate : events/sec double rate = RATE; // Create observations GObservations obs; // Add some observation for (int i = 0; i < 6; ++i) { // Random Generator GRan ran; ran.seed(i); // Allocate events pointer GEvents *events; // Create either a event list or an event cube if (mode == UN_BINNED) { events = model.generateList(rate,tmin,tmax,ran); } else { events = model.generateCube(rate,tmin,tmax,ran); } // Create an observation GTestObservation ob; ob.id(gammalib::str(i)); // Add events to the observation ob.events(*events); ob.ontime(tmax.secs()-tmin.secs()); obs.append(ob); // Delete events pointer delete events; } // Add the model to the observation obs.models(models); // Create a GLog for show the interations of optimizer. GLog log; // Create an optimizer. GOptimizerLM opt(log); opt.max_stalls(50); // Optimize obs.optimize(opt); // Get the result GModelPar result = (*(obs.models()[0]))[0]; // Check if converged test_assert(opt.status()==0, "Check if converged", "Optimizer did not converge"); // Check if value is correct test_value(result.factor_value(),RATE,result.factor_error()*3); // Return return; }
TImageP TImageReader::load0() { if (!m_reader && !m_vectorReader) open(); if (m_reader) { TImageInfo info = m_reader->getImageInfo(); if (info.m_lx <= 0 || info.m_ly <= 0) return TImageP(); // Initialize raster info assert(m_shrink > 0); // Build loading rect int x0 = 0; int x1 = info.m_lx - 1; int y0 = 0; int y1 = info.m_ly - 1; if (!m_region.isEmpty()) { // Intersect with the externally specified loading region x0 = tmax(x0, m_region.x0); y0 = tmax(y0, m_region.y0); x1 = tmin(x1, m_region.x1); y1 = tmin(y1, m_region.y1); if (x0 >= x1 || y0 >= y1) return TImageP(); } if (m_shrink > 1) { // Crop to shrink multiples x1 -= (x1 - x0) % m_shrink; y1 -= (y1 - y0) % m_shrink; } assert(x0 <= x1 && y0 <= y1); TDimension imageDimension = TDimension((x1 - x0) / m_shrink + 1, (y1 - y0) / m_shrink + 1); if (m_path.getType() == "tzp" || m_path.getType() == "tzu") { // Colormap case TRasterCM32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); // Build the savebox TRect saveBox(info.m_x0, info.m_y0, info.m_x1, info.m_y1); if (!m_region.isEmpty()) { // Intersect with the loading rect if (m_region.overlaps(saveBox)) { saveBox *= m_region; int sbx0 = saveBox.x0 - m_region.x0; int sby0 = saveBox.y0 - m_region.y0; int sbx1 = sbx0 + saveBox.getLx() - 1; int sby1 = sby0 + saveBox.getLy() - 1; assert(sbx0 >= 0); assert(sby0 >= 0); assert(sbx1 >= 0); assert(sby1 >= 0); saveBox = TRect(sbx0, sby0, sbx1, sby1); } else saveBox = TRect(0, 0, 1, 1); } if (m_shrink > 1) { saveBox.x0 = saveBox.x0 / m_shrink; saveBox.y0 = saveBox.y0 / m_shrink; saveBox.x1 = saveBox.x1 / m_shrink; saveBox.y1 = saveBox.y1 / m_shrink; } TToonzImageP ti(ras, ras->getBounds() * saveBox); ti->setDpi(info.m_dpix, info.m_dpiy); return ti; } else if (info.m_bitsPerSample >= 8) { // Common byte-based rasters (see below, we have black-and-white bit-based images too) if (info.m_samplePerPixel == 1 && m_readGreytones) { // Greymap case // NOTE: Uses a full 32-bit raster first, and then copies down to the GR8 // Observe that GR16 file images get immediately down-cast to GR8... // Should we implement that too? TRasterGR8P ras(imageDimension); readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } // assert(info.m_samplePerPixel == 3 || info.m_samplePerPixel == 4); TRasterP _ras; if (info.m_bitsPerSample == 16) { if (m_is64BitEnabled || m_path.getType() != "tif") { // Standard 64-bit case. // Also covers down-casting to 32-bit from a 64-bit image file whenever // not a tif file (see below). TRaster64P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } else { // The Tif reader has got an automatically down-casting readLine(char*, ...) // in case the input file is 64-bit. The advantage is that no intermediate // 64-bit raster is required in this case. TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } } else if (info.m_bitsPerSample == 8) { // Standard 32-bit case TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } else throw TImageException(m_path, "Image format not supported"); // 64-bit to 32-bit conversions if necessary (64 bit images not allowed) if (!m_is64BitEnabled && (TRaster64P)_ras) { TRaster32P raux(_ras->getLx(), _ras->getLy()); TRop::convert(raux, _ras); _ras = raux; } // Return the image TRasterImageP ri(_ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } else if (info.m_samplePerPixel == 1 && info.m_valid == true) { // Previously dubbed as 'Palette cases'. No clue about what is this... :| TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } else if (info.m_samplePerPixel == 1 && m_readGreytones) { // Black-and-White case, I guess. Standard greymaps were considered above... TRasterGR8P ras(imageDimension); readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); if (info.m_bitsPerSample == 1) // I suspect this always evaluates true... ri->setScanBWFlag(true); return ri; } else return TImageP(); } else if (m_vectorReader) { TVectorImage *vi = m_vectorReader->read(); return TVectorImageP(vi); } else return TImageP(); }