/// <summary> /// Check if the multiblock structure is complete. Ignores air blocks /// </summary> /// <param name="world"></param> /// <param name="centerPos"></param> /// <returns></returns> public int InCompleteBlockCount(IWorldAccessor world, BlockPos centerPos, PositionMismatchDelegate onMismatch = null) { if (TransformedOffsets == null) { throw new InvalidOperationException("call InitForUse() first"); } int qinc = 0; for (int i = 0; i < TransformedOffsets.Count; i++) { Vec4i offset = TransformedOffsets[i]; Block block = world.BlockAccessor.GetBlock(centerPos.X + offset.X, centerPos.Y + offset.Y, centerPos.Z + offset.Z); if (!WildcardUtil.Match(BlockCodes[offset.W], block.Code)) { onMismatch?.Invoke(block, BlockCodes[offset.W]); //world.Logger.Notification("Expected: {0}, Is: {1}", BlockCodes[offset.W], block.Code); qinc++; } } return(qinc); }
public void InitForUse(float rotateYDeg) { Matrixf mat = new Matrixf(); mat.RotateYDeg(rotateYDeg); BlockCodes = new Dictionary <int, AssetLocation>(); TransformedOffsets = new List <BlockOffsetAndNumber>(); foreach (var val in BlockNumbers) { BlockCodes[val.Value] = val.Key; } for (int i = 0; i < Offsets.Count; i++) { Vec4i offset = Offsets[i]; Vec4f offsetTf = new Vec4f(offset.X, offset.Y, offset.Z, 0); Vec4f tfedOffset = mat.TransformVector(offsetTf); TransformedOffsets.Add(new BlockOffsetAndNumber() { X = (int)Math.Round(tfedOffset.X), Y = (int)Math.Round(tfedOffset.Y), Z = (int)Math.Round(tfedOffset.Z), W = offset.W }); } }
public void HighlightIncompleteParts(IWorldAccessor world, IPlayer player, BlockPos centerPos) { List <BlockPos> blocks = new List <BlockPos>(); List <int> colors = new List <int>(); for (int i = 0; i < TransformedOffsets.Count; i++) { Vec4i offset = TransformedOffsets[i]; Block block = world.BlockAccessor.GetBlock(centerPos.X + offset.X, centerPos.Y + offset.Y, centerPos.Z + offset.Z); AssetLocation desireBlockLoc = BlockCodes[offset.W]; if (!WildcardUtil.Match(BlockCodes[offset.W], block.Code)) { blocks.Add(new BlockPos(offset.X, offset.Y, offset.Z).Add(centerPos)); if (block.Id != 0) { colors.Add(ColorUtil.ColorFromRgba(215, 94, 94, 64)); } else { int col = world.SearchBlocks(desireBlockLoc)[0].GetColor(world.Api as ICoreClientAPI, centerPos); col &= ~(255 << 24); col |= 96 << 24; colors.Add(col); } } } world.HighlightBlocks(player, HighlightSlotId, blocks, colors); }
public void NormVeci() { var vec = new Vec4i(10000, 20000, 30000, 40000); var norm = Cv2.Norm(vec, NormTypes.L1); Assert.Equal(100000, norm); }
public static void Write(this BinaryWriter writer, Vec4i vec) { writer.Write(vec.x); writer.Write(vec.y); writer.Write(vec.z); writer.Write(vec.w); }
public void FloodFillAt(WorldEdit worldEdit, Block blockToPlace, ItemStack withItemStack, int posX, int posY, int posZ) { bfsQueue.Clear(); fillablePositions.Clear(); if (posY <= 0 || posY >= mapheight - 1) { return; } bfsQueue.Enqueue(new Vec4i(posX, posY, posZ, 0)); fillablePositions.Add(new BlockPos(posX, posY, posZ)); float radius = SearchRadius; BlockFacing[] faces = Mode == 2 ? BlockFacing.HORIZONTALS : BlockFacing.ALLFACES; BlockPos curPos = new BlockPos(); while (bfsQueue.Count > 0) { Vec4i bpos = bfsQueue.Dequeue(); foreach (BlockFacing facing in faces) { curPos.Set(bpos.X + facing.Normali.X, bpos.Y + facing.Normali.Y, bpos.Z + facing.Normali.Z); Block block = blockAccessRev.GetBlock(curPos); bool inBounds = bpos.W < radius; if (inBounds) { if (block.Replaceable >= 6000 && !fillablePositions.Contains(curPos)) { bfsQueue.Enqueue(new Vec4i(curPos.X, curPos.Y, curPos.Z, bpos.W + 1)); fillablePositions.Add(curPos.Copy()); } } else { if (CheckEnclosure) { fillablePositions.Clear(); bfsQueue.Clear(); worldEdit.Bad("Cannot flood fill here, not enclosed area. Enforce enclosed area or disable enclosure check."); break; } } } } foreach (BlockPos p in fillablePositions) { blockAccessRev.SetBlock(blockToPlace.BlockId, p, withItemStack); } worldEdit.Bad(fillablePositions.Count + " blocks placed"); }
/// <summary> /// /// </summary> /// <param name="vec"></param> /// <returns></returns> public static HiearchyIndex FromVec4i(Vec4i vec) { return new HiearchyIndex { Next = vec.Item0, Previous = vec.Item1, Child = vec.Item2, Parent = vec.Item3 }; }
/// <summary> /// /// </summary> /// <param name="vec"></param> /// <returns></returns> public static HierarchyIndex FromVec4i(Vec4i vec) { return(new HierarchyIndex { Next = vec.Item0, Previous = vec.Item1, Child = vec.Item2, Parent = vec.Item3 }); }
/// <summary> /// 计算两条直线的交点。可能用不上 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> private Point2f computeIntersect(Vec4i a, Vec4i b) { int x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3]; int x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3]; float d = ((float)(x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)); Point2f pt = new Point2f(); if (d != 0) { pt.X = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d; pt.Y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d; return(pt); } else { pt.X = -1; pt.Y = -1; return(pt); } }
public void WalkMatchingBlocks(IWorldAccessor world, BlockPos centerPos, Action <Block, BlockPos> onBlock) { if (TransformedOffsets == null) { throw new InvalidOperationException("call InitForUse() first"); } BlockPos pos = new BlockPos(); for (int i = 0; i < TransformedOffsets.Count; i++) { Vec4i offset = TransformedOffsets[i]; pos.Set(centerPos.X + offset.X, centerPos.Y + offset.Y, centerPos.Z + offset.Z); Block block = world.BlockAccessor.GetBlock(pos); if (WildcardUtil.Match(BlockCodes[offset.W], block.Code)) { onBlock?.Invoke(block, pos); } } }
public static bool checkSolution(Grid grid, out Vec4i score) { bool vote1 = true; bool vote2 = true; bool vote3 = true; bool vote4 = true; bool vote5 = true; bool vote6 = true; bool vote7 = true; bool vote8 = true; //FP,FN,TP,TN Vec4i score1 = new Vec4i(0, 0, 0, 0); Vec4i score2 = new Vec4i(0, 0, 0, 0); Vec4i score3 = new Vec4i(0, 0, 0, 0); Vec4i score4 = new Vec4i(0, 0, 0, 0); Vec4i score5 = new Vec4i(0, 0, 0, 0); Vec4i score6 = new Vec4i(0, 0, 0, 0); Vec4i score7 = new Vec4i(0, 0, 0, 0); Vec4i score8 = new Vec4i(0, 0, 0, 0); for (int i = 0; i < problem.xTiles.Length; i++) { for (int j = 0; j < problem.xTiles[i].yTiles.Length; j++) { for (int k = 0; k < problem.xTiles[i].yTiles[j].zTiles.Length; k++) { int ii = (problem.xTiles.Length - 1) - i; int kk = (problem.xTiles[i].yTiles[j].zTiles.Length - 1) - k; //check symmetric solutions if (grid.GetTile(i, j, k).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote1 = false; if (grid.GetTile(i, j, k).GetIsOccupied()) { score1.i++; } else { score1.j++; } } else { if (grid.GetTile(i, j, k).GetIsOccupied()) { score1.k++; } else { score1.l++; } } //2 if (grid.GetTile(ii, j, k).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote2 = false; if (grid.GetTile(ii, j, k).GetIsOccupied()) { score2.i++; } else { score2.j++; } } else { if (grid.GetTile(ii, j, k).GetIsOccupied()) { score2.k++; } else { score2.l++; } } //3 if (grid.GetTile(i, j, kk).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote3 = false; if (grid.GetTile(i, j, kk).GetIsOccupied()) { score3.i++; } else { score3.j++; } } else { if (grid.GetTile(i, j, kk).GetIsOccupied()) { score3.k++; } else { score3.l++; } } //4 if (grid.GetTile(ii, j, kk).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote4 = false; if (grid.GetTile(ii, j, kk).GetIsOccupied()) { score4.i++; } else { score4.j++; } } else { if (grid.GetTile(ii, j, kk).GetIsOccupied()) { score4.k++; } else { score4.l++; } } //check inverse solutions //5 if (grid.GetTile(k, j, i).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote5 = false; if (grid.GetTile(k, j, i).GetIsOccupied()) { score5.i++; } else { score5.j++; } } else { if (grid.GetTile(k, j, i).GetIsOccupied()) { score5.k++; } else { score5.l++; } } //6 if (grid.GetTile(k, j, ii).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote6 = false; if (grid.GetTile(k, j, ii).GetIsOccupied()) { score6.i++; } else { score6.j++; } } else { if (grid.GetTile(k, j, ii).GetIsOccupied()) { score6.k++; } else { score6.l++; } } //7 if (grid.GetTile(kk, j, i).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote7 = false; if (grid.GetTile(kk, j, i).GetIsOccupied()) { score7.i++; } else { score7.j++; } } else { if (grid.GetTile(kk, j, i).GetIsOccupied()) { score7.k++; } else { score7.l++; } } //8 if (grid.GetTile(kk, j, ii).GetIsOccupied() == problem.xTiles[i].yTiles[j].zTiles[k].hasCube) { vote8 = false; if (grid.GetTile(kk, j, ii).GetIsOccupied()) { score8.i++; } else { score8.j++; } } else { if (grid.GetTile(kk, j, ii).GetIsOccupied()) { score8.k++; } else { score8.l++; } } } } } score = score1; if (score2.k + score2.l > score.k + score.l) { score = score2; } if (score3.k + score3.l > score.k + score.l) { score = score3; } if (score4.k + score4.l > score.k + score.l) { score = score4; } if (score5.k + score5.l > score.k + score.l) { score = score5; } if (score6.k + score6.l > score.k + score.l) { score = score6; } if (score7.k + score7.l > score.k + score.l) { score = score7; } if (score8.k + score8.l > score.k + score.l) { score = score8; } return(vote1 || vote2 || vote3 || vote4 || vote5 || vote6 || vote7 || vote8); }
public static extern ExceptionStatus core_FileStorage_shift_Vec4i(IntPtr fs, Vec4i val);
public static extern ExceptionStatus ximgproc_HoughPoint2Line( Point houghPoint, IntPtr srcImgInfo, int angleRange, int makeSkew, int rules, out Vec4i returnValue);
public Stack <BlockPos> FindTree(IWorldAccessor world, BlockPos startPos, out string treeType) { Queue <Vec4i> queue = new Queue <Vec4i>(); HashSet <BlockPos> checkedPositions = new HashSet <BlockPos>(); Stack <BlockPos> foundPositions = new Stack <BlockPos>(); treeType = ""; Block block = world.BlockAccessor.GetBlock(startPos); if (block.Code == null) { return(foundPositions); } if (block.Code.Path.StartsWith("log-grown") || block.Code.Path.StartsWith("beehive-inlog-") || block.Code.Path.StartsWith("log-resin") || block.Code.Path.StartsWith("bamboo-grown-")) { treeType = block.FirstCodePart(2); queue.Enqueue(new Vec4i(startPos.X, startPos.Y, startPos.Z, 2)); foundPositions.Push(startPos); checkedPositions.Add(startPos); } string logcode = block.Code.Path.StartsWith("bamboo") ? "bamboo-grown-" + treeType : "log-grown-" + treeType; if (block is BlockFernTree) { treeType = "fern"; logcode = "ferntree-normal"; queue.Enqueue(new Vec4i(startPos.X, startPos.Y, startPos.Z, 2)); foundPositions.Push(startPos); checkedPositions.Add(startPos); } string logcode2 = "log-resin-" + treeType; string logcode3 = "log-resinharvested-" + treeType; string leavescode = block.Code.Path.StartsWith("bamboo") ? "bambooleaves-" + treeType + "-grown" : "leaves-grown-" + treeType; string leavesbranchycode = "leavesbranchy-grown-" + treeType; while (queue.Count > 0) { if (foundPositions.Count > 2000) { break; } Vec4i pos = queue.Dequeue(); for (int i = 0; i < Vec3i.DirectAndIndirectNeighbours.Length; i++) { Vec3i facing = Vec3i.DirectAndIndirectNeighbours[i]; BlockPos neibPos = new BlockPos(pos.X + facing.X, pos.Y + facing.Y, pos.Z + facing.Z); float hordist = GameMath.Sqrt(neibPos.HorDistanceSqTo(startPos.X, startPos.Z)); float vertdist = (neibPos.Y - startPos.Y); // "only breaks blocks inside an upside down square base pyramid" if (hordist - 1 >= 2 * vertdist) { continue; } if (checkedPositions.Contains(neibPos)) { continue; } block = world.BlockAccessor.GetBlock(neibPos); if (block.Code == null) { continue; } if (block.Code.Path.StartsWith(logcode) || block.Code.Path.StartsWith(logcode2) || block.Code.Path.StartsWith(logcode3)) { if (pos.W < 2) { continue; } foundPositions.Push(neibPos.Copy()); queue.Enqueue(new Vec4i(neibPos.X, neibPos.Y, neibPos.Z, 2)); } else if (block.Code.Path.StartsWith(leavesbranchycode)) { if (pos.W < 1) { continue; } foundPositions.Push(neibPos.Copy()); queue.Enqueue(new Vec4i(neibPos.X, neibPos.Y, neibPos.Z, 1)); } else if (block.Code.Path.StartsWith(leavescode)) { foundPositions.Push(neibPos.Copy()); queue.Enqueue(new Vec4i(neibPos.X, neibPos.Y, neibPos.Z, 0)); } checkedPositions.Add(neibPos); } } return(foundPositions); }
public static extern ExceptionStatus core_Mat_push_back_Vec4i(IntPtr self, Vec4i v);
private bool shouldDecay(BlockPos startPos) { Queue <Vec4i> bfsQueue = new Queue <Vec4i>(); HashSet <BlockPos> checkedPositions = new HashSet <BlockPos>(); IBlockAccessor blockAccessor = sapi.World.BlockAccessor; Block block = blockAccessor.GetBlock(startPos); if (canDecay(block)) { bfsQueue.Enqueue(new Vec4i(startPos.X, startPos.Y, startPos.Z, 2)); checkedPositions.Add(startPos); } else { // sapi.World.SpawnParticles(10, ColorUtil.ToRgba(255, 128, 128, 0), startPos.ToVec3d().Add(0.7, 0.3, 0.3), startPos.ToVec3d().Add(0.7, 0.35, 0.3), new Vec3f(), new Vec3f(), 1f, 0f, 2, EnumParticleModel.Cube); return(false); } while (bfsQueue.Count > 0) { if (checkedPositions.Count > 600) { return(false); } Vec4i pos = bfsQueue.Dequeue(); for (int i = 0; i < Vec3i.DirectAndIndirectNeighbours.Length; i++) { Vec3i facing = Vec3i.DirectAndIndirectNeighbours[i]; BlockPos curPos = new BlockPos(pos.X + facing.X, pos.Y + facing.Y, pos.Z + facing.Z); if (checkedPositions.Contains(curPos)) { continue; } checkedPositions.Add(curPos); block = blockAccessor.GetBlock(curPos); // Let's just say a leaves block can grow as long as its connected to // something woody or something fertile if (preventsDecay(block)) { return(false); } int diffx = (curPos.X - startPos.X); int diffy = (curPos.Y - startPos.Y); int diffz = (curPos.Z - startPos.Z); // Only test within a 6x6x6 if (Math.Abs(diffx) > 4 || Math.Abs(diffy) > 4 || Math.Abs(diffz) > 4) { if (block.Id != 0) { // sapi.World.SpawnParticles(10, ColorUtil.ToRgba(255, 50, 0, 0), curPos.ToVec3d().Add(0.3, 0.3, 0.6), curPos.ToVec3d().Add(0.3, 0.35, 0.6), new Vec3f(), new Vec3f(), 1f, 0f, 1, EnumParticleModel.Cube); return(false); } continue; } if (canDecay(block)) { // sapi.World.SpawnParticles(10, ColorUtil.ToRgba(255, 255, 255, 255), curPos.ToVec3d().Add(0.5, 0, 0.5), curPos.ToVec3d().Add(0.5, 0.05, 0.5), new Vec3f(), new Vec3f(), 1f, 0f, 0.33f, EnumParticleModel.Cube); bfsQueue.Enqueue(new Vec4i(curPos.X, curPos.Y, curPos.Z, 0)); } } } return(true); }
public Stack <BlockPos> FindTree(IWorldAccessor world, BlockPos startPos) { Queue <Vec4i> queue = new Queue <Vec4i>(); HashSet <BlockPos> checkedPositions = new HashSet <BlockPos>(); Stack <BlockPos> foundPositions = new Stack <BlockPos>(); Block block = world.BlockAccessor.GetBlock(startPos); if (block.Code == null) { return(foundPositions); } string treeFellingGroupCode = block.Attributes?["treeFellingGroupCode"].AsString(); int spreadIndex = block.Attributes?["treeFellingGroupSpreadIndex"].AsInt(0) ?? 0; if (block.Attributes?["treeFellingCanChop"].AsBool(true) == false) { return(foundPositions); } EnumTreeFellingBehavior bh = EnumTreeFellingBehavior.Chop; if (block is ICustomTreeFellingBehavior ctfbh) { bh = ctfbh.GetTreeFellingBehavior(startPos, null, spreadIndex); if (bh == EnumTreeFellingBehavior.NoChop) { return(foundPositions); } } // Must start with a log if (spreadIndex < 2) { return(foundPositions); } if (treeFellingGroupCode == null) { return(foundPositions); } queue.Enqueue(new Vec4i(startPos.X, startPos.Y, startPos.Z, spreadIndex)); foundPositions.Push(startPos); checkedPositions.Add(startPos); while (queue.Count > 0) { if (foundPositions.Count > 2500) { break; } Vec4i pos = queue.Dequeue(); block = world.BlockAccessor.GetBlock(pos.X, pos.Y, pos.Z); if (block is ICustomTreeFellingBehavior ctfbhh) { bh = ctfbhh.GetTreeFellingBehavior(startPos, null, spreadIndex); } if (bh == EnumTreeFellingBehavior.NoChop) { continue; } for (int i = 0; i < Vec3i.DirectAndIndirectNeighbours.Length; i++) { Vec3i facing = Vec3i.DirectAndIndirectNeighbours[i]; BlockPos neibPos = new BlockPos(pos.X + facing.X, pos.Y + facing.Y, pos.Z + facing.Z); float hordist = GameMath.Sqrt(neibPos.HorDistanceSqTo(startPos.X, startPos.Z)); float vertdist = (neibPos.Y - startPos.Y); // "only breaks blocks inside an upside down square base pyramid" float f = bh == EnumTreeFellingBehavior.ChopSpreadVertical ? 0.5f : 2; if (hordist - 1 >= f * vertdist) { continue; } if (checkedPositions.Contains(neibPos)) { continue; } block = world.BlockAccessor.GetBlock(neibPos); if (block.Code == null || block.Id == 0) { continue; } string ngcode = block.Attributes?["treeFellingGroupCode"].AsString(); // Only break the same type tree blocks if (ngcode != treeFellingGroupCode) { continue; } // Only spread from "high to low". i.e. spread from log to leaves, but not from leaves to logs int nspreadIndex = block.Attributes?["treeFellingGroupSpreadIndex"].AsInt(0) ?? 0; if (pos.W < nspreadIndex) { continue; } checkedPositions.Add(neibPos); if (bh == EnumTreeFellingBehavior.ChopSpreadVertical && !facing.Equals(0, 1, 0) && nspreadIndex > 0) { continue; } foundPositions.Push(neibPos.Copy()); queue.Enqueue(new Vec4i(neibPos.X, neibPos.Y, neibPos.Z, nspreadIndex)); } } return(foundPositions); }
public static extern void imgproc_drawContours_vector(IntPtr image, IntPtr[] contours, int contoursSize1, int[] contoursSize2, int contourIdx, CvScalar color, int thickness, int lineType, Vec4i[] hierarchy, int hiearchyLength, int maxLevel, CvPoint offset);
public static extern ExceptionStatus core_FileNode_read_Vec4i(IntPtr node, out Vec4i returnValue);
public static extern void core_Mat_push_back_Vec4i(IntPtr self, Vec4i v);