internal DmtxBresLine(DmtxBresLine orig) { this._error = orig._error; this._loc = new DmtxPixelLoc() { X = orig._loc.X, Y = orig._loc.Y }; this._loc0 = new DmtxPixelLoc() { X = orig._loc0.X, Y = orig._loc0.Y }; this._loc1 = new DmtxPixelLoc() { X = orig._loc1.X, Y = orig._loc1.Y }; this._outward = orig._outward; this._steep = orig._steep; this._travel = orig._travel; this._xDelta = orig._xDelta; this._xOut = orig._xOut; this._xStep = orig._xStep; this._yDelta = orig._yDelta; this._yOut = orig._yOut; this._yStep = orig._yStep; }
internal void CacheFillQuad(DmtxPixelLoc p0, DmtxPixelLoc p1, DmtxPixelLoc p2, DmtxPixelLoc p3) { DmtxBresLine[] lines = new DmtxBresLine[4]; DmtxPixelLoc pEmpty = new DmtxPixelLoc() { X = 0, Y = 0 }; int[] scanlineMin; int[] scanlineMax; int minY, maxY, sizeY, posY, posX; int i, idx; lines[0] = new DmtxBresLine(p0, p1, pEmpty); lines[1] = new DmtxBresLine(p1, p2, pEmpty); lines[2] = new DmtxBresLine(p2, p3, pEmpty); lines[3] = new DmtxBresLine(p3, p0, pEmpty); minY = this._yMax; maxY = 0; minY = DmtxCommon.Min<int>(minY, p0.Y); maxY = DmtxCommon.Max<int>(maxY, p0.Y); minY = DmtxCommon.Min<int>(minY, p1.Y); maxY = DmtxCommon.Max<int>(maxY, p1.Y); minY = DmtxCommon.Min<int>(minY, p2.Y); maxY = DmtxCommon.Max<int>(maxY, p2.Y); minY = DmtxCommon.Min<int>(minY, p3.Y); maxY = DmtxCommon.Max<int>(maxY, p3.Y); sizeY = maxY - minY + 1; scanlineMin = new int[sizeY]; scanlineMax = new int[sizeY]; for (i = 0; i < sizeY; i++) { scanlineMin[i] = this._xMax; } for (i = 0; i < 4; i++) { while (lines[i].Loc.X != lines[i].Loc1.X || lines[i].Loc.Y != lines[i].Loc1.Y) { idx = lines[i].Loc.Y - minY; scanlineMin[idx] = DmtxCommon.Min<int>(scanlineMin[idx], lines[i].Loc.X); scanlineMax[idx] = DmtxCommon.Max<int>(scanlineMax[idx], lines[i].Loc.X); lines[i].Step(1, 0); } } for (posY = minY; posY < maxY && posY < this._yMax; posY++) { idx = posY - minY; for (posX = scanlineMin[idx]; posX < scanlineMax[idx] && posX < this._xMax; posX++) { if (posX < 0 || posY < 0) { continue; } try { int cacheIndex = GetCacheIndex(posX, posY); this._cache[cacheIndex] |= 0x80; } catch (Exception) { // FIXXXME: log here as soon as there is a logger } } } }
int TrailBlazeGapped(DmtxRegion reg, DmtxBresLine line, int streamDir) { bool onEdge; int distSq, distSqMax; int travel = 0; int outward = 0; int xDiff, yDiff; int steps; int stepDir = 0; int[] dirMap = { 0, 1, 2, 7, 8, 3, 6, 5, 4 }; bool err; DmtxPixelLoc beforeStep, afterStep; DmtxPointFlow flow, flowNext; DmtxPixelLoc loc0; int xStep, yStep; loc0 = line.Loc; flow = GetPointFlow(reg.FlowBegin.Plane, loc0, DmtxConstants.DmtxNeighborNone); distSqMax = (line.XDelta * line.XDelta) + (line.YDelta * line.YDelta); steps = 0; onEdge = true; beforeStep = loc0; int beforeCacheIndex = DecodeGetCache(loc0.X, loc0.Y); if (beforeCacheIndex == -1) return 0; else _cache[beforeCacheIndex] = 0; do { if (onEdge == true) { flowNext = FindStrongestNeighbor(flow, streamDir); if (flowNext.Mag == DmtxConstants.DmtxUndefined) break; err = (new DmtxBresLine(line)).GetStep(flowNext.Loc, ref travel, ref outward); if (flowNext.Mag < 50 || outward < 0 || (outward == 0 && travel < 0)) { onEdge = false; } else { line.Step(travel, outward); flow = flowNext; } } if (!onEdge) { line.Step(1, 0); flow = GetPointFlow(reg.FlowBegin.Plane, line.Loc, DmtxConstants.DmtxNeighborNone); if (flow.Mag > 50) onEdge = true; } afterStep = line.Loc; int afterCacheIndex = DecodeGetCache(afterStep.X, afterStep.Y); if (afterCacheIndex == -1) break; /* Determine step direction using pure magic */ xStep = afterStep.X - beforeStep.X; yStep = afterStep.Y - beforeStep.Y; if (Math.Abs(xStep) > 1 || Math.Abs(yStep) > 1) { throw new Exception("Invalid step directions!"); } stepDir = dirMap[3 * yStep + xStep + 4]; if (stepDir == 8) { throw new Exception("Invalid step direction!"); } if (streamDir < 0) { this._cache[beforeCacheIndex] |= (byte)(0x40 | stepDir); this._cache[afterCacheIndex] = (byte)(((stepDir + 4) % 8) << 3); } else { this._cache[beforeCacheIndex] |= (byte)(0x40 | (stepDir << 3)); this._cache[afterCacheIndex] = (byte)((stepDir + 4) % 8); } /* Guaranteed to have taken one step since top of loop */ xDiff = line.Loc.X - loc0.X; yDiff = line.Loc.Y - loc0.Y; distSq = (xDiff * xDiff) + (yDiff * yDiff); beforeStep = line.Loc; beforeCacheIndex = afterCacheIndex; steps++; } while (distSq < distSqMax); return steps; }
bool MatrixRegionAlignCalibEdge(DmtxRegion reg, DmtxEdge edgeLoc) { int streamDir; int steps; int avoidAngle; DmtxSymbolSize symbolShape; DmtxVector2 pTmp = new DmtxVector2(); DmtxPixelLoc loc0 = new DmtxPixelLoc(); DmtxPixelLoc loc1 = new DmtxPixelLoc(); DmtxPixelLoc locOrigin = new DmtxPixelLoc(); DmtxBresLine line; DmtxFollow follow; DmtxBestLine bestLine; /* Determine pixel coordinates of origin */ pTmp.X = 0.0; pTmp.Y = 0.0; pTmp *= reg.Fit2raw; locOrigin.X = (int)(pTmp.X + 0.5); locOrigin.Y = (int)(pTmp.Y + 0.5); if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolSquareAuto || (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol10x10 && this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol144x144)) symbolShape = DmtxSymbolSize.DmtxSymbolSquareAuto; else if (this._sizeIdxExpected == DmtxSymbolSize.DmtxSymbolRectAuto || (this._sizeIdxExpected >= DmtxSymbolSize.DmtxSymbol8x18 && this._sizeIdxExpected <= DmtxSymbolSize.DmtxSymbol16x48)) symbolShape = DmtxSymbolSize.DmtxSymbolRectAuto; else symbolShape = DmtxSymbolSize.DmtxSymbolShapeAuto; /* Determine end locations of test line */ if (edgeLoc == DmtxEdge.DmtxEdgeTop) { streamDir = reg.Polarity * -1; avoidAngle = reg.LeftLine.Angle; follow = FollowSeekLoc(reg.LocT); pTmp.X = 0.8; pTmp.Y = (symbolShape == DmtxSymbolSize.DmtxSymbolRectAuto) ? 0.2 : 0.6; } else { streamDir = reg.Polarity; avoidAngle = reg.BottomLine.Angle; follow = FollowSeekLoc(reg.LocR); pTmp.X = (symbolShape == DmtxSymbolSize.DmtxSymbolSquareAuto) ? 0.7 : 0.9; pTmp.Y = 0.8; } pTmp *= reg.Fit2raw; loc1.X = (int)(pTmp.X + 0.5); loc1.Y = (int)(pTmp.Y + 0.5); loc0 = follow.Loc; line = new DmtxBresLine(loc0, loc1, locOrigin); steps = TrailBlazeGapped(reg, line, streamDir); bestLine = FindBestSolidLine2(loc0, steps, streamDir, avoidAngle); if (bestLine.Mag < 5) { ; } if (edgeLoc == DmtxEdge.DmtxEdgeTop) { reg.TopKnown = 1; reg.TopAngle = bestLine.Angle; reg.TopLoc = bestLine.LocBeg; } else { reg.RightKnown = 1; reg.RightAngle = bestLine.Angle; reg.RightLoc = bestLine.LocBeg; } return true; }