private static Point3d DrawAnchor2(Point3d anchor1, Polyline outline, P1Core core, List <Line> baseAxis, double hFactor) { //output Point3d anchor2 = new Point3d(); //base setting double baseHalfVSize = core.BaseLine.PointAt(0.5).DistanceTo(baseAxis[0].PointAt(0)); double baseHalfHSize = core.BaseLine.Length / 2; //set horizontal limit List <double> limitCandidates = new List <double>(); limitCandidates.Add(0); limitCandidates.Add(baseAxis[0].Length - CorridorDimension.TwoWayWidth - baseHalfHSize); double shortHAxisLength = PCXTools.PCXByEquation(core.BaseLine.PointAt(0.5), outline, -baseAxis[0].UnitTangent).Length; limitCandidates.Add(CorridorDimension.MinRoomWidth - shortHAxisLength); limitCandidates.Sort((x, y) => - x.CompareTo(y)); double limitUpper = limitCandidates[0]; double limitLower = limitCandidates[1]; double hLimit = limitUpper - limitLower; //set vertical limit //draw anchors Vector3d hAxis = baseAxis[0].UnitTangent; anchor2 = anchor1 + hAxis * (hLimit * hFactor + limitLower); return(anchor2); }
private static Point3d DrawAnchor4(Point3d anchor3, Polyline outline, List <Line> baseAxis, double vFactor) { Point3d anchor4 = new Point3d(); double vLimit = PCXTools.PCXByEquation(anchor3, outline, -baseAxis[1].UnitTangent).Length - CorridorDimension.OneWayWidth / 2; anchor4 = anchor3 - baseAxis[1].UnitTangent * vLimit * vFactor; return(anchor4); }
private static Point3d DrawAnchor3(Point3d anchor2, Polyline outline, List <Line> baseAxis, double vFactor, double subLength) { Point3d anchor3 = new Point3d(); Point3d anchorBase = baseAxis[0].PointAt(0); double vLimit = PCXTools.PCXByEquation(anchor2, outline, -baseAxis[1].UnitTangent).Length - subLength / 2; anchor2 = anchor2 - baseAxis[1].UnitTangent * (vLimit * vFactor); return(anchor3); }
private static Point3d DrawAnchor2(Point3d anchor1, Polyline outline, List <Line> mainAxis, double hFactor) { Point3d anchor2 = new Point3d(); Vector3d hAxis = mainAxis[0].UnitTangent; double hLimit = PCXTools.PCXByEquation(anchor1, outline, hAxis).Length - CorridorDimension.TwoWayWidth / 2; anchor2 = anchor1 + hAxis * hLimit * hFactor; return(anchor2); }
public static PartitionParam DrawOrtho(PartitionParam param) { Line orthoLine = PCXTools.PCXByEquation(param.OriginPost.Point, param.OutlineLabel.Pure, param.OriginPost.BaseLine.UnitNormal); List <RoomLine> orthoList = new List <RoomLine> { new RoomLine(orthoLine, LineType.Inner) }; Partition dividerCurrent = new Partition(orthoList, param.OriginPost); PartitionParam paramNext = new PartitionParam(param.PartitionPre, dividerCurrent, dividerCurrent.Origin, param.OutlineLabel); return(paramNext); }
private static Point3d DrawAnchor2(Point3d anchor1, P1Core core, List <Line> baseAxis) { Point3d anchor2 = new Point3d(); double coreSideLimit = PCXTools.PCXByEquation(baseAxis[0].PointAt(0), core.CoreLine, -baseAxis[1].UnitTangent).Length; double scaledCorridorWidth = CorridorDimension.OneWayWidth / 2; double vLimit = coreSideLimit + scaledCorridorWidth; anchor2 = anchor1 - baseAxis[1].UnitTangent * vLimit; return(anchor2); }
private static Point3d DrawAnchor3(Point3d anchor2, Polyline outline, List <Line> mainAxis, double lengthFactor) { Point3d anchor3 = new Point3d(); Point3d anchor3Center = new Point3d(); double anchorLineLength = (PCXTools.PCXByEquation(anchor2, outline, mainAxis[0].UnitTangent).Length - CorridorDimension.OneWayWidth / 2) * lengthFactor; anchor3Center = anchor2 + mainAxis[0].UnitTangent * anchorLineLength; anchor3 = anchor3Center; //임시 return(anchor3); }
private static List <Point3d> DrawAnchor2(List <Point3d> anchor1, Polyline outline, List <Line> mainAxis, List <double> hFactors) { List <Point3d> anchor2 = new List <Point3d>(); for (int i = 0; i < anchor1.Count; i++) { Vector3d tempAxis = mainAxis[0].UnitTangent * Math.Pow(-1, i); double hLimit = PCXTools.PCXByEquation(anchor1[i], outline, tempAxis).Length - CorridorDimension.TwoWayWidth / 2; anchor2.Add(anchor1[i] + tempAxis * hLimit * hFactors[i]); } return(anchor2); }
private static Point3d DrawAnchor3(Point3d anchor2, Polyline outline, List <Line> baseAxis, Line baseLine) { Point3d anchor3 = new Point3d(); double outlineSideLimit = PCXTools.PCXByEquation(anchor2, outline, -baseAxis[0].UnitTangent).Length - CorridorDimension.OneWayWidth / 2; double hLimit = baseLine.Length; if (outlineSideLimit < hLimit) { hLimit = outlineSideLimit; } anchor3 = anchor2 - baseAxis[0].UnitTangent * hLimit; return(anchor3); }
//drawing method private static Point3d DrawAnchor1(Polyline outline, P1Core core, List <Line> baseAxis, out double subLength) { Point3d anchor1 = new Point3d(); Point3d anchorBase = baseAxis[0].PointAt(0); double coreSideLength = PCXTools.PCXByEquation(anchorBase, core.CoreLine, -baseAxis[1].UnitTangent).Length; double landingSideLength = core.BaseLine.PointAt(0.5).DistanceTo(anchorBase); double subCorridorWidth = coreSideLength + landingSideLength; double halfHLength = core.BaseLine.Length / 2; Vector3d hAxis = baseAxis[0].UnitTangent; Vector3d vAxis = -baseAxis[1].UnitTangent; anchor1 = anchorBase + vAxis * (subCorridorWidth / 2 - landingSideLength) + hAxis * (halfHLength + CorridorDimension.TwoWayWidth / 2); subLength = subCorridorWidth; return(anchor1); }
private static Point3d DrawAnchor2(Point3d anchor1, P1Core core, Polyline outline, List <Line> mainAxis) { Point3d anchor2 = new Point3d(); Point3d anchor2Center = new Point3d(); double anchorLineLength = PCXTools.PCXByEquation(mainAxis[1].PointAt(0), core.CoreLine, mainAxis[1].UnitTangent).Length; if (anchorLineLength < mainAxis[1].Length) { anchor2Center = anchor1 + mainAxis[1].UnitTangent * (anchorLineLength - CorridorDimension.OneWayWidth / 2); } else { anchor2Center = anchor1 + mainAxis[1].UnitTangent * (mainAxis[1].Length - CorridorDimension.OneWayWidth / 2); } anchor2 = anchor2Center; //임시 return(anchor2); }
public static List <List <Line> > Make(Polyline outline, P1Core core) { //output List <Line> baseAxis = new List <Line>(); List <Line> subAxis = new List <Line>(); Point3d basePt = core.CenterPt; //set horizontalAxis, 횡축은 외곽선에서 더 먼 쪽을 선택 Line horizonReached1 = PCXTools.PCXByEquation(basePt, outline, core.BaseLine.UnitTangent); Line horizonReached2 = PCXTools.PCXByEquation(basePt, outline, -core.BaseLine.UnitTangent); if (horizonReached1.Length > horizonReached2.Length) { baseAxis.Add(horizonReached1); subAxis.Add(horizonReached2); } else { baseAxis.Add(horizonReached2); subAxis.Add(horizonReached1); } //set verticalAxis, 종축은 외곽선에서 더 가까운 쪽을 선택 //한쪽만 붙어있다면 붙어있는 쪽을 종축으로 선택 Line verticalReached1 = PCXTools.PCXByEquation(basePt, outline, core.UpstairDirec); Line verticalReached2 = PCXTools.PCXByEquation(basePt, outline, -core.UpstairDirec); Line verticalToCore1 = PCXTools.PCXByEquation(basePt, core.CoreLine, core.UpstairDirec); Line verticalToCore2 = PCXTools.PCXByEquation(basePt, core.CoreLine, -core.UpstairDirec); bool isLongerThanToCore1 = verticalReached1.Length > verticalToCore1.Length + 0.5; bool isLongerThanToCore2 = verticalReached2.Length > verticalToCore2.Length + 0.5; if (isLongerThanToCore1 == isLongerThanToCore2) { if (verticalReached1.Length < verticalReached2.Length) { baseAxis.Add(verticalReached1); subAxis.Add(verticalReached2); } else { baseAxis.Add(verticalReached2); subAxis.Add(verticalReached1); } } else { if (!isLongerThanToCore1) { baseAxis.Add(verticalReached1); subAxis.Add(verticalReached2); } else { baseAxis.Add(verticalReached2); subAxis.Add(verticalReached1); } } List <List <Line> > axisSet = new List <List <Line> >(); axisSet.Add(baseAxis); axisSet.Add(subAxis); return(axisSet); }
public static PartitionParam GetCorner(PartitionParam param, double targetArea) { //나중에 좀 더 일반화할 수 있을 듯 List <RoomLine> coreSeg = param.OutlineLabel.Core; int originIndex = coreSeg.FindIndex(i => i.PureLine == param.OriginPost.BasePureLine); int preIndex = originIndex - 1; Point3d origin = param.OriginPost.Point; Polyline outline = param.OutlineLabel.Pure; Line cornerLinePre = PCXTools.PCXByEquation(origin, outline, coreSeg[preIndex].UnitNormal); Line cornerLinePost = PCXTools.PCXByEquation(origin, outline, coreSeg[originIndex].UnitNormal); double outlineParamPre = outline.ClosestParameter(cornerLinePre.PointAt(1)); double outlineParamPost = outline.ClosestParameter(cornerLinePost.PointAt(1)); double paramPreFloor = Math.Floor(outlineParamPre); double paramPostCeiling = Math.Ceiling(outlineParamPost); //vertexSetting //dividerDrawer랑 같은 코드... List <Point3d> partitionVertex = new List <Point3d>(); partitionVertex.Add(outline.PointAt(outlineParamPost)); if (outlineParamPre < outlineParamPost) //인덱스 꼬였을 때 { if (outlineParamPost != paramPostCeiling) { partitionVertex.Add(outline.PointAt(paramPostCeiling)); } double paramLast = outline.Count - 1; for (double i = paramPostCeiling + 1; i < paramLast; i++) { partitionVertex.Add(outline.PointAt(i)); } for (double i = 0; i < paramPreFloor; i++) { partitionVertex.Add(outline.PointAt(i)); } if (outlineParamPre != paramPreFloor) { partitionVertex.Add(outline.PointAt(paramPreFloor)); } } else { double betweenIndexCounter = paramPreFloor - paramPostCeiling; if (betweenIndexCounter == 0) { if ((outlineParamPost != paramPostCeiling) && (outlineParamPre != paramPreFloor)) { partitionVertex.Add(outline.PointAt(paramPostCeiling)); } } else if (betweenIndexCounter > 0) { if (outlineParamPost != paramPostCeiling) { partitionVertex.Add(outline.PointAt(paramPostCeiling)); } for (double i = paramPostCeiling + 1; i < paramPreFloor; i++) { partitionVertex.Add(outline.PointAt(i)); } if (outlineParamPre != paramPreFloor) { partitionVertex.Add(outline.PointAt(paramPreFloor)); } } } partitionVertex.Add(outline.PointAt(outlineParamPre)); //decider //확장성 있게 만들 수 있나? int vertextCount = partitionVertex.Count; if (vertextCount == 2) { return(DrawAtNoFoldOutline(param, targetArea, partitionVertex)); } if (vertextCount == 3) { return(DrawAtOneFoldOutline(param, targetArea, partitionVertex)); } return(DrawAtMultiFoldOutline(param, targetArea, partitionVertex)); }
//중복코드 나중에 지워보자.. 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); }
public static ICorridorP1Sub GetPattern(Polyline outline, P1Core core, List <double> areaSet) { //outline 과 landing 사이 거리,방향으로 가능한 복도타입 판정 double stickTolerance = 0.5; List <List <Line> > axisSet = AxisMaker.Make(outline, core); List <Line> mainAxis = axisSet[0]; List <Line> subAxis = axisSet[1]; //set distance Point3d basePt = core.CenterPt; double toOutlineDistH = subAxis[0].Length; double toCoreDistH = PCXTools.PCXByEquation(basePt, core.CoreLine, subAxis[0].UnitTangent).Length; double toOutlineDistV = mainAxis[1].Length; double toCoreDistV = PCXTools.PCXByEquation(basePt, core.CoreLine, mainAxis[1].UnitTangent).Length; double toLandingDistV = basePt.DistanceTo(core.BaseLine.PointAt(0.5)); //set decider bool IsHorizontalOff = toOutlineDistH > toCoreDistH + stickTolerance; bool IsHEnoughOff = toOutlineDistH > toCoreDistH + CorridorDimension.TwoWayWidth + stickTolerance; bool IsVerticalOff = toOutlineDistV > toCoreDistV + stickTolerance; bool IsVEnoughOff = toOutlineDistV > CorridorDimension.MinRoomWidth + toLandingDistV + stickTolerance; bool IsHLognerThanV = mainAxis[0].Length > subAxis[1].Length; //seive if (outline.GetArea() == core.CoreLine.GetArea()) { return(new CorridorP1S0()); } if (areaSet.Count <= 1) { return(new CorridorP1S0()); } //compare if (IsHorizontalOff) { if (IsVerticalOff) { if (!IsVEnoughOff) { return(new CorridorP1S0()); } if (IsHEnoughOff) { return(new CorridorP1S3()); } return(new CorridorP1S4()); } if (IsHEnoughOff) { return(new CorridorP1S3()); } return(new CorridorP1S4()); } if (IsVerticalOff) { if (IsHLognerThanV) { if (!IsVEnoughOff) { return(new CorridorP1S0()); } return(new CorridorP1S4()); } return(new CorridorP1S2()); } else { if (IsHLognerThanV) { CorridorP1S1 corrP1 = new CorridorP1S1(); if (mainAxis[0].Length < (mainAxis[1].Length + CorridorDimension.OneWayWidth / 2) * 2.0) { if (areaSet.Count <= 3) { corrP1.Param = new List <double> { 0.0 } } ; if (areaSet.Count > 3) { CorridorP1S2 corrP2 = new CorridorP1S2(); corrP2.Param = new List <double> { 0.0 }; return(corrP2); } } return(corrP1); } if (subAxis[1].Length < (mainAxis[1].Length + CorridorDimension.OneWayWidth / 2) * 2.0) { CorridorP1S2 corrP2 = new CorridorP1S2(); corrP2.Param = new List <double> { 0.0 }; return(corrP2); } return(new CorridorP1S2()); } } }