private static PartitionParam DrawAtMultiFoldOutline(PartitionParam param, double targetArea, List <Point3d> outlineVertex) { Line mainLine = GetMainLine(param, outlineVertex); List <Point3d> canMakePerpVertex = new List <Point3d>(); Vector3d mainAlign = mainLine.UnitTangent; Vector3d mainPerp = VectorTools.RotateVectorXY(mainAlign, Math.PI / 2); Point3d origin = param.OriginPost.Point; bool isMainAlignSameAsPostNormal = mainAlign.IsParallelTo(param.OriginPost.BaseLine.UnitNormal, 0.005) == 1; if (!isMainAlignSameAsPostNormal) { int originIndex = param.OutlineLabel.Core.FindIndex (i => i.PureLine == param.OriginPost.BasePureLine); param.OriginPost = new PartitionOrigin(origin, param.OutlineLabel.Core[originIndex - 1]); mainPerp = VectorTools.RotateVectorXY(mainAlign, -Math.PI / 2); } int lastVertexIndex = outlineVertex.Count - 1; for (int i = 1; i < lastVertexIndex; i++) { Vector3d toPreVector = new Vector3d(outlineVertex[i - 1] - outlineVertex[i]); Vector3d toPostVector = new Vector3d(outlineVertex[i + 1] - outlineVertex[i]); Vector3d toMainVector = -mainPerp; if (IsBetweenVector(toPreVector, toPostVector, toMainVector)) { canMakePerpVertex.Add(outlineVertex[i]); } } //SeivePerpVertex List <Point3d> finalVertex = new List <Point3d>(); foreach (Point3d i in outlineVertex) { Line toBaseLine = PCXTools.PCXByEquationStrict(i, CurveTools.ToPolyline(mainLine.ToNurbsCurve()), -mainPerp); Line toOutline = PCXTools.PCXByEquationStrict(toBaseLine.PointAt(1), param.OutlineLabel.Pure, mainPerp); if (toOutline.PointAt(1).DistanceTo(i) < 0.5) { finalVertex.Add(i); } } //DrawAtEachVertex List <PartitionParam> outputCandidate = new List <PartitionParam>(); foreach (Point3d i in finalVertex) { Line toBaseLine = PCXTools.PCXByEquationStrict(i, CurveTools.ToPolyline(mainLine.ToNurbsCurve()), -mainPerp); Point3d tempAnchor = toBaseLine.PointAt(1); Line toOutline = PCXTools.PCXByEquationStrict(tempAnchor, param.OutlineLabel.Pure, mainPerp); if (toOutline.PointAt(1).DistanceTo(i) > 0.5) { continue; } List <RoomLine> tempPartition = new List <RoomLine>(); tempPartition.Add(new RoomLine(new Line(origin, tempAnchor), LineType.Inner)); tempPartition.Add(new RoomLine(new Line(tempAnchor, i), LineType.Inner)); PartitionParam tempParam = new PartitionParam(param); tempParam.PartitionPost = new Partition(tempPartition, param.OriginPost); outputCandidate.Add(tempParam); } outputCandidate.Add(PartitionMaker.DrawOrtho(param)); //TestCandidate //나중에 수정.. 지금은 면적일치정도로만.. Plane cornerPlane = new Plane(origin, mainAlign, mainPerp); CornerComparer comparer = new CornerComparer(); List <PartitionParam> seived = comparer.Seive(outputCandidate, targetArea, cornerPlane); return(seived[0]); }
//중복코드 나중에 지워보자.. private static PartitionParam DrawAtNoFoldOutline(PartitionParam param, double targetArea, List <Point3d> outlineVertex) { Line mainLine = GetMainLine(param, outlineVertex); Vector3d mainAlign = mainLine.UnitTangent; Vector3d mainPerp = VectorTools.RotateVectorXY(mainAlign, Math.PI / 2); Point3d origin = param.OriginPost.Point; double dotProduct = Vector3d.Multiply(mainAlign, param.OriginPost.BaseLine.UnitNormal); double dotTolerance = 0.005; bool isMainDirecPreDiv = false; if (Math.Abs(dotProduct) < dotTolerance) { int originIndex = param.OutlineLabel.Core.FindIndex (i => i.PureLine == param.OriginPost.BasePureLine); param.OriginPost = new PartitionOrigin(origin, param.OutlineLabel.Core[originIndex - 1]); mainPerp = VectorTools.RotateVectorXY(mainAlign, -Math.PI / 2); isMainDirecPreDiv = true; } int iterNum = 10; int breaker = 0; double lowerBound = 0; double upperBound = mainLine.Length; Polyline polyOutput = new Polyline(); while (lowerBound < upperBound) { if (breaker > iterNum) { break; } double tempStatus = (upperBound - lowerBound) / 2 + lowerBound; Point3d tempAnchor = origin + mainAlign * tempStatus; if (isMainDirecPreDiv) { tempAnchor = origin + mainAlign * (mainLine.Length - tempStatus); } List <RoomLine> cornerPartitions = new List <RoomLine>(); cornerPartitions.Add(new RoomLine(new Line(origin, tempAnchor), LineType.Inner)); Line anchorToOutline = PCXTools.PCXByEquation(tempAnchor, param.OutlineLabel.Pure, mainPerp); cornerPartitions.Add(new RoomLine(anchorToOutline, LineType.Inner)); Partition tempPartition = new Partition(cornerPartitions, param.OriginPost); param.PartitionPost = tempPartition; double tempArea = PolylineTools.GetArea(param.Outline); if (targetArea > tempArea) { lowerBound = tempStatus; } else if (targetArea < tempArea) { upperBound = tempStatus; } else { lowerBound = tempArea; upperBound = tempArea; } breaker++; } return(param); }