// TODO: make it FillCircle () public void CutCircle(Vector2 center, float radius, IEnumerable <Collider2D> affectedColliders = null) { if (affectedColliders == null) { affectedColliders = Physics2D.OverlapCircleAll(center, radius); } var affectedSpriteRenderers = new HashSet <SpriteRenderer> (); foreach (var affectedCollider in affectedColliders) { SpriteRenderer spriteRenderer; if (colliderSpriteMap.TryGetValue(affectedCollider, out spriteRenderer)) { affectedSpriteRenderers.Add(spriteRenderer); } } foreach (var spriteRenderer in affectedSpriteRenderers) { if (RasterHelper.CutCircle(spriteRenderer, center, radius)) { UpdateSpriteColliders(spriteRenderer); } } }
public static Vector2 [][] Trace(Sprite sprite, Rect pixelRect) { return(Trace( sprite.texture, pixelRect, RasterHelper.GetPivot(sprite), RasterHelper.GetPixelsPerUnit(sprite) )); }
public static Vector2 [][] Trace(Sprite sprite) { var texture = sprite.texture; var pixelRect = new Rect(0, 0, texture.width, texture.height); return(Trace( sprite.texture, pixelRect, RasterHelper.GetPivot(sprite), RasterHelper.GetPixelsPerUnit(sprite) )); }
public static void CloneTextureAndSprite(SpriteRenderer spriteRenderer) { var sprite = spriteRenderer.sprite; var texClone = Object.Instantiate(sprite.texture) as Texture2D; spriteRenderer.sprite = Sprite.Create( texClone, sprite.rect, RasterHelper.GetPivot(sprite), RasterHelper.GetPixelsPerUnit(sprite) ); spriteRenderer.sprite.name = sprite.name + "(Clone)"; }
private void PerformTrace() { var spriteRenderer = GetComponent <SpriteRenderer> (); var sprite = spriteRenderer.sprite; var ms = new MarchingSquares( sprite.texture, alphaThreshold: AlphaThreshold, clockWise: ClockWise, mipLevel: MipLevel ); polyPath = ms.TraceContours(); float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite); float scale = (1 << MipLevel) / pixelsPerUnit; var pivot = RasterHelper.GetPivot(sprite); var offset = -Vector2.Scale(sprite.bounds.size, pivot); polyPath.Scale(scale); polyPath.Translate(offset); int pointCountBeforeOpt = polyPath.TotalPointCount; float worldScale = Common.WorldScale(spriteRenderer.transform); if (ReduceByMinDistance) { polyPath.ReduceByMinDistance(MinDistance, MinVertexCount); } if (ReduceByMinTriangleArea) { float globalScaleSq = worldScale * worldScale; polyPath.ReduceByMinTriangleArea(MinTriangleArea / globalScaleSq, MinVertexCount); } if (ReduceCodirected) { polyPath.ReduceCodirected(MinAngle * Mathf.Deg2Rad, MinVertexCount); } int pointCountAfterOpt = polyPath.TotalPointCount; print(string.Format( "Reduction: {0}/{1} ({2:P})", pointCountAfterOpt, pointCountBeforeOpt, 1.0f - ( float )pointCountAfterOpt / pointCountBeforeOpt )); }
// TODO: make it FillCircle () public static bool CutCircle(SpriteRenderer spriteRenderer, Vector2 center, float radius) { var tf = spriteRenderer.transform; center = tf.InverseTransformPoint(center); var localScaleVector = tf.InverseTransformPoint(tf.position + Vector3.right); var worldToLocalScale = localScaleVector.magnitude; radius *= worldToLocalScale; var sprite = spriteRenderer.sprite; int pixelX, pixelY; RasterHelper.SpriteCoordsToPixelCoords(sprite, center, out pixelX, out pixelY); float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite); int pixelRadius = Mathf.RoundToInt(radius * pixelsPerUnit); return(RasterHelper.CutCircle(sprite.texture, pixelX, pixelY, pixelRadius)); }
private PolygonPath BuildPolyPath(SpriteRenderer spriteRenderer) { var sprite = spriteRenderer.sprite; float buildPathStartTime = Time.realtimeSinceStartup; float msStartTime = Time.realtimeSinceStartup; var ms = new MarchingSquares( sprite.texture, alphaThreshold: AlphaThreshold, clockWise: ClockWise, mipLevel: MipLevel ); float msTimeElapsed = Time.realtimeSinceStartup - msStartTime; float traceStartTime = Time.realtimeSinceStartup; var polyPath = ms.TraceContours(); float traceTimeElapsed = Time.realtimeSinceStartup - traceStartTime; float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(sprite); float scale = (1 << MipLevel) / pixelsPerUnit; var pivot = RasterHelper.GetPivot(sprite); var offset = -Vector2.Scale(sprite.bounds.size, pivot); float transformStartTime = Time.realtimeSinceStartup; polyPath.Scale(scale); polyPath.Translate(offset); float transformTimeElapsed = Time.realtimeSinceStartup - transformStartTime; #if MUTABLE_COLLIDER_STATS float buildPathTimeElapsed = Time.realtimeSinceStartup - buildPathStartTime; print(string.Format( "Build path timing -- Trace: {0}, Transform: {1}, Get pixels: {2}, Total: {3}", traceTimeElapsed, transformTimeElapsed, msTimeElapsed, buildPathTimeElapsed )); #endif return(polyPath); }
void Start() { var spriteRenderer = GetComponent <SpriteRenderer> (); spriteRenderer.enabled = false; var initialPolyCollider = GetComponent <PolygonCollider2D> (); if (initialPolyCollider != null) { Destroy(initialPolyCollider); } // TODO: i don't remember why we clone texture here. Is this really needed? if (CloneTexture) { RasterHelper.CloneTextureAndSprite(spriteRenderer); } var initialSprite = spriteRenderer.sprite; spriteRenderer.sprite = null; // Prevent newly added polygon colliders from autotrace. var initialTexture = initialSprite.texture; float pixelsPerUnit = RasterHelper.GetPixelsPerUnit(initialSprite); /* TODO: unite small cells on the border with those which are inside. * UPD: no, don't unite. Make border cell and adjacent cell even sized, * thus guarantees that size of any cell is smaller than CellSize. */ for (int y = 0; y < initialTexture.height; y += CellSize) { int cellHeight = Mathf.Min(initialTexture.height - y, CellSize); for (int x = 0; x < initialTexture.width; x += CellSize) { int cellWidth = Mathf.Min(initialTexture.width - x, CellSize); var pixels = initialTexture.GetPixels(x, y, cellWidth, cellHeight); var cellTexture = new Texture2D(cellWidth, cellHeight); cellTexture.name = string.Format( "{0} [y: {1}, x: {2}]", initialTexture.name, y, x ); cellTexture.filterMode = FilterMode.Trilinear; cellTexture.wrapMode = TextureWrapMode.Clamp; cellTexture.SetPixels(pixels); cellTexture.Apply(); var pixelRect = new Rect(x, y, cellWidth, cellHeight); var cellPivot = RasterHelper.CalculateRelativePivot(initialSprite, pixelRect); var cellSprite = Sprite.Create( cellTexture, new Rect(0, 0, cellWidth, cellHeight), cellPivot, pixelsPerUnit ); cellSprite.name = string.Format( "{0} [y: {1}, x: {2}]", initialSprite.name, y, x ); var cellGameObject = new GameObject( string.Format( "{0} [y: {1}, x: {2}]", name, y, x ) ); var cellSpriteRenderer = cellGameObject.AddComponent <SpriteRenderer> (); cellSpriteRenderer.sprite = cellSprite; cellSpriteRenderer.sortingLayerID = spriteRenderer.sortingLayerID; cellSpriteRenderer.sortingOrder = spriteRenderer.sortingOrder; var cellTf = cellGameObject.transform; cellTf.parent = this.transform; cellTf.localPosition = Vector3.zero; cellTf.localRotation = Quaternion.identity; cellTf.localScale = Vector3.one; if (UsePolyCollider) { var cellPolyCollider = gameObject.AddComponent <PolygonCollider2D> (); cellPolyCollider.pathCount = 0; colliderSpriteMap [cellPolyCollider] = cellSpriteRenderer; } UpdateSpriteColliders(cellSpriteRenderer); } } spriteRenderer.sprite = initialSprite; }
/// <summary> /// 道路风险计算 /// </summary> /// <param name="workPath">存储路径</param> /// <param name="roadEvalPath">道路评价结果 </param> /// <param name="roadRainsShpPath">加了雨量字段的道路缓冲区</param> /// <returns></returns> public bool RoadRaskCaulte(string roadEvalName, string roadRainsName, string saveWorkspace) { //读取 道路评价结果栅格数据的信息 RasterHelper rh = new RasterHelper(); //IRasterWorkspace rasterWorkspace = new RasterLayer(); IWorkspaceFactory rWorkspaceFactory = new RasterWorkspaceFactory(); IWorkspace SWorkspace = rWorkspaceFactory.OpenFromFile(saveWorkspace, 0); IRasterWorkspace rasterWorkspace = SWorkspace as IRasterWorkspace; IRasterDataset rasterDt = rasterWorkspace.OpenRasterDataset(roadEvalName); // var t = rh.GetRasterProps(rasterDt); IRasterLayer rasterLayer = new RasterLayer(); rasterLayer.CreateFromFilePath(saveWorkspace + "\\" + roadEvalName); IRaster pRaster = rasterLayer.Raster; IRasterProps rasterProps = (IRasterProps)pRaster;;//存储了栅格信息 //初始化GP工具 Geoprocessor gp = new Geoprocessor(); gp.OverwriteOutput = true; //string path = @"D:\GISTest"; //gp.SetEnvironmentValue("workspace", path); //道路缓冲区 根据雨量转栅格 FeatureToRaster featureToRaster = new FeatureToRaster(); featureToRaster.cell_size = rasterProps.MeanCellSize().X;//这里可以提前规定一个值,而不是每次去读取 featureToRaster.in_features = OpenFeatureClass(saveWorkspace + "\\" + roadRainsName); featureToRaster.out_raster = saveWorkspace + "\\roadGrid"; featureToRaster.field = "RAINS";//这个字段需要矢量图层中加上 try { gp.Execute(featureToRaster, null); } catch (Exception ex) { Console.WriteLine("矢量转栅格失败!"); return(false); } //栅格计算器 计算风险级数 IMapAlgebraOp mapAlgebra = new RasterMapAlgebraOpClass(); IRasterDataset roadEvalRaster = OpenRasterDataSet(rasterWorkspace, roadEvalName); IRasterDataset roadGridRaster = OpenRasterDataSet(rasterWorkspace, saveWorkspace + @"\roadGrid"); IGeoDataset geo1 = roadEvalRaster as IGeoDataset; IGeoDataset geo2 = roadGridRaster as IGeoDataset; mapAlgebra.BindRaster(geo1, "EvalRaster"); mapAlgebra.BindRaster(geo2, "RoadRains"); IGeoDataset raskDataset = mapAlgebra.Execute("[EvalRaster] * [RoadRains] / 25");//然后存储 表达式必须间隔开 ISaveAs saveAs = raskDataset as ISaveAs; saveAs.SaveAs("roadPre", SWorkspace, ""); //加入图层 IRasterLayer rasterLayer2 = new RasterLayer(); rasterLayer2.CreateFromFilePath(saveWorkspace + "\\" + "roadPre"); MainFrom.m_mapControl.AddLayer(rasterLayer2, 0); //MainFrom.m_mapControl.Refresh(esriViewDrawPhase.esriViewGeography, null, null); MainFrom.m_pTocControl.Update(); //将生成的风险栅格重分类 //<0.2 一级:可能性小 //0.2-0.4 二级:可 //能性较小 //0.4-0.6 三级:可能性较大 //0.6-0.8 四级:可能性大 //>0.8 五级:可能性很大 // 输入:raskDataset // 输出:geoDataset_result IReclassOp pReclassOp = new RasterReclassOpClass(); INumberRemap pNumRemap = new NumberRemapClass(); IDictionary <int, RoadRange> roadRanges = this.roadRiskConfig.GetRoadRiskLevelFromConfig(); foreach (var v in roadRanges) { pNumRemap.MapRange(v.Value.MinValue, v.Value.MaxValue, v.Key); } /* * pNumRemap.MapRange(0, 0.2, 1); * pNumRemap.MapRange(0.2, 0.4, 2); * pNumRemap.MapRange(0.4, 0.6, 3); * pNumRemap.MapRange(0.6, 0.8, 4); * pNumRemap.MapRange(0.8,1000,5); */ //pNumRemap.MapRangeToNoData(-1000,0); //pNumRemap.MapRangeToNoData(1000, 20000); IRemap pRemap = pNumRemap as IRemap; // 重分类 // geoDataset为上一步得到的栅格 // IGeoDataset geoDataset_result = pReclassOp.ReclassByRemap(raskDataset, pRemap, true);//还没有测试成功 // RasterCalculator rasterCalculator = new RasterCalculator("[EvalRaster]*[RoadRains]/25", saveWorkspace + @"\RainEval.tif"); try { // gp.Execute(rasterCalculator, null); } catch (Exception ex) { Debug.Print(ex.Message); for (int i = 0; i < gp.MessageCount; i++) { Debug.Print(gp.GetMessage(i)); } Console.WriteLine("栅格计算失败!"); return(false); } return(true); }