void ClingyPath::Flatten (iMeshWrapper* thisMesh, float width) { RefreshWorkingPath (); // Flatten the terrain first. for (size_t i = 0 ; i < points.GetSize () ; i++) FitToTerrain (i, width, thisMesh); Dump (2); // Now fix the slope. for (size_t i = 0 ; i < points.GetSize () ; i++) FixSlope (i); size_t segIdx = 0; float maxRaiseY, maxLowerY; while (segIdx < points.GetSize ()-1) { CalcMinMaxDY (segIdx, width, thisMesh, maxRaiseY, maxLowerY); if (maxRaiseY > 0.0f || maxLowerY > 0.0f) { // The segment needs improving. Let's split it. SplitSegment (segIdx); FitToTerrain (segIdx+1, width, thisMesh); FixSlope (segIdx); FixSlope (segIdx+1); FixSlope (segIdx+2); } else { // This segment is ok. We can go to the next. segIdx++; } } }
static void WrapSegments(PVIEWERPARAMS pViewerParams, PVIEWERLINE pSegments, LONG lLimit) { PVIEWERLINE pCurrentSeg = pSegments; LONG lWidth=0; int i; char *pchTemp, *pchLastSpace; BOOL bInWord; BOOL bSplit; while (pCurrentSeg) /* alle Segmente */ { pchLastSpace=NULL; pchTemp = pCurrentSeg->pchLine; bSplit=FALSE; for (i=0; i < pCurrentSeg->ulLineLen && !bSplit; i++, pchTemp++) /* Alle Zeichen im Segment */ { if (*pchTemp == ' ' && bInWord) { pchLastSpace = pchTemp; bInWord = FALSE; } else bInWord = TRUE; if (pCurrentSeg->ulFlags & LINESEG_BOLD) lWidth += pViewerParams->lWidthsBold[*pchTemp]; else lWidth += pViewerParams->lWidths[*pchTemp]; if (lWidth > lLimit) { pCurrentSeg = SplitSegment(pCurrentSeg, pchTemp, pchLastSpace); lWidth=0; bSplit=TRUE; } } if (!bSplit) { if (pCurrentSeg->ulFlags & LINESEG_NEWLINE) lWidth=0; pCurrentSeg = pCurrentSeg->nextseg; } } return; }
void Flip_SL(Node * t1, Node * t2, Node * t3) { Node *t4, *a, *b, *c, *d; Segment *P1, *P2, *P3, *P4, *Q1, *Q2; Node *s1, *s2; int i, Temp; assert(t1->Pred == t2 || t1->Suc == t2); if (t3 == t2->Pred || t3 == t2->Suc) return; if (Groups == 1) { Flip(t1, t2, t3); return; } t4 = t2 == SUC(t1) ? PRED(t3) : SUC(t3); P1 = t1->Parent; P2 = t2->Parent; P3 = t3->Parent; P4 = t4->Parent; /* Split segments if needed */ if (P1 != P3 && P2 != P4) { if (P1 == P2) { SplitSegment(t1, t2); P1 = t1->Parent; P2 = t2->Parent; } if (P3 == P4 && P1 != P3 && P2 != P4) { SplitSegment(t3, t4); P3 = t3->Parent; P4 = t4->Parent; } } else if ((P1 == P3 && abs(t3->Rank - t1->Rank) > SPLIT_CUTOFF * GroupSize) || (P2 == P4 && abs(t4->Rank - t2->Rank) > SPLIT_CUTOFF * GroupSize)) { if (P1 == P2) { SplitSegment(t1, t2); P1 = t1->Parent; P2 = t2->Parent; P3 = t3->Parent; P4 = t4->Parent; } if (P3 == P4) { SplitSegment(t3, t4); P1 = t1->Parent; P2 = t2->Parent; P3 = t3->Parent; P4 = t4->Parent; } } /* Check if it is possible to flip locally within a segment */ b = 0; if (P1 == P3) { /* Either the t1 --> t3 path or the t2 --> t4 path lies within one segment */ if (t1->Rank < t3->Rank) { if (P1 == P2 && P1 == P4 && t2->Rank > t1->Rank) { a = t1; b = t2; c = t3; d = t4; } else { a = t2; b = t1; c = t4; d = t3; } } else { if (P1 == P2 && P1 == P4 && t2->Rank < t1->Rank) { a = t3; b = t4; c = t1; d = t2; } else { a = t4; b = t3; c = t2; d = t1; } } } else if (P2 == P4) { /* The t2 --> t4 path lies within one segment */ if (t4->Rank < t2->Rank) { a = t3; b = t4; c = t1; d = t2; } else { a = t1; b = t2; c = t3; d = t4; } } if (b) { int Cbc = C(b, c), Cda = C(d, a); /* Flip locally (b --> d) within a segment */ i = d->Rank; d->Suc = 0; s2 = b; while ((s1 = s2)) { s2 = s1->Suc; s1->Suc = s1->Pred; s1->Pred = s2; s1->Rank = i--; Temp = s1->SucCost; s1->SucCost = s1->PredCost; s1->PredCost = Temp; } d->Pred = a; b->Suc = c; d->PredCost = Cda; b->SucCost = Cbc; if (a->Suc == b) { a->Suc = d; a->SucCost = d->PredCost; } else { a->Pred = d; a->PredCost = d->PredCost; } if (c->Pred == d) { c->Pred = b; c->PredCost = b->SucCost; } else { c->Suc = b; c->SucCost = b->SucCost; } if (b->Parent->First == b) b->Parent->First = d; else if (d->Parent->First == d) d->Parent->First = b; if (b->Parent->Last == b) b->Parent->Last = d; else if (d->Parent->Last == d) d->Parent->Last = b; } else { int Ct2t3, Ct4t1; /* Reverse a sequence of segments */ if (P1->Suc != P2) { a = t1; t1 = t2; t2 = a; a = t3; t3 = t4; t4 = a; Q1 = P1; P1 = P2; P2 = Q1; Q1 = P3; P3 = P4; P4 = Q1; } /* Find the sequence with the smallest number of segments */ if ((i = P2->Rank - P3->Rank) < 0) i += Groups; if (2 * i > Groups) { a = t3; t3 = t2; t2 = a; a = t1; t1 = t4; t4 = a; Q1 = P3; P3 = P2; P2 = Q1; Q1 = P1; P1 = P4; P4 = Q1; } Ct2t3 = C(t2, t3); Ct4t1 = C(t4, t1); /* Reverse the sequence of segments (P3 --> P1). Mirrors the corresponding code in the Flip function */ i = P1->Rank; P1->Suc = 0; Q2 = P3; while ((Q1 = Q2)) { Q2 = Q1->Suc; Q1->Suc = Q1->Pred; Q1->Pred = Q2; Q1->Rank = i--; Q1->Reversed ^= 1; } P3->Suc = P2; P2->Pred = P3; P1->Pred = P4; P4->Suc = P1; if (t3->Suc == t4) { t3->Suc = t2; t3->SucCost = Ct2t3; } else { t3->Pred = t2; t3->PredCost = Ct2t3; } if (t2->Suc == t1) { t2->Suc = t3; t2->SucCost = Ct2t3; } else { t2->Pred = t3; t2->PredCost = Ct2t3; } if (t1->Pred == t2) { t1->Pred = t4; t1->PredCost = Ct4t1; } else { t1->Suc = t4; t1->SucCost = Ct4t1; } if (t4->Pred == t3) { t4->Pred = t1; t4->PredCost = Ct4t1; } else { t4->Suc = t1; t4->SucCost = Ct4t1; } } SwapStack[Swaps].t1 = t1; SwapStack[Swaps].t2 = t2; SwapStack[Swaps].t3 = t3; SwapStack[Swaps].t4 = t4; Swaps++; Hash ^= (Rand[t1->Id] * Rand[t2->Id]) ^ (Rand[t3->Id] * Rand[t4->Id]) ^ (Rand[t2->Id] * Rand[t3->Id]) ^ (Rand[t4->Id] * Rand[t1->Id]); }