public static DmtxVector2 operator -(DmtxVector2 v1, DmtxVector2 v2) { DmtxVector2 result = new DmtxVector2(v1.X, v1.Y); result.X -= v2.X; result.Y -= v2.Y; return result; }
public static DmtxVector2 operator -(DmtxVector2 v1, DmtxVector2 v2) { DmtxVector2 result = new DmtxVector2(v1.X, v1.Y); result.X -= v2.X; result.Y -= v2.Y; return(result); }
public static DmtxVector2 operator *(DmtxVector2 vector, DmtxMatrix3 matrix) { double w = Math.Abs(vector.X * matrix[0, 2] + vector.Y * matrix[1, 2] + matrix[2, 2]); if (w <= DmtxConstants.DmtxAlmostZero) { throw new ArgumentException("Multiplication of vector and matrix resulted in invalid result"); } DmtxVector2 result = new DmtxVector2((vector.X*matrix[0,0] + vector.Y * matrix[1,0] + matrix[2,0])/w, (vector.X * matrix[0,1] + vector.Y * matrix[1,1] + matrix[2,1])/w); return result; }
internal bool PointAlongRay2(DmtxRay2 ray, double t) { if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero) { throw new ArgumentException("PointAlongRay: The ray's V vector must be a unit vector"); } DmtxVector2 tmp = new DmtxVector2(ray.V._x * t, ray.V._y * t); this._x = ray.P._x + tmp._x; this._y = ray.P._y + tmp._y; return(true); }
public static DmtxVector2 operator *(DmtxVector2 vector, DmtxMatrix3 matrix) { double w = Math.Abs(vector.X * matrix[0, 2] + vector.Y * matrix[1, 2] + matrix[2, 2]); if (w <= DmtxConstants.DmtxAlmostZero) { throw new ArgumentException("Multiplication of vector and matrix resulted in invalid result"); } DmtxVector2 result = new DmtxVector2((vector.X * matrix[0, 0] + vector.Y * matrix[1, 0] + matrix[2, 0]) / w, (vector.X * matrix[0, 1] + vector.Y * matrix[1, 1] + matrix[2, 1]) / w); return(result); }
internal static double RightAngleTrueness(DmtxVector2 c0, DmtxVector2 c1, DmtxVector2 c2, double angle) { DmtxVector2 vA, vB; vA = (c0 - c1); vB = (c2 - c1); vA.Norm(); vB.Norm(); DmtxMatrix3 m = DmtxMatrix3.Rotate(angle); vB *= m; return(vA.Dot(vB)); }
internal DmtxMessage MatrixRegion(DmtxRegion reg, int fix) { DmtxMessage result = new DmtxMessage(reg.SizeIdx, DmtxFormat.Matrix); DmtxVector2 topLeft = new DmtxVector2(); DmtxVector2 topRight = new DmtxVector2(); DmtxVector2 bottomLeft = new DmtxVector2(); DmtxVector2 bottomRight = new DmtxVector2(); DmtxPixelLoc pxTopLeft = new DmtxPixelLoc(); DmtxPixelLoc pxTopRight = new DmtxPixelLoc(); DmtxPixelLoc pxBottomLeft = new DmtxPixelLoc(); DmtxPixelLoc pxBottomRight = new DmtxPixelLoc(); if (!PopulateArrayFromMatrix(reg, result)) { throw new Exception("Populating Array from matrix failed!"); } /* maybe place remaining logic into new dmtxDecodePopulatedArray() function so other people can pass in their own arrays */ ModulePlacementEcc200(result.Array, result.Code, reg.SizeIdx, DmtxConstants.DmtxModuleOnRed | DmtxConstants.DmtxModuleOnGreen | DmtxConstants.DmtxModuleOnBlue); if (DmtxCommon.DecodeCheckErrors(result.Code, 0, reg.SizeIdx, fix) != true) { return null; } topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1; topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1; topLeft *= reg.Fit2raw; topRight *= reg.Fit2raw; bottomLeft *= reg.Fit2raw; bottomLeft *= reg.Fit2raw; pxTopLeft.X = (int)(0.5 + topLeft.X); pxTopLeft.Y = (int)(0.5 + topLeft.Y); pxBottomLeft.X = (int)(0.5 + bottomLeft.X); pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y); pxTopRight.X = (int)(0.5 + topRight.X); pxTopRight.Y = (int)(0.5 + topRight.Y); pxBottomRight.X = (int)(0.5 + bottomRight.X); pxBottomRight.Y = (int)(0.5 + bottomRight.Y); CacheFillQuad(pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft); result.DecodeDataStream(reg.SizeIdx, null); return result; }
bool RegionUpdateXfrms(DmtxRegion reg) { double radians; DmtxRay2 rLeft = new DmtxRay2(); DmtxRay2 rBottom = new DmtxRay2(); DmtxRay2 rTop = new DmtxRay2(); DmtxRay2 rRight = new DmtxRay2(); DmtxVector2 p00 = new DmtxVector2(); DmtxVector2 p10 = new DmtxVector2(); DmtxVector2 p11 = new DmtxVector2(); DmtxVector2 p01 = new DmtxVector2(); if (!(reg.LeftKnown != 0 && reg.BottomKnown != 0)) { throw new ArgumentException("Error updating Xfrms!"); } /* Build ray representing left edge */ rLeft.P.X = (double)reg.LeftLoc.X; rLeft.P.Y = (double)reg.LeftLoc.Y; radians = reg.LeftAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rLeft.V.X = Math.Cos(radians); rLeft.V.Y = Math.Sin(radians); rLeft.TMin = 0.0; rLeft.TMax = rLeft.V.Norm(); /* Build ray representing bottom edge */ rBottom.P.X = (double)reg.BottomLoc.X; rBottom.P.Y = (double)reg.BottomLoc.Y; radians = reg.BottomAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rBottom.V.X = Math.Cos(radians); rBottom.V.Y = Math.Sin(radians); rBottom.TMin = 0.0; rBottom.TMax = rBottom.V.Norm(); /* Build ray representing top edge */ if (reg.TopKnown != 0) { rTop.P.X = (double)reg.TopLoc.X; rTop.P.Y = (double)reg.TopLoc.Y; radians = reg.TopAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rTop.V.X = Math.Cos(radians); rTop.V.Y = Math.Sin(radians); rTop.TMin = 0.0; rTop.TMax = rTop.V.Norm(); } else { rTop.P.X = (double)reg.LocT.X; rTop.P.Y = (double)reg.LocT.Y; radians = reg.BottomAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rTop.V.X = Math.Cos(radians); rTop.V.Y = Math.Sin(radians); rTop.TMin = 0.0; rTop.TMax = rBottom.TMax; } /* Build ray representing right edge */ if (reg.RightKnown != 0) { rRight.P.X = (double)reg.RightLoc.X; rRight.P.Y = (double)reg.RightLoc.Y; radians = reg.RightAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rRight.V.X = Math.Cos(radians); rRight.V.Y = Math.Sin(radians); rRight.TMin = 0.0; rRight.TMax = rRight.V.Norm(); } else { rRight.P.X = (double)reg.LocR.X; rRight.P.Y = (double)reg.LocR.Y; radians = reg.LeftAngle * (Math.PI / DmtxConstants.DmtxHoughRes); rRight.V.X = Math.Cos(radians); rRight.V.Y = Math.Sin(radians); rRight.TMin = 0.0; rRight.TMax = rLeft.TMax; } /* Calculate 4 corners, real or imagined */ if (!p00.Intersect(rLeft, rBottom)) return false; if (!p10.Intersect(rBottom, rRight)) return false; if (!p11.Intersect(rRight, rTop)) return false; if (!p01.Intersect(rTop, rLeft)) return false; if (!RegionUpdateCorners(reg, p00, p10, p11, p01)) return false; return true; }
bool RegionUpdateCorners(DmtxRegion reg, DmtxVector2 p00, DmtxVector2 p10, DmtxVector2 p11, DmtxVector2 p01) { double xMax, yMax; double tx, ty, phi, shx, scx, scy, skx, sky; double dimOT, dimOR, dimTX, dimRX, ratio; DmtxVector2 vOT, vOR, vTX, vRX, vTmp; xMax = (double)(this.Width - 1); yMax = (double)(this.Height - 1); if (p00.X < 0.0 || p00.Y < 0.0 || p00.X > xMax || p00.Y > yMax || p01.X < 0.0 || p01.Y < 0.0 || p01.X > xMax || p01.Y > yMax || p10.X < 0.0 || p10.Y < 0.0 || p10.X > xMax || p10.Y > yMax) return false; vOT = p01 - p00; vOR = p10 - p00; vTX = p11 - p01; vRX = p11 - p10; dimOT = vOT.Mag(); /* XXX could use MagSquared() */ dimOR = vOR.Mag(); dimTX = vTX.Mag(); dimRX = vRX.Mag(); /* Verify that sides are reasonably long */ if (dimOT <= 8.0 || dimOR <= 8.0 || dimTX <= 8.0 || dimRX <= 8.0) return false; /* Verify that the 4 corners define a reasonably fat quadrilateral */ ratio = dimOT / dimRX; if (ratio <= 0.5 || ratio >= 2.0) return false; ratio = dimOR / dimTX; if (ratio <= 0.5 || ratio >= 2.0) return false; /* Verify this is not a bowtie shape */ if (vOR.Cross(vRX) <= 0.0 || vOT.Cross(vTX) >= 0.0) return false; if (DmtxCommon.RightAngleTrueness(p00, p10, p11, Math.PI / 2.0) <= this._squareDevn) return false; if (DmtxCommon.RightAngleTrueness(p10, p11, p01, Math.PI / 2.0) <= this._squareDevn) return false; /* Calculate values needed for transformations */ tx = -1 * p00.X; ty = -1 * p00.Y; DmtxMatrix3 mtxy = DmtxMatrix3.Translate(tx, ty); phi = Math.Atan2(vOT.X, vOT.Y); DmtxMatrix3 mphi = DmtxMatrix3.Rotate(phi); DmtxMatrix3 m = mtxy * mphi; vTmp = p10 * m; shx = -vTmp.Y / vTmp.X; DmtxMatrix3 mshx = DmtxMatrix3.Shear(0.0, shx); m *= mshx; scx = 1.0 / vTmp.X; DmtxMatrix3 mscx = DmtxMatrix3.Scale(scx, 1.0); m *= mscx; vTmp = p11 * m; scy = 1.0 / vTmp.Y; DmtxMatrix3 mscy = DmtxMatrix3.Scale(1.0, scy); m *= mscy; vTmp = p11 * m; skx = vTmp.X; DmtxMatrix3 mskx = DmtxMatrix3.LineSkewSide(1.0, skx, 1.0); m *= mskx; vTmp = p01 * m; sky = vTmp.Y; DmtxMatrix3 msky = DmtxMatrix3.LineSkewTop(sky, 1.0, 1.0); reg.Raw2fit = m * msky; /* Create inverse matrix by reverse (avoid straight matrix inversion) */ msky = DmtxMatrix3.LineSkewTopInv(sky, 1.0, 1.0); mskx = DmtxMatrix3.LineSkewSideInv(1.0, skx, 1.0); m = msky * mskx; DmtxMatrix3 mscxy = DmtxMatrix3.Scale(1.0 / scx, 1.0 / scy); m *= mscxy; mshx = DmtxMatrix3.Shear(0.0, -shx); m *= mshx; mphi = DmtxMatrix3.Rotate(-phi); m *= mphi; mtxy = DmtxMatrix3.Translate(-tx, -ty); reg.Fit2raw = m * mtxy; return true; }
private int ReadModuleColor(DmtxRegion reg, int symbolRow, int symbolCol, DmtxSymbolSize sizeIdx, int colorPlane) { int i; int symbolRows, symbolCols; int color, colorTmp; double[] sampleX = { 0.5, 0.4, 0.5, 0.6, 0.5 }; double[] sampleY = { 0.5, 0.5, 0.4, 0.5, 0.6 }; DmtxVector2 p = new DmtxVector2(); symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx); symbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, sizeIdx); colorTmp = color = 0; for (i = 0; i < 5; i++) { p.X = (1.0 / symbolCols) * (symbolCol + sampleX[i]); p.Y = (1.0 / symbolRows) * (symbolRow + sampleY[i]); p *= reg.Fit2raw; GetPixelValue((int)(p.X + 0.5), (int)(p.Y + 0.5), colorPlane, ref colorTmp); color += colorTmp; } return color / 5; }
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; }
internal double Dot(DmtxVector2 v2) { return(Math.Sqrt(_x * v2._x + _y * v2._y)); }
internal double Cross(DmtxVector2 v2) { return(this._x * v2._y - this._y * v2._x); }
private void PrintPattern(Color? foreColor, Color? backColor) { int i, j; int symbolRow, symbolCol; int pixelRow, pixelCol; int moduleStatus; int rowSize, height; int[] rgb = new int[3]; double sxy, txy; DmtxVector2 vIn, vOut; txy = this._marginSize; sxy = 1.0 / this._moduleSize; DmtxMatrix3 m1 = DmtxMatrix3.Translate(-txy, -txy); DmtxMatrix3 m2 = DmtxMatrix3.Scale(sxy, -sxy); DmtxMatrix3 xfrm = m1 * m2; m1 = DmtxMatrix3.Translate(txy, txy); m2 = DmtxMatrix3.Scale(this._moduleSize, this._moduleSize); DmtxMatrix3 rxfrm = m2 * m1; rowSize = this._image.RowSizeBytes; height = this._image.Height; for (int pxlIndex = 0; pxlIndex < rowSize * height; pxlIndex++) { this._image.Pxl[pxlIndex] = 0xff; } for (symbolRow = 0; symbolRow < this._region.SymbolRows; symbolRow++) { for (symbolCol = 0; symbolCol < this._region.SymbolCols; symbolCol++) { vIn = new DmtxVector2(symbolCol, symbolRow); vOut = vIn * rxfrm; pixelCol = (int)(vOut.X); pixelRow = (int)(vOut.Y); moduleStatus = this._message.SymbolModuleStatus(this._region.SizeIdx, symbolRow, symbolCol); if (moduleStatus != 7) { bool rgb0 = (moduleStatus & DmtxConstants.DmtxModuleOnRed) == 0; bool rgb1 = (moduleStatus & DmtxConstants.DmtxModuleOnGreen) == 0; bool rgb2 = (moduleStatus & DmtxConstants.DmtxModuleOnBlue) == 0; } for (i = pixelRow; i < pixelRow + this._moduleSize; i++) { for (j = pixelCol; j < pixelCol + this._moduleSize; j++) { if (foreColor.HasValue && backColor.HasValue) { rgb[0] = ((moduleStatus & DmtxConstants.DmtxModuleOnRed) != 0x00) ? foreColor.Value.B : backColor.Value.B; rgb[1] = ((moduleStatus & DmtxConstants.DmtxModuleOnGreen) != 0x00) ? foreColor.Value.G : backColor.Value.G; rgb[2] = ((moduleStatus & DmtxConstants.DmtxModuleOnBlue) != 0x00) ? foreColor.Value.R : backColor.Value.R; } else { rgb[0] = ((moduleStatus & DmtxConstants.DmtxModuleOnBlue) != 0x00) ? 0 : 255; rgb[1] = ((moduleStatus & DmtxConstants.DmtxModuleOnGreen) != 0x00) ? 0 : 255; rgb[2] = ((moduleStatus & DmtxConstants.DmtxModuleOnRed) != 0x00) ? 0 : 255; } /* dmtxImageSetRgb(enc->image, j, i, rgb); */ this._image.SetPixelValue(j, i, 0, (byte)rgb[0]); this._image.SetPixelValue(j, i, 1, (byte)rgb[1]); this._image.SetPixelValue(j, i, 2, (byte)rgb[2]); } } } } }
internal double Cross(DmtxVector2 v2) { return (this._x * v2._y - this._y * v2._x); }
internal double Dot(DmtxVector2 v2) { return Math.Sqrt(_x * v2._x + _y * v2._y); }
internal bool PointAlongRay2(DmtxRay2 ray, double t) { if (Math.Abs(1.0 - ray.V.Mag()) > DmtxConstants.DmtxAlmostZero) { throw new ArgumentException("PointAlongRay: The ray's V vector must be a unit vector"); } DmtxVector2 tmp = new DmtxVector2(ray.V._x * t, ray.V._y * t); this._x = ray.P._x + tmp._x; this._y = ray.P._y + tmp._y; return true; }