Beispiel #1
0
            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);
            }
Beispiel #2
0
            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);
            }
Beispiel #3
0
            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);
            }
Beispiel #4
0
            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);
            }
Beispiel #5
0
                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);
                }
Beispiel #6
0
            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);
            }
Beispiel #7
0
            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);
            }
Beispiel #8
0
            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);
            }
Beispiel #9
0
            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);
            }
Beispiel #10
0
            //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);
            }
Beispiel #11
0
            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);
            }
Beispiel #12
0
            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);
            }
Beispiel #13
0
                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));
                }
Beispiel #14
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);
                }
Beispiel #15
0
            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());
                }
            }
        }