diff --git a/algorithms/Ahmed/LICENSE-2.0.txt b/algorithms/Ahmed/LICENSE-2.0.txt new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/algorithms/Ahmed/LICENSE-2.0.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/algorithms/Ahmed/NOTICE.txt b/algorithms/Ahmed/NOTICE.txt new file mode 100644 index 0000000..e795d96 --- /dev/null +++ b/algorithms/Ahmed/NOTICE.txt @@ -0,0 +1,26 @@ + +Copyright 2013 Mahmuda Ahmed and Carola Wenk + +This software was developed at the University of Texas at San Antonio +in collaboration with Tulane University. + +The updates of version 2.0 were done during Mahmuda Ahmed's internship with Google. + +This material is based upon work supported by the National Science +Foundation under grants NSF CCF-0643597 and NSF CCF-1301911 +(previously NSF CCF-1216602). Any opinions, findings, and conclusions +or recommendations expressed in this material are those of the +author(s) and do not necessarily reflect the views of the National +Science Foundation. + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +Mahmuda Ahmed and Carola Wenk, "Constructing Street Networks from GPS +Trajectories", European Symposium on Algorithms (ESA): 60-71, +Ljubljana, Slovenia, 2012 + + +The original software is available from + http://www.mapconstruction.org/ + diff --git a/algorithms/Ahmed/README.txt b/algorithms/Ahmed/README.txt new file mode 100644 index 0000000..c6eab61 --- /dev/null +++ b/algorithms/Ahmed/README.txt @@ -0,0 +1,19 @@ +Input file format +================== +when HAS_ALTITUDE is true "x y z timestamp" otherwise "x y timestamp" + +Output file format +=================== +vertex file: "vertexid x y z" +edge file: "edgeid vertexid1 vertexid2" + +To compile and run +==================== +(1) Option 1: see commands in script_to_run.sh +(2) Option 2: Importing MapConstruction as a project in Eclipse and run from there. + +Questions +========== +Please email mahmudaahmed@gmail.com or cwenk@tulane.edu + + diff --git a/algorithms/Ahmed/script_to_run.sh b/algorithms/Ahmed/script_to_run.sh new file mode 100644 index 0000000..2ea1215 --- /dev/null +++ b/algorithms/Ahmed/script_to_run.sh @@ -0,0 +1,13 @@ +#To Compile: +CODE_PATH="MapConstruction/" #path to the MapConstruction folder. +cd $CODE_PATH +javac -d bin/ src/mapconstruction2/*.java + +#To Run: +INPUT_PATH="" #path to the folder that constains all input tracks +OUTPUT_PATH="" #path to the folder where output will be written +EPS=150.0 #epsilon in meters +HAS_ALTITUDE=false #if input file has altitude information +ALT_EPS=4.0 #minimum altitude difference in meters between two streets + +java -cp bin/ mapconstruction2.MapConstruction $INPUT_PATH $OUTPUT_PATH $EPS $HAS_ALTITUDE $ALT_EPS diff --git a/algorithms/Ahmed/src/mapconstruction2/Edge.java b/algorithms/Ahmed/src/mapconstruction2/Edge.java new file mode 100644 index 0000000..208dfd0 --- /dev/null +++ b/algorithms/Ahmed/src/mapconstruction2/Edge.java @@ -0,0 +1,226 @@ +package mapconstruction2; + +/** + * Frechet-based map construction 2.0 Copyright 2013 Mahmuda Ahmed and Carola Wenk + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * ------------------------------------------------------------------------ + * + * This software is based on the following article. Please cite this article when using this code + * as part of a research publication: + * + * Mahmuda Ahmed and Carola Wenk, "Constructing Street Networks from GPS Trajectories", European + * Symposium on Algorithms (ESA): 60-71, Ljubljana, Slovenia, 2012 + * + * ------------------------------------------------------------------------ + * + * Author: Mahmuda Ahmed Filename: Edge.java + * + */ + + +import java.util.ArrayList; +import java.util.List; + + +/** + * An object that represents an edge from vertex1 to vertex2. + */ + +class Edge implements Comparable { + + private Vertex vertex1; // first endpoint of edge + private Vertex vertex2; // second endpoint of edge + private double curveStart; // contains start point of white interval on curve + private double curveEnd; // contains end point of white interval on curve + private double edgeStart; // contains corresponding points on that edge + private double edgeEnd; // contains corresponding points on that edge + private Line line; // line from vertex v1 to v2 + /** + * done is marked as true when an edge is done being compared with all segments of a curve. + */ + private boolean done; + /** + * Contains start and end index of curves for white intervals corresponding to the edge. + */ + private int curveStartIndex; + private int curveEndIndex; + + /** + * Contains a sorted list (in descending order) of positions indicating where to split this edge. + */ + private List edgeSplitPositions; + + /** + * For each split position the corresponding new vertex is saved in this list. + */ + private List edgeSplitVertices; + + // private static final FormattingLogger logger = FormattingLogger.getLogger(Edge.class); + + Edge(Vertex v1, Vertex v2) { + this.vertex1 = v1; + this.vertex2 = v2; + edgeSplitPositions = new ArrayList(); + edgeSplitVertices = new ArrayList(); + this.reset(); + } + + void reset() { + this.curveStart = Double.MAX_VALUE; + this.curveEnd = -1.0; + this.edgeStart = Double.MAX_VALUE; + this.edgeEnd = -1.0; + this.line = new Line(vertex1, vertex2); + this.done = false; + } + + void set(Edge edge) { + this.curveStart = edge.curveStart; + this.curveEnd = edge.curveEnd; + this.edgeStart = edge.edgeStart; + this.edgeEnd = edge.edgeEnd; + this.line = new Line(vertex1, vertex2); + this.done = edge.done; + } + + public Vertex getVertex1() { + return this.vertex1; + } + + public Vertex getVertex2() { + return this.vertex2; + } + + public Line getLine() { + return this.line; + } + + public boolean getDone() { + return this.done; + } + + public void setDone(boolean done) { + this.done = done; + } + + public double getCurveStart() { + return this.curveStart; + } + + public void setCurveStart(double cstart) { + this.curveStart = cstart; + } + + public double getCurveEnd() { + return this.curveEnd; + } + + public void setCurveEnd(double cend) { + this.curveEnd = cend; + } + + public double getEdgeStart() { + return this.edgeStart; + } + + public void setEdgeStart(double vstart) { + this.edgeStart = vstart; + } + + public double getEdgeEnd() { + return this.edgeEnd; + } + + public void setEdgeEnd(double vend) { + this.edgeEnd = vend; + } + + public int getCurveStartIndex() { + return this.curveStartIndex; + } + + public void setCurveStartIndex(int startIndex) { + if (startIndex >= 0) { + this.curveStartIndex = startIndex; + } else { + // logger.log(Level.SEVERE, "Invalid assignment of Edge.startIndex"); + } + } + + public int getCurveEndIndex() { + return this.curveEndIndex; + } + + public void setCurveEndIndex(int endIndex) { + this.curveEndIndex = endIndex; + } + + public List getEdgeSplitVertices() { + return this.edgeSplitVertices; + } + + public List getEdgeSplitPositions() { + return this.edgeSplitPositions; + } + + /** + * Inserts a new split position if the list doesn't have it, otherwise return. + * + * @param position indicate the new split position + * @param vertex indicates the vertex which should be inserted in this edge. + * + */ + + public void addSplit(double position, int vertex) { + int i = 0; + //logger.log(Level.FINEST, "Inside updateSplits"); + for (i = 0; i < this.edgeSplitPositions.size(); i++) { + if (this.edgeSplitPositions.get(i).doubleValue() == position) { + return; + } else if (this.edgeSplitPositions.get(i).doubleValue() > position) { + this.edgeSplitPositions.add(i, position); + this.edgeSplitVertices.add(i, vertex); + return; + } + } + this.edgeSplitPositions.add(position); + this.edgeSplitVertices.add(vertex); + } + + @Override + public String toString() { + return vertex1.toString() + vertex2.toString(); + } + + + /** + * Orders edges based on first their curveStart and then curveEnd. + */ + @Override + public int compareTo(Edge edge) { + + if (this.getCurveStart() < edge.getCurveStart()) { + return -1; + } else if (this.getCurveStart() > edge.getCurveStart()) { + return 1; + } else if (this.getCurveEnd() < edge.getCurveEnd()) { + return -1; + } else if (this.getCurveEnd() > edge.getCurveEnd()) { + return 1; + } else { + return 0; + } + } + + +} diff --git a/algorithms/Ahmed/src/mapconstruction2/Line.java b/algorithms/Ahmed/src/mapconstruction2/Line.java new file mode 100644 index 0000000..efe448e --- /dev/null +++ b/algorithms/Ahmed/src/mapconstruction2/Line.java @@ -0,0 +1,763 @@ +package mapconstruction2; + +/** + * Frechet-based map construction 2.0 Copyright 2013 Mahmuda Ahmed and Carola Wenk + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * ------------------------------------------------------------------------ + * + * This software is based on the following article. Please cite this article when using this code + * as part of a research publication: + * + * Mahmuda Ahmed and Carola Wenk, "Constructing Street Networks from GPS Trajectories", European + * Symposium on Algorithms (ESA): 60-71, Ljubljana, Slovenia, 2012 + * + * ------------------------------------------------------------------------ + * + * Author: Mahmuda Ahmed Filename: Line.java + * + */ + + + +/** + * An object that represents a line segment between vertex p1 and p2. + */ +public class Line { + + private Vertex p1; // first endpoint + private Vertex p2; // second endpoint + private double xdiff; // difference between x-coordinates of p1 and p2 + private double ydiff; // difference between y-coordinates of p1 and p2 + private double zdiff; // difference between z-coordinates of p1 and p2 + private double c; // y-intersect of line equation + private double m; // slope of line + private double theta; // smallest angle between x-axis and this Line object + // private static final FormattingLogger logger = FormattingLogger.getLogger(Line.class); + + /** + * Constructor for a Line object. + * + * @param p1 first endpoint + * + * @param p2 second endpoint + */ + public Line(Vertex p1, Vertex p2) { + this.p1 = p1; + this.p2 = p2; + + this.xdiff = p2.getX() - p1.getX(); + this.ydiff = p2.getY() - p1.getY(); + this.zdiff = p2.getZ() - p1.getZ(); + + /* + * y = mx + c this equation was used unless this line is parallel to y axis. + * + * y1 = mx1 + c y2 = mx2 + c + * + * c = ((y1+y2)-m(x1+x2))/2 m = (y2-y1)/(x2-x1) + */ + + if (this.xdiff != 0.0) { + this.m = this.ydiff / this.xdiff; + + //R2Vector vector1 = new R2Vector(p1.getX(), p1.getY()); + //R2Vector vector2 = new R2Vector(p2.getX(), p2.getY()); + Vertex vector = new Vertex(p2.getX()-p1.getX(),p2.getY()-p1.getY(),0); + double angle1 = Vertex.dotProd(vector, new Vertex(1.0, 0.0,0.0)) + / vector.norm(); + double cosAngle1 = Math.acos(angle1); + if (this.ydiff >= 0) { + this.theta = Math.toDegrees(cosAngle1); + } else { + this.theta = -1 * Math.toDegrees(cosAngle1); + } + + this.c = ((p1.getY() + p2.getY()) - this.m * (p1.getX() + p2.getX())) / 2.0; + + } else if (this.ydiff > 0.0) { + this.theta = Math.toDegrees(Math.PI / 2.0); + } else { + this.theta = -Math.toDegrees(Math.PI / 2.0); + } + } + + public Vertex getP1() { + return this.p1; + } + + public Vertex getP2() { + return this.p2; + } + + public double getXdiff() { + return this.xdiff; + } + + public double getYdiff() { + return this.ydiff; + } + + public double getZdiff() { + return this.zdiff; + } + + public double getM() { + return this.m; + } + + public double getC() { + return this.c; + } + + public double getTheta() { + return this.theta; + } + + public void setM(double m) { + this.m = m; + } + + public void setC(double c) { + this.c = c; + } + + public void setTheta(double theta) { + this.theta = theta; + } + + @Override + public String toString() { + + return String.format("[ %f %f %f; %f %f %f]", + this.p1.getX(), + this.p1.getY(), + this.p1.getZ(), + this.p2.getX(), + this.p2.getY(), + this.p2.getZ()); + + } + + /** + * Compute average altitude of points p1 and p2 + */ + public double avgAltitude() { + return (this.p1.getZ() + this.p2.getZ()) / 2.0; + } + + /** + * Compute intersection of eps-disc around p and line + * + * @param p the center of the disc + * + * @param eps the radius of the disc + * + * @return a double[2] containing two intersection points or null when they don't intersect. + */ + + public double[] pIntersection(Vertex p, double eps, boolean precisionCompromise) { + + /* + * Line 1: x1+(x2-x1)*t = x; x1+xdiff*t = x y1+(y2-y1)*t = y; y1+ydiff*t = y + * + * Equation of disc around vertex p: (x-a)^2+(y-b)^2=eps^2 + * (x1+xdiff*t-a)^2+(y1+ydiff*t-b)^2=eps^2 (xdiff^2+ydiff^2)t^2 + (2(x1-a)xdiff+2(y1-b)ydiff)t + + * (x1-a)^2+(y1-b)^2-eps^2=0 + * + * Quadratic solution for t, gives us intersection of disc points with line + * + * t = (-(2(x1-a)xdiff+2(y1-b)ydiff)) +- sqrt((2(x1-a)xdiff+2(y1-b)ydiff))^2 - + * 4(xdiff^2+ydiff^2)(x1^2+y1^2-eps^2)))/(2*(xdiff^2+ydiff^2)) + * + * a*t^2 + b*t + c = 0 + */ + + double t[] = new double[2]; + double b = 2 * ((p1.getX() - p.getX()) * this.xdiff + (p1.getY() - p.getY()) * this.ydiff); + double c = (p1.getX() - p.getX()) * (p1.getX() - p.getX()) + (p1.getY() - p.getY()) + * (p1.getY() - p.getY()) - eps * eps; + double a = this.xdiff * this.xdiff + this.ydiff * this.ydiff; + + if (a == 0) { + return null; + } + + double determinant = b * b - 4 * a * c; + final double dist = Math.sqrt(a); + if (determinant >= 0) { + t[1] = (-b + Math.sqrt(determinant)) / (2 * a); + t[0] = (-b - Math.sqrt(determinant)) / (2 * a); + } else if (precisionCompromise) { + double newEps = eps + 0.1; + double newC = (p1.getX() - p.getX()) * (p1.getX() - p.getX()) + (p1.getY() - p.getY()) + * (p1.getY() - p.getY()) - newEps * newEps; + double newDeterminant = b * b - 4 * a * newC; + if (newDeterminant >= 0) { + t[1] = (-b + Math.sqrt(newDeterminant)) / (2 * a); + t[0] = (-b - Math.sqrt(newDeterminant)) / (2 * a); + } else { + return null; + } + } else { + return null; + } + + double min = Math.min(t[0], t[1]); + double max = Math.max(t[0], t[1]); + + t[0] = min; + t[1] = max; + + return t; + } + + /** + * Returns intersection points of this line and two lines in Line[] (neighborhood). For detail see + * {@link package-info} + * + * @return an array of four double values, first two values represents interval start and end + * points on this line and next two corresponds to intersections with lines[0] and + * lines[1] respectively. + */ + public double[] getIntervals(Line[] lines) { + double cIntervalStart; + double cIntervalEnd; + double neighborhoodStart; + double neighborhoodEnd; + + if (lines[0].getXdiff() == 0.0) { + // when the edge is a vertical line + cIntervalStart = this.m * lines[0].getP1().getX() + this.c; + cIntervalEnd = this.m * lines[1].getP1().getX() + this.c; + + neighborhoodStart = (cIntervalStart - lines[0].getP1().getY()) / lines[0].getYdiff(); + neighborhoodEnd = (cIntervalEnd - lines[1].getP1().getY()) / lines[1].getYdiff(); + if (this.ydiff != 0.0) { + cIntervalStart = (cIntervalStart - this.getP1().getY()) / this.ydiff; + cIntervalEnd = (cIntervalEnd - this.getP1().getY()) / this.ydiff; + } else { + cIntervalStart = (lines[0].getP1().getX() - this.p1.getX()) / this.xdiff; + cIntervalEnd = (lines[1].getP1().getX() - this.p1.getX()) / this.xdiff; + } + + } else if (this.xdiff == 0.0) { + // when the line is a vertical line + cIntervalStart = lines[0].getM() * this.getP1().getX() + lines[0].getC(); + cIntervalEnd = lines[1].getM() * this.getP1().getX() + lines[1].getC(); + + if (lines[0].getYdiff() != 0.0) { + neighborhoodStart = (cIntervalStart - lines[0].getP1().getY()) / lines[0].getYdiff(); + neighborhoodEnd = (cIntervalEnd - lines[1].getP1().getY()) / lines[1].getYdiff(); + } else { + neighborhoodStart = (this.p1.getX() - lines[0].getP1().getX()) / lines[0].getXdiff(); + neighborhoodEnd = (this.p1.getX() - lines[1].getP1().getX()) / lines[1].getXdiff(); + } + cIntervalStart = (cIntervalStart - this.getP1().getY()) / this.ydiff; + cIntervalEnd = (cIntervalEnd - this.getP1().getY()) / this.ydiff; + } else { + + cIntervalStart = -(this.c - lines[0].getC()) / (this.m - lines[0].getM()); + cIntervalEnd = -(this.c - lines[1].getC()) / (this.m - lines[1].getM()); + + neighborhoodStart = (cIntervalStart - lines[0].getP1().getX()) / lines[0].getXdiff(); + neighborhoodEnd = (cIntervalEnd - lines[1].getP1().getX()) / lines[1].getXdiff(); + + cIntervalStart = (cIntervalStart - this.getP1().getX()) / this.xdiff; + cIntervalEnd = (cIntervalEnd - this.getP1().getX()) / this.xdiff; + } + double temp[] = new double[4]; + temp[0] = cIntervalStart; + temp[1] = cIntervalEnd; + temp[2] = neighborhoodStart; + temp[3] = neighborhoodEnd; + return temp; + } + + /** + * Sets curveStart, curveEnd, edgeStart and edgeEnd on edge. + */ + public void setIntervalOnEdge(Edge e, + double eps, + double cIntervalStart, + double cIntervalEnd, + double vstart, + double vend) { + // compute intersection points on the edge + + double interval[] = new double[2]; + + interval[0] = Math.max(0, cIntervalStart); + + if (vstart == -1) { + + double[] in1 = e.getLine().pIntersection(this.getVertex(interval[0]), eps, true); + + if (in1 == null) { + //logger.log(Level.SEVERE, "Problem computing Line intersection: in1."); + throw new RuntimeException(); + } + + if (in1[0] >= 0 && in1[0] <= 1 && in1[1] >= 0 && in1[1] <= 1) { + vstart = (in1[0] + in1[1]) / 2; + } else if (in1[0] >= 0 && in1[0] <= 1) { + vstart = in1[0]; + } else if (in1[1] >= 0 && in1[1] <= 1) { + vstart = in1[1]; + } else { + vstart = 0; + } + } + + interval[1] = Math.min(1, cIntervalEnd); + + if (vend == -1) { + + double[] in2 = e.getLine().pIntersection(this.getVertex(interval[1]), eps, true); + + if (in2 == null) { + //logger.log(Level.SEVERE, "Problem computing Line intersection: in2."); + throw new RuntimeException(); + } + + if (in2[0] >= 0 && in2[0] <= 1 && in2[1] >= 0 && in2[1] <= 1) { + vend = (in2[0] + in2[1]) / 2; + } else if (in2[0] >= 0 && in2[0] <= 1) { + vend = in2[0]; + } else if (in2[1] >= 0 && in2[1] <= 1) { + vend = in2[1]; + } else { + vend = 1; + } + } + + e.setCurveStart(interval[0]); + e.setCurveEnd(interval[1]); + e.setEdgeStart(vstart); + e.setEdgeEnd(vend); + + } + + /** + * Compute intersection of eps-region around edge e and this line. + * + * @param e is the edge around which we would consider eps-region + * + * @param eps the radius of the disc + * + * @return true when they have intersection or false when they don't intersect. + */ + // TODO(mahmuda): Add unit test for this method. + public boolean pIntersection(Edge e, double eps) { + + /* + * Line 1: x1+(x2-x1)*t = x y1+(y2-y1)*t = y + * + * Line 2: y = mx + c + * + * y1+(y2-y1)*t = (x1+(x2-x1)*t)*m + c (y2-y1)*t - (x2-x1)*t*m = x1*m + c- y1 + * + * t = (x1*m + c - y1)/((y2-y1)-(x2-x1)*m) + */ + + Line vline = e.getLine(); + + Line lines[] = Line.getEpsilonNeighborhood(vline, eps); + double cIntervalStart; + double cIntervalEnd; + double neighborhoodStart; + double neighborhoodEnd; + + double vstart = -1; + double vend = -1; + + if (Math.abs(this.theta - vline.getTheta()) == 0 + || Math.abs(this.theta - vline.getTheta()) == 180.0) {// For parallel lines + + double t[] = this.getTParallel(vline, eps); + + if (t == null) { + return false; + } + + cIntervalStart = t[0]; + cIntervalEnd = t[1]; + + t = vline.pIntersection(this.getVertex(cIntervalStart), eps, true); + if (t == null) { + return false; + } + neighborhoodStart = (t[0] + t[1]) / 2.0; + t = vline.pIntersection(this.getVertex(cIntervalEnd), eps, true); + if (t == null) { + return false; + } + neighborhoodEnd = (t[0] + t[1]) / 2.0; + + } else { + double[] temp = getIntervals(lines); + cIntervalStart = temp[0]; + cIntervalEnd = temp[1]; + neighborhoodStart = temp[2]; + neighborhoodEnd = temp[3]; + } + + + if (cIntervalStart > cIntervalEnd) { + double temp = cIntervalStart; + cIntervalStart = cIntervalEnd; + cIntervalEnd = temp; + + temp = neighborhoodStart; + neighborhoodStart = neighborhoodEnd; + neighborhoodEnd = temp; + } + + + // computing intersection with endpoint p1 + + double[] interval1 = this.pIntersection(vline.getP1(), eps, false); + + // computing intersection with endpoint p2 + + double[] interval2 = this.pIntersection(vline.getP2(), eps, false); + + double minInterval1 = 0; + double minInterval2 = 0; + double maxInterval1 = 1; + double maxInterval2 = 1; + + + // line doesn't intersect either of the eps-disc at end points + + if (interval1 == null && interval2 == null) { + + // intersection of line and eps-neighborhood of e is non-empty + if (cIntervalStart > 1 || cIntervalEnd < 0) { + return false; + } + + // intersection of line and eps-neighborhood of e is empty + if ((neighborhoodStart > 1 && neighborhoodEnd > 1) + || (neighborhoodStart < 0 && neighborhoodEnd < 0)) { + return false; + } + + // intersection needs to be in the eps-region + if (neighborhoodStart >= 0 && neighborhoodStart <= 1 && neighborhoodEnd >= 0 + && neighborhoodEnd <= 1) { + cIntervalStart = Math.max(0, cIntervalStart); + cIntervalEnd = Math.min(1, cIntervalEnd); + } else { + return false; + } + } + // line doesn't intersect with eps-disc of first endpoint + + if (interval1 != null) { + minInterval1 = Math.min(interval1[0], interval1[1]); + maxInterval1 = Math.max(interval1[0], interval1[1]); + + if (((neighborhoodStart > 1 && neighborhoodEnd > 1) + || (neighborhoodStart < 0 && neighborhoodEnd < 0)) + && (minInterval1 > 1 || maxInterval1 < 0)) { + return false; + } + if (neighborhoodStart < 0) { + if (minInterval1 <= 1) { + cIntervalStart = Math.max(cIntervalStart, minInterval1); + } + if (cIntervalStart == minInterval1) { + vstart = 0; + } + } + + if (neighborhoodEnd < 0) { + if (maxInterval1 >= 0) { + cIntervalEnd = Math.min(cIntervalEnd, maxInterval1); + } + if (cIntervalEnd == maxInterval1) { + vend = 0; + } + } + } + + // line doesn't intersect with eps-disc of second end point + + if (interval2 != null) { + + minInterval2 = Math.min(interval2[0], interval2[1]); + maxInterval2 = Math.max(interval2[0], interval2[1]); + + if (((neighborhoodStart > 1 && neighborhoodEnd > 1) + || (neighborhoodStart < 0 && neighborhoodEnd < 0)) + && (minInterval2 > 1 || maxInterval2 < 0)) { + return false; + } + + if (neighborhoodStart > 1) { + if (minInterval2 <= 1) { + cIntervalStart = Math.max(cIntervalStart, minInterval2); + } + if (cIntervalStart == minInterval2) { + vstart = 1; + } + } + + if (neighborhoodEnd > 1) { + if (maxInterval2 >= 0) { + cIntervalEnd = Math.min(cIntervalEnd, maxInterval2); + } + if (cIntervalEnd == maxInterval2) { + vend = 1; + } + } + } + + if (interval1 == null && interval2 != null) { + if (!(neighborhoodStart >= 0 && neighborhoodStart <= 1 && neighborhoodEnd >= 0 + && neighborhoodEnd <= 1)) { + if (neighborhoodStart >= 0 && neighborhoodStart <= 1) { + if (cIntervalStart > 1 && minInterval2 > 1) { + return false; + } + if (cIntervalStart < 0 && maxInterval2 < 0) { + return false; + } + } + if (neighborhoodEnd >= 0 && neighborhoodEnd <= 1) { + if (cIntervalEnd > 1 && minInterval2 > 1) { + return false; + } + if (cIntervalEnd < 0 && maxInterval2 < 0) { + return false; + } + } + } + } + if (interval1 != null && interval2 == null) { + if (!(neighborhoodStart >= 0 && neighborhoodStart <= 1 && neighborhoodEnd >= 0 + && neighborhoodEnd <= 1)) { + + if (neighborhoodStart >= 0 && neighborhoodStart <= 1) { + if (cIntervalStart > 1 && minInterval1 > 1) { + return false; + } + if (cIntervalStart < 0 && maxInterval1 < 0) { + return false; + } + } + if (neighborhoodEnd >= 0 && neighborhoodEnd <= 1) { + if (cIntervalEnd > 1 && minInterval1 > 1) { + return false; + } + if (cIntervalEnd < 0 && maxInterval1 < 0) { + return false; + } + } + } + } + + if (cIntervalStart > cIntervalEnd) { + double temp = cIntervalStart; + cIntervalStart = cIntervalEnd; + cIntervalEnd = temp; + + temp = vend; + vend = vstart; + vstart = temp; + } + + if (cIntervalStart > 1 || cIntervalEnd < 0) { + return false; + } + + if (Math.max(maxInterval1, maxInterval2) < 0 || Math.min(minInterval1, minInterval2) > 1) { + return false; + } + + this.setIntervalOnEdge(e, eps, cIntervalStart, cIntervalEnd, vstart, vend); + + return true; + + } + + /** + * Get a Vertex on this line with parameter t. + * + * @param t the parameter + * + * @return a vertex on this line with parameter t. + */ + public Vertex getVertex(double t) { + return new Vertex(this.p1.getX() + this.xdiff * t, this.p1.getY() + this.ydiff * t, + this.p1.getZ() + this.zdiff * t); + } + + /** + * Computes two lines which along with two eps-discs around endpoints of the line defines the + * boundary of eps-region around the vline. + * + * @param vline the original segment + * + * @return Line[2] containing two lines + */ + public static Line[] getEpsilonNeighborhood(Line vline, double eps) { + // compute the equations of boundaries of eps-region around the line + Line lines[] = new Line[2]; + + double dTheta; + if (vline.getXdiff() != 0) { + dTheta = Math.atan(vline.getM()) + Math.PI / 2.0; + } else if (vline.ydiff > 0.0) { + dTheta = Math.PI / 2.0; + } else { + dTheta = -Math.PI / 2.0; + } + double dx, dy; + dx = eps * Math.cos(dTheta); + dy = eps * Math.sin(dTheta); + + lines[0] = new Line( + new Vertex(vline.getP1().getX() - dx, vline.getP1().getY() - dy, vline.getP1().getZ()), + new Vertex(vline.getP2().getX() - dx, vline.getP2().getY() - dy, vline.getP2().getZ())); + lines[1] = new Line( + new Vertex(vline.getP1().getX() + dx, vline.getP1().getY() + dy, vline.getP1().getZ()), + new Vertex(vline.getP2().getX() + dx, vline.getP2().getY() + dy, vline.getP2().getZ())); + + if (lines[0].getM() != lines[1].getM()) { + lines[0].setM(lines[1].getM()); + lines[0].setTheta(lines[1].getTheta()); + } + return lines; + } + + /** + * Computes the distance between this line and a point. + * + * @param p the vertex from which we will compute distance + * + * @return a double value containing distance + */ + public double distance(Vertex p) { + + double distance = 0; + + if (this.xdiff != 0) { + distance = + Math.abs(-this.m * p.getX() + p.getY() + this.c) / Math.sqrt(Math.pow(this.m, 2) + 1); + } else { + distance = Math.abs(this.p1.getX() - p.getX()); + } + + double t[] = this.pIntersection(p, distance, false); + + if (t == null || t[0] > 1 || t[0] < 0) { + return Math.min(Math.sqrt((p1.getX() - p.getX()) * (p1.getX() - p.getX()) + + (p1.getY() - p.getY()) * (p1.getY() - p.getY())), Math.sqrt((p2.getX() - p.getX()) + * (p2.getX() - p.getX()) + (p2.getY() - p.getY()) * (p2.getY() - p.getY()))); + } else { + return distance; + } + } + + /** + * Computes intersections between eps-region around this line and a line segment when two lines + * are parallel. + * + * @param line is a line parallel to this line + * + * @return a double[2] containing two intersection points or null when they don't intersect + */ + + public double[] getTParallel(Line line, double eps) { + double t[] = new double[2]; + double newm; + double x1, y1, x2, y2; + if (Math.abs(line.getTheta()) == Math.PI / 2) { + newm = 0; + x1 = this.p1.getX(); + y1 = line.getP1().getY(); + x2 = this.p2.getX(); + y2 = line.getP2().getY(); + } else if (Math.abs(line.getTheta()) == 0) { + newm = 0; + x1 = line.getP1().getX(); + y1 = this.p1.getY(); + x2 = line.getP2().getX(); + y2 = this.p2.getY(); + } else { + newm = 1 / line.getM(); + double c1 = line.getP1().getY() + newm * line.getP1().getX(); + double c2 = line.getP2().getY() + newm * line.getP2().getX(); + + x1 = (c1 - this.c) / (this.m + newm); + y1 = this.m * x1 + this.c; + + x2 = (c2 - this.c) / (this.m + newm); + y2 = this.m * x2 + this.c; + } + + if (Math.sqrt((line.getP1().getX() - x1) * (line.getP1().getX() - x1) + + (line.getP1().getY() - y1) * (line.getP1().getY() - y1)) > eps) { + return null; + } + + double intersection1; + double intersection2; + + if (this.xdiff != 0.0) { + intersection1 = (x1 - this.p1.getX()) / this.xdiff; + intersection2 = (x2 - this.p1.getX()) / this.xdiff; + } else { + intersection1 = (y1 - this.p1.getY()) / this.ydiff; + intersection2 = (y2 - this.p1.getY()) / this.ydiff; + } + t[0] = Math.min(intersection1, intersection2); + t[1] = Math.max(intersection1, intersection2); + + if (t[1] < 0 || t[0] > 1) { + return null; + } + + t[0] = Math.max(t[0], 0); + t[1] = Math.min(t[1], 1); + return t; + } + + /** + * Computes t value on this line for Vertex v, t = 0 at p1 and t = 1 at p2. + * + * @return a double value. + */ + public double tValueOnLine(Vertex v) { + if (this.xdiff == 0) { + return (v.getY() - this.p1.getY()) / this.ydiff; + } else { + return (v.getX() - this.p1.getX()) / this.xdiff; + } + } + + /** + * Check if the vertex, v lies on this line. + * + * @return boolean true, if the vertex lies on this line or false otherwise. + */ + public boolean onLine(Vertex v) { + + if (this.xdiff == 0 && v.getX() == this.p1.getX()) { + return true; + } else { + return (v.getY() - this.m * v.getX() - this.c) == 0; + } + } +} \ No newline at end of file diff --git a/algorithms/Ahmed/src/mapconstruction2/MapConstruction.java b/algorithms/Ahmed/src/mapconstruction2/MapConstruction.java new file mode 100644 index 0000000..58e19ab --- /dev/null +++ b/algorithms/Ahmed/src/mapconstruction2/MapConstruction.java @@ -0,0 +1,795 @@ +package mapconstruction2; + +/** + * Frechet-based map construction 2.0 Copyright 2013 Mahmuda Ahmed and Carola Wenk + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * ------------------------------------------------------------------------ + * + * This software is based on the following article. Please cite this article when using this code + * as part of a research publication: + * + * Mahmuda Ahmed and Carola Wenk, "Constructing Street Networks from GPS Trajectories", European + * Symposium on Algorithms (ESA): 60-71, Ljubljana, Slovenia, 2012 + * + * ------------------------------------------------------------------------ + * + * Author: Mahmuda Ahmed Filename: MapConstruction.java + * + */ + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * An object that represents a track. + * + */ +class PoseFile { + String fileName; + ArrayList curve; + + PoseFile() { + this.fileName = ""; + this.curve = new ArrayList(); + } + + PoseFile(String curveName, ArrayList curve) { + this.fileName = curveName; + this.curve = curve; + } + + public String getFileName() { + return fileName; + } + + public ArrayList getPose() { + return curve; + } + + public double getLength() { + double length = 0; + for (int i = 1; i < curve.size(); i++) { + length = length + curve.get(i - 1).dist(curve.get(i)); + } + return length; + } + + public static PoseFile readFile(File inputFile, boolean hasAltitude) { + PoseFile poseFile = new PoseFile(); + poseFile.fileName = inputFile.getName(); + String str = ""; + + try { + BufferedReader in = new BufferedReader(new FileReader( + inputFile.getAbsolutePath())); + double prev_time = 0; + double x, y, z; + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str); + // strToken.nextToken(); + // track file in "x y timestamp" or "x y z timestamp" format + + x = Double.parseDouble(strToken.nextToken()); + y = Double.parseDouble(strToken.nextToken()); + if (hasAltitude) { + z = Double.parseDouble(strToken.nextToken()); + } else { + z = 0.0; + } + double timestamp = Double.parseDouble(strToken.nextToken()); + Vertex newPoint = new Vertex(x, y, z, timestamp); + if (poseFile.curve.size() > 0) { + double dist = newPoint.dist(poseFile.curve + .get(poseFile.curve.size() - 1)); + if (timestamp - prev_time > 120) + break; + if (dist > 2.0) + poseFile.curve.add(newPoint); + } else { + poseFile.curve.add(newPoint); + } + prev_time = timestamp; + + } + in.close(); + + } catch (Exception e) { + e.printStackTrace(); + } + return poseFile; + } +} + +/** + * An object that takes a set of poses as input, construct graph and write two + * files one for vertices and one for edges. + */ +public class MapConstruction { + + public static int curveid; // counter for pose + public static String curveName; // file name for the pose + + private static final Logger logger = Logger.getAnonymousLogger(); + + /** + * Writes the constructed map into files. + */ + + public static void writeToFile(List vList, String fileName) { + + try { + int count = 0; + BufferedWriter bwedges = new BufferedWriter(new FileWriter(fileName + + "edges.txt")); + BufferedWriter bvertex = new BufferedWriter(new FileWriter(fileName + + "vertices.txt")); + + + for (int i = 0; i < vList.size(); i++) { + Vertex v = vList.get(i); + bvertex.write(i + "," + v.getX() + "," + v.getY() +","+ v.getZ() + "\n"); + + for (int j = 0; j < v.getDegree(); j++) { + + if (i != v.getAdjacentElementAt(j)) { + + bwedges.write(count + "," + i + "," + + v.getAdjacentElementAt(j) + "\n"); + + count++; + } + } + } + + + bwedges.close(); + bvertex.close(); + } catch (Exception ex) { + System.out.println(ex.toString()); + } + } + + /** + * Computes interval on edge e for a line segment consists of + * (currentIndex-1)-th and currentIndex-th vertices of pose and return true + * if edge e has a part of white interval else false. + */ + + public boolean isWhiteInterval(Edge edge, List pose, + int currentIndex, double eps, double altEps) { + Line line = new Line(pose.get(currentIndex - 1), pose.get(currentIndex)); + + if (Math.abs(line.avgAltitude() - edge.getLine().avgAltitude()) <= altEps) { + return line.pIntersection(edge, eps); + } else { + return false; + } + } + + /** + * Sets corresponding interval endpoints on Edge. + */ + public void setEndPointsOnEdge(Edge edge, int startIndex, int endIndex, + double cstart, double vstart) { + edge.setCurveStartIndex(startIndex); + edge.setCurveStart(startIndex + cstart); + edge.setEdgeStart(vstart); + + edge.setCurveEnd(endIndex - 1 + edge.getCurveEnd()); + edge.setCurveEndIndex(endIndex); + } + + /** + * Scans for next white interval on an Edge starting from index newstart of + * pose. + */ + public void computeNextInterval(Edge edge, List pose, int newstart, + double eps, double altEps) { + + // Compute next white interval on edge. + boolean first = true; + boolean debug = false; + + int startIndex = 0; + double cstart = 0, vstart = 0; + + if (newstart >= pose.size()) { + edge.setCurveEndIndex(pose.size()); + edge.setDone(true); + return; + } + + for (int i = newstart; i < pose.size(); i++) { + boolean result = isWhiteInterval(edge, pose, i, eps, altEps); + + // first = true means we are still looking for our first interval + // starting from newstart. + // !result indicate Line(pose.get(i), pose.get(i+1)) doesn't contain + // white interval. + // we can just ignore if(first && !result). + + if (first && result) { + // first segment on the white interval + first = false; + startIndex = i - 1; + cstart = edge.getCurveStart(); + vstart = edge.getEdgeStart(); + + // if the white interval ends within the same segment + if (edge.getCurveEnd() < 1) { + this.setEndPointsOnEdge(edge, startIndex, i, cstart, vstart); + return; + } + } else if (!first && result) { + // not the first segment on the white interval + if (edge.getCurveEnd() < 1) { + // if the white interval ends within that segment + this.setEndPointsOnEdge(edge, startIndex, i, cstart, vstart); + return; + } + } else if (!first && !result) { + // the white interval ends at 1.0 of previous segment + this.setEndPointsOnEdge(edge, startIndex, i, cstart, vstart); + return; + } + } + + if (first) { + // if the last segment on the curve is the first segment of that + // interval + edge.setCurveEndIndex(pose.size()); + edge.setDone(true); + } else { + edge.setCurveStartIndex(startIndex); + edge.setCurveStart(startIndex + cstart); + edge.setEdgeStart(vstart); + + edge.setCurveEnd(pose.size() - 2 + edge.getCurveEnd()); + edge.setCurveEndIndex(pose.size() - 2); + } + + return; + } + + /** + * Updates constructedMap by adding an Edge. Detail description of the + * algorithm is in the publication. + */ + public void updateMap(List constructedMap, + Map map, Edge edge) { + + // update the map by adding a new edge + Vertex v; + int parent = -1; + int child = -1; + + String keyParent = edge.getVertex1().toString(); + String keyChild = edge.getVertex2().toString(); + // find the index of parent node + if (map.containsKey(keyParent)) { + parent = map.get(keyParent).intValue(); + } else { + v = edge.getVertex1(); + constructedMap.add(v); + parent = constructedMap.indexOf(v); + map.put(keyParent, parent); + } + // find the index of child node + if (map.containsKey(keyChild)) { + child = map.get(keyChild).intValue(); + } else { + v = edge.getVertex2(); + constructedMap.add(v); + child = constructedMap.indexOf(v); + map.put(keyChild, child); + } + // update the map + if (parent == -1 || child == -1) { + logger.log(Level.SEVERE, "inconsistent graph child, parent :" + + child + ", " + parent); + } else if (parent != child) { + + constructedMap.get(parent).addElementAdjList(child); + constructedMap.get(child).addElementAdjList(parent); + + logger.log(Level.FINEST, "child, parent :" + child + ", " + parent); + logger.log(Level.FINEST, "child, parent :" + parent + ", " + child); + + } + } + + /** + * Adds a split point on an Edge. + * + * @param newVertexPosition + * represents position of a new Vertex + */ + public void edgeSplit(List constructedMap, + Map map, Edge edge, double newVertexPosition) { + + Vertex v1 = edge.getVertex1(); + Vertex v2 = edge.getVertex2(); + + String key1 = v1.toString(); + String key2 = v2.toString(); + + // call of this method always after updateMap which ensures + // map.containsKey(key1) is + // always true. + int index1 = map.get(key1).intValue(); + int index2 = map.get(key2).intValue(); + + Vertex v = edge.getLine().getVertex(newVertexPosition); + + // splitting an edge on split point vertex v + + String key = v.toString(); + + int index = map.get(key).intValue(); + + if (index == index1 || index == index2) { + return; + } + + logger.log(Level.FINER, "Index = " + index1 + " " + index2 + " " + + index); + + edge.addSplit(newVertexPosition, index); + } + + /** + * Commits edge splitting listed in List Edge.edgeSplitVertices. + */ + + public void commitEdgeSplits(List edges, Map map, + List graph) { + + if (edges.size() != 2) { + // logger.log(Level.SEVERE, "created."); + return; + } + + Edge edge = edges.get(0); + + for (int i = 0; i < edges.get(1).getEdgeSplitPositions().size(); i++) { + double newPosition = 1 - edges.get(1).getEdgeSplitPositions() + .get(i).doubleValue(); + edge.addSplit(newPosition, + edges.get(1).getEdgeSplitVertices().get(i)); + } + + List edgeVertexSplits = edge.getEdgeSplitVertices(); + int splitSize = edgeVertexSplits.size(); + + if (splitSize == 0) { + return; + } + + Vertex v1 = edge.getVertex1(); + Vertex v2 = edge.getVertex2(); + + String key1 = v1.toString(); + String key2 = v2.toString(); + + int index1 = map.get(key1).intValue(); + int index2 = map.get(key2).intValue(); + + boolean updateV1 = false, updateV2 = false; + + logger.log(Level.FINER, "commitEdgeSplits " + splitSize); + + for (int i = 0; i < v1.getDegree(); i++) { + if (v1.getAdjacentElementAt(i) == index2) { + v1.setAdjacentElementAt(i, edgeVertexSplits.get(0).intValue()); + graph.get(edgeVertexSplits.get(0).intValue()) + .addElementAdjList(index1); + updateV1 = true; + } + } + + for (int i = 0; i < v2.getDegree(); i++) { + if (v2.getAdjacentElementAt(i) == index1) { + v2.setAdjacentElementAt(i, edgeVertexSplits.get(splitSize - 1) + .intValue()); + graph.get(edgeVertexSplits.get(splitSize - 1).intValue()) + .addElementAdjList(index2); + updateV2 = true; + } + } + + for (int i = 0; i < splitSize - 1; i++) { + int currentVertex = edgeVertexSplits.get(i).intValue(); + int nextVertex = edgeVertexSplits.get(i + 1).intValue(); + graph.get(currentVertex).addElementAdjList(nextVertex); + graph.get(nextVertex).addElementAdjList(currentVertex); + } + if (!(updateV1 && updateV2)) { + logger.log(Level.SEVERE, "inconsistent graph: (" + splitSize + ")" + + index1 + " " + index2 + " " + + v1.getAdjacencyList().toString() + " " + + v2.getAdjacencyList().toString()); + } + } + + /** + * Commits edge splitting for all edges. + */ + + public void commitEdgeSplitsAll(List constructedMap, + Map map, Map> siblingMap, + List edges) { + for (int i = 0; i < edges.size(); i++) { + String key1 = edges.get(i).getVertex1().toString() + " " + + edges.get(i).getVertex2().toString(); + String key2 = edges.get(i).getVertex2().toString() + " " + + edges.get(i).getVertex1().toString(); + + ArrayList siblings1, siblings2; + if (siblingMap.containsKey(key1)) + siblings1 = siblingMap.get(key1); + else { + siblings1 = new ArrayList(); + } + if (siblingMap.containsKey(key2)) + siblings2 = siblingMap.get(key2); + else { + siblings2 = new ArrayList(); + } + if (siblings1.size() != 0) { + this.commitEdgeSplits(siblings1, map, constructedMap); + siblingMap.remove(key1); + } else if (siblings2.size() != 0) { + this.commitEdgeSplits(siblings2, map, constructedMap); + siblingMap.remove(key2); + } + } + } + + /** + * Adds a portion of a pose as edges into constructedMap. + */ + + public void addToGraph(List constructedMap, List pose, + Map map, int startIndex, int endIndex) { + for (int i = startIndex; i < endIndex; i++) { + this.updateMap(constructedMap, map, + new Edge(pose.get(i), pose.get(i + 1))); + } + + } + + /** + * Updates siblingHashmap for an edge. + */ + + public void updateSiblingHashMap(Map> siblingMap, + Edge edge) { + String key1 = edge.getVertex1().toString() + " " + + edge.getVertex2().toString(); + String key2 = edge.getVertex2().toString() + " " + + edge.getVertex1().toString(); + Collection siblings1, siblings2; + if (siblingMap.containsKey(key1)) { + siblings1 = siblingMap.get(key1); + } else { + siblings1 = new ArrayList(); + } + if (siblingMap.containsKey(key1)) { + siblings2 = siblingMap.get(key2); + } else { + siblings2 = new ArrayList(); + } + + if (siblings1.size() == 0 && siblings2.size() == 0) { + siblingMap.put(key1, new ArrayList()); + siblingMap.get(key1).add(edge); + } else if (siblings1.size() != 0) { + siblings1.add(edge); + } else if (siblings2.size() != 0) { + siblings2.add(edge); + } + } + + /** + * Update the map for a pose/curve. Definition of black and white interval. + */ + // @TODO(mahmuda): extract some shorter well-named methods. + public void mapConstruction(List constructedMap, List edges, + Map map, List pose, double eps, + double altEps) { + + PriorityQueue pq = new PriorityQueue(); + + for (int i = 0; i < edges.size(); i++) { + this.computeNextInterval(edges.get(i), pose, 1, eps, altEps); + if (!edges.get(i).getDone()) { + pq.add(edges.get(i)); + } + } + try { + + // The whole curve will be added as an edge because no white + // interval + + if (pq.isEmpty()) { + + logger.log(Level.FINER, MapConstruction.curveName + + " inserted as an edge"); + + this.addToGraph(constructedMap, pose, map, 0, pose.size() - 1); + + logger.log(Level.FINER, MapConstruction.curveName + + " inserted as an edge"); + return; + } + + Edge edge = pq.poll(); + + double cend = edge.getCurveEnd(); + Edge cedge = edge; + + // There is a black interval until edge.curveStart + + if (edge.getCurveStart() > 0) { + + logger.log(Level.FINER, MapConstruction.curveName + + " inserted as an edge until " + edge.getCurveStart()); + + int index = (int) Math.floor(edge.getCurveStart()); + + this.addToGraph(constructedMap, pose, map, 0, index); + + Line newLine = new Line(pose.get(index), pose.get(index + 1)); + double t = edge.getCurveStart() + - Math.floor(edge.getCurveStart()); + this.updateMap(constructedMap, map, new Edge(pose.get(index), + newLine.getVertex(t))); + + this.updateMap(constructedMap, map, + new Edge(newLine.getVertex(t), edge.getLine() + .getVertex(edge.getEdgeStart()))); + this.edgeSplit(constructedMap, map, edge, edge.getEdgeStart()); + } + + // the while loop will search through all the intervals until we + // reach the end of the pose + + while (cend < pose.size()) { + + logger.log(Level.FINEST, MapConstruction.curveName + + " has white interval " + edge.getCurveStart() + " " + + edge.getCurveEnd() + " " + cend); + + if (cend < edge.getCurveEnd()) { + cend = edge.getCurveEnd(); + cedge = edge; + } + + if (edge.getCurveEnd() == pose.size() - 1) { + logger.log(Level.FINER, MapConstruction.curveName + + " processing completed."); + return; + } + + this.computeNextInterval(edge, pose, + edge.getCurveEndIndex() + 1, eps, altEps); + + if (!edge.getDone()) { + pq.add(edge); + } + + if (pq.isEmpty()) { + logger.log(Level.FINER, MapConstruction.curveName + + " inserted as an edge from " + cend + " to end"); + + int index = (int) Math.floor(cend); + Line newLine = new Line(pose.get(index), + pose.get(index + 1)); + double t = cend - Math.floor(cend); + this.updateMap( + constructedMap, + map, + new Edge(cedge.getLine().getVertex( + cedge.getEdgeEnd()), newLine.getVertex(t))); + this.edgeSplit(constructedMap, map, cedge, + cedge.getEdgeEnd()); + this.updateMap(constructedMap, map, + new Edge(newLine.getVertex(t), pose.get(index + 1))); + this.addToGraph(constructedMap, pose, map, index + 1, + pose.size() - 1); + + return; + } + + edge = pq.poll(); + + if (edge.getCurveStart() > cend) { + logger.log(Level.FINER, MapConstruction.curveName + + " inserted as an edge from " + cend + " to " + + edge.getCurveStart()); + + // need to add rest of the line segment + + int index = (int) Math.floor(cend); + int indexStart = (int) Math.floor(edge.getCurveStart()); + Line newLine = new Line(pose.get(index), + pose.get(index + 1)); + double t = cend - Math.floor(cend); + + this.updateMap( + constructedMap, + map, + new Edge(cedge.getLine().getVertex( + cedge.getEdgeEnd()), newLine.getVertex(t))); + this.edgeSplit(constructedMap, map, cedge, + cedge.getEdgeEnd()); + + if (index == indexStart) { + this.updateMap( + constructedMap, + map, + new Edge(newLine.getVertex(t), + newLine.getVertex(edge.getCurveStart() + - index))); + index = (int) Math.floor(edge.getCurveStart()); + newLine = new Line(pose.get(index), pose.get(index + 1)); + t = edge.getCurveStart() + - Math.floor(edge.getCurveStart()); + } else { + this.updateMap( + constructedMap, + map, + new Edge(newLine.getVertex(t), pose + .get(index + 1))); + + this.addToGraph(constructedMap, pose, map, index + 1, + (int) Math.floor(edge.getCurveStart())); + index = (int) Math.floor(edge.getCurveStart()); + newLine = new Line(pose.get(index), pose.get(index + 1)); + t = edge.getCurveStart() + - Math.floor(edge.getCurveStart()); + this.updateMap(constructedMap, map, + new Edge(pose.get(index), newLine.getVertex(t))); + + } + this.updateMap(constructedMap, map, + new Edge(newLine.getVertex(t), edge.getLine() + .getVertex(edge.getEdgeStart()))); + this.edgeSplit(constructedMap, map, edge, + edge.getEdgeStart()); + } + } + } catch (Exception ex) { + logger.log(Level.SEVERE, ex.toString()); + throw new RuntimeException(ex); + } + return; + } + + public List readAllFiles(File folder, boolean hasAltitude) { + List poseFiles = new ArrayList(); + for (File file : folder.listFiles()) { + poseFiles.add(PoseFile.readFile(file, hasAltitude)); + } + return poseFiles; + } + + /** + * Constructs map from poses and returns string representation of the map. + */ + + public List constructMapMain(List poseFiles, double eps, + double altEps) { + + List constructedMap = new ArrayList(); + // map contains mapping between vertex keys and their indices in + // constructedMap + Map map = new HashMap(); + try { + double length = 0; + + // generate list of files in the folder to process + for (int k = 0; k < poseFiles.size(); k++) { + + Long startTime = System.currentTimeMillis(); + MapConstruction.curveid = k; + MapConstruction.curveName = poseFiles.get(k).getFileName(); + + length += poseFiles.get(k).getLength(); + + if (poseFiles.get(k).getPose().size() < 2) { + continue; + } + + List edges = new ArrayList(); + + /* + * siblingMap contains map of key and sibling edges, sibling + * edges are line segments between two vertices but going in + * opposite direction. + */ + Map> siblingMap = new HashMap>(); + + for (int i = 0; i < constructedMap.size(); i++) { + Vertex v = constructedMap.get(i); + for (int j = 0; j < v.getDegree(); j++) { + Vertex v1 = constructedMap.get(v + .getAdjacentElementAt(j)); + if (!v.equals(v1)) { + Edge newEdge = new Edge(v, v1); + edges.add(newEdge); + updateSiblingHashMap(siblingMap, newEdge); + } + } + } + + this.mapConstruction(constructedMap, edges, map, + poseFiles.get(k).getPose(), eps, altEps); + this.commitEdgeSplitsAll(constructedMap, map, siblingMap, edges); + + logger.info("k :" + k + " " + MapConstruction.curveName + " " + + length + " :" + + (System.currentTimeMillis() - startTime) / 60000.00); + + } + } catch (Exception e) { + logger.log(Level.SEVERE, e.toString()); + throw new RuntimeException(e); + } + return constructedMap; + } + + public static void main(String args[]) { + MapConstruction mapConstruction = new MapConstruction(); + + // path to the folder that contains input tracks. + String inputPath = args[0]; + + // path to the folder where the output will be written. + String outputpath = args[1]; + + // epsilon; see the paper for detail + double eps = Double.parseDouble(args[2]); + + // if the input files contains altitude information + boolean hasAltitude = Boolean.parseBoolean(args[3]); + + // minimum altitude difference between two streets. + double altEps; + if (args.length > 4) { + altEps = Double.parseDouble(args[4]); + } else { + altEps = 4.0; + } + + System.out.println(inputPath); + List constructedMap = mapConstruction.constructMapMain( + mapConstruction.readAllFiles(new File(inputPath), hasAltitude), + eps, altEps); + MapConstruction.writeToFile(constructedMap, outputpath); + } +} diff --git a/algorithms/Ahmed/src/mapconstruction2/Vertex.java b/algorithms/Ahmed/src/mapconstruction2/Vertex.java new file mode 100644 index 0000000..bf23147 --- /dev/null +++ b/algorithms/Ahmed/src/mapconstruction2/Vertex.java @@ -0,0 +1,237 @@ +package mapconstruction2; + +/** + * Frechet-based map construction 2.0 Copyright 2013 Mahmuda Ahmed and Carola Wenk + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * + * ------------------------------------------------------------------------ + * + * This software is based on the following article. Please cite this article when using this code + * as part of a research publication: + * + * Mahmuda Ahmed and Carola Wenk, "Constructing Street Networks from GPS Trajectories", European + * Symposium on Algorithms (ESA): 60-71, Ljubljana, Slovenia, 2012 + * + * ------------------------------------------------------------------------ + * + * Author: Mahmuda Ahmed Filename: Vertex.java + * + */ + + +import java.util.ArrayList; +import java.util.List; + +/** + * An object that represents a point in 3D. + */ + +public class Vertex { + + private double x; // x coordinate(meters) after Mercator projection + private double y; // y coordinate(meters) after Mercator projection + private double z; // z coordinate(meters), it represents altitude + private double lat; // latitude in WGS84 + private double lng; // longitude in WGS84 + private double alt; // altitude in meters + + /** + * Contains the indices of adjacent vertices. + */ + private List adjacencyList; + + private boolean done = false; + + /** + * Timestamp in milliseconds, this field is used when a pose is represented as a list of vertices. + */ + private double timestamp = -1; + + // TODO(Mahmuda): Better to have static factory methods instead of constructor overloading. + + public Vertex() { + this.adjacencyList = new ArrayList(); + this.done = false; + } + + public Vertex(double x, double y, double z) { + this(); + this.x = x; + this.y = y; + this.z = z; + } + + public Vertex(double x, double y, double z, double timestamp) { + this(x, y, z); + this.timestamp = timestamp; + } + + public Vertex(double lat, double lng, double alt, double x, double y, double z) { + this(x, y, z); + this.lat = lat; + this.lng = lng; + this.alt = alt; + } + + public Vertex(double lat, + double lng, + double alt, + double x, + double y, + double z, + double timestamp) { + this(lat, lng, alt, x, y, z); + this.timestamp = timestamp; + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + + public double getZ() { + return this.z; + } + + public double getLat() { + return this.lat; + } + + public double getLng() { + return this.lng; + } + + public double getAlt() { + return this.alt; + } + + public double norm(){ + return Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2)+Math.pow(z, 2)); + } + public static double dotProd(Vertex vector1, Vertex vector2){ + return vector1.getX()*vector2.getX()+vector1.getY()*vector2.getY()+vector1.getZ()*vector2.getZ(); + } + public int getDegree() { + return this.adjacencyList.size(); + } + + public boolean getDone() { + return this.done; + } + + public double getTimestamp() { + return this.timestamp; + } + + + public void setDone(boolean done) { + this.done = done; + } + + public List getAdjacencyList() { + return this.adjacencyList; + } + + /** + * Adds an element to its adjacency list. + * + * @param v is the value to be added in adjacency list + */ + void addElementAdjList(int v) { + for (int i = 0; i < this.getDegree(); i++) { + if (this.adjacencyList.get(i).intValue() == v) { + return; + } + } + + this.adjacencyList.add(new Integer(v)); + } + + /** + * Returns the index of a vertex in the adjacency list. + * + * @param v the vertex we are looking for + * + * @return an int, the index of vertex k if found or -1 otherwise + */ + public int getIndexAdjacent(int v) { + return this.adjacencyList.indexOf(v); + } + + /** + * Returns the value in the adjacency list at index k + * + * @param k the index + * + * @return an int, the value at index k or -1 otherwise + */ + + public int getAdjacentElementAt(int k) { + return this.adjacencyList.get(k).intValue(); + } + + /** + * Set the adjacent vertex as value at index + * + * @param index the index to update + * + * @param value the new value at index + */ + + public void setAdjacentElementAt(int index, int value) { + this.adjacencyList.remove(index); + this.adjacencyList.add(index, value); + } + + /** + * Computes distance between two vertices. + * + * @param v2 the vertex with which we should compute distance from this vertex + * + * @return a double value which is the distance + */ + + public double dist(Vertex v2) { + return Math.sqrt(Math.pow(this.x - v2.x, 2) + Math.pow(this.y - v2.y, 2)); + } + + /** + * Resets a vertex's processing state. + */ + + public void reset() { + done = false; + } + + @Override + public String toString() { + return String.format("%f %f %f", this.x, this.y, this.z); + } + + /** + * @return a deep copy of this vertex + */ + public Vertex deepCopy() { + Vertex vertex = + new Vertex(this.lat, this.lng, this.alt, this.x, this.y, this.z, this.timestamp); + vertex.done = this.done; + + for (int i = 0; i < this.adjacencyList.size(); i++) { + vertex.adjacencyList.add(this.adjacencyList.get(i).intValue()); + } + return vertex; + } + +} diff --git a/algorithms/Karagiorgou_tracebundle/LICENSE-2.0.txt b/algorithms/Karagiorgou_tracebundle/LICENSE-2.0.txt new file mode 100755 index 0000000..f433b1a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/LICENSE-2.0.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/algorithms/Karagiorgou_tracebundle/NOTICE.txt b/algorithms/Karagiorgou_tracebundle/NOTICE.txt new file mode 100755 index 0000000..a34e149 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/NOTICE.txt @@ -0,0 +1,29 @@ + +Copyright 2013 Sophia Karagiorgou and Dieter Pfoser + +This software was developed at the Institute for Management of Information +Systems (IMIS), Research Center ATHENA, Greece +in collaboration with George Mason University. + +This material is based upon work supported by the +European Union Seventh Framework Programme - +Marie Curie Actions, Initial Training Network GEOCROWD +(http://www.geocrowd.eu) under grant agreement No. FP7- +PEOPLE-2010-ITN-264994. + +This software is based on the following article(s). Please cite this +article when using this code as part of a research publication: + +S. Karagiorgou and D. Pfoser. +On Vehicle Tracking Data-Based Road Network Generation. +In Proc. 20th ACM SIGSPATIAL GIS Conference, pp. 89-98, 2012. + +S. Karagiorgou and D. Pfoser. +Segmentation-Based Road Network Construction. +In Proc. 21th ACM SIGSPATIAL GIS Conference, pp. 470-473, 2013. + + + +The original software is available from + http://www.mapconstruction.org/ + diff --git a/algorithms/Karagiorgou_tracebundle/README.txt b/algorithms/Karagiorgou_tracebundle/README.txt new file mode 100644 index 0000000..08d91a5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/README.txt @@ -0,0 +1,9 @@ +1) Add the two directories /source and /libraries to the current working path of the MATLAB +2) The source code is in the /source directory +3) The trajectory files should be in the form of: +4) You should firstly run the intersection_nodes_extraction.m file + This file loads trajectories and generates intersection nodes +5) You should then run the tracebundle.m file + This file loads trajectories and intersection nodes and generates road network vertices and edges. + It generates two files tracebundle_vertices.txt, tracebundle_edges.txt. +6) For more information, please contact: karagior@gmail.com \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/line_angle.m b/algorithms/Karagiorgou_tracebundle/libraries/line_angle.m new file mode 100644 index 0000000..c7420cf --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/line_angle.m @@ -0,0 +1,28 @@ +function a = line_angle(varargin) +% Computes the angle of the line segments with respect to +% the four quadrant coordinate system. + +% process input arguments +if length(varargin)==2 + p1 = varargin{1}; + p2 = varargin{2}; +elseif length(varargin)==1 + var = varargin{1}; + p1 = var(1,:); + p2 = var(2,:); +end + +% ensure data have same size +if size(p1, 1)==1 + p1 = p1(ones(size(p2,1), 1), :); +elseif size(p2, 1)==1 + p2 = p2(ones(size(p1,1), 1), :); +elseif size(p1, 1)~=size(p2, 1) + error('angle2Points: wrong size for inputs'); +end + +% angle of line (P2 P1) +dp = p2-p1; +theta = mod(atan2(dp(:,2), dp(:,1)) + 2*pi, 2*pi); + +a=theta*180/pi; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/lines_angle.m b/algorithms/Karagiorgou_tracebundle/libraries/lines_angle.m new file mode 100644 index 0000000..96e1c9b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/lines_angle.m @@ -0,0 +1,3 @@ +function p = lines_angle(P,R,S,T) +% Returns the angle between two lines PR, ST in degrees. +p = (rad2deg(angle2Points(P,R))-rad2deg(angle2Points(S,T))); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/Contents.m new file mode 100644 index 0000000..48f9aea --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/Contents.m @@ -0,0 +1,29 @@ +%MATGEOM Geometric Computing Toolbox +% Version 1.0 21-Mar-2011 . +% +% MatGeom Provides low-level functions for geometric computing. It is +% possible to create, display, compute intersections... of various +% geometrical primitives, in 2D and 3D. +% +% The library is organized into several modules: +% geom2d - General function in euclidean plane +% polygons2d - Functions operating on point lists +% polynomialCurves2d - Representation of smooth polynomial curves +% geom3d - General function in 3D euclidean space +% meshes3d - Manipulation of 3D surfacic meshes +% +% Type 'help(MODULENAME)' for further info. +% +% To install the library, with all sub-directories, run the script +% 'setupMatGeom'. +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-03-21, using Matlab 7.9.0.529 (R2009b) +% Homepage: http://matgeom.sourceforge.net/ +% http://www.pfl-cepia.inra.fr/index.php?page=geom3d +% Copyright 2011 INRA - Cepia Software Platform. + +help(mfilename); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/Contents.m new file mode 100644 index 0000000..a837bab --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/Contents.m @@ -0,0 +1,210 @@ +% GEOM2D Geometry 2D Toolbox +% Version 1.0 21-Mar-2011 . +% +% Library to handle and visualize geometric primitives such as points, +% lines, circles and ellipses, polygons... +% +% The goal is to provide a low-level library for manipulating geometrical +% primitives, making easier the development of more complex geometric +% algorithms. +% +% Most functions works for planar shapes, but some ones have been +% extended to 3D or to any dimension. +% +% Points +% points2d - Description of functions operating on points +% clipPoints - Clip a set of points by a box +% centroid - Compute centroid (center of mass) of a set of points +% boundingBox - Bounding box of a set of points +% midPoint - Middle point of two points or of an edge +% circumCenter - Circumcenter of three points +% isCounterClockwise - Compute relative orientation of 3 points +% polarPoint - Create a point from polar coordinates (rho + theta) +% angle2Points - Compute horizontal angle between 2 points +% angle3Points - Compute oriented angle made by 3 points +% angleSort - Sort points in the plane according to their angle to origin +% distancePoints - Compute distance between two points +% minDistancePoints - Minimal distance between several points +% nndist - Nearest-neighbor distances of each point in a set +% transformPoint - Transform a point with an affine transform +% drawPoint - Draw the point on the axis. +% +% Vectors +% vectors2d - Description of functions operating on plane vectors +% createVector - Create a vector from two points +% vectorNorm - Compute norm of a vector, or of a set of vectors +% vectorAngle - Angle of a vector, or between 2 vectors +% normalizeVector - Normalize a vector to have norm equal to 1 +% isPerpendicular - Check orthogonality of two vectors +% isParallel - Check parallelism of two vectors +% transformVector - Transform a vector with an affine transform +% rotateVector - Rotate a vector by a given angle +% +% Straight lines +% lines2d - Description of functions operating on planar lines +% createLine - Create a straight line from 2 points, or from other inputs +% medianLine - Create a median line between two points +% cartesianLine - Create a straight line from cartesian equation coefficients +% orthogonalLine - Create a line orthogonal to another one. +% parallelLine - Create a line parallel to another one. +% intersectLines - Return all intersection points of N lines in 2D +% lineAngle - Computes angle between two straight lines +% linePosition - Position of a point on a line +% lineFit - Fit a straight line to a set of points +% clipLine - Clip a line with a box +% reverseLine - Return same line but with opposite orientation +% transformLine - Transform a line with an affine transform +% drawLine - Draw the line on the current axis +% +% Edges (line segments between 2 points) +% edges2d - Description of functions operating on planar edges +% createEdge - Create an edge between two points, or from a line +% edgeToLine - Convert an edge to a straight line +% edgeAngle - Return angle of edge +% edgeLength - Return length of an edge +% midPoint - Middle point of two points or of an edge +% edgePosition - Return position of a point on an edge +% clipEdge - Clip an edge with a rectangular box +% reverseEdge - Intervert the source and target vertices of edge +% intersectEdges - Return all intersections between two set of edges +% intersectLineEdge - Return intersection between a line and an edge +% transformEdge - Transform an edge with an affine transform +% edgeToPolyline - Convert an edge to a polyline with a given number of segments +% drawEdge - Draw an edge given by 2 points +% drawCenteredEdge - Draw an edge centered on a point +% +% Rays +% rays2d - Description of functions operating on planar rays +% createRay - Create a ray (half-line), from various inputs +% bisector - Return the bisector of two lines, or 3 points +% clipRay - Clip a ray with a box +% drawRay - Draw a ray on the current axis +% +% Relations between points and lines +% distancePointEdge - Minimum distance between a point and an edge +% distancePointLine - Minimum distance between a point and a line +% projPointOnLine - Project of a point orthogonally onto a line +% pointOnLine - Create a point on a line at a given position on the line +% isPointOnLine - Test if a point belongs to a line +% isPointOnEdge - Test if a point belongs to an edge +% isPointOnRay - Test if a point belongs to a ray +% isLeftOriented - Test if a point is on the left side of a line +% +% Circles +% circles2d - Description of functions operating on circles +% createCircle - Create a circle from 2 or 3 points +% createDirectedCircle - Create a directed circle +% intersectCircles - Intersection points of two circles +% intersectLineCircle - Intersection point(s) of a line and a circle +% circleToPolygon - Convert a circle into a series of points +% circleArcToPolyline - Convert a circle arc into a series of points +% isPointInCircle - Test if a point is located inside a given circle +% isPointOnCircle - Test if a point is located on a given circle. +% enclosingCircle - Find the minimum circle enclosing a set of points. +% radicalAxis - Compute the radical axis (or radical line) of 2 circles +% drawCircle - Draw a circle on the current axis +% drawCircleArc - Draw a circle arc on the current axis +% circumCircle - Circumscribed circle of a triangle +% +% Ellipses and Parabola +% ellipses2d - Description of functions operating on ellipses +% inertiaEllipse - Inertia ellipse of a set of points +% isPointInEllipse - Check if a point is located inside a given ellipse +% ellipseToPolygon - Convert an ellipse into a series of points +% drawEllipse - Draw an ellipse on the current axis +% drawEllipseArc - Draw an ellipse arc on the current axis +% drawParabola - Draw a parabola on the current axis +% +% Geometric transforms +% transforms2d - Description of functions operating on transforms +% createTranslation - Create the 3*3 matrix of a translation +% createRotation - Create the 3*3 matrix of a rotation +% createScaling - Create the 3*3 matrix of a scaling in 2 dimensions +% createHomothecy - Create the the 3x3 matrix of an homothetic transform +% createBasisTransform - Compute matrix for transforming a basis into another basis +% createLineReflection - Create the the 3x3 matrix of a line reflection +% fitAffineTransform2d - Fit an affine transform using two point sets +% +% Angles +% angles2d - Description of functions for manipulating angles +% normalizeAngle - Normalize an angle value within a 2*PI interval +% angleAbsDiff - Absolute difference between two angles +% angleDiff - Difference between two angles +% deg2rad - Convert angle from degrees to radians +% rad2deg - Convert angle from radians to degrees +% +% Boxes +% boxes2d - Description of functions operating on bounding boxes +% intersectBoxes - Intersection of two bounding boxes +% mergeBoxes - Merge two boxes, by computing their greatest extent +% randomPointInBox - Generate random point within a box +% drawBox - Draw a box defined by coordinate extents +% +% Triangles +% isPointInTriangle - Test if a point is located inside a triangle +% triangleArea - Signed area of a triangle +% +% Rectangles +% rectToPolygon - Convert a rectangle into a polygon (set of vertices) +% drawRect - Draw rectangle on the current axis +% orientedBoxToPolygon - Convert an oriented box to a polygon (set of vertices) +% drawOrientedBox - Draw centered oriented rectangle +% +% Splines +% cubicBezierToPolyline - Compute equivalent polyline from bezier curve control +% drawBezierCurve - Draw a cubic bezier curve defined by 4 control points +% +% Various drawing functions +% drawArrow - Draw an arrow on the current axis +% drawLabels - Draw labels at specified positions +% drawShape - Draw various types of shapes (circles, polygons...) +% +% Other shapes +% squareGrid - Generate equally spaces points in plane. +% hexagonalGrid - Generate hexagonal grid of points in the plane. +% triangleGrid - Generate triangular grid of points in the plane. +% crackPattern - Create a (bounded) crack pattern tessellation +% crackPattern2 - Create a (bounded) crack pattern tessellation +% +% +% Credits: +% * function 'enclosingCircle' rewritten from a file from Yazan Ahed +% (yash78@gmail.com), available on Matlab File Exchange +% +% ----- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-07 +% Copyright INRA - Cepia Software Platform. +% Homepage: http://matgeom.sourceforge.net/ +% http://www.pfl-cepia.inra.fr/index.php?page=geom2d + +help('Contents'); + + +%% Deprecated functions + +% createMedian - create a median line +% minDistance - compute minimum distance between a point and a set of points +% homothecy - create a homothecy as an affine transform +% rotation - return 3*3 matrix of a rotation +% translation - return 3*3 matrix of a translation +% scaling - return 3*3 matrix of a scaling in 2 dimensions +% lineSymmetry - create line symmetry as 2D affine transform +% vecnorm - compute norm of vector or of set of vectors +% normalize - normalize a vector +% onCircle - test if a point is located on a given circle. +% inCircle - test if a point is located inside a given circle. +% onEdge - test if a point belongs to an edge +% onLine - test if a point belongs to a line +% onRay - test if a point belongs to a ray +% invertLine - return same line but with opposite orientation +% clipLineRect - clip a line with a polygon +% formatAngle - Ensure an angle value is comprised between 0 and 2*PI +% drawRect2 - Draw centered rectangle on the current axis +% circleAsPolygon - Convert a circle into a series of points +% circleArcAsCurve - Convert a circle arc into a series of points +% ellipseAsPolygon - Convert an ellipse into a series of points + + +%% Others... diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle2Points.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle2Points.m new file mode 100644 index 0000000..eaf4376 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle2Points.m @@ -0,0 +1,43 @@ +function theta = angle2Points(varargin) +%ANGLE2POINTS Compute horizontal angle between 2 points +% +% ALPHA = angle2Points(P1, P2), +% Pi are either [1*2] arrays, or [N*2] arrays, in this case ALPHA is a +% [N*1] array. The angle computed is the horizontal angle of the line +% (P1 P2) +% Result is always given in radians, between 0 and 2*pi. +% +% See Also: +% points2d, angles2d, angle3points, normalizeAngle, vectorAngle +% +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 02/03/2007. +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY: +% 2011-01-11 use bsxfun + +% process input arguments +if length(varargin)==2 + p1 = varargin{1}; + p2 = varargin{2}; +elseif length(varargin)==1 + var = varargin{1}; + p1 = var(1,:); + p2 = var(2,:); +end + +% ensure data have correct size +n1 = size(p1, 1); +n2 = size(p2, 1); +if n1~=n2 && min(n1, n2)>1 + error('angle2Points: wrong size for inputs'); +end + +% angle of line (P2 P1), between 0 and 2*pi. +dp = bsxfun(@minus, p2, p1); +theta = mod(atan2(dp(:,2), dp(:,1)) + 2*pi, 2*pi); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle3Points.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle3Points.m new file mode 100644 index 0000000..dc3e419 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angle3Points.m @@ -0,0 +1,38 @@ +function theta = angle3Points(varargin) +%ANGLE3POINTS Compute oriented angle made by 3 points +% +% ALPHA = angle3Points(P1, P2, P3); +% Computes the angle between the points P1, P2 and P3. +% Pi are either [1*2] arrays, or [N*2] arrays, in this case ALPHA is a +% [N*1] array. The angle computed is the directed angle between line +% (P2P1) and line (P2P3). +% Result is always given in radians, between 0 and 2*pi. +% +% See Also: +% points2d, angles2d, angle2points +% +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 23/02/2004. +% Copyright 2010 INRA - Cepia Software Platform. + + +% HISTORY : +% 25/09/2005 : enable single parameter + +if length(varargin)==3 + p1 = varargin{1}; + p2 = varargin{2}; + p3 = varargin{3}; +elseif length(varargin)==1 + var = varargin{1}; + p1 = var(1,:); + p2 = var(2,:); + p3 = var(3,:); +end + +% angle line (P2 P1) +theta = lineAngle(createLine(p2, p1), createLine(p2, p3)); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleAbsDiff.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleAbsDiff.m new file mode 100644 index 0000000..6e811b2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleAbsDiff.m @@ -0,0 +1,28 @@ +function dif = angleAbsDiff(angle1, angle2) +%ANGLEABSDIFF Absolute difference between two angles +% +% AD = angleAbsDiff(ANGLE1, ANGLE2) +% Computes the absolute angular difference between two angles in radians. +% The result is comprised between 0 and PI. +% +% Example +% A = angleAbsDiff(pi/2, pi/3) +% A = +% 0.5236 % equal to pi/6 +% +% See also +% angles2d, angleDiff +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-07-27, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% first, normalization +angle1 = normalizeAngle(angle1); +angle2 = normalizeAngle(angle2); + +% compute difference and normalize +dif = normalizeAngle(angle1 - angle2); +dif = min(dif, 2*pi - dif); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleDiff.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleDiff.m new file mode 100644 index 0000000..ede29a7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleDiff.m @@ -0,0 +1,29 @@ +function dif = angleDiff(angle1, angle2) +%ANGLEDIFF Difference between two angles +% +% Computes the signed angular difference between two angles in radians. +% The result is comprised between -PI and +PI. +% +% Example +% A = angleDiff(-pi/4, pi/4) +% A = +% 1.5708 % equal to pi/2 +% A = angleDiff(pi/4, -pi/4) +% A = +% -1.5708 % equal to -pi/2 +% +% See also +% angles2d, angleAbsDiff +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-07-27, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% first, normalization +angle1 = normalizeAngle(angle1); +angle2 = normalizeAngle(angle2); + +% compute difference and normalize in [-pi pi] +dif = normalizeAngle(angle2 - angle1, 0); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleSort.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleSort.m new file mode 100644 index 0000000..da9167f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angleSort.m @@ -0,0 +1,65 @@ +function varargout = angleSort(pts, varargin) +%ANGLESORT Sort points in the plane according to their angle to origin +% +% +% PTS2 = angleSort(PTS); +% Computes angle of points with origin, and sort points with increasing +% angles in Counter-Clockwise direction. +% +% PTS2 = angleSort(PTS, PTS0); +% Computes angles between each point of PTS and PT0, which can be +% different from origin. +% +% PTS2 = angleSort(..., THETA0); +% Specifies the starting angle for sorting. +% +% [PTS2, I] = angleSort(...); +% Also returns in I the indices of PTS, such that PTS2 = PTS(I, :); +% +% See Also: +% points2d, angles2d, angle2points, normalizeAngle +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-24 +% Copyright 2010 INRA - Cepia Software Platform. + + +% HISTORY : + +% default values +pt0 = [0 0]; +theta0 = 0; + +if length(varargin)==1 + var = varargin{1}; + if size(var, 2)==1 + % specify angle + theta0 = var; + else + pt0 = var; + end +elseif length(varargin)==2 + pt0 = varargin{1}; + theta0 = varargin{2}; +end + + +n = size(pts, 1); +pts2 = pts - repmat(pt0, [n 1]); +angle = lineAngle([zeros(n, 2) pts2]); +angle = mod(angle - theta0 + 2*pi, 2*pi); + +[dummy, I] = sort(angle); + +% format output +if nargout<2 + varargout{1} = pts(I, :); +elseif nargout==2 + varargout{1} = pts(I, :); + varargout{2} = I; +end + + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angles2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angles2d.m new file mode 100644 index 0000000..0341883 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/angles2d.m @@ -0,0 +1,24 @@ +function angles2d +%ANGLES2D Description of functions for manipulating angles +% +% Angles are normalized in an interval of width 2*PI. Most geom2d +% functions return results in the [0 2*pi] interval, but it can be +% convenient to consider the [-pi pi] interval as well. See the +% normalizeAngle function to switch between conventions. +% +% Angles are usually oriented. The default orientation is the CCW +% (Counter-Clockwise) orientation. +% +% See also: +% normalizeAngle, angleDiff, angleAbsDiff, angleSort +% angle2Points, angle3Points, vectorAngle, lineAngle, edgeAngle +% deg2rad, rad2deg +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-03-31, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + + +help('angles2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/bisector.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/bisector.m new file mode 100644 index 0000000..d0c6f83 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/bisector.m @@ -0,0 +1,64 @@ +function ray = bisector(varargin) +%BISECTOR Return the bisector of two lines, or 3 points +% +% RAY = bisector(LINE1, LINE2); +% create the bisector of the two lines, given as [x0 y0 dx dy]. +% +% RAY = bisector(P1, P2, P3); +% create the bisector of lines (P2 P1) and (P2 P3). +% +% The result has the form [x0 y0 dx dy], with [x0 y0] being the origin +% point ans [dx dy] being the direction vector, normalized to have unit +% norm. +% +% See also: +% lines2d, rays2d +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 31/10/2003. +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2005-07-07 add bisector of 3 points +% 2010-11-05 ode cleanup + +if length(varargin)==2 + % two lines + line1 = varargin{1}; + line2 = varargin{2}; + + point = intersectLines(line1, line2); + +elseif length(varargin)==3 + % three points + p1 = varargin{1}; + p2 = varargin{2}; + p3 = varargin{3}; + + line1 = createLine(p2, p1); + line2 = createLine(p2, p3); + point = p2; + +elseif length(varargin)==1 + % three points, given in one array + var = varargin{1}; + p1 = var(1, :); + p2 = var(2, :); + p3 = var(3, :); + + line1 = createLine(p2, p1); + line2 = createLine(p2, p3); + point = p2; +end + +% compute line angles +a1 = lineAngle(line1); +a2 = lineAngle(line2); + +% compute bisector angle (angle of first line + half angle between lines) +angle = mod(a1 + mod(a2-a1+2*pi, 2*pi)/2, pi*2); + +% create the resulting ray +ray = [point cos(angle) sin(angle)]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boundingBox.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boundingBox.m new file mode 100644 index 0000000..e8aae06 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boundingBox.m @@ -0,0 +1,44 @@ +function box = boundingBox(points) +%BOUNDINGBOX Bounding box of a set of points +% +% BOX = boundingBox(POINTS) +% Returns the bounding box of the set of points POINTS. POINTS can be +% either a N-by-2 or N-by-3 array. The result BOX is a 1-by-4 or 1-by-6 +% array, containing: +% [XMIN XMAX YMIN YMAX] (2D point sets) +% [XMIN XMAX YMIN YMAX ZMIN ZMAX] (3D point sets) +% +% Example +% % Draw the bounding box of a set of random points +% points = rand(30, 2); +% drawPoint(points, '.'); +% hold on; +% box = boundingBox(points); +% drawBox(box, 'r'); +% +% See also +% polygonBounds, drawBox +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-01, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2011-04-08 add example +% 2011-12-09 rename to boundingBox + +% compute extreme x and y values +xmin = min(points(:,1)); +xmax = max(points(:,1)); +ymin = min(points(:,2)); +ymax = max(points(:,2)); +box = [xmin xmax ymin ymax]; + +% process case of 3D points +if size(points, 2) > 2 + zmin = min(points(:,3)); + zmax = max(points(:,3)); + box = [xmin xmax ymin ymax zmin zmax]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boxes2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boxes2d.m new file mode 100644 index 0000000..b68418d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/boxes2d.m @@ -0,0 +1,21 @@ +function boxes2d(varargin) +%BOXES2D Description of functions operating on bounding boxes +% +% A box is represented as a set of limits in each direction: +% BOX = [XMIN XMAX YMIN YMAX]. +% +% Boxes are used as result of computation for bounding boxes, and to clip +% shapes. +% +% See also +% boundingBox, lipPoints, clipLine, clipEdge, clipRay +% mergeBoxes, intersectBoxes, randomPointInBox +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +help('boxes2d'); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cartesianLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cartesianLine.m new file mode 100644 index 0000000..208eef4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cartesianLine.m @@ -0,0 +1,38 @@ +function line = cartesianLine(varargin) +%CARTESIANLINE Create a straight line from cartesian equation coefficients +% +% L = cartesianLine(A, B, C); +% Create a line verifying the Cartesian equation: +% A*x + B*x + C = 0; +% +% See also: +% lines2d, createLine +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 25/05/2004. +% Copyright 2010 INRA - Cepia Software Platform. + + +if length(varargin)==1 + var = varargin{1}; + a = var(:,1); + b = var(:,2); + c = var(:,3); +elseif length(varargin)==3 + a = varargin{1}; + b = varargin{2}; + c = varargin{3}; +end + +% normalisation factor +d = a.*a + b.*b; + +x0 = -a.*c./d; +y0 = -b.*c./d; +theta = atan2(-a, b); +dx = cos(theta); +dy = sin(theta); + +line = [x0 y0 dx dy]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/centroid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/centroid.m new file mode 100644 index 0000000..9d2673f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/centroid.m @@ -0,0 +1,82 @@ +function center = centroid(varargin) +%CENTROID Compute centroid (center of mass) of a set of points +% +% PTS = centroid(POINTS) +% PTS = centroid(PTX, PTY) +% Computes the ND-dimensional centroid of a set of points. +% POINTS is an array with as many rows as the number of points, and as +% many columns as the number of dimensions. +% PTX and PTY are two column vectors containing coordinates of the +% 2-dimensional points. +% The result PTS is a row vector with Nd columns. +% +% PTS = centroid(POINTS, MASS) +% PTS = centroid(PTX, PTY, MASS) +% Computes center of mass of POINTS, weighted by coefficient MASS. +% POINTS is a Np-by-Nd array, MASS is Np-by-1 array, and PTX and PTY are +% also both Np-by-1 arrays. +% +% Example: +% pts = [2 2;6 1;6 5;2 4]; +% centroid(pts) +% ans = +% 4 3 +% +% See Also: +% points2d, polygonCentroid +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 07/04/2003. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 2009-06-22 support for 3D points +% 2010-04-12 fix bug in weighted centroid +% 2010-12-06 update doc + + +%% extract input arguments + +% use empty mass by default +mass = []; + +if nargin==1 + % give only array of points + pts = varargin{1}; + +elseif nargin==2 + % either POINTS+MASS or PX+PY + var = varargin{1}; + if size(var, 2)>1 + % arguments are POINTS, and MASS + pts = var; + mass = varargin{2}; + else + % arguments are PX and PY + pts = [var varargin{2}]; + end + +elseif nargin==3 + % arguments are PX, PY, and MASS + pts = [varargin{1} varargin{2}]; + mass = varargin{3}; +end + +%% compute centroid + +if isempty(mass) + % no weight + center = mean(pts); + +else + % format mass to have sum equal to 1, and column format + mass = mass(:)/sum(mass(:)); + + % compute weighted centroid + center = sum(bsxfun(@times, pts, mass), 1); + % equivalent to: + % center = sum(pts .* mass(:, ones(1, size(pts, 2)))); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/changelog.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/changelog.txt new file mode 100644 index 0000000..994c753 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/changelog.txt @@ -0,0 +1,158 @@ +change log for geom2d + +geom2d, release 2011.??.?? +========================== + +New functions +- added angleDiff and angleAbsDiff + +various doc updates + + +geom2d, release 2011.06.30 +========================== + +New functions +- added function rotateVector +- added function randomPointInBox + +Changes +- Shape orientation is now represented using degrees +- function vectorAngle can now compute the angle between two vectors + +Bug fixes +- enhanced function distancePointEdge +- enhanced function isPointOnEdge +- enhanced function isParallel +- fixed bugs intersectLineCircle + + +geom2d, release 2011.03.21 +========================== + +New functions +- added functions intersectLineCircle and intersectCircles +- added functions inertiaEllipse, isPointInEllipse +- added function drawBezierCurve +- added functions intersectBoxes and mergeBoxes + +Changes +- re-organized the library in three sub-directories: geom2d, polygons2d, and + polynomialCurves2d +- cleanup of code and doc + +Bug fixes +- several bugs fixed in clipEdge, isPointOnEdge + + +geom2d, release 2010.08.06 +========================== + +New functions +- polygonToRow and rowToPolygon, to convert polygon to a row vector +- midPoint, to compute middle points of either 2 points or an edge +- added rad2deg and deg2rad, for angle conversions + +Changes +- createCircle and createdirectedCircle are now vectorized, and use different + convention for 2 input variables (center + point and circle) +- median line has been vectorized + +Bug fixes +- fix bugs in intersectEdges +- fix bugs in clipLine +- rewrite drawLine using clipLine + + +geom2d, release 2010.07.19 +========================== + +new functions + +- isCounterClockwise +- intersectRayPolygon +- clipRay +- reverseEdge +- drawBox +- fitAffineTransform2d + +Changes + +- updated inertiaEllipse +- fixed bugs in intersectEdges.m, isParallel.m and isPerpendicular.m +- vectorized intersectLinePolygon +- fixed precision bug in isPointOnEdge +- renamed formatAngle to normalizeAngle +- created help file 'angles2d' +- fixed bug in weighted centroid computation + +various bug fixes, and doc updates. + + + +geom2d, release 2009.07.22 +========================== + +new features + +- new functions for polygons: + polygonPoint, polygonSubcurve, polygonLoops, distancePointPolygon, + distancePolygons, expandPolygon, polygonSelfIntersections, + projPointOnPolygon, isPointInPolygon, reveresPolygon + +- new functions for polylines: + intersectPolylines, polylineSelfIntersections, distancePolylines, + isPointOnPolyline, reveresPolyline + +- projPointOnPolyline can also return the distance of the point to the polyline + +- function 'edgeToLine' converts an edge to its supporting line + + +Changes + +- Renamed functions + + subcurve -> polylineSubCurve + + curveCentroid -> polylineCentroid + + invertLine -> reverseLine + +- Compatibility considerations + + parallelLine: changed convention for signed distance + +various bug fixes, and doc updates. + + +geom2d, release 2009.06.15 +========================== + +* new features + +- radicalAxis from 2 circles: +- moment of a curve (polyline): curveMoment, curveCMoment, curveCSMoment +- new functions for polylines + distancePointPolyline, drawPolyline, polylineLength, polylinePoint, + polylineSubcurve, projPointOnPolyline + +* changes + +- changed some function names to avoid potential name conflicts, and to make + function names more explicit: + + rotation -> createRotation + + scaling -> createScaling + + translation -> createRotation + + homothecy -> createHomothecy + + lineSymmetry -> createLineReflection + + inCircle -> isPointInCircle + + onCircle -> isPointOnCircle + + onEdge -> isPointOnEdge + + onLine -> isPointOnLine + + onRay -> isPointOnRay + + normalize -> normalizeVector + + +* bug fixes + +- fixed bug in intersectEdges + +many updates in doc. + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcAsCurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcAsCurve.m new file mode 100644 index 0000000..39b43f7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcAsCurve.m @@ -0,0 +1,27 @@ +function varargout = circleArcAsCurve(arc, N) +%CIRCLEARCASCURVE Convert a circle arc into a series of points +% +% deprecated: replaced by circleArcToPolyline +% +% +% --------- +% author : David Legland +% created the 22/05/2006. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 2011-03-30 use angles in degrees, add default value for N +% 2011-12-09 deprecate + + +warning('matGeom:deprecated', ... + 'function "circleArcAsCurve" is deprecated, use "circleArcToPolygon" instead'); + +% format output +if nargout <= 1 + varargout = {circleArcToPolyline(arc, N)}; +else + [x y] = circleArcToPolyline(arc, N); + varargout = {x, y}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcToPolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcToPolyline.m new file mode 100644 index 0000000..822272c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleArcToPolyline.m @@ -0,0 +1,52 @@ +function varargout = circleArcToPolyline(arc, N) +%CIRCLEARCTOPOLYLINE Convert a circle arc into a series of points +% +% P = circleArcToPolyline(ARC, N); +% convert the circle ARC into a series of N points. +% ARC is given in the format: [XC YC R THETA1 DTHETA] +% where XC and YC define the center of the circle, R its radius, THETA1 +% is the start of the arc and DTHETA is the angle extent of the arc. Both +% angles are given in degrees. +% N is the number of vertices of the resulting polyline, default is 65. +% +% The result is a N-by-2 array containing coordinates of the N points. +% +% [X Y] = circleArcToPolyline(ARC, N); +% Return the result in two separate arrays with N lines and 1 column. +% +% +% See also: +% circles2d, circleToPolygon, drawCircle, drawPolygon +% +% +% --------- +% author : David Legland +% created the 22/05/2006. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 2011-03-30 use angles in degrees, add default value for N +% 2011-12-09 rename to circleArcToPolyline + + +% default value for N +if nargin < 2 + N = 65; +end + +% vector of positions +t0 = deg2rad(arc(4)); +t1 = t0 + deg2rad(arc(5)); +t = linspace(t0, t1, N)'; + +% compute coordinates of vertices +x = arc(1) + arc(3) * cos(t); +y = arc(2) + arc(3) * sin(t); + +% format output +if nargout <= 1 + varargout = {[x y]}; +else + varargout = {x, y}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleAsPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleAsPolygon.m new file mode 100644 index 0000000..9cd52b2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleAsPolygon.m @@ -0,0 +1,40 @@ +function varargout = circleAsPolygon(circle, varargin) +%CIRCLEASPOLYGON Convert a circle into a series of points +% +% P = circleAsPolygon(CIRCLE, N); +% convert circle given as [x0 y0 r], where x0 and y0 are coordinate of +% center, and r is the radius, into an array of [(N+1)x2] double, +% containing x and y values of points. +% The polygon is closed +% +% P = circleAsPolygon(CIRCLE); +% uses a default value of N=64 points +% +% Example +% circle = circleAsPolygon([10 0 5], 16); +% figure; +% drawPolygon(circle); +% +% See also: +% circles2d, polygons2d, createCircle +% +% +% --------- +% author : David Legland +% created the 06/04/2005. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 20/04/2007: return a closed polygon with N+1 vertices, use default N=64 + +warning('matGeom:deprecated', ... + 'function "circleAsPolygon" is deprecated, use "circleToPolygon" instead'); + +% format output +if nargout <= 1 + varargout = {circleToPolygon(circle, varargin{:})}; +else + [x y] = circleToPolygon(circle, varargin{:}); + varargout = {x, y}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleToPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleToPolygon.m new file mode 100644 index 0000000..f7a29a6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circleToPolygon.m @@ -0,0 +1,48 @@ +function varargout = circleToPolygon(circle, varargin) +%CIRCLETOPOLYGON Convert a circle into a series of points +% +% P = circleToPolygon(CIRCLE, N); +% convert circle given as [x0 y0 r], where x0 and y0 are coordinate of +% center, and r is the radius, into an array of [(N+1)x2] double, +% containing x and y values of points. +% The polygon is closed +% +% P = circleToPolygon(CIRCLE); +% uses a default value of N=64 points +% +% Example +% circle = circleToPolygon([10 0 5], 16); +% figure; +% drawPolygon(circle); +% +% See also: +% circles2d, polygons2d, circleArcToPolyline, ellipseToPolygon +% +% +% --------- +% author : David Legland +% created the 06/04/2005. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 2007-04-20 return a closed polygon with N+1 vertices, use default N=64 +% 2011-12-09 rename to 'circleToPolygon' + +% determines number of points +N = 64; +if ~isempty(varargin) + N = varargin{1}; +end + +% create circle +t = linspace(0, 2*pi, N+1)'; +x = circle(1) + circle(3) * cos(t); +y = circle(2) + circle(3) * sin(t); + +if nargout == 1 + varargout{1} = [x y]; +elseif nargout == 2 + varargout{1} = x; + varargout{2} = y; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circles2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circles2d.m new file mode 100644 index 0000000..7b0c30b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circles2d.m @@ -0,0 +1,31 @@ +function circles2d(varargin) +%CIRCLES2D Description of functions operating on circles +% +% Circles are represented by their center and their radius: +% C = [xc yc r]; +% One sometimes considers orientation of circle, by adding an extra +% boolean value in 4-th position, with value TRUE for direct (i.e. +% turning Counter-clockwise) circles. +% +% Circle arcs are represented by their center, their radius, the starting +% angle and the angle extent, both in degrees: +% CA = [xc yc r theta0 dtheta]; +% +% Ellipses are represented by their center, their 2 semi-axis length, and +% their angle (in degrees) with Ox direction. +% E = [xc yc A B theta]; +% +% See also: +% ellipses2d, createCircle, createDirectedCircle, +% isPointInCircle, isPointOnCircle, enclosingCircle, triangleCircumCircle +% intersectLineCircle, intersectCircles, radicalAxis +% circleToPolygon, circleArcToPolyline +% drawCircle, drawCircleArc +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +help('circles2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCenter.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCenter.m new file mode 100644 index 0000000..d27ad4c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCenter.m @@ -0,0 +1,38 @@ +function varargout = circumCenter(a, b, c) +%CIRCUMCENTER Circumcenter of three points +% +% CC = circumCenter(P1, P2, P3) +% +% Example +% circumcenter +% +% See also +% points2d, circumCircle, centroid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% pre-compute some terms +ah = sum(a .^ 2); +bh = sum(b .^ 2); +ch = sum(c .^ 2); + +dab = a - b; +dbc = b - c; +dca = c - a; + +% common denominator +D = .5 / (a(1) * dbc(2) + b(1) * dca(2) + c(1) * dab(2)); + +% center coordinates +xc = (ah * dbc(2) + bh * dca(2) + ch * dab(2) ) * D; +yc = -(ah * dbc(1) + bh * dca(1) + ch * dab(1) ) * D; + +if nargout <= 1 + varargout = {[xc yc]}; +else + varargout = {xc, yc}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCircle.m new file mode 100644 index 0000000..91e5b40 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/circumCircle.m @@ -0,0 +1,34 @@ +function varargout = circumCircle(varargin) +%CIRCUMCIRCLE Circumscribed circle of a triangle +% +% CIRC = circumCircle(TRI) +% CIRC = circumCircle(P1, P2, P3) +% Compute circumcircle of a triangle given by 3 points. +% +% Example +% T = [10 20; 70 20; 30 70]; +% C = circumCircle(T); +% figure; drawPolygon(T, 'linewidth', 2); +% hold on; drawCircle(C); +% axis equal; axis([0 100 0 100]); +% +% See also +% enclosingCircle, circumCenter +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-01, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% extract the three points +[a b c] = parseThreePoints(varargin{:}); + +% circle center +center = circumCenter(a, b, c); + +% radius +r = distancePoints(center, a); + +% format output +varargout = {[center r]}; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipEdge.m new file mode 100644 index 0000000..9f17366 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipEdge.m @@ -0,0 +1,123 @@ +function edge2 = clipEdge(edge, box) +%CLIPEDGE Clip an edge with a rectangular box +% +% EDGE2 = clipEdge(EDGE, BOX); +% EDGE: [x1 y1 x2 y2], +% BOX : [xmin xmax ; ymin ymax] or [xmin xmax ymin ymax]; +% return : +% EDGE2 = [xc1 yc1 xc2 yc2]; +% +% If clipping is null, return [0 0 0 0]; +% +% if EDGE is a [nx4] array, return an [nx4] array, corresponding to each +% clipped edge. +% +% See also +% edges2d, boxes2d, clipLine +% +% --------- +% author : David Legland +% created the 14/05/2005. +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2007-01-08 sort points according to position on edge, not to x coord +% -> this allows to return edges with same orientation a source, and +% to keep first or end points at the same position if their are not +% clipped. +% 01/10/2010 fix bug due to precision, thanks to Reto Zingg. + +% process data input +if size(box, 1)==2 + box = box'; +end + +% get limits of window +xmin = box(1); +xmax = box(2); +ymin = box(3); +ymax = box(4); + + +% convert window limits into lines +lineX0 = [xmin ymin xmax-xmin 0]; +lineX1 = [xmin ymax xmax-xmin 0]; +lineY0 = [xmin ymin 0 ymax-ymin]; +lineY1 = [xmax ymin 0 ymax-ymin]; + + +% compute outcodes of each vertex +p11 = edge(:,1)xmax; p22 = edge(:,3)>xmax; +p13 = edge(:,2)ymax; p24 = edge(:,4)>ymax; +out1 = [p11 p12 p13 p14]; +out2 = [p21 p22 p23 p24]; + +% detect edges totally inside window -> no clip. +inside = sum(out1 | out2, 2)==0; + +% detect edges totally outside window +outside = sum(out1 & out2, 2)>0; + +% select edges not totally outside, and process separately edges totally +% inside window +ind = find(~(inside | outside)); + + +edge2 = zeros(size(edge)); +edge2(inside, :) = edge(inside, :); + + +for i=1:length(ind) + % current edge + iedge = edge(ind(i), :); + + % compute intersection points with each line of bounding window + px0 = intersectLineEdge(lineX0, iedge); + px1 = intersectLineEdge(lineX1, iedge); + py0 = intersectLineEdge(lineY0, iedge); + py1 = intersectLineEdge(lineY1, iedge); + + % create array of points + points = [px0; px1; py0; py1; iedge(1:2); iedge(3:4)]; + + % remove infinite points (edges parallel to box edges) + points = points(all(isfinite(points), 2), :); + + % sort points by x then y + points = sortrows(points); + + % get center positions between consecutive points + centers = (points(2:end,:) + points(1:end-1,:))/2; + + % find the centers (if any) inside window + inside = find( centers(:,1)>=xmin & centers(:,2)>=ymin & ... + centers(:,1)<=xmax & centers(:,2)<=ymax); + + % if multiple segments are inside box, which can happen due to finite + % resolution, only take the longest segment + if length(inside)>1 + % compute delta vectors of the segments + dv = points(inside+1,:) - points(inside,:); + % compute lengths of segments + len = hypot(dv(:,1), dv(:,2)); + % find index of longest segment + [a, I] = max(len); %#ok + inside = inside(I); + end + + % if one of the center points is inside box, then the according edge + % segment is indide box + if length(inside)==1 + % restore same direction of edge + if iedge(1)>iedge(3) || (iedge(1)==iedge(3) && iedge(2)>iedge(4)) + edge2(i, :) = [points(inside+1,:) points(inside,:)]; + else + edge2(i, :) = [points(inside,:) points(inside+1,:)]; + end + end + +end % end of loop of edges + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLine.m new file mode 100644 index 0000000..49bd565 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLine.m @@ -0,0 +1,104 @@ +function edge = clipLine(line, box, varargin) +%CLIPLINE Clip a line with a box +% +% EDGE = clipLine(LINE, BOX); +% LINE is a straight line given as a 4 element row vector: [x0 y0 dx dy], +% with (x0 y0) being a point of the line and (dx dy) a direction vector, +% BOX is the clipping box, given by its extreme coordinates: +% [xmin xmax ymin ymax]. +% The result is given as an edge, defined by the coordinates of its 2 +% extreme points: [x1 y1 x2 y2]. +% If line does not intersect the box, [NaN NaN NaN NaN] is returned. +% +% Function works also if LINE is a Nx4 array, if BOX is a Nx4 array, or +% if both LINE and BOX are Nx4 arrays. In these cases, EDGE is a Nx4 +% array. +% +% +% Example +% line = [30 40 10 0]; +% box = [0 100 0 100]; +% res = clipLine(line, box) +% res = +% 0 40 100 40 +% +% See also: +% lines2d, boxes2d, edges2d +% clipEdge, clipRay +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-08-27, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2010-05-16 rewrite using intersectLines, add precision management +% 2010-08-03 fix bugs (thanks to Reto Zingg) +% 2010-08-06 remove management of EPS by checking edge midpoint (thanks +% again to Reto Zingg) + +% adjust size of two input arguments +if size(line, 1)==1 + line = repmat(line, size(box, 1), 1); +elseif size(box, 1)==1 + box = repmat(box, size(line, 1), 1); +elseif size(line, 1) ~= size(box, 1) + error('bad sizes for input'); +end + +% allocate memory +nbLines = size(line, 1); +edge = zeros(nbLines, 4); + +% main loop on lines +for i=1:nbLines + % extract limits of the box + xmin = box(i, 1); + xmax = box(i, 2); + ymin = box(i, 3); + ymax = box(i, 4); + + % use direction vector for box edges similar to direction vector of the + % line in order to reduce computation errors + delta = hypot(line(i,3), line(i,4)); + + + % compute intersection with each edge of the box + + % lower edge + px1 = intersectLines(line(i,:), [xmin ymin delta 0]); + % right edge + px2 = intersectLines(line(i,:), [xmax ymin 0 delta]); + % upper edge + py1 = intersectLines(line(i,:), [xmax ymax -delta 0]); + % left edge + py2 = intersectLines(line(i,:), [xmin ymax 0 -delta]); + + % remove undefined intersections (case of lines parallel to box edges) + points = [px1 ; px2 ; py1 ; py2]; + points = points(isfinite(points(:,1)), :); + + % sort points according to their position on the line + pos = linePosition(points, line(i,:)); + [pos inds] = sort(pos); %#ok + points = points(inds, :); + + % create clipped edge by using the two points in the middle + ind = size(points, 1)/2; + inter1 = points(ind,:); + inter2 = points(ind+1,:); + edge(i, 1:4) = [inter1 inter2]; + + % check that middle point of the edge is contained in the box + midX = mean(edge(i, [1 3])); + xOk = xmin <= midX && midX <= xmax; + midY = mean(edge(i, [2 4])); + yOk = ymin <= midY && midY <= ymax; + + % if one of the bounding condition is not met, set edge to NaN + if ~(xOk && yOk) + edge (i,:) = NaN; + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLineRect.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLineRect.m new file mode 100644 index 0000000..603da49 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipLineRect.m @@ -0,0 +1,51 @@ +function edge = clipLineRect(line, rect) +%CLIPLINERECT clip a line with a polygon +% +% EDGE = clipLineRect(LINE, RECT); +% LINE: line in the form [x0 y0 dx dy] +% RECT: a rectangle in the form [xr yr wr hr] (xr and yr: coordinate of +% first point, wr and hr are width and height of rectangle) +% +% Deprecated: use function clipLine instead +% +% --------- +% author : David Legland +% created the 24/07/2006. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY + +if size(line, 1)==1 + line = repmat(line, size(rect, 1), 1); +elseif size(rect, 1)==1 + rect = repmat(rect, size(line, 1), 1); +elseif size(line, 1) ~= size(rect, 1) + error('bad sizes for input'); +end + +edge = zeros(size(line, 1), 4); +for i=1:size(line, 1) + x = rect(i, 1); y = rect(i, 2); w = rect(i, 3); h = rect(i, 4); + + % intersection with axis : x=xmin + px1 = intersectLineEdge(line(i,:), [x y x+w y]); + px2 = intersectLineEdge(line(i,:), [x+w y x+w y+h]); + py1 = intersectLineEdge(line(i,:), [x+w y+h x y+h]); + py2 = intersectLineEdge(line(i,:), [x y+h x y]); + + % sort points along the x coordinate, and draw a line between + % the two in the middle + points = sortrows([px1 ; px2 ; py1 ; py2], 1); + if points(2,1)>=x-1e-14 && points(2,1)<=x+w+1e-14 + if isfinite(points(3,1)) + edge(i, 1:4) = [points(2,:) points(3,:)]; + else + edge(i, 1:4) = [points(1,:) points(2,:)]; + end + else + % line outside the rectangle + edge(i, 1:4) = [0 0 0 0]; + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipPoints.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipPoints.m new file mode 100644 index 0000000..178cade --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipPoints.m @@ -0,0 +1,29 @@ +function points = clipPoints(points, box) +%CLIPPOINTS Clip a set of points by a box +% +% CLIP = clipPoints(POINTS, BOX); +% Returns the set of points which are located inside of the box BOX. +% +% +% See also +% points2d, boxes2d, clipLine, drawPoint +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +% get bounding box limits +xmin = box(1); +xmax = box(2); +ymin = box(3); +ymax = box(4); + +% compute indices of points inside visible area +xOk = points(:,1)>=xmin & points(:,1)<=xmax; +yOk = points(:,2)>=ymin & points(:,2)<=ymax; + +% keep only points inside box +points = points(xOk & yOk, :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipRay.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipRay.m new file mode 100644 index 0000000..d943445 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/clipRay.m @@ -0,0 +1,57 @@ +function [edge isInside] = clipRay(ray, box) +% Clip a ray with a box +% +% EDGE = clipRay(RAY, BOX); +% RAY is a straight ray given as a 4 element row vector: [x0 y0 dx dy], +% with (x0 y0) being the origin of the ray and (dx dy) its direction +% vector, BOX is the clipping box, given by its extreme coordinates: +% [xmin xmax ymin ymax]. +% The result is given as an edge, defined by the coordinates of its 2 +% extreme points: [x1 y1 x2 y2]. +% If the ray does not intersect the box, [NaN NaN NaN NaN] is returned. +% +% Function works also if RAY is a Nx4 array, if BOX is a Nx4 array, or +% if both RAY and BOX are Nx4 arrays. In these cases, EDGE is a Nx4 +% array. +% +% See also: +% rays2d, boxes2d, edges2d, clipLine, drawRay +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-05-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2010-05-13 create from clipLine + +% adjust size of two input arguments +if size(ray, 1)==1 + ray = repmat(ray, size(box, 1), 1); +elseif size(box, 1)==1 + box = repmat(box, size(ray, 1), 1); +elseif size(ray, 1) ~= size(box, 1) + error('bad sizes for input'); +end + +% first compute clipping of supporting line +edge = clipLine(ray, box); + +% detectes valid edges (edges outside box are all NaN) +inds = find(isfinite(edge(:, 1))); + +% compute position of edge extremities relative to the ray +pos1 = linePosition(edge(inds,1:2), ray(inds,:)); +pos2 = linePosition(edge(inds,3:4), ray(inds,:)); + +% if first point is before ray origin, replace by origin +edge(inds(pos1<0), 1:2) = ray(inds(pos1<0), 1:2); + +% if last point of edge is before origin, set all edge to NaN +edge(inds(pos2<0), :) = NaN; + +% eventually returns result about inside or outside +if nargout>1 + isInside = isfinite(edge(:,1)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/crackPattern.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/crackPattern.m new file mode 100644 index 0000000..9a1783a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/crackPattern.m @@ -0,0 +1,158 @@ +function edges = crackPattern(box, points, alpha, varargin) +%CRACKPATTERN Create a (bounded) crack pattern tessellation +% +% E = crackPattern(BOX, POINTS, ALPHA) +% create a crack propagation pattern wit following parameters : +% - pattern is bounded by area BOX given by [xmin xmax ymin ymax]. +% - each crack originates from points given in POINTS +% - direction of each crack is given by array ALPHA +% - a crack stop when it reaches another already created crack. +% - all cracks stop when they reach the border of the frame, given by box +% (a serie of 4 points). +% The result is a collection of edges, in the form [x1 y1 x2 y2]. +% +% E = crackPattern(BOX, POINTS, ALPHA, SPEED) +% Also specify speed of propagation of each crack. +% +% +% See the result with : +% figure; +% drawEdge(E); +% +% See also drawEdge +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 25/05/2004. +% + +% HISTORY : + +if ~isempty(varargin) + speed = varargin{1}; +else + speed = ones(size(points, 1), 1); +end + +% Compute line equations for each initial crack. +% The two 'Inf' at the end correspond to the position of the limit. +% If an intersection point is found with another line, but whose position +% is after this value, this means that another crack stopped it before it +% reach the intersection point. +% There is one 'end position' for each side of the crack. +lines = [points speed.*cos(alpha) speed.*sin(alpha) Inf*ones(size(points, 1), 2)]; + +% initialize lines for borders, but assign a very high speed, to be sure +% borders will stop all cracks. +dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5; +dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5; + +% add borders to the lines set +lines = [lines ; createLine(box, dx, dy) Inf*ones(4,2)]; + +edges = zeros(0, 4); + + +while true + modif = 0; + + % try to update each line + for i=1:size(points, 1) + + % compute intersections with all other lines + pi = intersectLines(lines(i,:), lines); + + % compute position of all intersection points on the current line + pos = linePosition(pi, lines(i,:)); + + % consider points to the right (positive position), and sort them + indr = find(pos>=0 & pos~=Inf); + [posr, indr2] = sort(pos(indr)); + + + % look for the closest intersection to the right + for i2=1:length(indr2) + + % index of intersected line + il = indr(indr2(i2)); + + % position of point relative to intersected line + pos2 = linePosition(pi(il, :), lines(il, :)); + + % depending on the sign of position, tests if the line2 can + % stop the current line, or if it was stopped before + if pos2>0 + if pos20 + if pos21e-12 & pos~=Inf); + [posr, indr2] = sort(pos(indr)); + + + % look for the closest intersection to the right + for i2=1:length(indr2) + + % index of intersected line + il = indr(indr2(i2)); + + % position of point relative to intersected line + pos2 = linePosition(pi(il, :), lines(il, :)); + + % depending on the sign of position, tests if the line2 can + % stop the current line, or if it was stopped before + if pos2>0 + if pos22*pi; +end + + +circle = [x0 y0 r d]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createEdge.m new file mode 100644 index 0000000..81d8a02 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createEdge.m @@ -0,0 +1,96 @@ +function edge = createEdge(varargin) +%CREATEEDGE Create an edge between two points, or from a line +% +% The internal format for edge representation is given by coordinates of +% two points : [x1 y1 x2 y2]. +% This function can serve as a line to edge converter. +% +% +% E = createEdge(P1, P2); +% Returns the edge between the two given points P1 and P2. +% +% E = createEdge(x0, y0, dx, dy); +% Returns the edge going through point (x0, y0) and with direction +% vector (dx,dy). +% +% E = createEdge(param); +% where param is an array of 4 values, creates the edge going through the +% point (param(1) param(2)), and with direction vector given by +% (param(3) param(4)). +% +% E = createEdge(LINE, D); +% create the edge contained in LINE, with same direction and start point, +% but with length given by D. +% +% +% Note: in all cases, parameters can be vertical arrays of the same +% dimension. The result is then an array of edges, of dimensions [N*4]. +% +% +% See also: +% edges2d, lines2d, drawEdge, clipEdge +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY : +% 18/02/2004 : add more possibilities to create edges, not only from 2 +% points. Also add support for arrays. +% 31/03/2004 : convert to [P1 P2] format + +if length(varargin)==1 + % Only one input parameter. It can be : + % - line angle + % - array of four parameters + % TODO : add control for arrays of lines. + var = varargin{1}; + + if size(var, 2)==4 + % 4 parameters of the line in a single array. + %edge = var; + edge = zeros(size(var)); + edge(:, 1:2) = var(:,1:2); + edge(:, 3:4) = edge(:, 1:2)+var(:,3:4); + elseif size(var, 2)==1 + % 1 parameter : angle of the line, going through origin. + edge = [zeros(size(var,1)) zeros(size(var,1)) cos(var) sin(var)]; + else + error('wrong number of dimension for arg1 : can be 1 or 4'); + end + +elseif length(varargin)==2 + % 2 input parameters. They can be : + % - 2 points, then 2 arrays of 1*2 double, + % - a line, and a distance. + v1 = varargin{1}; + v2 = varargin{2}; + if size(v1, 2)==2 + % first input parameter is first point, and second input is the + % second point. + %edge = [v1(:,1), v1(:,2), v2(:,1), v2(:,2)]; + edge = [v1 v2]; + else + % first input parameter is a line, and second one a distance. + angle = atan2(v1(:,4), v1(:,3)); + edge = [v1(:,1), v1(:,2), v1(:,1)+v2.*cos(angle), v1(:,2)+v2.*sin(angle)]; + end + +elseif length(varargin)==3 + % 3 input parameters : + % first one is a point belonging to the line, + % second and third ones are direction vector of the line (dx and dy). + p = varargin{1}; + edge = [p(:,1) p(:,2) p(:,1)+varargin{2} p(:,2)+varargin{3}]; + +elseif length(varargin)==4 + % 4 input parameters : + % they are x0, y0 (point belonging to line) and dx, dy (direction + % vector of the line). + % All parameters should have the same size. + edge = [varargin{1} varargin{2} varargin{1}+varargin{3} varargin{2}+varargin{4}]; +else + error('Wrong number of arguments in ''createLine'' '); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createHomothecy.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createHomothecy.m new file mode 100644 index 0000000..0cf2650 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createHomothecy.m @@ -0,0 +1,32 @@ +function trans = createHomothecy(point, ratio) +%CREATEHOMOTHECY Create the the 3x3 matrix of an homothetic transform +% +% TRANS = createHomothecy(POINT, K); +% POINT is the center of the homothecy, K is its factor. +% +% See also: +% transforms2d, transformPoint, createTranslation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/01/2005. +% + +% HISTORY +% 22/04/2009: rename as createHomothecy + +% extract coordinate of center +x0 = point(:,1); +y0 = point(:,2); + +% compute coefficients of the matrix +m00 = ratio; +m01 = 0; +m02 = x0*(1-ratio); +m10 = 0; +m11 = ratio; +m12 = y0*(1-ratio); + +% create transformation +trans = [m00 m01 m02; m10 m11 m12; 0 0 1]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLine.m new file mode 100644 index 0000000..9e9758b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLine.m @@ -0,0 +1,122 @@ +function line = createLine(varargin) +%CREATELINE Create a straight line from 2 points, or from other inputs +% +% Line is represented in a parametric form : [x0 y0 dx dy] +% x = x0 + t*dx +% y = y0 + t*dy; +% +% +% L = createLine(p1, p2); +% Returns the line going through the two given points. +% +% L = createLine(x0, y0, dx, dy); +% Returns the line going through point (x0, y0) and with direction +% vector(dx, dy). +% +% L = createLine(LINE); +% where LINE is an array of 4 values, creates the line going through the +% point (LINE(1) LINE(2)), and with direction given by vector (LINE(3) +% LINE(4)). +% +% L = createLine(THETA); +% Create a polar line originated at (0,0) and with angle THETA. +% +% L = createLine(RHO, THETA); +% Create a polar line with normal theta, and with min distance to origin +% equal to rho. rho can be negative, in this case, the line is the same +% as with CREATELINE(-rho, theta+pi), but the orientation is different. +% +% +% Note: in all cases, parameters can be vertical arrays of the same +% dimension. The result is then an array of lines, of dimensions [N*4]. +% +% +% See also: +% lines2d, createEdge, createRay +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY : +% 18/02/2004 : add more possibilities to create lines (4 parameters, +% all param in a single tab, and point + dx + dy. +% Also add support for creation of arrays of lines. + +% NOTE : A line can also be represented with a 1*5 array : +% [x0 y0 dx dy t]. +% whith 't' being one of the following : +% - t=0 : line is a singleton (x0,y0) +% - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx, +% y0+dy). +% - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity +% in the direction(dx,dy). +% - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity +% in the direction(-dx,-dy). +% - t=NaN : line is a real straight line, and contains all points +% verifying the above equation. +% This seems us a convenient way to represent uniformly all kind of lines +% (including edges, rays, and even point). +% + +% NOTE2 : Any line object can be represented using a 1x6 array : +% [x0 y0 dx dy t0 t1] +% the first 4 parameters define the supporting line, +% t0 represent the position of the first point on the line, +% and t1 the position of the last point. +% * for edges : t0 = 0, and t1=1 +% * for straight lines : t0 = -inf, t1=inf +% * for rays : t0=0, t1=inf (or t0=-inf,t1=0 for inverted ray). +% I propose to call these objects 'lineArc' + +if length(varargin)==1 + % Only one input parameter. It can be : + % - line angle + % - array of four parameters + % TODO : add control for arrays of lines. + var = varargin{1}; + + if size(var, 2)==4 + % 4 parameters of the line in a single array. + line = var; + elseif size(var, 2)==1 + % 1 parameter : angle of the line, going through origin. + line = [zeros(size(var)) zeros(size(var)) cos(var) sin(var)]; + else + error('wrong number of dimension for arg1 : can be 1 or 4'); + end + +elseif length(varargin)==2 + % 2 input parameters. They can be : + % - line angle and signed distance to origin. + % - 2 points, then 2 arrays of 1*2 double. + v1 = varargin{1}; + v2 = varargin{2}; + if size(v1, 2)==1 + % first param is angle of line, and second param is signed distance + % to origin. + line = [v1.*cos(v2) v1.*sin(v2) -sin(v2) cos(v2)]; + else + % first input parameter is first point, and second input is the + % second point. + line = [v1(:,1), v1(:,2), v2(:,1)-v1(:,1), v2(:,2)-v1(:,2)]; + end + +elseif length(varargin)==3 + % 3 input parameters : + % first one is a point belonging to the line, + % second and third ones are direction vector of the line (dx and dy). + p = varargin{1}; + line = [p(:,1) p(:,2) varargin{2} varargin{3}]; + +elseif length(varargin)==4 + % 4 input parameters : + % they are x0, y0 (point belongng to line) and dx, dy (direction vector + % of the line). + % All parameters should have the same size. + line = [varargin{1} varargin{2} varargin{3} varargin{4}]; +else + error('Wrong number of arguments in ''createLine'' '); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLineReflection.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLineReflection.m new file mode 100644 index 0000000..1ecb869 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createLineReflection.m @@ -0,0 +1,40 @@ +function trans = createLineReflection(line) +%CREATELINEREFLECTION Create the the 3x3 matrix of a line reflection +% +% TRANS = createLineReflection(LINE); +% where line is given as [x0 y0 dx dy], return the affine tansform +% corresponding to the desired line reflection +% +% +% See also: +% lines2d, transforms2d, transformPoint, +% createTranslation, createHomothecy, createScaling +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 19/01/2005. +% + +% HISTORY +% 22/04/2009: rename as createLineReflection + +% extract line parameters +x0 = line(:,1); +y0 = line(:,2); +dx = line(:,3); +dy = line(:,4); + +% normalisation coefficient of line direction vector +delta = dx*dx + dy*dy; + +% compute coefficients of transform +m00 = (dx*dx - dy*dy)/delta; +m01 = 2*dx*dy/delta; +m02 = 2*dy*(dy*x0 - dx*y0)/delta; +m10 = 2*dx*dy/delta; +m11 = (dy*dy - dx*dx)/delta; +m12 = 2*dx*(dx*y0 - dy*x0)/delta; + +% create transformation +trans = [m00 m01 m02; m10 m11 m12; 0 0 1]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createMedian.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createMedian.m new file mode 100644 index 0000000..c7e36d2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createMedian.m @@ -0,0 +1,58 @@ +function line = createMedian(varargin) +%CREATEMEDIAN create a median line +% +% DEPRECATED: use medianLine instead +% +% l = CREATEMEDIAN(P1, P2) create the median line of points P1 and P2, +% that is the line containing all points located at equal distance of +% P1 and P2. +% +% l = CREATEMEDIAN(points) create the median line of 2 points, given as +% a 2*2 array. array has the form : +% [ [ x1 y1 ] ; [ x2 y2 ] ] +% +% l = CREATEMEDIAN(edge) create the median of the edge. Edge is a 1*4 +% array, containing [x0 y0] coordiantes of first point, and [dx dy], +% the vector from first point to second point. +% +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% deprecation warning +warning('geom2d:deprecated', ... + '''createMedian'' is deprecated, use ''medianLine'' instead'); + + +nargs = length(varargin); +x0=0; +y0=0; +dx=0; +dy=0; + +if nargs == 1 + tab = varargin{1}; + if size(tab, 2)==2 + % array of two points + x0 = tab(1,1); y0 = tab(1,2); + dx = tab(2,1)-x0; dy = tab(2,2)-y0; + else + % edge equation + x0 = tab(1); y0 = tab(2); + dx = tab(3); dy = tab(4); + end +elseif nargs==2 + % two points + p1 = varargin{1}; + p2 = varargin{2}; + x0 = p1(1); y0 = p1(2); + dx = p2(1)-x0; dy = p2(2)-y0; +end + + +line = [x0+dx/2, y0+dy/2, -dy, dx]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRay.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRay.m new file mode 100644 index 0000000..e84e49f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRay.m @@ -0,0 +1,56 @@ +function ray = createRay(varargin) +%CREATERAY Create a ray (half-line), from various inputs +% +% RAY = createRay(POINT, ANGLE) +% POINT is a N*2 array giving starting point of the ray, and ANGLE is the +% orientation of the ray. +% +% RAY = createRay(X0, Y0, ANGLE) +% Specify ray origin with 2 input arguments. +% +% RAY = createRay(P1, P2) +% Create a ray starting from point P1 and going in the direction of point +% P2. +% +% Ray is represented in a parametric form: [x0 y0 dx dy] +% x = x0 + t*dx +% y = y0 + t*dy; +% for all t>0 +% +% Example +% origin = [3 4]; +% theta = pi/6; +% ray = createRay(origin, theta); +% figure(1); clf; hold on; +% axis([0 10 0 10]); +% drawRay(ray); +% +% See also: +% rays2d, createLine, points2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-18 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +if length(varargin)==2 + p0 = varargin{1}; + arg = varargin{2}; + if size(arg, 2)==1 + % second input is the ray angle + ray = [p0 cos(arg) sin(arg)]; + else + % second input is another point + ray = [p0 arg-p0]; + end + +elseif length(varargin)==3 + x = varargin{1}; + y = varargin{2}; + theta = varargin{3}; + ray = [x y cos(theta) sin(theta)]; + +else + error('Wrong number of arguments in ''createRay'' '); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRotation.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRotation.m new file mode 100644 index 0000000..6f43691 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createRotation.m @@ -0,0 +1,58 @@ +function trans = createRotation(varargin) +%CREATEROTATION Create the 3*3 matrix of a rotation +% +% TRANS = createRotation(THETA); +% Returns the rotation corresponding to angle THETA (in radians) +% The returned matrix has the form : +% [cos(theta) -sin(theta) 0] +% [sin(theta) cos(theta) 0] +% [0 0 1] +% +% TRANS = createRotation(POINT, THETA); +% TRANS = createRotation(X0, Y0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0), rotation(THETA), and translation(X0, Y0). +% +% +% See also: +% transforms2d, transformPoint, createTranslation, createScaling +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 22/04/2009: rename as createRotation + +% default values +cx = 0; +cy = 0; +theta = 0; + +% get input values +if length(varargin)==1 + % only angle + theta = varargin{1}; +elseif length(varargin)==2 + % origin point (as array) and angle + var = varargin{1}; + cx = var(1); + cy = var(2); + theta = varargin{2}; +elseif length(varargin)==3 + % origin (x and y) and angle + cx = varargin{1}; + cy = varargin{2}; + theta = varargin{3}; +end + +% compute coefs +cot = cos(theta); +sit = sin(theta); +tx = cy*sit - cx*cot + cx; +ty = -cy*cot - cx*sit + cy; + +% create transformation matrix +trans = [cot -sit tx; sit cot ty; 0 0 1]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createScaling.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createScaling.m new file mode 100644 index 0000000..50ad22d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createScaling.m @@ -0,0 +1,59 @@ +function trans = createScaling(varargin) +%CREATESCALING Create the 3*3 matrix of a scaling in 2 dimensions +% +% TRANS = createScaling(SX, SY); +% return the matrix corresponding to scaling by SX and SY in the 2 +% main directions. +% The returned matrix has the form: +% [SX 0 0] +% [0 SY 0] +% [0 0 1] +% +% TRANS = createScaling(SX); +% Assume SX and SY are equals. +% +% See also: +% transforms2d, transformPoint, createTranslation, createRotation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. + + +% HISTORY +% 04/01/2007: rename as scaling +% 22/04/2009: rename as createScaling + +% defined default arguments +sx = 1; +sy = 1; +cx = 0; +cy = 0; + +% process input arguments +if length(varargin)==1 + % the argument is either the scaling factor in both direction, + % or a 1x2 array containing scaling factor in each direction + var = varargin{1}; + sx = var(1); + sy = var(1); + if length(var)>1 + sy = var(2); + end +elseif length(varargin)==2 + % the 2 arguments are the scaling factors in each dimension + sx = varargin{1}; + sy = varargin{2}; +elseif length(varargin)==3 + % first argument is center, 2nd and 3d are scaling factors + center = varargin{1}; + cx = center(1); + cy = center(2); + sx = varargin{2}; + sy = varargin{3}; +end + +% create result matrix +trans = [sx 0 cx*(1-sx); 0 sy cy*(1-sy); 0 0 1]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createTranslation.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createTranslation.m new file mode 100644 index 0000000..6ad5775 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createTranslation.m @@ -0,0 +1,41 @@ +function trans = createTranslation(varargin) +%CREATETRANSLATION Create the 3*3 matrix of a translation +% +% TRANS = createTranslation(DX, DY); +% Returns the translation corresponding to DX and DY. +% The returned matrix has the form : +% [1 0 TX] +% [0 1 TY] +% [0 0 1] +% +% TRANS = createTranslation(VECTOR); +% Returns the matrix corresponding to a translation by the vector [x y]. +% +% +% See also: +% transforms2d, transformPoint, createRotation, createScaling +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 22/04/2009: rename as createTranslation + +% process input arguments +if isempty(varargin) + tx = 0; + ty = 0; +elseif length(varargin)==1 + var = varargin{1}; + tx = var(1); + ty = var(2); +else + tx = varargin{1}; + ty = varargin{2}; +end + +% create the matrix representing the translation +trans = [1 0 tx ; 0 1 ty ; 0 0 1]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createVector.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createVector.m new file mode 100644 index 0000000..24acbb6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/createVector.m @@ -0,0 +1,28 @@ +function vect = createVector(p1, p2) +%CREATEVECTOR Create a vector from two points +% +% V12 = createVector(P1, P2) +% Creates the vector V12, defined as the difference between coordinates +% of points P1 and P2. +% P1 and P2 are row vectors with ND elements, ND being the space +% dimension. +% +% If one of the inputs is a N-by-Nd array, the other input is +% automatically repeated, and the result is N-by-Nd. +% +% If both inputs have the same size, the result also have the same size. +% +% +% Example +% +% See also +% vectors2d, vectors3d, points2d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-12-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +vect = bsxfun(@minus, p2, p1); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cubicBezierToPolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cubicBezierToPolyline.m new file mode 100644 index 0000000..f5fefc8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/cubicBezierToPolyline.m @@ -0,0 +1,80 @@ +function varargout = cubicBezierToPolyline(points, varargin) +%CUBICBEZIERTOPOLYLINE Compute equivalent polyline from bezier curve control +% +% POLY = cubicBezierToPolyline(POINTS, N) +% Creates a polyline with N edges from the coordinates of the 4 control +% points stored in POINTS. +% POINTS is either a 4-by-2 array (vertical concatenation of point +% coordinates), or a 1-by-8 array (horizontal concatenation of point +% coordinates). +% The result is a (N-1)-by-2 array. +% +% POLY = cubicBezierToPolyline(POINTS) +% Assumes N = 64 edges as default. +% +% [X Y] = cubicBezierToPolyline(...) +% Returns the result in two separate arrays for X and Y coordinates. +% +% +% Example +% poly = cubicBezierToPolyline([0 0;5 10;10 5;10 0], 100); +% drawPolyline(poly, 'linewidth', 2, 'color', 'g'); +% +% See also +% drawBezierCurve, drawPolyline +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-10-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% default number of discretization steps +N = 64; + +% check if discretization step is specified +if ~isempty(varargin) + var = varargin{1}; + if length(var) == 1 && isnumeric(var) + N = round(var); + end +end + +% parametrization variable for bezier (use N+1 points to have N edges) +t = linspace(0, 1, N+1)'; + +% rename points +if size(points, 2)==2 + % case of points given as a 4-by-2 array + p1 = points(1,:); + c1 = points(2,:); + c2 = points(3,:); + p2 = points(4,:); +else + % case of points given as a 1-by-8 array, [X1 Y1 CX1 CX2..] + p1 = points(1:2); + c1 = points(3:4); + c2 = points(5:6); + p2 = points(7:8); +end + +% compute coefficients of Bezier Polynomial, using polyval ordering +coef(4, 1) = p1(1); +coef(4, 2) = p1(2); +coef(3, 1) = 3 * c1(1) - 3 * p1(1); +coef(3, 2) = 3 * c1(2) - 3 * p1(2); +coef(2, 1) = 3 * p1(1) - 6 * c1(1) + 3 * c2(1); +coef(2, 2) = 3 * p1(2) - 6 * c1(2) + 3 * c2(2); +coef(1, 1) = p2(1) - 3 * c2(1) + 3 * c1(1) - p1(1); +coef(1, 2) = p2(2) - 3 * c2(2) + 3 * c1(2) - p1(2); + +% compute position of vertices +x = polyval(coef(:, 1), t); +y = polyval(coef(:, 2), t); + +if nargout <= 1 + varargout = {[x y]}; +else + varargout = {x, y}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/deg2rad.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/deg2rad.m new file mode 100644 index 0000000..bc4b96e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/deg2rad.m @@ -0,0 +1,25 @@ +function rad = deg2rad(deg) +%DEG2RAD Convert angle from degrees to radians +% +% Usage: +% R = deg2rad(D) +% convert an angle in degrees to an angle in radians. +% +% Example +% deg2rad(180) % gives pi +% ans = +% 3.1416 +% deg2rad(60) % gives pi/3 +% ans = +% 1.0472 +% +% See Also +% angles2d, rad2deg +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 09/12/2004. +% + +rad = deg*pi/180; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointEdge.m new file mode 100644 index 0000000..1343562 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointEdge.m @@ -0,0 +1,59 @@ +function varargout = distancePointEdge(point, edge) +%DISTANCEPOINTEDGE Minimum distance between a point and an edge +% +% DIST = distancePointEdge(POINT, EDGE); +% Return the euclidean distance between edge EDGE and point POINT. +% EDGE has the form: [x1 y1 x2 y2], and POINT is [x y]. +% +% If EDGE is N-by-4 array, result is N-by-1 array computed for each edge. +% If POINT is a N-by-2 array, the result is computed for each point. +% If both POINT and EDGE are array, they must have the same number of +% rows, and the result is computed for each couple point(i,:);edge(i,:). +% +% [DIST POS] = distancePointEdge(POINT, EDGE); +% Also returns the position of closest point on the edge. POS is +% comprised between 0 (first point) and 1 (last point). +% +% See also: +% edges2d, points2d, distancePoints, distancePointLine +% +% +% --------- +% author : David Legland +% INRA - CEPIA URPOI - MIA MathCell +% created the 07/04/2004. +% + +% HISTORY +% 2005-06-24 rename, and change arguments sequence +% 2009-04-30 add possibility to return position of closest point +% 2011-04-14 add checkup for degenerate edges, improve speed, update doc + +% direction vector of each edge +dx = edge(:, 3) - edge(:,1); +dy = edge(:, 4) - edge(:,2); + +% compute position of points projected on the supporting line +% (Size of tp is the max number of edges or points) +delta = dx .* dx + dy .* dy; +tp = ((point(:, 1) - edge(:, 1)) .* dx + (point(:, 2) - edge(:, 2)) .* dy) ./ delta; + +% ensure degenerated edges are correclty processed (consider the first +% vertex is the closest) +tp(delta < eps) = 0; + +% change position to ensure projected point is located on the edge +tp(tp < 0) = 0; +tp(tp > 1) = 1; + +% coordinates of projected point +p0 = [edge(:,1) + tp .* dx, edge(:,2) + tp .* dy]; + +% compute distance between point and its projection on the edge +dist = sqrt((point(:,1) - p0(:,1)) .^ 2 + (point(:,2) - p0(:,2)) .^ 2); + +% process output arguments +varargout{1} = dist; +if nargout > 1 + varargout{2} = tp; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointLine.m new file mode 100644 index 0000000..33a0db0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePointLine.m @@ -0,0 +1,51 @@ +function dist = distancePointLine(point, line) +%DISTANCEPOINTLINE Minimum distance between a point and a line +% +% D = distancePointLine(POINT, LINE) +% Return the euclidean distance between line LINE and point POINT. +% +% LINE has the form : [x0 y0 dx dy], and POINT is [x y]. +% +% If LINE is N-by-4 array, result is N-by-1 array computes for each line. +% +% If POINT is N-by-2, then result is computed for each point. +% +% If both POINT and LINE are array, result is N-by-1, computed for each +% corresponding point and line. +% +% +% See also: +% lines2d, points2d, distancePoints, distancePointEdge +% +% +% --------- +% author : David Legland +% INRA - CEPIA URPOI - MIA MathCell +% created the 24/06/2005 +% + +% HISTORY : + + +if size(line, 1)==1 && size(point, 1)>1 + line = repmat(line, [size(point, 1) 1]); +end + +if size(point, 1)==1 && size(line, 1)>1 + point = repmat(point, [size(line, 1) 1]); +end + +dx = line(:, 3); +dy = line(:, 4); + +% compute position of points projected on line +tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy); +p0 = line(:, 1:2) + [tp tp].*[dx dy]; + + +% compute distances between points and their projections +dx = point - p0; +dist = sqrt(sum(dx.*dx, 2)); + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePoints.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePoints.m new file mode 100644 index 0000000..d7d619b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/distancePoints.m @@ -0,0 +1,122 @@ +function dist = distancePoints(p1, p2, varargin) +%DISTANCEPOINTS Compute distance between two points +% +% D = distancePoints(P1, P2) +% Return the Euclidean distance between points P1 and P2. +% +% If P1 and P2 are two arrays of points, result is a N1*N2 array +% containing distance between each point of P1 and each point of P2. +% +% D = distancePoints(P1, P2, NORM) +% Compute distance using the specified norm. NORM=2 corresponds to usual +% euclidean distance, NORM=1 corresponds to Manhattan distance, NORM=inf +% is assumed to correspond to maximum difference in coordinate. Other +% values (>0) can be specified. +% +% D = distancePoints(..., 'diag') +% compute only distances between P1(i,:) and P2(i,:). +% +% See also: +% points2d, minDistancePoints, nndist +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 24/02/2004. +% + +% HISTORY : +% 25/05/2004: manage 2 array of points +% 07/04/2004: add option for computing only diagonal. +% 30/10/2006: generalize to any dimension, and manage different norms +% 03/01/2007: bug for arbitrary norm, and update doc +% 28/08/2007: fix bug for norms 2 and infinite, in diagonal case + + +%% Setup options + +% default values +diag = false; +norm = 2; + +% check first argument: norm or diag +if ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) + norm = var; + elseif strncmp('diag', var, 4) + diag = true; + end + varargin(1) = []; +end + +% check last argument: diag +if ~isempty(varargin) + var = varargin{1}; + if strncmp('diag', var, 4) + diag = true; + end +end + + +% number of points in each array and their dimension +n1 = size(p1, 1); +n2 = size(p2, 1); +d = size(p1, 2); + +if diag + % compute distance only for apparied couples of pixels + dist = zeros(n1, 1); + if norm==2 + % Compute euclidian distance. this is the default case + % Compute difference of coordinate for each pair of point + % and for each dimension. -> dist is a [n1*n2] array. + for i=1:d + dist = dist + (p2(:,i)-p1(:,i)).^2; + end + dist = sqrt(dist); + elseif norm==inf + % infinite norm corresponds to maximal difference of coordinate + for i=1:d + dist = max(dist, abs(p2(:,i)-p1(:,i))); + end + else + % compute distance using the specified norm. + for i=1:d + dist = dist + power((abs(p2(:,i)-p1(:,i))), norm); + end + dist = power(dist, 1/norm); + end +else + % compute distance for all couples of pixels + dist = zeros(n1, n2); + if norm==2 + % Compute euclidian distance. this is the default case + % Compute difference of coordinate for each pair of point + % and for each dimension. -> dist is a [n1*n2] array. + for i=1:d + % equivalent to: + % dist = dist + ... + % (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2; + dist = dist + (p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))').^2; + end + dist = sqrt(dist); + elseif norm==inf + % infinite norm corresponds to maximal difference of coordinate + for i=1:d + dist = max(dist, abs(p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))')); + end + else + % compute distance using the specified norm. + for i=1:d + % equivalent to: + % dist = dist + power((abs(repmat(p1(:,i), [1 n2]) - ... + % repmat(p2(:,i)', [n1 1]))), norm); + dist = dist + power((abs(p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))')), norm); + end + dist = power(dist, 1/norm); + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawArrow.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawArrow.m new file mode 100644 index 0000000..f2f1721 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawArrow.m @@ -0,0 +1,118 @@ +function varargout = drawArrow(varargin) +%DRAWARROW Draw an arrow on the current axis +% +% DRAWARROW(x1, y1, x2, y2) +% draw an arrow between the points (x1 y1) and (x2 y2). +% +% DRAWARROW([x1 y1 x2 y2]) +% gives argument as a single array. +% +% DRAWARROW(..., L, W) +% specify length and width of the arrow. +% +% DRAWARROW(..., L, W, TYPE) +% also specify arrow type. TYPE can be one of the following : +% 0: draw only two strokes +% 1: fill a triangle +% .5: draw a half arrow (try it to see ...) +% +% Arguments can be single values or array of size [N*1]. In this case, +% the function draws multiple arrows. +% +% +% H = DRAWARROW(...) return handle(s) to created edges(s) +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 11/11/2004 from drawEdge +% + +% HISTORY + + +if isempty(varargin) + error('should specify at least one argument'); +end + +% parse arrow coordinate +var = varargin{1}; +if size(var, 2)==4 + x1 = var(:,1); + y1 = var(:,2); + x2 = var(:,3); + y2 = var(:,4); + varargin = varargin(2:end); +elseif length(varargin)>3 + x1 = varargin{1}; + y1 = varargin{2}; + x2 = varargin{3}; + y2 = varargin{4}; + varargin = varargin(5:end); +else + error('wrong number of arguments, please read the doc'); +end + +l = 10*size(size(x1)); +w = 5*ones(size(x1)); +h = zeros(size(x1)); + +% exctract length of arrow +if ~isempty(varargin) + l = varargin{1}; + if length(x1)>length(l) + l = l(1)*ones(size(x1)); + end +end + +% extract width of arrow +if length(varargin)>1 + w = varargin{2}; + if length(x1)>length(w) + w = w(1)*ones(size(x1)); + end +end + +% extract 'ratio' of arrow +if length(varargin)>2 + h = varargin{3}; + if length(x1)>length(h) + h = h(1)*ones(size(x1)); + end +end + +hold on; +axis equal; + +% angle of the edge +theta = atan2(y2-y1, x2-x1); + +% point on the 'left' +xa1 = x2 - l.*cos(theta) - w.*sin(theta)/2; +ya1 = y2 - l.*sin(theta) + w.*cos(theta)/2; +% point on the 'right' +xa2 = x2 - l.*cos(theta) + w.*sin(theta)/2; +ya2 = y2 - l.*sin(theta) - w.*cos(theta)/2; +% point on the middle of the arrow +xa3 = x2 - l.*cos(theta).*h; +ya3 = y2 - l.*sin(theta).*h; + +% draw main edge +line([x1'; x2'], [y1'; y2'], 'color', [0 0 1]); + +% draw only 2 wings +ind = find(h==0); +line([xa1(ind)'; x2(ind)'], [ya1(ind)'; y2(ind)'], 'color', [0 0 1]); +line([xa2(ind)'; x2(ind)'], [ya2(ind)'; y2(ind)'], 'color', [0 0 1]); + +% draw a full arrow +ind = find(h~=0); +patch([x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)]', ... + [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)]', [0 0 1]); + + +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBezierCurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBezierCurve.m new file mode 100644 index 0000000..e83410f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBezierCurve.m @@ -0,0 +1,67 @@ +function varargout = drawBezierCurve(points, varargin) +%DRAWBEZIERCURVE Draw a cubic bezier curve defined by 4 control points +% +% drawBezierCurve(POINTS) +% Draw the Bezier curve defined by the 4 control points stored in POINTS. +% POINTS is either a 4-by-2 array (vertical concatenation of control +% points coordinates), or a 1-by-8 array (horizontal concatenation of +% control point coordinates). +% +% drawBezierCurve(..., PARAM, VALUE) +% Specifies additional drawing parameters, see the line function for +% details. +% +% drawBezierCurve(AX, ...); +% Spcifies the handle of the axis to draw on. +% +% H = drawBezierCurve(...); +% Return a handle to the created graphic object. +% +% +% Example +% drawBezierCurve([0 0;5 10;10 5;10 0]); +% drawBezierCurve([0 0;5 10;10 5;10 0], 'linewidth', 2, 'color', 'g'); +% +% See also +% drawPolyline, cubicBezierToPolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-03-16, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw on +if isscalar(points) && ishandle(points) + ax = points; + points = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% default number of discretization steps +N = 64; + +% check if discretization step is specified +if ~isempty(varargin) + var = varargin{1}; + if length(var) == 1 && isnumeric(var) + N = round(var); + varargin(1) = []; + end +end + +% convert control coordinates to polyline +poly = cubicBezierToPolyline(points, N); + +% draw the curve +h = drawPolyline(ax, poly, varargin{:}); + +% eventually return a handle to the created object +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBox.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBox.m new file mode 100644 index 0000000..2b6ecea --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawBox.m @@ -0,0 +1,76 @@ +function varargout = drawBox(box, varargin) +%DRAWBOX Draw a box defined by coordinate extents +% +% drawBox(BOX) +% Draws a box defined by its extent: BOX = [XMIN XMAX YMIN YMAX]. +% +% drawBox(..., NAME, VALUE) +% Specifies drawing parameters using parameter name and value. See plot +% function for syntax. +% +% drawBox(AX, ...) +% Specifies the handle of the axis to draw on. +% +% Example +% % define some points, compute their box, display everything +% points = [10 30; 20 50; 20 20; 30 10;40 30;50 20]; +% box = pointSetBounds(points); +% figure; hold on; +% drawPoint(points, 's'); +% drawBox(box); +% axis([0 60 0 60]); +% +% See Also: +% drawOrientedBox, drawRect +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/12/2003. +% + +% HISTORY +% 2010-02-22 creation +% 2011-04-01 add support for drawing option, fix bug for several boxes +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw on +if isscalar(box) && ishandle(box) + ax = box; + box = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% default values +xmin = box(:,1); +xmax = box(:,2); +ymin = box(:,3); +ymax = box(:,4); + +nBoxes = size(box, 1); +r = zeros(nBoxes, 1); + +% iterate on boxes +for i = 1:nBoxes + % exract min and max values + tx(1) = xmin(i); + ty(1) = ymin(i); + tx(2) = xmax(i); + ty(2) = ymin(i); + tx(3) = xmax(i); + ty(3) = ymax(i); + tx(4) = xmin(i); + ty(4) = ymax(i); + tx(5) = xmin(i); + ty(5) = ymin(i); + + % display polygon + r(i) = plot(ax, tx, ty, varargin{:}); +end + +% format output +if nargout > 0 + varargout = {r}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCenteredEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCenteredEdge.m new file mode 100644 index 0000000..2fca182 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCenteredEdge.m @@ -0,0 +1,142 @@ +function varargout = drawCenteredEdge(varargin) +%DRAWCENTEREDEDGE Draw an edge centered on a point +% +% drawCenteredEdge(EDGE) +% Draws an edge centered on a point. EDGE has format [XC YC L THETA], +% with (Xc, YC) being edge center, L being the edge length, and THETA +% beigng the edge orientation, in degrees (counted Counter-clockwise from +% horizontal). +% Input argument can also be a N-by-4 array, in that can several edges +% are drawn. +% +% drawCenteredEdge(CENTER, L, THETA) +% Specifies argument in seperate inputs. +% +% drawCenteredEdge(..., NAME, VALUE) +% Also specifies drawing options by using one or several parameter name - +% value pairs (see doc of plot function for details). +% +% drawCenteredEdge(AX, ...) +% Specifies the axis to draw the edge on. +% +% H = drawCenteredEdge(...) +% Returns handle(s) to the created edges(s). +% +% Example +% % Draw an ellipse with its two axes +% figure(1); clf; +% center = [50 40]; +% r1 = 30; r2 = 10; +% theta = 20; +% elli = [center r1 r2 theta]; +% drawEllipse(elli, 'linewidth', 2); +% axis([0 100 0 100]); axis equal; +% hold on; +% edges = [center 2*r1 theta ; center 2*r2 theta+90]; +% drawCenteredEdge(edges, 'linewidth', 2, 'color', 'g'); +% +% See also: +% edges2d, drawEdge +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/08/2005. +% + +% HISTORY +% 2007-06-15 update doc, clean up code +% 2011-05-18 use angle in degrees, cleanup code and doc +% 2011-10-11 add management of axes handle + + +%% process input variables + +if nargin < 1 + error('Function requires an input argument'); +end + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +var = varargin{1}; +if size(var, 2) == 4 + % manage edge in single parameter + len = var(:, 3); + theta = var(:, 4); + center = var(:, 1:2); + + N = size(center, 1); + varargin(1) = []; + +elseif length(varargin) >= 3 + % parameters given in different arguments + + % size of data + center = varargin{1}; + len = varargin{2}; + theta = varargin{3}; + varargin(1:3) = []; + + % ensure all data have same size + NP = size(center, 1); + NL = size(len, 1); + ND = size(theta, 1); + N = max([NP NL ND]); + if N > 1 + if NP == 1, center = repmat(center, [N 1]); end + if NL == 1, len = repmat(len, [N 1]); end + if ND == 1, theta = repmat(theta, [N 1]); end + end + +end + +% extract drawing options +options = varargin(:); + + +%% Draw edges + +% coordinates of center point +xc = center(:, 1); +yc = center(:, 2); + +% convert angle to radians +theta = theta * pi / 180; + +% computation shortcuts +cot = cos(theta); +sit = sin(theta); + +% compute starting and ending points +x1 = xc - len .* cot / 2; +x2 = xc + len .* cot / 2; +y1 = yc - len .* sit / 2; +y2 = yc + len .* sit / 2; + + +% draw the edges +h = zeros(N, 1); +for i = 1:N + h(i) = plot(ax, [x1(i) x2(i)], [y1(i) y2(i)]); +end + +% apply style to edges +if ~isempty(options) > 0 + for i = 1:N + set(h(i), options{:}); + end +end + + +%% Format output + +% process output arguments +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircle.m new file mode 100644 index 0000000..b7f7435 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircle.m @@ -0,0 +1,119 @@ +function varargout = drawCircle(varargin) +%DRAWCIRCLE Draw a circle on the current axis +% +% drawCircle(X0, Y0, R); +% Draw the circle with center (X0,Y0) and the radius R. If X0, Y0 and R +% are column vectors of the same length, draw each circle successively. +% +% drawCircle(CIRCLE); +% Concatenate all parameters in a Nx3 array, where N is the number of +% circles to draw. +% +% drawCircle(CENTER, RADIUS); +% Specify CENTER as Nx2 array, and radius as a Nx1 array. +% +% drawCircle(..., NSTEP); +% Specify the number of edges that will be used to draw the circle. +% Default value is 72, creating an approximation of one point for each 5 +% degrees. +% +% drawCircle(..., NAME, VALUE); +% Specifies plotting options as pair of parameters name/value. See plot +% documentation for details. +% +% drawCircle(AX, ...) +% Specifies the handle of the axis to draw on. +% +% H = drawCircle(...); +% return handles to each created curve. +% +% Example +% figure; +% hold on; +% drawCircle([10 20 30]); +% drawCircle([15 15 40], 'color', 'r', 'linewidth', 2); +% axis equal; +% +% See also +% circles2d, drawCircleArc, drawEllipse, circleToPolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 02/11/2004: add possibility to draw multiple circles in one call +% 12/01/2005: allow more than 3 parameters +% 26/02/2007: add possibility to specify plot options, number of +% discretization steps, and circle as center+radius. +% 2011-10-11 add support for axis handle + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% process input parameters +var = varargin{1}; +if size(var, 2) == 1 + x0 = varargin{1}; + y0 = varargin{2}; + r = varargin{3}; + varargin(1:3) = []; + +elseif size(var, 2) == 2 + x0 = var(:,1); + y0 = var(:,2); + r = varargin{2}; + varargin(1:2) = []; + +elseif size(var, 2) == 3 + x0 = var(:,1); + y0 = var(:,2); + r = var(:,3); + varargin(1) = []; +else + error('bad format for input in drawCircle'); +end + +% ensure each parameter is column vector +x0 = x0(:); +y0 = y0(:); +r = r(:); + +% default number of discretization steps +N = 72; + +% check if discretization step is specified +if ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) && isscalar(var) + N = round(var); + varargin(1) = []; + end +end + +% parametrization variable for circle (use N+1 as first point counts twice) +t = linspace(0, 2*pi, N+1); +cot = cos(t); +sit = sin(t); + +% empty array for graphic handles +h = zeros(size(x0)); + +% compute discretization of each circle +for i = 1:length(x0) + xt = x0(i) + r(i) * cot; + yt = y0(i) + r(i) * sit; + + h(i) = plot(ax, xt, yt, varargin{:}); +end + +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircleArc.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircleArc.m new file mode 100644 index 0000000..f7460fd --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawCircleArc.m @@ -0,0 +1,106 @@ +function varargout = drawCircleArc(varargin) +%DRAWCIRCLEARC Draw a circle arc on the current axis +% +% drawCircleArc(ARC); +% Draws circle arc defined by ARC = [XC YC R START EXTENT], with (XC, YC) +% being the circle center, R being the circle radius, starting from angle +% START, and with angular extent given by EXTENT. START and EXTENT angles +% are given in degrees. +% +% drawCircleArc(XC, YC, R, START, EXTENT); +% Alternative syntax that seperates inputs. +% +% drawCircleArc(..., PARAM, VALUE); +% specifies plot properties by using one or several parameter name-value +% pairs. +% +% drawCircleArc(AX, ...); +% Specifies handle of the axis to draw on. +% +% H = drawCircleArc(...); +% Returns a handle to the created line object. +% +% Example +% % Draw a red thick circle arc +% arc = [10 20 30 -120 240]; +% figure; +% axis([-50 100 -50 100]); +% hold on +% drawCircleArc(arc, 'LineWidth', 3, 'Color', 'r') +% +% See also: +% circles2d, drawCircle, drawEllipse, circleArcToPolyline +% +% -------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 12/12/2003. +% + +% HISTORY +% 2004-05-03 angles are given as radians +% 2007-06-27 Now uses angle extent +% 2011-03-30 use angles in degrees +% 2011-06-09 add support for line styles +% 2011-10-11 add management of axes handle + +if nargin == 0 + error('Need to specify circle arc'); +end + + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +circle = varargin{1}; +if size(circle, 2) == 5 + x0 = circle(:,1); + y0 = circle(:,2); + r = circle(:,3); + start = circle(:,4); + extent = circle(:,5); + varargin(1) = []; + +elseif length(varargin) >= 5 + x0 = varargin{1}; + y0 = varargin{2}; + r = varargin{3}; + start = varargin{4}; + extent = varargin{5}; + varargin(1:5) = []; + +else + error('drawCircleArc: please specify center, radius and angles of circle arc'); +end + +% convert angles in radians +t0 = deg2rad(start); +t1 = t0 + deg2rad(extent); + +% number of line segments +N = 60; + +% initialize handles vector +h = zeros(length(x0), 1); + +% draw each circle arc individually +for i = 1:length(x0) + % compute basis + t = linspace(t0(i), t1(i), N+1)'; + + % compute vertices coordinates + xt = x0(i) + r(i)*cos(t); + yt = y0(i) + r(i)*sin(t); + + % draw the circle arc + h(i) = plot(ax, xt, yt, varargin{:}); +end + +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEdge.m new file mode 100644 index 0000000..41d9857 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEdge.m @@ -0,0 +1,134 @@ +function varargout = drawEdge(varargin) +%DRAWEDGE Draw an edge given by 2 points +% +% drawEdge(x1, y1, x2, y2); +% draw an edge between the points (x1 y1) and (x2 y2). +% +% drawEdge([x1 y1 x2 y2]) ; +% drawEdge([x1 y1], [x2 y2]); +% specify data either as bundled edge, or as 2 points +% +% The function supports 3D edges: +% drawEdge([x1 y1 z1 x2 y2 z2]); +% drawEdge([x1 y1 z1], [x2 y2 z2]); +% drawEdge(x1, y1, z1, x2, y2, z2); +% +% Arguments can be single values or array of size [N*1]. In this case, +% the function draws multiple edges. +% +% H = drawEdge(..., OPT), with OPT being a set of pairwise options, can +% specify color, line width and so on... +% +% H = drawEdge(...) return handle(s) to created edges(s) +% +% See also: +% edges2d, drawCenteredEdge, drawLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 19/02/2004 add support for arrays of edges. +% 31/03/2004 change format of edges to [P1 P2] and variants. +% 28/11/2004 add support for 3D edges +% 01/08/2005 add support for drawing options +% 31/05/2007 update doc, and code makeup +% 03/08/2010 re-organize code + +% separate edge and optional arguments +[ax edge options] = parseInputArguments(varargin{:}); + +% draw the edges +if size(edge, 2) == 4 + h = drawEdge_2d(ax, edge, options); +else + h = drawEdge_3d(ax, edge, options); +end + +% eventually return handle to created edges +if nargout > 0 + varargout = {h}; +end + + +function h = drawEdge_2d(ax, edge, options) + +h = -1 * ones(size(edge, 1), 1); + +for i = 1:size(edge, 1) + if isnan(edge(i,1)) + continue; + end + + h(i) = plot(ax, edge(i, [1 3]), edge(i, [2 4]), options{:}); +end + + +function h = drawEdge_3d(ax, edge, options) + +h = -1 * ones(size(edge, 1), 1); + +for i = 1:size(edge, 1) + if isnan(edge(i,1)) + continue; + end + + h(i) = plot3(ax, edge(i, [1 4]), edge(i, [2 5]), edge(i, [3 6]), options{:}); +end + + +function [ax edge options] = parseInputArguments(varargin) + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% find the number of arguments defining edges +nbVal = 0; +for i = 1:length(varargin) + if isnumeric(varargin{i}) + nbVal = nbVal+1; + else + % stop at the first non-numeric value + break; + end +end + +% extract drawing options +options = varargin(nbVal+1:end); + +% ensure drawing options have correct format +if length(options) == 1 + options = [{'color'}, options]; +end + +% extract edges characteristics +switch nbVal + case 1 + % all parameters in a single array + edge = varargin{1}; + + case 2 + % parameters are two points, or two arrays of points, of size N*2. + p1 = varargin{1}; + p2 = varargin{2}; + edge = [p1 p2]; + + case 4 + % parameters are 4 parameters of the edge : x1 y1 x2 and y2 + edge = [varargin{1} varargin{2} varargin{3} varargin{4}]; + + case 6 + % parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 + edge = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; + + otherwise + error('drawEdge:WrongNumberOfParameters', 'Wrong number of parameters'); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipse.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipse.m new file mode 100644 index 0000000..e282324 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipse.m @@ -0,0 +1,127 @@ +function varargout = drawEllipse(varargin) +%DRAWELLIPSE Draw an ellipse on the current axis +% +% drawEllipse(ELLI); +% Draws the ellipse ELLI in the form [XC YC RA RB THETA], with center +% (XC, YC), with main axis of half-length RA and RB, and orientation +% THETA in degrees counted counter-clockwise. +% +% drawEllipse(XC, YC, RA, RB); +% drawEllipse(XC, YC, RA, RB, THETA); +% Specifies ellipse parameters as separate arguments (old syntax). +% +% drawEllipse(..., NAME, VALUE); +% Specifies drawing style of ellipse, see the help of plot function. +% +% H = drawEllipse(...); +% Also returns handles to the created line objects. +% +% -> Parameters can also be arrays. In this case, all arrays are supposed +% to have the same size. +% +% Example: +% % Draw an ellipse centered in [50 50], with semi major axis length of +% % 40, semi minor axis length of 20, and rotated by 30 degrees. +% figure(1); clf; hold on; +% drawEllipse([50 50 40 20 30]); +% axis equal; +% +% % add another ellipse with different orientation and style +% drawEllipse([50 50 40 20 -10], 'linewidth', 2, 'color', 'g'); +% +% See also: +% ellipses2d, drawCircle, drawEllipseArc, ellipseToPolygon +% +% --------- +% author : David Legland +% e-mail: david.legland@grignon.inra.fr +% INRA - TPV URPOI - BIA IMASTE +% created the 11/12/2003. +% + +% HISTORY +% 2004-01-08 returns coord of points when 2 output args are asked +% 2004-01-08 fix bug in extraction of input parameters, theta was not +% initialized in case of array of size 1*5 +% 2005-08-13 uses radians instead of degrees +% 2008-02-21 add support for drawing styles, code cleanup +% 2011-03-30 use degrees instead of radians, remove [x y] = ... format +% 2011-10-11 add support for axis handle + + +%% Extract input arguments + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% extract dawing style strings +styles = {}; +for i = 1:length(varargin) + if ischar(varargin{i}) + styles = varargin(i:end); + varargin(i:end) = []; + break; + end +end + +% extract ellipse parameters +if length(varargin) == 1 + % ellipse is given in a single array + ellipse = varargin{1}; + x0 = ellipse(:, 1); + y0 = ellipse(:, 2); + a = ellipse(:, 3); + b = ellipse(:, 4); + if length(ellipse) > 4 + theta = ellipse(:, 5); + else + theta = zeros(size(x0)); + end + +elseif length(varargin) >= 4 + % ellipse parameters given as separate arrays + x0 = varargin{1}; + y0 = varargin{2}; + a = varargin{3}; + b = varargin{4}; + if length(varargin) > 4 + theta = varargin{5}; + else + theta = zeros(size(x0)); + end + +else + error('drawEllipse: incorrect input arguments'); +end + + +%% Process drawing of a set of ellipses + +% angular positions of vertices +t = linspace(0, 2*pi, 145); + +% compute position of points to draw each ellipse +h = zeros(length(x0), 1); +for i = 1:length(x0) + % pre-compute rotation angles (given in degrees) + cot = cosd(theta(i)); + sit = sind(theta(i)); + + % compute position of points used to draw current ellipse + xt = x0(i) + a(i) * cos(t) * cot - b(i) * sin(t) * sit; + yt = y0(i) + a(i) * cos(t) * sit + b(i) * sin(t) * cot; + + % stores handle to graphic object + h(i) = plot(ax, xt, yt, styles{:}); +end + +% return handles if required +if nargout > 0 + varargout = {h}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipseArc.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipseArc.m new file mode 100644 index 0000000..2bb0144 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawEllipseArc.m @@ -0,0 +1,151 @@ +function varargout = drawEllipseArc(varargin) +%DRAWELLIPSEARC Draw an ellipse arc on the current axis +% +% drawEllipseArc(ARC) +% draw ellipse arc specified by ARC. ARC has the format: +% ARC = [XC YC A B THETA T1 T2] +% or: +% ARC = [XC YC A B T1 T2] (isothetic ellipse) +% with center (XC, YC), main axis of half-length A, second axis of +% half-length B, and ellipse arc running from t1 to t2 (both in degrees, +% in Counter-Clockwise orientation). +% +% Parameters can also be arrays. In this case, all arrays are suposed to +% have the same size... +% +% drawEllipseArc(..., NAME, VALUE) +% Specifies one or more parameters name-value pairs, as in the plot +% function. +% +% drawEllipseArc(AX, ...) +% Sepcifies the handle of theaxis to draw on. +% +% H = drawEllipseArc(...) +% Returns handle(s) of the created graphic objects. +% +% Example +% % draw an ellipse arc: center = [10 20], radii = 50 and 30, theta = 45 +% arc = [10 20 50 30 45 -90 270]; +% figure; +% axis([-50 100 -50 100]); axis equal; +% hold on +% drawEllipseArc(arc, 'color', 'r') +% +% % draw another ellipse arc, between angles -60 and 70 +% arc = [10 20 50 30 45 -60 (60+70)]; +% figure; +% axis([-50 100 -50 100]); axis equal; +% hold on +% drawEllipseArc(arc, 'LineWidth', 2); +% ray1 = createRay([10 20], deg2rad(-60+45)); +% drawRay(ray1) +% ray2 = createRay([10 20], deg2rad(70+45)); +% drawRay(ray2) +% +% See also: +% ellipses2d, drawEllipse, drawCircleArc +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 12/12/2003. +% + + +% HISTORY +% 2008/10/10 uses fixed number of points for arc. +% 2011-03-30 use angles in degrees +% 2011-10-11 add management of axes handle + +%% Extract input arguments + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% extract dawing style strings +styles = {}; +for i = 1:length(varargin) + if ischar(varargin{i}) + styles = varargin(i:end); + varargin(i:end) = []; + break; + end +end + +if length(varargin)==1 + ellipse = varargin{1}; + x0 = ellipse(1); + y0 = ellipse(2); + a = ellipse(3); + b = ellipse(4); + if size(ellipse, 2)>6 + theta = ellipse(5); + start = ellipse(6); + extent = ellipse(7); + else + theta = zeros(size(x0)); + start = ellipse(5); + extent = ellipse(6); + end + +elseif length(varargin)>=6 + x0 = varargin{1}; + y0 = varargin{2}; + a = varargin{3}; + b = varargin{4}; + if length(varargin)>6 + theta = varargin{5}; + start = varargin{6}; + extent = varargin{7}; + else + theta = zeros(size(x0)); + start = varargin{5}; + extent = varargin{6}; + end + +else + error('drawEllipseArc: please specify center x, center y and radii a and b'); +end + + +%% Drawing + +% allocate memory for handles +h = zeros(size(x0)); + +for i = 1:length(x0) + % start and end angles + t1 = deg2rad(start); + t2 = t1 + deg2rad(extent); + + % vertices of ellipse + t = linspace(t1, t2, 60); + + % convert angles to ellipse parametrisation + sup = cos(t) > 0; + t(sup) = atan(a(i) / b(i) * tan(t(sup))); + t(~sup) = atan2(a(i) / b(i) * tan(2*pi - t(~sup)), -1); + t = mod(t, 2*pi); + + % precompute cos and sin of theta (given in degrees) + cot = cosd(theta(i)); + sit = sind(theta(i)); + + % compute position of points + xt = x0(i) + a(i)*cos(t)*cot - b(i)*sin(t)*sit; + yt = y0(i) + a(i)*cos(t)*sit + b(i)*sin(t)*cot; + + h(i) = plot(ax, xt, yt, styles{:}); +end + + +%% Process output arguments + +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLabels.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLabels.m new file mode 100644 index 0000000..1f94d16 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLabels.m @@ -0,0 +1,92 @@ +function varargout = drawLabels(varargin) +%DRAWLABELS Draw labels at specified positions +% +% DRAWLABELS(X, Y, LBL) draw labels LBL at position X and Y. +% LBL can be either a string array, or a number array. In this case, +% string are created by using sprintf function, with '%.2f' mask. +% +% DRAWLABELS(POS, LBL) draw labels LBL at position specified by POS, +% where POS is a N*2 int array. +% +% DRAWLABELS(..., NUMBERS, FORMAT) create labels using sprintf function, +% with the mask given by FORMAT (e. g. '%03d' or '5.3f'), and the +% corresponding values. +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 15/12/2003. +% + +% HISTORY +% 09/03/2007: (re)implement it... +% 2011-10-11 add management of axes handle + +% check if enough inputs are given +if isempty(varargin) + error('wrong number of arguments in drawLabels'); +end + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% process input parameters +var = varargin{1}; +if size(var, 2) == 1 + % coordinates given as separate arguments + if length(varargin) < 3 + error('wrong number of arguments in drawLabels'); + end + px = var; + py = varargin{2}; + lbl = varargin{3}; + varargin(1:3) = []; +else + % parameters given as a packed array + if length(varargin) < 2 + error('wrong number of arguments in drawLabels'); + end + px = var(:,1); + py = var(:,2); + lbl = varargin{2}; + varargin(1:2) = []; +end + +% format for displaying numeric values +format = '%.2f'; +if ~isempty(varargin) + format = varargin{1}; +end +if size(format, 1) == 1 && size(px, 1) > 1 + format = repmat(format, size(px, 1), 1); +end + +% compute the strings that have to be displayed +labels = cell(length(px), 1); +if isnumeric(lbl) + for i = 1:length(px) + labels{i} = sprintf(format(i,:), lbl(i)); + end +elseif ischar(lbl) + for i = 1:length(px) + labels{i} = lbl(i,:); + end +elseif iscell(lbl) + labels = lbl; +end +labels = char(labels); + +% display the text +h = text(px, py, labels, 'parent', ax); + +% format output +if nargout > 0 + varargout = {h}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLine.m new file mode 100644 index 0000000..46ff461 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawLine.m @@ -0,0 +1,67 @@ +function varargout = drawLine(lin, varargin) +%DRAWLINE Draw the line on the current axis +% +% drawline(LINE); +% Draws the line LINE on the current axis, by using current axis to clip +% the line. +% +% drawline(LINE, PARAM, VALUE); +% Specifies drawing options. +% +% H = drawLine(...) +% Returns a handle to the created line object. If clipped line is not +% contained in the axis, the function returns -1. +% +% Example +% figure; hold on; axis equal; +% axis([0 100 0 100]); +% drawLine([30 40 10 20]); +% drawLine([30 40 20 -10], 'color', 'm', 'linewidth', 2); +% drawLine([-30 140 10 20]); +% +% See also: +% lines2d, createLine, drawEdge +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 25/05/2004 add support for multiple lines (loop) +% 23/05/2005 add support for arguments +% 03/08/2010 bug for lines outside box (thanks to Reto Zingg) +% 04/08/2010 rewrite using clipLine +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw in +if isscalar(lin) && ishandle(lin) + ax = lin; + lin = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% default style for drawing lines +varargin = [{'color', 'r'}, varargin]; + +% extract bounding box of the current axis +xlim = get(ax, 'xlim'); +ylim = get(ax, 'ylim'); + +% clip lines with current axis box +clip = clipLine(lin, [xlim ylim]); +ok = isfinite(clip(:,1)); + +% initialize result array to invalide handles +h = -1*ones(size(lin, 1), 1); + +% draw valid lines +h(ok) = plot(ax, clip(ok, [1 3])', clip(ok, [2 4])', varargin{:}); + +% return line handle if needed +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawOrientedBox.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawOrientedBox.m new file mode 100644 index 0000000..68f1a40 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawOrientedBox.m @@ -0,0 +1,109 @@ +function varargout = drawOrientedBox(box, varargin) +%DRAWORIENTEDBOX Draw centered oriented rectangle +% +% Syntax +% drawOrientedBox(BOX) +% drawOrientedBox(BOX, 'PropertyName', propertyvalue, ...) +% +% Description +% drawOrientedBox(OBOX) +% Draws an oriented rectangle (or bounding box) on the current axis. +% OBOX is a 1-by-5 row vector containing box center, dimension (length +% and width) and orientation (in degrees): +% OBOX = [CX CY LENGTH WIDTH THETA]. +% +% When OBOX is a N-by-5 array, the N boxes are drawn. +% +% drawOrientedBox(AX, ...) +% Specifies the axis to draw to point in. AX should be a handle to a axis +% object. By default, display on current axis. +% +% HB = drawOrientedBox(...) +% Returns a handle to the created graphic object(s). Object style can be +% modified using syntaw like: +% set(HB, 'color', 'g', 'linewidth', 2); +% +% Example +% % draw an ellipse together with its oriented box +% elli = [30 40 60 30 20]; +% figure; +% drawEllipse(elli, 'linewidth', 2, 'color', 'g'); +% hold on +% box = [30 40 120 60 20]; +% drawOrientedBox(box, 'color', 'k'); +% axis equal; +% +% See also +% drawPolygon, drawRect, drawBox +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-09, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2011-07-22 simplifies code +% 2011-10-11 add management of axes handle + + +%% Parses input arguments + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +if length(varargin) > 4 && sum(cellfun(@isnumeric, varargin(1:4))) == 4 + % input given as separate arguments + cx = box; + cy = varargin{1}; + hl = varargin{2} / 2; + hw = varargin{3} / 2; + theta = varargin{4}; + varargin = varargin(5:end); + +else + % input given as packed array + cx = box(:,1); + cy = box(:,2); + hl = box(:,3) / 2; + hw = box(:,4) / 2; + theta = box(:,5); +end + + +%% Draw each box + +% allocate memory for graphical handle +hr = zeros(length(cx), 1); + +% iterate on oriented boxes +for i = 1:length(cx) + % pre-compute angle data + cot = cosd(theta(i)); + sit = sind(theta(i)); + + % x and y shifts + lc = hl(i) * cot; + ls = hl(i) * sit; + wc = hw(i) * cot; + ws = hw(i) * sit; + + % coordinates of box vertices + vx = cx(i) + [-lc + ws; lc + ws ; lc - ws ; -lc - ws ; -lc + ws]; + vy = cy(i) + [-ls - wc; ls - wc ; ls + wc ; -ls + wc ; -ls - wc]; + + % draw polygons + hr(i) = plot(ax, vx, vy, varargin{:}); +end + + +%% Format output + +if nargout > 0 + varargout = {hr}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawParabola.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawParabola.m new file mode 100644 index 0000000..d8dc20c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawParabola.m @@ -0,0 +1,123 @@ +function varargout = drawParabola(varargin) +%DRAWPARABOLA Draw a parabola on the current axis +% +% drawParabola(PARABOLA); +% Draws a vertical parabola, defined by its vertex and its parameter. +% Such a parabola admits a vertical axis of symetry. +% +% The algebraic equation of parabola is given by: +% (Y - YV) = A * (X - VX)^2 +% Where XV and YV are vertex coordinates and A is parabola parameter. +% +% A parametric equation of parabola is given by: +% x(t) = t + VX; +% y(t) = A * t^2 + VY; +% +% PARABOLA can also be defined by [XV YV A THETA], with theta being the +% angle of rotation of the parabola (in degrees and Counter-Clockwise). +% +% drawParabola(PARABOLA, T); +% Specifies which range of 't' are used for drawing parabola. If T is an +% array with only two values, the first and the last values are used as +% interval bounds, and several values are distributed within this +% interval. +% +% drawParabola(..., NAME, VALUE); +% Can specify one or several graphical options using parameter name-value +% pairs. +% +% drawParabola(AX, ...); +% Specifies handle of the axis to draw on. +% +% H = drawParabola(...); +% Returns an handle to the created graphical object. +% +% +% Example: +% figure(1); clf; hold on; +% drawParabola([50 50 .2 30]); +% drawParabola([50 50 .2 30], [-1 1], 'color', 'r', 'linewidth', 2); +% axis equal; +% +% See Also: +% drawCircle, drawEllipse +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 02/06/2006. +% + +% HISTORY +% 2010-11-17 rewrite, change parametrisation, update doc +% 2011-03-30 use degrees for angle +% 2011-10-11 add management of axes handle + +% Extract parabola +if nargin < 1 + error('geom2d:drawParabola:IllegalArgument', ... + 'Please specify parabola representation'); +end + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% input parabola is given as a packed array +parabola = varargin{1}; +varargin(1) = []; +x0 = parabola(:,1); +y0 = parabola(:,2); +a = parabola(:,3); + +% check if parabola orientation is specified +if size(parabola, 2) > 3 + theta = parabola(:, 4); +else + theta = zeros(length(a), 1); +end + +% extract parametrisation bounds +bounds = [-100 100]; +if ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) + bounds = var; + varargin(1) = []; + end +end + +% create parametrisation array +if length(bounds) > 2 + t = bounds; +else + t = linspace(bounds(1), bounds(end), 100); +end + +% create handle array (in the case of several parabola) +h = zeros(size(x0)); + +% draw each parabola +for i = 1:length(x0) + % compute transformation + trans = ... + createTranslation(x0(i), y0(i)) * ... + createRotation(deg2rad(theta(i))) * ... + createScaling(1, a); + + % compute points on the parabola + [xt yt] = transformPoint(t(:), t(:).^2, trans); + + % draw it + h(i) = plot(ax, xt, yt, varargin{:}); +end + +% process output arguments +if nargout > 0 + varargout = {h}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawPoint.m new file mode 100644 index 0000000..6eed7d7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawPoint.m @@ -0,0 +1,86 @@ +function varargout = drawPoint(varargin) +%DRAWPOINT Draw the point on the axis. +% +% drawPoint(X, Y); +% Draws points defined by coordinates X and Y. +% X and Y should be array the same size. +% +% drawPoint(COORD); +% Packs coordinates in a single N-by-2 array. +% +% drawPoint(..., OPT); +% Draws each point with given option. OPT is a series of arguments pairs +% compatible with 'plot' model. Default drawing option is 'bo', +% corresponding to blue circles. +% +% drawPoint(AX, ...); +% Specifies the axis to draw to point in. AX should be a handle to a axis +% object. By default, display on current axis. +% +% H = drawPoint(...) also return a handle to each of the drawn points. +% +% Example +% % display a single point +% figure; +% drawPoint([10 10]); +% +% % display several points forming a circle +% t = linspace(0, 2*pi, 20)'; +% drawPoint([5*cos(t)+10 3*sin(t)+10], 'r+'); +% axis equal; +% +% See also +% points2d, clipPoints +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 23/02/2004 add more documentation. Manage different kind of inputs. +% Does not draw points outside visible area. +% 26/02/2007 update processing of input arguments. +% 30/04/2009 remove clipping of points (use clipPoints if necessary) +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw on +if isscalar(varargin{1}) && ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% extract point(s) coordinates +var = varargin{1}; +if size(var, 2) == 1 + % points stored in separate arrays + px = varargin{1}; + py = varargin{2}; + varargin(1:2) = []; +else + % points packed in one array + px = var(:, 1); + py = var(:, 2); + varargin(1) = []; +end + +% ensure we have column vectors +px = px(:); +py = py(:); + +% default drawing options, but keep specified options if it has the form of +% a bundled string +if length(varargin) ~= 1 + varargin = [{'linestyle', 'none', 'marker', 'o', 'color', 'b'}, varargin]; +end + +% plot the points, using specified drawing options +h = plot(ax, px(:), py(:), varargin{:}); + +% process output arguments +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRay.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRay.m new file mode 100644 index 0000000..0a07964 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRay.m @@ -0,0 +1,55 @@ +function varargout = drawRay(ray, varargin) +%DRAWRAY Draw a ray on the current axis +% +% drawRay(RAY) +% With RAY having the syntax: [x0 y0 dx dy], draws the ray starting from +% point (x0 y0) and going to direction (dx dy), clipped with the current +% window axis. +% +% drawRay(RAY, PARAMS, VALUE) +% Can specify param-pair values. +% +% H = drawRay(...) +% Returns handle on line object +% +% See also: +% rays2d, drawLine +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 2005-07-06 add support for multiple rays +% 2007-10-18 add support for drawing options +% 2011-03-12 rewrite using clipRay +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw in +if isscalar(ray) && ishandle(ray) + ax = lin; + ray = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% get bounding box limits +box = axis(ax); + +% compute clipped shapes +[clipped isInside] = clipRay(ray, box); + +% allocate memory for handle +h = -ones(size(ray, 1), 1); + +% draw visible rays +h(isInside) = drawEdge(ax, clipped(isInside, :), varargin{:}); + +% process output +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect.m new file mode 100644 index 0000000..7260b18 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect.m @@ -0,0 +1,63 @@ +function varargout = drawRect(rect, varargin) +%DRAWRECT Draw rectangle on the current axis +% +% drawRect(RECT) +% draws the rectangles defined by RECT = [X0 Y0 W H]. +% the four corners of rectangle are then : +% (X0, Y0), (X0+W, Y0), (X0, Y0+H), (X0+W, Y0+H). +% +% RECT = [X0 Y0 W H THETA] also specifies orientation for the rectangle. +% Theta is given in degrees. +% +% If RECT is a N-by-4 or N-by-5 array, several rectangles are drawn. +% +% drawRect(..., PARAM, VALUE) +% Specifies one or several parameters name-value pairs, see plot function +% for details. +% +% drawRect(AX, ...) +% Specifies the handle of the axis to draw the rectangle on. +% +% H = drawRect(...) +% Returns handle of the created graphic objects. +% +% See Also: +% drawOrientedBox, drawBox, rectToPolygon +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/12/2003. +% + +% HISTORY +% 2003-12-12 add support for multiple rectangles +% 2011-10-09 rewrite using rectToPolygon, add support for drawing options +% 2011-10-11 add management of axes handle + +% extract handle of axis to draw on +if isscalar(rect) && ishandle(rect) + ax = rect; + rect = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% number of rectangles to draw +n = size(rect, 1); + +% display each rectangle +r = zeros(n, 1); +for i = 1:n + % compute vertex corodinates + poly = rectToPolygon(rect(i, :)); + % display resulting polygon + r(i) = drawPolygon(ax, poly, varargin{:}); +end + +% process output +if nargout > 0 + varargout = {r}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect2.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect2.m new file mode 100644 index 0000000..de5d98d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawRect2.m @@ -0,0 +1,86 @@ +function varargout = drawRect2(varargin) +%DRAWRECT2 Draw centered rectangle on the current axis +% +% r = drawRect2(x, y, w, h) draw rectangle with width W and height H, +% whose center is located at (x, y); +% +% The four corners of rectangle are then : +% (X-W/2, Y-H/2), (X+W/2, Y-H/2), (X+W/2, Y+H/2), (X-W/2, Y+H/2). +% +% r = drawRect2(x, y, w, h, theta) also specifies orientation for +% rectangle. Theta is given in radians. +% +% r = drawRect2(coord) is the same as DRAWRECT2(X,Y,W,H), but all +% parameters are packed into one array, whose dimensions is 4*1 or 5*1. +% +% deprecated: use 'drawOrientedBox' instead +% +% See Also : +% drawRect +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 04/05/2004. +% + +warning('polygons2d:deprecated', ... + 'This function is deprecated, use "drawOrientedBox" instead'); + +% default values +theta = 0; + +% get entered values +if length(varargin)>3 + x = varargin{1}; + y = varargin{2}; + w = varargin{3}; + h = varargin{4}; + if length(varargin)>4 + theta = varargin{5}; + end +else + coord = varargin{1}; + x = coord(:, 1); + y = coord(:, 2); + w = coord(:, 3); + h = coord(:, 4); + + if length(coord)>4 + theta = coord(:, 5); + else + theta = zeros(size(x)); + end +end + +% use only the half length of each rectanhle +w = w/2; +h = h/2; + +hr = zeros(length(x), 1); +for i=1:length(x) + tx = zeros(5, 1); + ty = zeros(5, 1); + + tx(1) = x(i) - w(i)*cos(theta(i)) + h(i)*sin(theta(i)); + ty(1) = y(i) - w(i)*sin(theta(i)) - h(i)*cos(theta(i)); + + tx(2) = x(i) + w(i)*cos(theta(i)) + h(i)*sin(theta(i)); + ty(2) = y(i) + w(i)*sin(theta(i)) - h(i)*cos(theta(i)); + + tx(3) = x(i) + w(i)*cos(theta(i)) - h(i)*sin(theta(i)); + ty(3) = y(i) + w(i)*sin(theta(i)) + h(i)*cos(theta(i)); + + tx(4) = x(i) - w(i)*cos(theta(i)) - h(i)*sin(theta(i)); + ty(4) = y(i) - w(i)*sin(theta(i)) + h(i)*cos(theta(i)); + + tx(5) = x(i) - w(i)*cos(theta(i)) + h(i)*sin(theta(i)); + ty(5) = y(i) - w(i)*sin(theta(i)) - h(i)*cos(theta(i)); + + hr(i) = line(tx, ty); +end + +if nargout > 0 + varargout{1} = hr; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawShape.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawShape.m new file mode 100644 index 0000000..46e772a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/drawShape.m @@ -0,0 +1,78 @@ +function varargout = drawShape(type, param, varargin) +%DRAWSHAPE Draw various types of shapes (circles, polygons...) +% +% drawShape(TYPE, PARAM) +% Draw the shape of type TYPE, specified by given parameter PARAM. TYPE +% can be one of {'circle', 'ellipse', 'rect', 'polygon', 'curve'} +% PARAM depend on the type. For example, if TYPE is 'circle', PARAM will +% contain [x0 y0 R]. +% +% Examples : +% drawShape('circle', [20 10 30]); +% Draw circle centered on [20 10] with radius 10. +% drawShape('rect', [20 20 40 10 pi/3]); +% Draw rectangle centered on [20 20] with length 40 and width 10, and +% oriented pi/3 wrt axis Ox. +% +% +% drawShape(..., OPTION) +% also specifies drawing options. OPTION can be 'draw' (default) or +% 'fill'. +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2005. +% + +% HISTORY + +if ~iscell(type) + type = {type}; +end +if ~iscell(param) + tmp = cell(1, size(param, 1)); + for i=1:size(param, 1) + tmp{i} = param(i,:); + end + param = tmp; +end + +option = 'draw'; +if ~isempty(varargin) + var = varargin{1}; + if strcmpi(var, 'fill') + option = 'fill'; + end +end + + +% transform each shape into a polygon +shape = cell(1,length(type)); +for i=1:length(type) + if strcmpi(type{i}, 'circle') + shape{i} = circleAsPolygon(param{i}, 128); + elseif strcmpi(type{i}, 'rect') + shape{i} = rectAsPolygon(param{i}); + elseif strcmpi(type{i}, 'polygon') + shape{i} = param{i}; + end +end + + +hold on; +h = zeros(length(shape), 1); +if strcmp(option, 'draw') + for i=1:length(shape) + h(i) = drawPolygon(shape{i}); + end +else + for i=1:length(shape) + h(i) = fillPolygon(shape{i}); + end +end + +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeAngle.m new file mode 100644 index 0000000..d261e13 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeAngle.m @@ -0,0 +1,28 @@ +function theta = edgeAngle(edge) +%EDGEANGLE Return angle of edge +% +% A = edgeAngle(EDGE) +% Returns the angle between horizontal, right-axis and the edge EDGE. +% Angle is given in radians, between 0 and 2*pi, in counter-clockwise +% direction. +% Notation for edge is [x1 y1 x2 y2] (coordinates of starting and ending +% points). +% +% Example +% p1 = [10 20]; +% p2 = [30 40]; +% rad2deg(edgeAngle([p1 p2])) +% ans = +% 45 +% +% See also +% edges2d, angles2d, edgeAngle, lineAngle, edgeLength +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2003. +% + +line = createLine(edge(:,1:2), edge(:,3:4)); +theta = lineAngle(line); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeLength.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeLength.m new file mode 100644 index 0000000..fb0b66a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgeLength.m @@ -0,0 +1,39 @@ +function len = edgeLength(varargin) +%EDGELENGTH Return length of an edge +% +% L = edgeLength(EDGE); +% Returns the length of an edge, with parametric representation: +% [x1 y1 x2 y2]. +% +% The function also works for several edges, in this case input is a +% N-by-4 array, containing parametric representation of each edge, and +% output is a N-by-1 array containing length of each edge. +% +% See also: +% edges2d, edgeAngle +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 19/02/2004 +% + +% HISTORY +% 15/04/2005 changes definition for edge, uses [x1 y1 x2 y2] instead of +% [x0 y0 dx dy]. + +% TODO : specify norm (euclidian, taxi, ...). + +if nargin == 1 + % input is an edge [X1 Y1 X2 Y2] + edge = varargin{1}; + len = hypot(edge(:,3)-edge(:,1), edge(:,4)-edge(:,2)); + +elseif nargin == 2 + % input are two points [X1 Y1] and [X2 Y2] + p1 = varargin{1}; + p2 = varargin{2}; + len = hypot(p2(:,1)-p1(:,1), p2(:,2)-p1(:,2)); + +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgePosition.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgePosition.m new file mode 100644 index 0000000..06b50be --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/edgePosition.m @@ -0,0 +1,63 @@ +function d = edgePosition(point, edge) +%EDGEPOSITION Return position of a point on an edge +% +% POS = edgePosition(POINT, EDGE); +% Computes position of point POINT on the edge EDGE, relative to the +% position of edge vertices. +% EDGE has the form [x1 y1 x2 y2], +% POINT has the form [x y], and is assumed to belong to edge. +% The position POS has meaning: +% POS<0: POINT is located before the first vertex +% POS=0: POINT is located on the first vertex +% 0 4 + theta = ellipse(:,5); +end + +% get ellipse parameters +xc = ellipse(:,1); +yc = ellipse(:,2); +a = ellipse(:,3); +b = ellipse(:,4); + +% create time basis +t = linspace(0, 2*pi, N+1)'; + +% pre-compute trig functions (angles is in degrees) +cot = cosd(theta); +sit = sind(theta); + +% position of points +x = xc + a * cos(t) * cot - b * sin(t) * sit; +y = yc + a * cos(t) * sit + b * sin(t) * cot; + +% format output depending on number of a param. +if nargout == 1 + varargout = {[x y]}; +elseif nargout == 2 + varargout = {x, y}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/ellipses2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/ellipses2d.m new file mode 100644 index 0000000..f6733e8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/ellipses2d.m @@ -0,0 +1,18 @@ +function ellipses2d(varargin) +%ELLIPSES2D Description of functions operating on ellipses +% +% Ellipses are represented by their center, the length of their 2 +% semi-axes length, and their angle from the Ox direction (in degrees). +% E = [XC YC A B THETA]; +% +% See also: +% circles2d, inertiaEllipse, isPointInEllipse, ellipseToPolygon +% drawEllipse, drawEllipseArc +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2010 INRA - Cepia Software Platform. + +help('ellipses2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/enclosingCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/enclosingCircle.m new file mode 100644 index 0000000..03a7681 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/enclosingCircle.m @@ -0,0 +1,67 @@ +function circle = enclosingCircle(pts) +%ENCLOSINGCIRCLE Find the minimum circle enclosing a set of points. +% +% CIRCLE = enclosingCircle(POINTS); +% compute cirlce CIRCLE=[xc yc r] which enclose all points POINTS given +% as an [Nx2] array. +% +% +% Rewritten from a file from +% Yazan Ahed (yash78@gmail.com) +% +% which was rewritten from a Java applet by Shripad Thite: +% http://heyoka.cs.uiuc.edu/~thite/mincircle/ +% +% See also: +% circles2d, points2d, boxes2d, triangleCircumCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/07/2005. +% + +% works on convex hull : it is faster +pts = pts(convhull(pts(:,1), pts(:,2)), :); + +circle = recurseCircle(size(pts, 1), pts, 1, zeros(3, 2)); + + + +function circ = recurseCircle(n, p, m, b) +% n: number of points given +% m: an argument used by the function. Always use 1 for m. +% bnry: an argument (3x2 array) used by the function to set the points that +% determines the circle boundry. You have to be careful when choosing this +% array's values. I think the values should be somewhere outside your points +% boundary. For my case, for example, I know the (x,y) I have will be something +% in between (-5,-5) and (5,5), so I use bnry as: +% [-10 -10 +% -10 -10 +% -10 -10] + + +if m==4 + circ = createCircle(b(1,:), b(2,:), b(3,:)); + return; +end + +circ = [Inf Inf 0]; + +if m == 2 + circ = [b(1,1:2) 0]; +elseif m == 3 + c = (b(1,:) + b(2,:))/2; + circ = [c distancePoints(b(1,:), c)]; +end + + +for i = 1:n + if distancePoints(p(i,:), circ(1:2)) > circ(3) + if sum(b(:,1)==p(i,1) & b(:,2)==p(i,2)) == 0 + b(m,:) = p(i,:); + circ = recurseCircle(i, p, m+1, b); + end + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/fitAffineTransform2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/fitAffineTransform2d.m new file mode 100644 index 0000000..ef73acf --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/fitAffineTransform2d.m @@ -0,0 +1,39 @@ +function trans = fitAffineTransform2d(pts1, pts2) +%FITAFFINETRANSFORM2D Fit an affine transform using two point sets +% TRANS = fitAffineTransform2d(PTS1, PTS2) +% +% Example +% N = 10; +% pts = rand(N, 2)*10; +% trans = createRotation(3, 4, pi/4); +% pts2 = transformPoint(pts, trans); +% pts3 = pts2 + randn(N, 2)*2; +% fitted = fitAffineTransform2d(pts, pts2); +% +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-07-31, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + + +% number of points +N = size(pts1, 1); + +% main matrix of the problem +A = [... + pts1(:,1) pts1(:,2) ones(N,1) zeros(N, 3) ; ... + zeros(N, 3) pts1(:,1) pts1(:,2) ones(N,1) ]; + +% conditions initialisations +B = [pts2(:,1) ; pts2(:,2)]; + +% compute coefficients using least square +coefs = A\B; + +% format to a matrix +trans = [coefs(1:3)' ; coefs(4:6)'; 0 0 1]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/formatAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/formatAngle.m new file mode 100644 index 0000000..569f082 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/formatAngle.m @@ -0,0 +1,28 @@ +function alpha = formatAngle(alpha) +%FORMATANGLE Ensure an angle value is comprised between 0 and 2*PI +% ALPHA2 = formatAngle(ALPHA) +% ALPHA2 is the same as ALPHA modulo 2*PI and is positive. +% +% Example: +% formatAngle(5*pi) +% ans = +% 3.1416 +% +% See also +% vectorAngle, lineAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-03-10, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 2010-03-31 deprecate and replace by function 'normalizeAngle' + +% deprecation warning +warning('geom2d:deprecated', ... + '''formatAngle'' is deprecated, use ''normalizeAngle'' instead'); + +alpha = mod(alpha, 2*pi); +alpha(alpha<0) = 2*pi + alpha(alpha<0); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/hexagonalGrid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/hexagonalGrid.m new file mode 100644 index 0000000..ad11194 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/hexagonalGrid.m @@ -0,0 +1,88 @@ +function varargout = hexagonalGrid(bounds, origin, size, varargin) +%HEXAGONALGRID Generate hexagonal grid of points in the plane. +% +% usage +% PTS = hexagonalGrid(BOUNDS, ORIGIN, SIZE) +% generate points, lying in the window defined by BOUNDS (=[xmin ymin +% xmax ymax]), starting from origin with a constant step equal to size. +% SIZE is constant and is equals to the length of the sides of each +% hexagon. +% +% TODO: add possibility to use rotated grid +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/08/2005. +% +size = size(1); +dx = 3*size; +dy = size*sqrt(3); + + + +% consider two square grids with different centers +pts1 = squareGrid(bounds, origin + [0 0], [dx dy], varargin{:}); +pts2 = squareGrid(bounds, origin + [dx/3 0], [dx dy], varargin{:}); +pts3 = squareGrid(bounds, origin + [dx/2 dy/2], [dx dy], varargin{:}); +pts4 = squareGrid(bounds, origin + [-dx/6 dy/2], [dx dy], varargin{:}); + +% gather points +pts = [pts1;pts2;pts3;pts4]; + + + + +% eventually compute also edges, clipped by bounds +% TODO : manage generation of edges +if nargout>1 + edges = zeros([0 4]); + x0 = origin(1); + y0 = origin(2); + + % find all x coordinate + x1 = bounds(1) + mod(x0-bounds(1), dx); + x2 = bounds(3) - mod(bounds(3)-x0, dx); + lx = (x1:dx:x2)'; + + % horizontal edges : first find y's + y1 = bounds(2) + mod(y0-bounds(2), dy); + y2 = bounds(4) - mod(bounds(4)-y0, dy); + ly = (y1:dy:y2)'; + + % number of points in each coord, and total number of points + ny = length(ly); + nx = length(lx); + + if bounds(1)-x1+dx0 + varargout{1} = pts; + + if nargout>1 + varargout{2} = edges; + end +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/homothecy.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/homothecy.m new file mode 100644 index 0000000..8a2f6e4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/homothecy.m @@ -0,0 +1,24 @@ +function trans = homothecy(point, ratio) +%HOMOTHECY create a homothecy as an affine transform +% +% TRANS = homothecy(POINT, K); +% POINT is the center of the homothecy, K is its factor. +% +% See also: +% transforms2d, transformPoint, createTranslation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/01/2005. +% + +% HISTORY +% 22/04/2009: copy to createHomothecy and deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''homothecy'' is deprecated, use ''createHomothecy'' instead'); + +% call current implementation +trans = createHomothecy(point, ratio); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inCircle.m new file mode 100644 index 0000000..f121dab --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inCircle.m @@ -0,0 +1,32 @@ +function b = inCircle(point, circle) +%INCIRCLE test if a point is located inside a given circle. +% +% B = inCircle(POINT, CIRCLE) +% return true if point is located inside the circle +% +% Example: +% inCircle([1 0], [0 0 1]) +% inCircle([0 0], [0 0 1]) +% returns true, whereas +% inCircle([1 1], [0 0 1]) +% return false +% +% See also: +% circles2d, onCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + +% HISTORY +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''inCircle'' is deprecated, use ''isPointInCircle'' instead'); + +d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); +b = d-circle(:,3)<=1e-12; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inertiaEllipse.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inertiaEllipse.m new file mode 100644 index 0000000..35b27a9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/inertiaEllipse.m @@ -0,0 +1,66 @@ +function ell = inertiaEllipse(points) +%INERTIAELLIPSE Inertia ellipse of a set of points +% +% ELL = inertiaEllipse(PTS); +% where PTS is a N*2 array containing coordinates of N points, computes +% the inertia ellispe of the set of points. +% +% The result has the form: +% ELL = [XC YC A B THETA], +% with XC and YC being the center of mass of the point set, A and B are +% the lengths of the inertia ellipse (see below), and THETA is the angle +% of the main inertia axis with the horizontal (counted in degrees +% between 0 and 180). +% A and B are the standard deviations of the point coordinates when +% ellipse is aligned with the inertia axes. +% +% Example +% pts = randn(100, 2); +% pts = transformPoint(pts, createScaling(5, 2)); +% pts = transformPoint(pts, createRotation(pi/6)); +% pts = transformPoint(pts, createTranslation(3, 4)); +% ell = inertiaEllipse(pts); +% figure(1); clf; hold on; +% drawPoint(pts); +% drawEllipse(ell, 'linewidth', 2, 'color', 'r'); +% +% See also +% ellipses2d, drawEllipse +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-02-21, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 2009-07-29 take into account ellipse orientation +% 2011-03-12 rewrite using inertia moments + +% ellipse center +xc = mean(points(:,1)); +yc = mean(points(:,2)); + +% recenter points +x = points(:,1) - xc; +y = points(:,2) - yc; + +% number of points +n = size(points, 1); + +% inertia parameters +Ixx = sum(x.^2) / n; +Iyy = sum(y.^2) / n; +Ixy = sum(x.*y) / n; + +% compute ellipse semi-axis lengths +common = sqrt( (Ixx - Iyy)^2 + 4 * Ixy^2); +ra = sqrt(2) * sqrt(Ixx + Iyy + common); +rb = sqrt(2) * sqrt(Ixx + Iyy - common); + +% compute ellipse angle in degrees +theta = atan2(2 * Ixy, Ixx - Iyy) / 2; +theta = rad2deg(theta); + +% create the resulting inertia ellipse +ell = [xc yc ra rb theta]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectBoxes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectBoxes.m new file mode 100644 index 0000000..8a7827d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectBoxes.m @@ -0,0 +1,37 @@ +function box = intersectBoxes(box1, box2) +%INTERSECTBOXES Intersection of two bounding boxes +% +% RES = intersectBoxes(BOX1, BOX2) +% +% Example +% box1 = [5 20 5 30]; +% box2 = [0 15 0 15]; +% intersectBoxes(box1, box2) +% ans = +% 5 15 5 15 +% +% See also +% boxes2d, drawBox, mergeBoxes +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% unify sizes of data +if size(box1,1) == 1 + box1 = repmat(box1, size(box2,1), 1); +elseif size(box2, 1) == 1 + box2 = repmat(box2, size(box1,1), 1); +elseif size(box1,1) ~= size(box2,1) + error('Bad size for inputs'); +end + +% compute extreme coords +mini = min(box1(:,[2 4]), box2(:,[2 4])); +maxi = max(box1(:,[1 3]), box2(:,[1 3])); + +% concatenate result into a new box structure +box = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2)]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectCircles.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectCircles.m new file mode 100644 index 0000000..f2709ec --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectCircles.m @@ -0,0 +1,101 @@ +function points = intersectCircles(circle1, circle2) +%INTERSECTCIRCLES Intersection points of two circles +% +% POINTS = intersectCircles(CIRCLE1, CIRCLE2) +% Computes the intersetion point of the two circles CIRCLE1 and CIRCLE1. +% Both circles are given with format: [XC YC R], with (XC,YC) being the +% coordinates of the center and R being the radius. +% POINTS is a 2-by-2 array, containing coordinate of an intersection +% point on each row. +% In the case of tangent circles, the intersection is returned twice. It +% can be simplified by using the 'unique' function. +% +% Example +% % intersection points of two distant circles +% c1 = [0 0 10]; +% c2 = [10 0 10]; +% pts = intersectCircles(c1, c2) +% pts = +% 5 -8.6603 +% 5 8.6603 +% +% % intersection points of two tangent circles +% c1 = [0 0 10]; +% c2 = [20 0 10]; +% pts = intersectCircles(c1, c2) +% pts = +% 10 0 +% 10 0 +% pts2 = unique(pts, 'rows') +% pts2 = +% 10 0 +% +% References +% http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/ +% http://mathworld.wolfram.com/Circle-CircleIntersection.html +% +% See also +% circles2d, intersectLineCircle, radicalAxis +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-01-20, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2011-06-06 add support for multiple inputs + + +% adapt sizes of inputs +n1 = size(circle1, 1); +n2 = size(circle2, 1); +if n1 ~= n2 + if n1 > 1 && n2 == 1 + circle2 = repmat(circle2, n1, 1); + elseif n2 > 1 && n1 == 1 + circle1 = repmat(circle1, n2, 1); + else + error('Both input should have same number of rows'); + end +end + +% extract center and radius of each circle +center1 = circle1(:, 1:2); +center2 = circle2(:, 1:2); +r1 = circle1(:,3); +r2 = circle2(:,3); + +% allocate memory for result +nPoints = length(r1); +points = NaN * ones(2*nPoints, 2); + +% distance between circle centers +d12 = distancePoints(center1, center2, 'diag'); + +% get indices of circle couples with intersections +inds = d12 >= abs(r1 - r2) & d12 <= (r1 + r2); + +if sum(inds) == 0 + return; +end + +% angle of line from center1 to center2 +angle = angle2Points(center1(inds,:), center2(inds,:)); + +% position of intermediate point, located at the intersection of the +% radical axis with the line joining circle centers +d1m = d12(inds) / 2 + (r1(inds).^2 - r2(inds).^2) ./ (2 * d12(inds)); +tmp = polarPoint(center1(inds, :), d1m, angle); + +% distance between intermediate point and each intersection point +h = sqrt(r1(inds).^2 - d1m.^2); + +% indices of valid intersections +inds2 = find(inds)*2; +inds1 = inds2 - 1; + +% create intersection points +points(inds1, :) = polarPoint(tmp, h, angle - pi/2); +points(inds2, :) = polarPoint(tmp, h, angle + pi/2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectEdges.m new file mode 100644 index 0000000..8ebfe74 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectEdges.m @@ -0,0 +1,151 @@ +function point = intersectEdges(edge1, edge2) +%INTERSECTEDGES Return all intersections between two set of edges +% +% P = intersectEdges(E1, E2); +% returns the intersection point of lines L1 and L2. E1 and E2 are 1-by-4 +% arrays, containing parametric representation of each edge (in the form +% [x1 y1 x2 y2], see 'createEdge' for details). +% +% In case of colinear edges, returns [Inf Inf]. +% In case of parallel but not colinear edges, returns [NaN NaN]. +% +% If each input is [N*4] array, the result is a [N*2] array containing +% intersections of each couple of edges. +% If one of the input has N rows and the other 1 row, the result is a +% [N*2] array. +% +% See also: +% edges2d, intersectLines +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 19/02/2004 add support for multiple edges. +% 15/08/2005 rewrite a lot, and create unit tests +% 08/03/2007 update doc +% 21/09/2009 fix bug for edge arrays (thanks to Miquel Cubells) +% 03/08/2010 fix another bug for edge arrays (thanks to Reto Zingg) + +%% Initialisations + +% ensure input arrays are same size +N1 = size(edge1, 1); +N2 = size(edge2, 1); + +% ensure input have same size +if N1~=N2 + if N1==1 + edge1 = repmat(edge1, [N2 1]); + N1 = N2; + elseif N2==1 + edge2 = repmat(edge2, [N1 1]); + end +end + +% tolerance for precision +tol = 1e-14; + +% initialize result array +x0 = zeros(N1, 1); +y0 = zeros(N1, 1); + + +%% Detect parallel and colinear cases + +% indices of parallel edges +%par = abs(dx1.*dy2 - dx1.*dy2) return [NaN NaN] +x0(par & ~col) = NaN; +y0(par & ~col) = NaN; + + +%% Process colinear edges + +% colinear edges may have 0, 1 or infinite intersection +% Discrimnation based on position of edge2 vertices on edge1 +if sum(col)>0 + % array for storing results of colinear edges + resCol = Inf*ones(size(col)); + + % compute position of edge2 vertices wrt edge1 + t1 = edgePosition(edge2(col, 1:2), edge1(col, :)); + t2 = edgePosition(edge2(col, 3:4), edge1(col, :)); + + % control location of vertices: we want t1t2 + tmp = t1; + t1 = t2; + t2 = tmp; + end + + % edge totally before first vertex or totally after last vertex + resCol(col(t2<-eps)) = NaN; + resCol(col(t1>1+eps)) = NaN; + + % set up result into point coordinate + x0(col) = resCol; + y0(col) = resCol; + + % touches on first point of first edge + touch = col(abs(t2)<1e-14); + x0(touch) = edge1(touch, 1); + y0(touch) = edge1(touch, 2); + + % touches on second point of first edge + touch = col(abs(t1-1)<1e-14); + x0(touch) = edge1(touch, 3); + y0(touch) = edge1(touch, 4); +end + + +%% Process non parallel cases + +% process intersecting edges whose interecting lines intersect +i = find(~par); + +% use a test to avoid process empty arrays +if sum(i)>0 + % extract base parameters of supporting lines for non-parallel edges + x1 = edge1(i,1); + y1 = edge1(i,2); + dx1 = edge1(i,3)-x1; + dy1 = edge1(i,4)-y1; + x2 = edge2(i,1); + y2 = edge2(i,2); + dx2 = edge2(i,3)-x2; + dy2 = edge2(i,4)-y2; + + % compute intersection points of supporting lines + delta = (dx2.*dy1-dx1.*dy2); + x0(i) = ((y2-y1).*dx1.*dx2 + x1.*dy1.*dx2 - x2.*dy2.*dx1) ./ delta; + y0(i) = ((x2-x1).*dy1.*dy2 + y1.*dx1.*dy2 - y2.*dx2.*dy1) ./ -delta; + + % compute position of intersection points on each edge + % t1 is position on edge1, t2 is position on edge2 + t1 = ((y0(i)-y1).*dy1 + (x0(i)-x1).*dx1) ./ (dx1.*dx1+dy1.*dy1); + t2 = ((y0(i)-y2).*dy2 + (x0(i)-x2).*dx2) ./ (dx2.*dx2+dy2.*dy2); + + % check position of points on edges. + % it should be comprised between 0 and 1 for both t1 and t2. + % if not, the edges do not intersect + out = t1<-tol | t1>1+tol | t2<-tol | t2>1+tol; + x0(i(out)) = NaN; + y0(i(out)) = NaN; +end + + +%% format output arguments + +point = [x0 y0]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineCircle.m new file mode 100644 index 0000000..95682bc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineCircle.m @@ -0,0 +1,82 @@ +function points = intersectLineCircle(line, circle) +%INTERSECTLINECIRCLE Intersection point(s) of a line and a circle +% +% INTERS = intersectLineCircle(LINE, CIRCLE); +% Returns a 2-by-2 array, containing on each row the coordinates of an +% intersection point. If the line and circle do not intersect, the result +% is filled with NaN. +% +% Example +% % base point +% center = [10 0]; +% % create vertical line +% l1 = [center 0 1]; +% % circle +% c1 = [center 5]; +% pts = intersectLineCircle(l1, c1) +% pts = +% 10 -5 +% 10 5 +% % draw the result +% figure; clf; hold on; +% axis([0 20 -10 10]); +% drawLine(l1); +% drawCircle(c1); +% drawPoint(pts, 'rx'); +% axis equal; +% +% See also +% lines2d, circles2d, intersectLines, intersectCircles +% +% References +% http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/ +% http://mathworld.wolfram.com/Circle-LineIntersection.html +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-01-14, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2011-06-06 fix bug in delta test + + +% local precision +eps = 1e-14; + +% center parameters +center = circle(:, 1:2); +radius = circle(:, 3); + +% line parameters +dp = line(:, 1:2) - center; +vl = line(:, 3:4); + +% coefficient of second order equation +a = sum(line(:, 3:4).^2, 2); +b = 2*sum(dp .* vl, 2); +c = sum(dp.^2, 2) - radius.^2; + +% discriminant +delta = b .^ 2 - 4 * a .* c; + +if delta > eps + % find two roots of second order equation + u1 = (-b - sqrt(delta)) / 2 ./ a; + u2 = (-b + sqrt(delta)) / 2 ./ a; + + % convert into 2D coordinate + points = [line(1:2) + u1 * line(3:4) ; line(1:2) + u2 * line(3:4)]; + +elseif abs(delta) < eps + % find unique root, and convert to 2D coord. + u = -b / 2 ./ a; + points = line(1:2) + u*line(3:4); + +else + % fill with NaN + points = NaN * ones(2, 2); + return; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineEdge.m new file mode 100644 index 0000000..6dc4372 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLineEdge.m @@ -0,0 +1,79 @@ +function point = intersectLineEdge(line, edge) +%INTERSECTLINEEDGE Return intersection between a line and an edge +% +% P = intersectLineEdge(LINE, EDGE); +% returns the intersection point of lines LINE and edge EDGE. +% LINE is a 1x4 array containing parametric representation of the line +% (in the form [x0 y0 dx dy], see 'createLine' for details). +% EDGE is a 1x4 array containing coordinates of first and second point +% (in the form [x1 y1 x2 y2], see 'createEdge' for details). +% +% In case of colinear line and edge, returns [Inf Inf]. +% If line does not intersect edge, returns [NaN NaN]. +% +% If each input is [N*4] array, the result is a [N*2] array containing +% intersections for each couple of edge and line. +% If one of the input has N rows and the other 1 row, the result is a +% [N*2] array. +% +% See also: +% lines2d, edges2d, intersectEdges, intersectLines +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 19/02/2004: add support for multiple lines. +% 08/03/2007: update doc + +x0 = line(:,1); +y0 = line(:,2); +dx1 = line(:,3); +dy1 = line(:,4); +x1 = edge(:,1); +y1 = edge(:,2); +x2 = edge(:,3); +y2 = edge(:,4); +dx2 = x2-x1; +dy2 = y2-y1; + +N1 = length(x0); +N2 = length(x1); + +% indices of parallel lines +par = abs(dx1.*dy2-dx2.*dy1)<1e-14; + +% indices of colinear lines +col = abs((x1-x0).*dy1-(y1-y0).*dx1)<1e-14 & par ; + +xi(col) = Inf; +yi(col) = Inf; +xi(par & ~col) = NaN; +yi(par & ~col) = NaN; + +i = ~par; + +% compute intersection points +if N1==N2 + xi(i) = ((y1(i)-y0(i)).*dx1(i).*dx2(i) + x0(i).*dy1(i).*dx2(i) - x1(i).*dy2(i).*dx1(i)) ./ ... + (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ; + yi(i) = ((x1(i)-x0(i)).*dy1(i).*dy2(i) + y0(i).*dx1(i).*dy2(i) - y1(i).*dx2(i).*dy1(i)) ./ ... + (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ; +elseif N1==1 + xi(i) = ((y1(i)-y0).*dx1.*dx2(i) + x0.*dy1.*dx2(i) - x1(i).*dy2(i).*dx1) ./ ... + (dx2(i).*dy1-dx1.*dy2(i)) ; + yi(i) = ((x1(i)-x0).*dy1.*dy2(i) + y0.*dx1.*dy2(i) - y1(i).*dx2(i).*dy1) ./ ... + (dx1.*dy2(i)-dx2(i).*dy1) ; +elseif N2==1 + xi(i) = ((y1-y0(i)).*dx1(i).*dx2 + x0(i).*dy1(i).*dx2 - x1(i).*dy2.*dx1(i)) ./ ... + (dx2.*dy1(i)-dx1(i).*dy2) ; + yi(i) = ((x1-x0(i)).*dy1(i).*dy2 + y0(i).*dx1(i).*dy2 - y1(i).*dx2.*dy1(i)) ./ ... + (dx1(i).*dy2-dx2.*dy1(i)) ; +end + +point = [xi' yi']; +out = find(~isPointOnEdge(point, edge)); +point(out, :) = repmat([NaN NaN], [length(out) 1]); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLines.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLines.m new file mode 100644 index 0000000..44a01a6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/intersectLines.m @@ -0,0 +1,126 @@ +function point = intersectLines(line1, line2, varargin) +%INTERSECTLINES Return all intersection points of N lines in 2D +% +% PT = intersectLines(L1, L2); +% returns the intersection point of lines L1 and L2. L1 and L2 are 1-by-4 +% row arrays, containing parametric representation of each line (in the +% form [x0 y0 dx dy], see 'createLine' for details). +% +% In case of colinear lines, returns [Inf Inf]. +% In case of parallel but not colinear lines, returns [NaN NaN]. +% +% If each input is [N*4] array, the result is a [N*2] array containing +% intersections of each couple of lines. +% If one of the input has N rows and the other 1 row, the result is a +% [N*2] array. +% +% PT = intersectLines(L1, L2, EPS); +% Specifies the tolerance for detecting parallel lines. Default is 1e-14. +% +% Example +% line1 = createLine([0 0], [10 10]); +% line2 = createLine([0 10], [10 0]); +% point = intersectLines(line1, line2) +% point = +% 5 5 +% +% See also +% lines2d, edges2d, intersectEdges, intersectLineEdge +% intersectLineCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 2004-02-19 add support for multiple lines. +% 2007-03-08 update doc +% 2011-10-07 code cleanup + + +%% Process input arguments + +% extract tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% check size of each input +N1 = size(line1, 1); +N2 = size(line2, 1); +N = max(N1, N2); +if N1 ~= N2 && N1*N2 ~= N + error('matGeom:IntersectLines:IllegalArgument', ... + 'The two input arguments must have same number of lines'); +end + + +%% Check parallel and colinear lines + +% coordinate differences of origin points +dx = bsxfun(@minus, line2(:,1), line1(:,1)); +dy = bsxfun(@minus, line2(:,2), line1(:,2)); + +% indices of parallel lines +denom = line1(:,3) .* line2(:,4) - line2(:,3) .* line1(:,4); +par = abs(denom) < tol; + +% indices of colinear lines +col = abs(dx .* line1(:,4) - dy .* line1(:,3)) < tol & par ; + +% initialize result array +x0 = zeros(N, 1); +y0 = zeros(N, 1); + +% initialize result for parallel lines +x0(col) = Inf; +y0(col) = Inf; +x0(par & ~col) = NaN; +y0(par & ~col) = NaN; + +% in case all line couples are parallel, return +if all(par) + point = [x0 y0]; + return; +end + + +%% Extract coordinates of itnersecting lines + +% indices of intersecting lines +inds = ~par; + +% extract base coordinates of first lines +if N1 > 1 + line1 = line1(inds,:); +end +x1 = line1(:,1); +y1 = line1(:,2); +dx1 = line1(:,3); +dy1 = line1(:,4); + +% extract base coordinates of second lines +if N2 > 1 + line2 = line2(inds,:); +end +x2 = line2(:,1); +y2 = line2(:,2); +dx2 = line2(:,3); +dy2 = line2(:,4); + +% re-compute coordinate differences of origin points +dx = bsxfun(@minus, line2(:,1), line1(:,1)); +dy = bsxfun(@minus, line2(:,2), line1(:,2)); + + +%% Compute intersection points + +denom = denom(inds); +x0(inds) = (x2 .* dy2 .* dx1 - dy .* dx1 .* dx2 - x1 .* dy1 .* dx2) ./ denom ; +y0(inds) = (dx .* dy1 .* dy2 + y1 .* dx1 .* dy2 - y2 .* dx2 .* dy1) ./ denom ; + +% concatenate result +point = [x0 y0]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/invertLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/invertLine.m new file mode 100644 index 0000000..7094fc0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/invertLine.m @@ -0,0 +1,37 @@ +function line = invertLine(var) +%INVERTLINE return same line but with opposite orientation +% +% INVLINE = invertLine(LINE); +% Returns the opposite line of LINE. +% LINE has the format [x0 y0 dx dy], then INVLINE will have following +% parameters: [x0 y0 -dx -dy]. +% +% See also: +% lines2d, createLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/01/2004. +% + +% HISTORY +% 30/06/2009 deprecate and replace by 'reverseLine'. + +% deprecation warning +warning('geom2d:deprecated', ... + '''invertLine'' is deprecated, use ''reverseLine'' instead'); + +line = 0; + +if size(var, 1)==1 + % only one line in a single array + line = [var(1) var(2) -var(3) -var(4)]; +else + % several lines in a single array + n = size(var, 1); + line(1:n, 1) = var(1:n, 1); + line(1:n, 2) = var(1:n, 2); + line(1:n, 3) = -var(1:n, 3); + line(1:n, 4) = -var(1:n, 4); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isCounterClockwise.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isCounterClockwise.m new file mode 100644 index 0000000..4ff7b62 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isCounterClockwise.m @@ -0,0 +1,85 @@ +function res = isCounterClockwise(p1, p2, p3, varargin) +%ISCOUNTERCLOCKWISE Compute relative orientation of 3 points +% +% CCW = isCounterClockwise(P1, P2, P3); +% Computes the orientation of the 3 points. The returns is: +% +1 if the path P1->P2->P3 turns Counter-Clockwise (i.e., the point P3 +% is located "on the left" of the line P1-P2) +% -1 if the path turns Clockwise (i.e., the point P3 lies "on the right" +% of the line P1-P2) +% 0 if the point P3 is located on the line segment [P1 P2]. +% +% This function can be used in more complicated algorithms: detection of +% line segment intersections, convex hulls, point in triangle... +% +% CCW = isCounterClockwise(P1, P2, P3, EPS); +% Specifies the threshold used for detecting colinearity of the 3 points. +% Default value is 1e-12 (absolute). +% +% Example +% isCounterClockwise([0 0], [10 0], [10 10]) +% ans = +% 1 +% isCounterClockwise([0 0], [0 10], [10 10]) +% ans = +% -1 +% isCounterClockwise([0 0], [10 0], [5 0]) +% ans = +% 0 +% +% See also +% points2d, isPointOnLine, isPointInTriangle +% +% References +% Algorithm adapated from Sedgewick's book. +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-04-09 +% Copyright 2011 INRA - Cepia Software Platform. + + +% HISTORY +% 2011-05-16 change variable names, add support for point arrays + + +% get threshold value +eps = 1e-12; +if ~isempty(varargin) + eps = varargin{1}; +end + +% ensure all data have same size +np = max([size(p1, 1) size(p2, 1) size(p3,1)]); +if np > 1 + if size(p1,1) == 1 + p1 = repmat(p1, np, 1); + end + if size(p2,1) == 1 + p2 = repmat(p2, np, 1); + end + if size(p3,1) == 1 + p3 = repmat(p3, np, 1); + end +end + +% init with 0 +res = zeros(np, 1); + +% extract vector coordinates +x0 = p1(:, 1); +y0 = p1(:, 2); +dx1 = p2(:, 1) - x0; +dy1 = p2(:, 2) - y0; +dx2 = p3(:, 1) - x0; +dy2 = p3(:, 2) - y0; + +% check non colinear cases +res(dx1 .* dy2 > dy1 .* dx2) = 1; +res(dx1 .* dy2 < dy1 .* dx2) = -1; + +% case of colinear points +ind = abs(dx1 .* dy2 - dy1 .* dx2) < eps; +res(ind( (dx1(ind) .* dx2(ind) < 0) | (dy1(ind) .* dy2(ind) < 0) )) = -1; +res(ind( hypot(dx1(ind), dy1(ind)) < hypot(dx2(ind), dy2(ind)) )) = 1; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isLeftOriented.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isLeftOriented.m new file mode 100644 index 0000000..a261436 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isLeftOriented.m @@ -0,0 +1,28 @@ +function b = isLeftOriented(point, line) +%ISLEFTORIENTED Test if a point is on the left side of a line +% +% B = isLeftOriented(POINT, LINE); +% Returns TRUE if the point lies on the left side of the line with +% respect to the line direction. +% +% See also: +% lines2d, points2d, isCounterClockwise, isPointOnLine, distancePointLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/07/2005. +% + +Nl = size(line, 1); +Np = size(point, 1); + +x0 = repmat(line(:,1)', Np, 1); +y0 = repmat(line(:,2)', Np, 1); +dx = repmat(line(:,3)', Np, 1); +dy = repmat(line(:,4)', Np, 1); +xp = repmat(point(:,1), 1, Nl); +yp = repmat(point(:,2), 1, Nl); + + +b = (xp-x0).*dy-(yp-y0).*dx < 0; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isParallel.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isParallel.m new file mode 100644 index 0000000..8482a74 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isParallel.m @@ -0,0 +1,70 @@ +function b = isParallel(v1, v2, varargin) +%ISPARALLEL Check parallelism of two vectors +% +% B = isParallel(V1, V2) +% where V1 and V2 are two row vectors of length ND, ND being the +% dimension, returns 1 if the vectors are parallel, and 0 otherwise. +% +% Also works when V1 and V2 are two N-by-ND arrays with same number of +% rows. In this case, return a N-by-1 array containing 1 at the positions +% of parallel vectors. +% +% Also works when one of V1 or V2 is N-by-1 and the other one is N-by-ND +% array, in this case return N-by-1 results. +% +% B = isParallel(V1, V2, ACCURACY) +% specifies the accuracy for numerical computation. Default value is +% 1e-14. +% +% +% Example +% isParallel([1 2], [2 4]) +% ans = +% 1 +% isParallel([1 2], [1 3]) +% ans = +% 0 +% +% See also +% vectors2d, isPerpendicular, lines2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-04-25 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 2007-09-18 copy from isParallel3d, adapt to any dimension, and add psb +% to specify precision +% 2007-01-16 fix bug +% 2009-09-21 fix bug for array of 3 vectors +% 2011-01-20 replace repmat by ones-indexing (faster) +% 2011-06-16 use direct computation (faster) + +% default accuracy +acc = 1e-14; +if ~isempty(varargin) + acc = abs(varargin{1}); +end + +% adapt size of inputs if needed +n1 = size(v1, 1); +n2 = size(v2, 1); +if n1 ~= n2 + if n1 == 1 + v1 = v1(ones(n2,1), :); + elseif n2 == 1 + v2 = v2(ones(n1,1), :); + end +end + +% performs computation +if size(v1, 2) == 2 + % computation for plane vectors + b = abs(v1(:, 1) .* v2(:, 2) - v1(:, 2) .* v2(:, 1)) < acc; +else + % computation in greater dimensions + b = vectorNorm(cross(v1, v2, 2)) < acc; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPerpendicular.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPerpendicular.m new file mode 100644 index 0000000..2dbdac0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPerpendicular.m @@ -0,0 +1,64 @@ +function b = isPerpendicular(v1, v2, varargin) +%ISPERPENDICULAR Check orthogonality of two vectors +% +% B = isPerpendicular(V1, V2) +% where V1 and V2 are two 1-by-2 row arrays, returns 1 if the vectors are +% perpendicular, and 0 otherwise. +% +% Also works when V1 and V2 are two N-by-2 arrays with same number of +% rows. In this case, return a N-by-1 array containing 1 at the positions +% of perpendicular vectors. +% +% Also works when one of V1 or V2 is 1-by-2 and the other one is a N-by-2 +% array. In this case the result has size N-by-1. +% +% B = isPerpendicular(V1, V2, ACCURACY) +% specifies accuracy of numerical tests, default is 1e-14. +% +% +% Example +% isPerpendicular([1 2 1], [2 4 2]) +% ans = +% 1 +% +% isPerpendicular([1 2 1], [1 3 2]) +% ans = +% 0 +% +% See also +% vectors2d, isParallel, lines2d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-04-25 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 2007-09-18 copy from isPerpendicular, adapt to any dimension, and add +% psb to specify precision +% 2009-09-21 fix bug for array of 3 vectors +% 2011-01-20 replace repmat by ones-indexing (faster) + +% default accuracy +acc = 1e-14; +if ~isempty(varargin) + acc = abs(varargin{1}); +end + +% adapt size of inputs +n1 = size(v1, 1); +n2 = size(v2, 1); +if n1~=n2 + if n1==1 + v1 = v1(ones(n2, 1), :); + elseif n2==1 + v2 = v2(ones(n1, 1), :); + else + error('Inputs must either have same size, or one must be scalar'); + end +end + +% performs test +b = abs(dot(v1, v2, 2)) < acc; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInCircle.m new file mode 100644 index 0000000..d57868d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInCircle.m @@ -0,0 +1,38 @@ +function b = isPointInCircle(point, circle, varargin) +%ISPOINTINCIRCLE Test if a point is located inside a given circle +% +% B = isPointInCircle(POINT, CIRCLE) +% Returns true if point is located inside the circle, i.e. if distance to +% circle center is lower than the circle radius. +% +% B = isPointInCircle(POINT, CIRCLE, TOL) +% Specifies the tolerance value +% +% Example: +% isPointInCircle([1 0], [0 0 1]) +% isPointInCircle([0 0], [0 0 1]) +% returns true, whereas +% isPointInCircle([1 1], [0 0 1]) +% return false +% +% See also: +% circles2d, isPointOnCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + +% HISTORY +% 22/05/2009 rename to isPointInCircle, add psb to specify tolerance + +% extract computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); +b = d-circle(:,3)<=tol; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInEllipse.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInEllipse.m new file mode 100644 index 0000000..a8e54c9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInEllipse.m @@ -0,0 +1,52 @@ +function b = isPointInEllipse(point, ellipse, varargin) +%ISPOINTINELLIPSE Check if a point is located inside a given ellipse +% +% B = isPointInEllipse(POINT, ELLIPSE) +% Returns true if point is located inside the given ellipse. +% +% B = isPointInEllipse(POINT, ELLIPSE, TOL) +% Specifies the tolerance value +% +% Example: +% isPointInEllipse([1 0], [0 0 2 1 0]) +% ans = +% 1 +% isPointInEllipse([0 0], [0 0 2 1 0]) +% ans = +% 1 +% isPointInEllipse([1 1], [0 0 2 1 0]) +% ans = +% 0 +% isPointInEllipse([1 1], [0 0 2 1 30]) +% ans = +% 1 +% +% See also: +% ellipses2d, isPointInCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 11/03/2011 +% + +% HISTORY + +% extract computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% compute ellipse to unit circle transform +rot = createRotation(-deg2rad(ellipse(5))); +sca = createScaling(1./ellipse(3:4)); +trans = sca * rot; + +% transform points to unit circle basis +pTrans = bsxfun(@minus, point, ellipse(:,1:2)); +pTrans = transformPoint(pTrans, trans); + +% test if distance to origin smaller than 1 +b = sqrt(sum(power(pTrans, 2), 2)) - 1 <= tol; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInTriangle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInTriangle.m new file mode 100644 index 0000000..218770d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointInTriangle.m @@ -0,0 +1,73 @@ +function b = isPointInTriangle(point, p1, p2, p3) +%ISPOINTINTRIANGLE Test if a point is located inside a triangle +% +% B = isPointInTriangle(POINT, V1, V2, V3) +% POINT is a 1-by-2 row vector containing coordinates of the test point, +% V1, V2 and V3 are 1-by-2 row vectors containing coordinates of triangle +% vertices. The function returns 1 is the point is inside or on the +% boundary of the triangle, and 0 otherwise. +% +% B = isPointInTriangle(POINT, VERTICES) +% Specifiy the coordinates of vertices as a 3-by-2 array. +% +% If POINT contains more than one row, the result B has as many rows as +% the input POINT. +% +% +% Example +% % vertices of the triangle +% p1 = [0 0]; +% p2 = [10 0]; +% p3 = [5 10]; +% tri = [p1;p2;p3]; +% % check if points are inside +% isPointInTriangle([0 0], tri) +% ans = +% 1 +% isPointInTriangle([5 5], tri) +% ans = +% 1 +% isPointInTriangle([10 5], tri) +% ans = +% 0 +% % check for an array of points +% isPointInTriangle([0 0;1 0;0 1], tri) +% ans = +% 1 +% 1 +% 0 +% +% See also +% polygons2d, isPointInPolygon, isCounterClockwise +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-16, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% if triangle vertices are given as a single array, extract vertices +if nargin == 2 + p2 = p1(2, :); + p3 = p1(3, :); + p1 = p1(1, :); +end + +% check triangle orientation +isDirect = isCounterClockwise(p1, p2, p3); + +% check location of point with respect to each side +if isDirect + b12 = isCounterClockwise(p1, p2, point) >= 0; + b23 = isCounterClockwise(p2, p3, point) >= 0; + b31 = isCounterClockwise(p3, p1, point) >= 0; +else + b12 = isCounterClockwise(p1, p2, point) <= 0; + b23 = isCounterClockwise(p2, p3, point) <= 0; + b31 = isCounterClockwise(p3, p1, point) <= 0; +end + +% combines the 3 results +b = b12 & b23 & b31; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnCircle.m new file mode 100644 index 0000000..6d7cf75 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnCircle.m @@ -0,0 +1,36 @@ +function b = isPointOnCircle(point, circle, varargin) +%ISPOINTONCIRCLE Test if a point is located on a given circle. +% +% B = isPointOnCircle(POINT, CIRCLE) +% return true if point is located on the circle, i.e. if the distance to +% the circle center equals the radius up to an epsilon value. +% +% B = isPointOnCircle(POINT, CIRCLE, TOL) +% Specifies the tolerance value. +% +% Example: +% isPointOnCircle([1 0], [0 0 1]) +% returns true, whereas +% isPointOnCircle([1 1], [0 0 1]) +% return false +% +% See also: +% circles2d, isPointInCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + +% HISTORY +% 22/05/2009 rename to isPointOnCircle, add psb to specify tolerance + +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); +b = abs(d-circle(:,3)) abs(dy); +t = zeros(size(dx)); +t(ind) = lx( ind) ./ dx( ind); +t(~ind) = ly(~ind) ./ dy(~ind); + +% check if point is located between edge bounds +b = t >- tol & t-1 < tol & b1; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnLine.m new file mode 100644 index 0000000..f31d3a3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnLine.m @@ -0,0 +1,60 @@ +function b = isPointOnLine(point, line, varargin) +%ISPOINTONLINE Test if a point belongs to a line +% +% B = isPointOnLine(POINT, LINE) +% with POINT being [xp yp], and LINE being [x0 y0 dx dy]. +% Returns 1 if point lies on the line, 0 otherwise. +% +% If POINT is an N*2 array of points, B is a N*1 array of booleans. +% +% If LINE is a N*4 array of line, B is a 1*N array of booleans. +% +% See also: +% lines2d, points2d, isPointOnEdge, isPointOnRay, angle3Points +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 11/03/2004 support for multiple inputs +% 08/12/2004 complete implementation, add doc +% 22/05/2009 rename to isPointOnLine, add psb to specify tolerance + +% extract computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% number of lines and of points +Nl = size(line, 1); +Np = size(point, 1); + +% adapt the size of inputs +x0 = repmat(line(:,1)', Np, 1); +y0 = repmat(line(:,2)', Np, 1); +dx = repmat(line(:,3)', Np, 1); +dy = repmat(line(:,4)', Np, 1); +xp = repmat(point(:,1), 1, Nl); +yp = repmat(point(:,2), 1, Nl); + +% test if lines are colinear +b = abs((xp-x0).*dy-(yp-y0).*dx)./hypot(dx, dy) < tol; + + + + + + + + + + + + + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnRay.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnRay.m new file mode 100644 index 0000000..40aa9a6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/isPointOnRay.m @@ -0,0 +1,51 @@ +function b = isPointOnRay(point, ray, varargin) +%ISPOINTONRAY Test if a point belongs to a ray +% +% B = isPointOnRay(PT, RAY); +% Returns 1 if point PT belongs to the ray RAY. +% PT is given by [x y] and RAY by [x0 y0 dx dy]. +% +% See also: +% rays2d, points2d, isPointOnLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 07/07/2005 normalize condition to test if on the line and add support +% of multiple rays or points +% 22/05/2009 rename to isPointOnRay, add psb to specify tolerance +% 26/01/2010 was drawing a line before making test + +% extract computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% number of rays and points +Nr = size(ray, 1); +Np = size(point, 1); + +% if several rays or several points, adapt sizes of arrays +x0 = repmat(ray(:,1)', Np, 1); +y0 = repmat(ray(:,2)', Np, 1); +dx = repmat(ray(:,3)', Np, 1); +dy = repmat(ray(:,4)', Np, 1); +xp = repmat(point(:,1), 1, Nr); +yp = repmat(point(:,2), 1, Nr); + +% test if points belongs to the supporting line +b1 = abs((xp-x0).*dy-(yp-y0).*dx) ./ hypot(dx, dy) < tol; + +% check if points lie the good direction on the rays +ind = abs(dx) > abs(dy); +t = zeros(size(b1)); +t(ind) = (xp(ind) - x0(ind)) ./ dx(ind); +t(~ind) = (yp(~ind) - y0(~ind)) ./ dy(~ind); + +% combine the two tests +b = b1 & (t >= 0); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineAngle.m new file mode 100644 index 0000000..ce51d1c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineAngle.m @@ -0,0 +1,37 @@ +function theta = lineAngle(varargin) +%LINEANGLE Computes angle between two straight lines +% +% A = lineAngle(LINE); +% Returns the angle between horizontal, right-axis and the given line. +% Angle is fiven in radians, between 0 and 2*pi, in counter-clockwise +% direction. +% +% A = lineAngle(LINE1, LINE2); +% Returns the directed angle between the two lines. Angle is given in +% radians between 0 and 2*pi, in counter-clockwise direction. +% +% See also +% lines2d, angles2d, createLine, normalizeAngle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 2004-02-19 added support for multiple lines. +% 2011-01-20 use bsxfun + +nargs = length(varargin); +if nargs == 1 + % angle of one line with horizontal + line = varargin{1}; + theta = mod(atan2(line(:,4), line(:,3)) + 2*pi, 2*pi); + +elseif nargs==2 + % angle between two lines + theta1 = lineAngle(varargin{1}); + theta2 = lineAngle(varargin{2}); + theta = mod(bsxfun(@minus, theta2, theta1)+2*pi, 2*pi); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineFit.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineFit.m new file mode 100644 index 0000000..754754c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/lineFit.m @@ -0,0 +1,99 @@ +function line = lineFit(varargin) +%LINEFIT Fit a straight line to a set of points +% +% L = lineFit(X, Y) +% Computes parametric line minimizing square error of all points (X,Y). +% Result is a 4*1 array, containing coordinates of a point of the line, +% and the direction vector of the line, that is L=[x0 y0 dx dy]; +% +% L = lineFit(PTS) +% Gives coordinats of points in a single array. +% +% L = lineFit(PT0, PTS); +% L = lineFit(PT0, X, Y); +% with PT0 = [x0 y0], imposes the line to contain point PT0. +% +% Requires: +% Optimiaztion toolbox +% +% See also: +% lines2d, polyfit, polyfit2, lsqlin +% +% +% ----- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 30/04/2004. +% + +% HISTORY +% 09/12/2004 : update implementation + + + +% --------------------------------------------- +% extract input arguments + +if length(varargin)==1 + % argument is an array of points + var = varargin{1}; + x = var(:,1); + y = var(:,2); +elseif length(varargin)==2 + var = varargin{1}; + if size(var, 1)==1 + var = varargin{2}; + x = var(:,1); + y = var(:,2); + else + % two arguments : x and y + x = var; + y = varargin{2}; + end +elseif length(varargin)==3 + % three arguments : ref point, x and y + x = varargin{2}; + y = varargin{3}; +end + +% --------------------------------------------- +% Initializations : + + +N = size(x, 1); + +% --------------------------------------------- +% Main algorithm : + + +% main matrix of the problem +X = [x y ones(N,1)]; + +% conditions initialisations +A = zeros(0, 3); +b = []; +Aeq1 = [1 1 0]; +beq1 = 1; +Aeq2 = [1 -1 0]; +beq2 = 1; + +% disable verbosity of optimisation +opt = optimset('lsqlin'); +opt.LargeScale = 'off'; +opt.Display = 'off'; + +% compute line coefficients [a;b;c] , in the form a*x + b*y + c = 0 +% using linear regression +% Not very clean : I could not impose a*a+b*b=1, so I checked for both a=1 +% and b=1, and I kept the result with lowest residual error.... +[coef1 res1] = lsqlin(X, zeros(N, 1), A, b, Aeq1, beq1, [], [], [], opt); +[coef2 res2] = lsqlin(X, zeros(N, 1), A, b, Aeq2, beq2, [], [], [], opt); + +% choose the best line +if res11 + error('geom2d:midPoint', ... + 'Inputs must have same size, or one must have length 1'); + end + + % compute middle point + mid = bsxfun(@plus, p1, p2) / 2; +end + +% process output arguments +if nargout<=1 + varargout{1} = mid; +else + varargout = {mid(:,1), mid(:,2)}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistance.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistance.m new file mode 100644 index 0000000..c4d3179 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistance.m @@ -0,0 +1,40 @@ +function [dist, varargout] = minDistance(p, curve) +%MINDISTANCE compute minimum distance between a point and a set of points +% +% Deprecated: use minDistancePoints instead +% +% usage: +% d = MINDISTANCE(P, POINTS) +% POINTS is a [N*2] array of points, and P a single point. function +% return the minimum distance between P and one of the points. +% +% Also works for several points in P. In this case, return minimum +% distance between each element of P and all element of POINTS. d is the +% same length than P. +% +% [d, i] = MINDISTANCE(P, POINTS) +% also return index of closest point in POINTS. +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 23/02/2004. +% + +% HISTORY : +% 18/03/2004 : can also return index of closest point +% 08/04/2004 : return vertical array when input multiple points + +dist = inf; + +for i=1:size(p, 1) + dx = curve(:,1)-p(i,1); + dy = curve(:,2)-p(i,2); + [dist(i,1), ind(i,1)] = min(sqrt(dx.*dx + dy.*dy)); +end + +if nargout>1 + varargout{1} = ind; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistancePoints.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistancePoints.m new file mode 100644 index 0000000..fb0cf66 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/minDistancePoints.m @@ -0,0 +1,203 @@ +function varargout = minDistancePoints(p1, varargin) +%MINDISTANCEPOINTS Minimal distance between several points +% +% DIST = minDistancePoints(PTS) +% Returns the minimum distance between all couple of points in PTS. PTS is +% an array of [NxND] values, N being the number of points and ND the +% dimension of the points. +% +% DIST = minDistancePoints(PTS1, PTS2) +% Computes for each point in PTS1 the minimal distance to every point of +% PTS2. PTS1 and PTS2 are [NxD] arrays, where N is the number of points, +% and D is the dimension. Dimension must be the same for both arrays, but +% number of points can be different. +% The result is an array the same length as PTS1. +% +% +% DIST = minDistancePoints(..., NORM) +% Uses a user-specified norm. NORM=2 means euclidean norm (the default), +% NORM=1 is the Manhattan (or "taxi-driver") distance. +% Increasing NORM growing up reduces the minimal distance, with a limit +% to the biggest coordinate difference among dimensions. +% +% +% [DIST I J] = minDistancePoints(PTS) +% Returns indices I and J of the 2 points which are the closest. DIST +% verifies relation: +% DIST = distancePoints(PTS(I,:), PTS(J,:)); +% +% [DIST J] = minDistancePoints(PTS1, PTS2, ...) +% Also returns the indices of points which are the closest. J has the +% same size as DIST. It verifies relation : +% DIST(I) = distancePoints(PTS1(I,:), PTS2(J,:)); +% +% +% Examples: +% % minimal distance between random planar points +% points = rand(20,2)*100; +% minDist = minDistancePoints(points); +% +% % minimal distance between random space points +% points = rand(30,3)*100; +% [minDist ind1 ind2] = minDistancePoints(points); +% minDist +% distancePoints(points(ind1, :), points(ind2, :)) +% % results should be the same +% +% % minimal distance between 2 sets of points +% points1 = rand(30,2)*100; +% points2 = rand(30,2)*100; +% [minDists inds] = minDistancePoints(points1, points2); +% minDists(10) +% distancePoints(points1(10, :), points2(inds(10), :)) +% % results should be the same +% +% See Also +% points2d, distancePoints, nndist +% +% --------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 15/06/2004. +% + +% HISTORY: +% 22/06/2005 compute sqrt only at the end (faster), and change behaviour +% for 2 inputs: compute min distance for each point in PTS1. +% Also add support for different norms. +% 15/08/2005 make difference when 1 array or 2 arrays of points +% 25/10/2006 also returns indices of closest points +% 30/10/2006 generalize to points of any dimension +% 28/08/2007 code cleanup, add comments and help + + +%% Initialisations + +% default norm (euclidean) +n = 2; + +% flag for processing of all points +allPoints = false; + +% process input variables +if isempty(varargin) + % specify only one array of points, not the norm + p2 = p1; + +elseif length(varargin)==1 + var = varargin{1}; + if length(var)>1 + % specify two arrays of points + p2 = var; + allPoints = true; + else + % specify array of points and the norm + n = var; + p2 = p1; + end + +else + % specify two array of points and the norm + p2 = varargin{1}; + n = varargin{2}; + allPoints = true; +end + + +% number of points in each array +n1 = size(p1, 1); +n2 = size(p2, 1); + +% dimension of points +d = size(p1, 2); + + +%% Computation of distances + +% allocate memory +dist = zeros(n1, n2); + +% different behaviour depending on the norm used +if n == 2 + % Compute euclidian distance. this is the default case + % Compute difference of coordinate for each pair of point and for each + % dimension. Result "dist" is a n1-by-n2 array. + % in 2D: dist = dx.*dx + dy.*dy; + for i = 1:d + dist = dist + (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2; + end + + % compute minimal distance: + if ~allPoints + % either on all couple of points + mat = repmat((1:n1)', [1 n1]); + ind = mat < mat'; + [minSqDist ind] = min(dist(ind)); + else + % or for each point of P1 + [minSqDist ind] = min(dist, [], 2); + end + + % convert squared distance to distance + minDist = sqrt(minSqDist); + +elseif n == inf + % infinite norm corresponds to maximum absolute value of differences + % in 2D: dist = max(abs(dx) + max(abs(dy)); + for i = 1:d + dist = max(dist, abs(p1(:,i)-p2(:,i))); + end + +else + % compute distance using the specified norm. + % in 2D: dist = power(abs(dx), n) + power(abs(dy), n); + for i=1:d + dist = dist + power((abs(repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1]))), n); + end + + % compute minimal distance + if ~allPoints + % either on all couple of points + mat = repmat((1:n1)', [1 n1]); + ind = mat < mat'; + [minSqDist ind] = min(dist(ind)); + else + % or for each point of P1 + [minSqDist ind] = min(dist, [], 2); + end + + % convert squared distance to distance + minDist = power(minSqDist, 1/n); + +end + +if ~allPoints + % convert index in array to row ad column subindices. + % This uses the fact that index are sorted in a triangular matrix, + % with the last index of each column being a so-called triangular + % number + ind2 = ceil((-1+sqrt(8*ind+1))/2); + ind1 = ind - ind2*(ind2-1)/2; + ind2 = ind2 + 1; +end + + +%% format output parameters + +% format output depending on number of asked parameters +if nargout <= 1 + varargout{1} = minDist; + +elseif nargout == 2 + % If two arrays are asked, 'ind' is an array of indices, one for each + % point in PTS1, corresponding to the result in minDist + varargout{1} = minDist; + varargout{2} = ind; + +elseif nargout == 3 + % If only one array is asked, minDist is a scalar, ind1 and ind2 are 2 + % indices corresponding to the closest points. + varargout{1} = minDist; + varargout{2} = ind1; + varargout{3} = ind2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/nndist.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/nndist.m new file mode 100644 index 0000000..8522e5b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/nndist.m @@ -0,0 +1,49 @@ +function [dists neighInds] = nndist(points) +%NNDIST Nearest-neighbor distances of each point in a set +% +% DISTS = nndist(POINTS) +% Returns the distance to the nearest enighbor of each point in the given +% pattern. +% POINTS is an array of points, NP-by-ND. +% DISTS is a NP-by-1 array containing the distances to the nearest +% neighbor. +% +% This functions first computes the Delaunay triangulation of the set of +% points, then search for nearest distance in the set of each vertex +% neighbors. This reduces the overall complexity, but difference was +% noticed only for large sets (>10000 points) +% +% Example +% % Display Stienen diagram of a set of random points in unit square +% pts = rand(100, 2); +% dists = nndist(pts); +% figure; drawPoint(pts, '.'); +% hold on; drawCircle([pts dists/2]); +% axis equal; axis([-.1 1.1 -.1 1.1]); +% +% See also +% points2d, distancePoints, minDistancePoints +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-01, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +n = size(points, 1); + +dists = zeros(n, 1); +neighInds = zeros(n, 1); + +tri = DelaunayTri(points); + +% compute distance to nearest neighbor of each point in the pattern +for i = 1:n + % find indices of neighbor vertices in Delaunay Triangulation. + % this contains the nearest neighbor + inds = unique(tri.Triangulation(sum(tri.Triangulation == i, 2) > 0, :)); + + % compute minimal distance + [dists(i) indN] = min(distancePoints(points(i,:), points(inds(inds~=i), :))); + neighInds(i) = inds(indN); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalize.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalize.m new file mode 100644 index 0000000..4c62275 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalize.m @@ -0,0 +1,32 @@ +function vn = normalize(v) +%NORMALIZE normalize a vector +% +% V2 = normalize(V); +% Returns the normalization of vector V, such that ||V|| = 1. V can be +% either a row or a column vector. +% +% When V is a MxN array, normalization is performed for each row of the +% array. +% +% See Also: +% vectors2d, vecnorm +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/11/2004. +% + +% HISTORY +% 14/01/2005 : correct bug + + +dim = size(v); + +if dim(1)==1 || dim(2)==1 + vn = v/sqrt(sum(v.*v)); +else + vn = v./repmat(sqrt(sum(v.*v, 2)), [1 dim(2)]); +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeAngle.m new file mode 100644 index 0000000..9ba110b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeAngle.m @@ -0,0 +1,45 @@ +function alpha = normalizeAngle(alpha, varargin) +%NORMALIZEANGLE Normalize an angle value within a 2*PI interval +% +% ALPHA2 = normalizeAngle(ALPHA); +% ALPHA2 is the same as ALPHA modulo 2*PI and is positive. +% +% ALPHA2 = normalizeAngle(ALPHA, CENTER); +% Specifies the center of the angle interval. +% If CENTER==0, the interval is [-pi ; +pi] +% If CENTER==PI, the interval is [0 ; 2*pi] (default). +% +% Example: +% % normalization between 0 and 2*pi (default) +% normalizeAngle(5*pi) +% ans = +% 3.1416 +% +% % normalization between -pi and +pi +% normalizeAngle(7*pi/2, 0) +% ans = +% -1.5708 +% +% See also +% vectorAngle, lineAngle +% +% References +% Follows the same convention as apache commons library, see: +% http://commons.apache.org/math/api-2.2/org/apache/commons/math/util/MathUtils.html +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-03-10, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 2010-03-31 rename as normalizeAngle, and add psb to specify interval +% center + +center = pi; +if ~isempty(varargin) + center = varargin{1}; +end + +alpha = mod(alpha-center+pi, 2*pi) + center-pi; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeVector.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeVector.m new file mode 100644 index 0000000..cf77b91 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/normalizeVector.m @@ -0,0 +1,44 @@ +function vn = normalizeVector(v) +%NORMALIZEVECTOR Normalize a vector to have norm equal to 1 +% +% V2 = normalizeVector(V); +% Returns the normalization of vector V, such that ||V|| = 1. V can be +% either a row or a column vector. +% +% When V is a MxN array, normalization is performed for each row of the +% array. +% +% Example: +% vn = normalizeVector([3 4]) +% vn = +% 0.6000 0.8000 +% vectorNorm(vn) +% ans = +% 1 +% +% See Also: +% vectors2d, vectorNorm +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/11/2004. +% + +% HISTORY +% 2005-01-14 correct bug +% 2009-05-22 rename as normalizeVector +% 2011-01-20 use bsxfun + +dim = size(v); + +if dim(1)==1 || dim(2)==1 + % in case of one vector, the norm is a scalar + vn = v / sqrt(sum(v.^2)); +else + % for several vectors, need to adapt size of norm + vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); + %same as: vn = v./repmat(sqrt(sum(v.*v, 2)), [1 dim(2)]); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onCircle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onCircle.m new file mode 100644 index 0000000..9778402 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onCircle.m @@ -0,0 +1,31 @@ +function b = onCircle(point, circle) +%ONCIRCLE test if a point is located on a given circle. +% +% B = onCircle(POINT, CIRCLE) +% return true if point is located on the circle +% +% Example : +% onCircle([1 0], [0 0 1]) +% returns true, whereas +% onCircle([1 1], [0 0 1]) +% return false +% +% See also: +% circles2d, inCircle +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + +% HISTORY +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''onCircle'' is deprecated, use ''isPointOnCircle'' instead'); + +d = sqrt(sum(power(point - circle(:,1:2), 2), 2)); +b = abs(d-circle(:,3))<1e-12; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onEdge.m new file mode 100644 index 0000000..8ebfb3e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onEdge.m @@ -0,0 +1,58 @@ +function b = onEdge(point, edge) +%ONEDGE test if a point belongs to an edge +% +% B = onEdge(POINT, EDGE) +% with POINT being [xp yp], and EDGE being [x1 y1 x2 y2]. +% +% See also: +% edges2d, points2d, onLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 11/03/2004 : change input format : edge is [x1 y1 x2 y2]. +% 17/01/2005 : if test N edges with N points, return N boolean. +% 21/01/2005 : normalize test for colinearity, so enhance precision +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''onEdge'' is deprecated, use ''isPointOnEdge'' instead'); + +Np = size(point, 1); +Ne = size(edge, 1); + +if Np==1 || Ne==1 + x0 = repmat(edge(:,1)', Np, 1); + y0 = repmat(edge(:,2)', Np, 1); + dx = repmat(edge(:,3)', Np, 1)-x0; + dy = repmat(edge(:,4)', Np, 1)-y0; + xp = repmat(point(:,1), 1, Ne); + yp = repmat(point(:,2), 1, Ne); +elseif Np==Ne + x0 = edge(:,1); + y0 = edge(:,2); + dx = edge(:,3)-x0; + dy = edge(:,4)-y0; + xp = point(:,1); + yp = point(:,2); + +end + + +% test if lines are colinear +b1 = abs((xp-x0).*dy - (yp-y0).*dx)./(dx.*dx+dy.*dy)<1e-13; + +ind = abs(dx)>abs(dy); +t = zeros(max(Np, Ne), 1); +t(ind) = (xp(ind)-x0(ind))./dx(ind); +t(~ind) = (yp(~ind)-y0(~ind))./dy(~ind); +b = t>-1e-14 & t-1<1e-14 & b1; + + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onLine.m new file mode 100644 index 0000000..6dc400e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onLine.m @@ -0,0 +1,58 @@ +function b = onLine(point, line) +%ONLINE test if a point belongs to a line +% +% B = onLine(POINT, LINE) +% with POINT being [xp yp], and LINE being [x0 y0 dx dy]. +% Returns 1 if point lies on the line, 0 otherwise. +% +% If POINT is an N*2 array of points, B is a N*1 array of booleans. +% +% If LINE is a N*4 arrat of line, B is a 1*N array of booleans. +% +% See also: +% lines2d, points2d, onEdge, onRay, angle3Points +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 11/03/2004 : support for multiple inputs +% 08/12/2004 : complete implementation, add doc +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''onLine'' is deprecated, use ''isPointOnLine'' instead'); + +Nl = size(line, 1); +Np = size(point, 1); + +x0 = repmat(line(:,1)', Np, 1); +y0 = repmat(line(:,2)', Np, 1); +dx = repmat(line(:,3)', Np, 1); +dy = repmat(line(:,4)', Np, 1); +xp = repmat(point(:,1), 1, Nl); +yp = repmat(point(:,2), 1, Nl); + + + +% test if lines are colinear +b = abs((xp-x0).*dy-(yp-y0).*dx)./sqrt(dx.*dx+dy.*dy) < 1e-14; + + + + + + + + + + + + + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onRay.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onRay.m new file mode 100644 index 0000000..84fa146 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/onRay.m @@ -0,0 +1,48 @@ +function b = onRay(point, ray) +%ONRAY test if a point belongs to a ray +% +% B = onRay(PT, RAY); +% Returns 1 if point PT belongs to the ray RAY. +% PT is given by [x y] and RAY by [x0 y0 dx dy]. +% +% See also: +% rays2d, points2d, onLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 07/07/2005 : normalize condition to test if on the line +% and add support of multiple rays or points +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''onRay'' is deprecated, use ''isPointOnRay'' instead'); + +% number of rays and points +Nr = size(line, 1); +Np = size(point, 1); + +% if several rays or several points, adapt sizes of arrays +x0 = repmat(ray(:,1)', Np, 1); +y0 = repmat(ray(:,2)', Np, 1); +dx = repmat(ray(:,3)', Np, 1); +dy = repmat(ray(:,4)', Np, 1); +xp = repmat(point(:,1), 1, Nr); +yp = repmat(point(:,2), 1, Nr); + +% test if points belongs to the ray +b1 = abs((xp-x0).*dy-(yp-y0).*dx)./sqrt(dx.*dx+dy.*dy) < 1e-13; + +% check if points lie the good direction on the rays +ind = abs(dx)>abs(dy); +t = zeros(size(b1)); +t(ind) = (xp(ind)-x0(ind))./dx(ind); +t(~ind) = (yp(~ind)-y0(~ind))./dy(~ind); + +% combine the two tests +b = b1 && (t>0); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orientedBoxToPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orientedBoxToPolygon.m new file mode 100644 index 0000000..1a61982 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orientedBoxToPolygon.m @@ -0,0 +1,64 @@ +function varargout = orientedBoxToPolygon(obox) +%ORIENTEDBOXTOPOLYGON Convert an oriented box to a polygon (set of vertices) +% +% POLY = orientedBoxToPolygon(OBOX); +% Converts the oriented box OBOX given either as [XC YC W H] or as +% [XC YC W H THETA] into a 4-by-2 array of double, containing coordinates +% of box vertices. +% XC and YC are center of the box. W and H are the width and the height +% (dimension in the main directions), and THETA is the orientation, in +% degrees between 0 and 360. +% +% See also: +% polygons2d, drawOrientedBox, drawPolygon +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2005. +% + +% HISTORY +% 2011-10-09 rewrite from rectAsPolygon to orientedBoxToPolygon + +% extract box parameters +theta = 0; +x = obox(1); +y = obox(2); +hw = obox(3) / 2; % easier to compute with w and h divided by 2 +hh = obox(4) / 2; +if length(obox) > 4 + theta = obox(5); +end + +% pre-compute angles +cot = cosd(theta); +sit = sind(theta); + +% precompute shifts +wc = hw * cot; +ws = hw * sit; +hc = hh * cot; +hs = hh * sit; + +% allocate memory +tx = zeros(4, 1); +ty = zeros(4, 1); + +% compute +tx(1) = x - wc + hs; +ty(1) = y - wc - hc; +tx(2) = x + wc + hs; +ty(2) = y + ws - hc; +tx(3) = x + wc - hs; +ty(3) = y + ws + hc; +tx(4) = x - wc - hs; +ty(4) = y - ws + hc; + +% format output +if nargout <= 1 + varargout = {[tx ty]}; +elseif nargout == 2 + varargout = {tx, ty}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orthogonalLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orthogonalLine.m new file mode 100644 index 0000000..84d05b0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/orthogonalLine.m @@ -0,0 +1,37 @@ +function res = orthogonalLine(line, point) +%ORTHOGONALLINE Create a line orthogonal to another one. +% +% PERP = orthogonalLine(LINE, POINT); +% Returns the line orthogonal to the line LINE and going through the +% point given by POINT. Directed angle from LINE to PERP is pi/2. +% LINE is given as [x0 y0 dx dy] and POINT is [xp yp]. +% +% See also: +% lines2d, parallelLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 19/02/2004 added control for multiple lines and/or points + + +N = max(size(point, 1), size(line, 1)); + +if size(point, 1)>1 + res = point; +else + res = ones(N, 1)*point; +end + +if size(line, 1)>1 + res(:,3) = -line(:,4); + res(:,4) = line(:,3); +else + res(:,3) = -ones(N,1)*line(4); + res(:,4) = ones(N,1)*line(3); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/parallelLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/parallelLine.m new file mode 100644 index 0000000..3d580c1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/parallelLine.m @@ -0,0 +1,39 @@ +function res = parallelLine(line, point) +%PARALLELLINE Create a line parallel to another one. +% +% RES = parallelLine(LINE, POINT); +% Returns the line with same direction vector than LINE and going through +% the point given by POINT. +% LINE is given as [x0 y0 dx dy] and POINT is [xp yp]. +% +% +% RES = parallelLine(LINE, DIST); +% Uses relative distance to specify position. The new line will be +% located at distance DIST, counted positive in the right side of LINE +% and negative in the left side. +% +% See also: +% lines2d, orthogonalLine, distancePointLine +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 31/07/2005 add usage of distance +% 15/06/2009 change convention for distance sign + + +if size(point, 1)==1 + % use a distance. Compute position of point located at distance DIST on + % the line orthogonal to the first one. + point = pointOnLine([line(:,1) line(:,2) line(:,4) -line(:,3)], point); +end + +% normal case: compute line through a point with given direction +res = zeros(1, 4); +res(1:2) = point; +res(3:4) = line(3:4); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/pointOnLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/pointOnLine.m new file mode 100644 index 0000000..cff1361 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/pointOnLine.m @@ -0,0 +1,24 @@ +function point = pointOnLine(line, pos) +%POINTONLINE Create a point on a line at a given position on the line +% +% P = pointOnLine(LINE, POS); +% Creates the point belonging to the line LINE, and located at the +% distance D from the line origin. +% LINE has the form [x0 y0 dx dy]. +% LINE and D should have the same number N of rows. The result will have +% N rows ans 2 column (x and y positions). +% +% See also: +% lines2d, points2d, onLine, onLine, linePosition +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + + +angle = lineAngle(line); +point = [line(:,1) + pos .* cos(angle), line(:,2) + pos .* sin(angle)]; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/points2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/points2d.m new file mode 100644 index 0000000..a400e89 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/points2d.m @@ -0,0 +1,27 @@ +function points2d +%POINTS2D Description of functions operating on points +% +% A point is defined by its two cartesian coordinate, put into a row +% vector of 2 elements: +% P = [x y]; +% +% Several points are stores in a matrix with two columns, one for the +% x-coordinate, one for the y-coordinate. +% PTS = [x1 y1 ; x2 y2 ; x3 y3]; +% +% Example +% P = [5 6]; +% +% See also: +% centroid, midPoint, boundingBox, polarPoint +% distancePoints, minDistancePoints, nndist, circumCenter +% isCounterClockwise, angle2Points, angle3Points, angleSort +% transformPoint, clipPoints, drawPoint +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +help('points2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/polarPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/polarPoint.m new file mode 100644 index 0000000..a3ac50a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/polarPoint.m @@ -0,0 +1,56 @@ +function point = polarPoint(varargin) +%POLARPOINT Create a point from polar coordinates (rho + theta) +% +% POINT = polarPoint(RHO, THETA); +% Creates a point using polar coordinate. THETA is angle with horizontal +% (counted counter-clockwise, and in radians), and RHO is the distance to +% origin. +% +% POINT = polarPoint(THETA) +% Specify angle, radius RHO is assumed to be 1. +% +% POINT = polarPoint(POINT, RHO, THETA) +% POINT = polarPoint(X0, Y0, RHO, THETA) +% Adds the coordinate of the point to the coordinate of the specified +% point. For example, creating a point with : +% P = polarPoint([10 20], 30, pi/2); +% will give a result of [40 20]. +% +% +% See Also: +% points2d +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 03/05/2004 +% + + +% default values +x0 = 0; y0=0; +rho = 1; +theta =0; + +% process input parameters +if length(varargin)==1 + theta = varargin{1}; +elseif length(varargin)==2 + rho = varargin{1}; + theta = varargin{2}; +elseif length(varargin)==3 + var = varargin{1}; + x0 = var(:,1); + y0 = var(:,2); + rho = varargin{2}; + theta = varargin{3}; +elseif length(varargin)==4 + x0 = varargin{1}; + y0 = varargin{2}; + rho = varargin{3}; + theta = varargin{4}; +end + + +point = [x0 + rho.*cos(theta) , y0+rho.*sin(theta)]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/private/parseThreePoints.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/private/parseThreePoints.m new file mode 100644 index 0000000..f2238c9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/private/parseThreePoints.m @@ -0,0 +1,38 @@ +function [a b c] = parseThreePoints(varargin) +%PARSETHREEPOINTS Parse three points from variable length input array +% +% [A B C] = parseThreePoints(PTS); +% [A B C] = parseThreePoints(P1, P2, P3); +% [A B C] = parseThreePoints(VERTICES, INDS); +% +% Example +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% extract input args +if nargin == 1 + % inputs are 3 points packed into a 3-by-2 array + var = varargin{1}; + a = var(1,:); + b = var(2,:); + c = var(3,:); + +elseif nargin == 3 + % inputs are 3 separate points + a = varargin{1}; + b = varargin{2}; + c = varargin{3}; + +elseif nargin == 2 + % inputs are a vertex array, and index array + pts = varargin{1}; + inds = varargin{2}; + a = pts(inds(1), :); + b = pts(inds(2), :); + c = pts(inds(3), :); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/projPointOnLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/projPointOnLine.m new file mode 100644 index 0000000..147714f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/projPointOnLine.m @@ -0,0 +1,42 @@ +function point = projPointOnLine(point, line) +%PROJPOINTONLINE Project of a point orthogonally onto a line +% +% PT2 = projPointOnLine(PT, LINE). +% Computes the (orthogonal) projection of point PT onto the line LINE. +% +% Function works also for multiple points and lines. In this case, it +% returns multiple points. +% Point PT1 is a [N*2] array, and LINE is a [N*4] array (see createLine +% for details). Result PT2 is a [N*2] array, containing coordinates of +% orthogonal projections of PT1 onto lines LINE. +% +% See also: +% lines2d, points2d, isPointOnLine, linePosition +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2005. +% + +% HISTORY +% 06/08/2005 : correct bug when several points were passed as param. + + +% ensure input arguments have same size +if size(line, 1)==1 && size(point, 1)>1 + line = repmat(line, [size(point, 1) 1]); +end +if size(point, 1)==1 && size(line, 1)>1 + point = repmat(point, [size(line, 1) 1]); +end + +% slope of line +dx = line(:, 3); +dy = line(:, 4); + +% first find relative position of projection on the line, +tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy); + +% convert position on line to cartesian coordinate +point = line(:,1:2) + [tp tp].*[dx dy]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rad2deg.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rad2deg.m new file mode 100644 index 0000000..568c712 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rad2deg.m @@ -0,0 +1,25 @@ +function deg = rad2deg(rad) +%RAD2DEG Convert angle from radians to degrees +% +% Usage: +% R = rad2deg(D) +% convert an angle in radians to angle in degrees +% +% Example: +% rad2deg(pi) +% ans = +% 180 +% rad2deg(pi/3) +% ans = +% 60 +% +% See Also +% angles2d, deg2rad +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 09/12/2004. +% + +deg = rad*180/pi; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/radicalAxis.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/radicalAxis.m new file mode 100644 index 0000000..903c314 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/radicalAxis.m @@ -0,0 +1,55 @@ +function line = radicalAxis(circle1, circle2) +%RADICALAXIS Compute the radical axis (or radical line) of 2 circles +% +% L = radicalAxis(C1, C2) +% Computes the radical axis of 2 circles. +% +% Example +% C1 = [10 10 5]; +% C2 = [60 50 30]; +% L = radicalAxis(C1, C2); +% hold on; axis equal;axis([0 100 0 100]); +% drawCircle(C1);drawCircle(C2);drawLine(L); +% +% See also +% lines2d, circles2d, createCircle +% +% Ref: +% http://mathworld.wolfram.com/RadicalLine.html +% http://en.wikipedia.org/wiki/Radical_axis +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-05-15, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. +% + +% extract circles parameters +x1 = circle1(:,1); +x2 = circle2(:,1); +y1 = circle1(:,2); +y2 = circle2(:,2); +r1 = circle1(:,3); +r2 = circle2(:,3); + +% distance between each couple of centers +dist = sqrt((x2-x1).^2 + (y2-y1).^2); + +% relative position of intersection point of +% the radical line with the line joining circle centers +d = (dist.^2 + r1.^2 - r2.^2) * .5 ./ dist; + +% compute angle of radical axis +angle = lineAngle(createLine([x1 y1], [x2 y2])); +cot = cos(angle); +sit = sin(angle); + +% parameters of the line +x0 = x1 + d*cot; +y0 = y1 + d*sit; +dx = -sit; +dy = cot; + +% concatenate into one structure +line = [x0 y0 dx dy]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/randomPointInBox.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/randomPointInBox.m new file mode 100644 index 0000000..f25f5c3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/randomPointInBox.m @@ -0,0 +1,49 @@ +function points = randomPointInBox(box, N, varargin) +%RANDOMPOINTINBOX Generate random point within a box +% +% PTS = randomPointInBox(BOX) +% Generate a random point within the box BOX. The result is a 1-by-2 row +% vector. +% +% PTS = randomPointInBox(BOX, N) +% Generates N points within the box. The result is a N-by-2 array. +% +% BOX has the format: +% BOX = [xmin xmax ymin ymax]. +% +% Example +% % draw points within a box +% box = [10 80 20 60]; +% pts = randomPointInBox(box, 500); +% figure(1); clf; hold on; +% drawBox(box); +% drawPoint(pts, '.'); +% axis('equal'); +% axis([0 100 0 100]); +% +% See also +% points2d, boxes2d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +if nargin < 2 + N = 1; +end + +% extract box bounds +xmin = box(1); +xmax = box(2); +ymin = box(3); +ymax = box(4); + +% compute size of box +dx = xmax - xmin; +dy = ymax - ymin; + +% compute point coordinates +points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rays2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rays2d.m new file mode 100644 index 0000000..0f0f8d4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rays2d.m @@ -0,0 +1,29 @@ +function rays2d(varargin) +%RAYS2D Description of functions operating on planar rays +% +% A ray is defined by a point (its origin), and a vector (its +% direction). The different parameters are bundled into a row vector: +% RAY = [x0 y0 dx dy]; +% +% The ray contains all the points (x,y) such that: +% x = x0 + t*dx +% y = y0 + t*dy; +% for all t>0 +% +% Contrary to a (straight) line, the points located before the origin do +% not belong to the ray. +% However, as rays and lines have the same representation, some functions +% working on lines are also working on rays (like 'transformLine'). +% +% See also: +% points2d, vectors2d, lines2d +% createRay, bisector, isPointOnRay +% clipRay, drawRay +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +help('rays2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/readme.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/readme.txt new file mode 100644 index 0000000..e7672eb --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/readme.txt @@ -0,0 +1,34 @@ +Description of the geom2d library. + +The aim of geom2d library is to handle and visualize geometric primitives such +as points, lines, circles and ellipses, polylines and polygons... It provides +low-level functions for manipulating geometrical primitives, making easier the +development of more complex geometric algorithms. + +Some features of the library are: + +- creation of various shapes (points, circles, lines, ellipses, polylines, + polygons...) through an intuitive syntax. + Ex: createCircle(p1, p2, p3) to create a circle through 3 points. + +- derivation of new shapes: intersection between 2 lines, between line and + circle, between polylines... or point on a curve from its parametrisation + +- functions for polylines and polygons: compute centroid and area, expand, + self-intersections, clipping with half-plane... + +- manipulation of planar transformation. Ex.: + ROT = createRotation(CENTER, THETA); + P2 = transformPoint(P1, ROT); + +- direct drawing of shapes with specialized functions. Clipping is performed + automatically for infinite shapes such as lines or rays. Ex: + drawCircle([50 50 25]); % draw circle with radius 25 and center [50 50] + drawLine([X0 Y0 DX DY]); % clip and draw straight line + +- measure distances (between points, a point and a line, a point and a group + of points), angle (of a line, between 3 points), or test geometry (point + on a line, on a circle). + +Additional help is provided in geom/Contents.m file, as well as summary files + like 'points2d.m' or 'lines2d.m'. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rectToPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rectToPolygon.m new file mode 100644 index 0000000..0090b40 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rectToPolygon.m @@ -0,0 +1,51 @@ +function varargout = rectToPolygon(rect) +%RECTTOPOLYGON Convert a rectangle into a polygon (set of vertices) +% +% POLY = rectToPolygon(RECT); +% Converts rectangle given as [x0 y0 w h] or [x0 y0 w h theta] into a +% 4*2 array double, containing coordinate of rectangle vertices. +% +% See also: +% orientedBoxToPolygon, ellipseToPolygon, drawRect, drawPolygon +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2005. +% + +% HISTORY + +% extract rectangle parameters +theta = 0; +x0 = rect(1); +y0 = rect(2); +w = rect(3); +h = rect(4); +if length(rect) > 4 + theta = rect(5); +end + +% precompute angular quantities +cot = cosd(theta); +sit = sind(theta); + +% compute vertex coordinates +tx = zeros(4, 1); +ty = zeros(4, 1); +tx(1) = x0; +ty(1) = y0; +tx(2) = x0 + w * cot; +ty(2) = y0 + w * sit; +tx(3) = x0 + w * cot - h * sit; +ty(3) = y0 + w * sit + h * cot; +tx(4) = x0 - h * sit; +ty(4) = y0 + h * cot; + +% format output +if nargout <= 1 + varargout = {[tx ty]}; +else + varargout = {tx, ty}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseEdge.m new file mode 100644 index 0000000..6101d90 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseEdge.m @@ -0,0 +1,18 @@ +function res = reverseEdge(edge) +%REVERSEEDGE Intervert the source and target vertices of edge +% +% REV = reverseEdge(EDGE); +% Returns the opposite edge of EDGE. +% EDGE has the format [X1 Y1 X2 Y2]. The resulting edge REV has value +% [X2 Y2 X1 Y1]; +% +% See also: +% edges2d, createEdge, reverseLine +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-05-13, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +res = [edge(:,3:4) edge(:,1:2)]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseLine.m new file mode 100644 index 0000000..d8f3311 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/reverseLine.m @@ -0,0 +1,24 @@ +function line = reverseLine(line) +%REVERSELINE Return same line but with opposite orientation +% +% INVLINE = reverseLine(LINE); +% Returns the opposite line of LINE. +% LINE has the format [x0 y0 dx dy], then INVLINE will have following +% parameters: [x0 y0 -dx -dy]. +% +% See also: +% lines2d, createLine +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/01/2004. +% + +% HISTORY +% 30/06/2009 rename as reverseLine +% 15/03/2011 simplify code + +line(:, 3:4) = -line(:, 3:4); + + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotateVector.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotateVector.m new file mode 100644 index 0000000..66fb4b7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotateVector.m @@ -0,0 +1,26 @@ +function vr = rotateVector(v, angle) +%ROTATEVECTOR Rotate a vector by a given angle +% +% VR = rotateVector(V, THETA) +% Rotate the vector V by an angle THETA, given in radians. +% +% Example +% rotateVector([1 0], pi/2) +% ans = +% 0 1 +% +% See also +% vectors2d, transformVector, createRotation +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-14, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% precomputes angles +cot = cos(angle); +sit = sin(angle); + +% compute rotated coordinates +vr = [cot * v(:,1) - sit * v(:,2) , sit * v(:,1) + cot * v(:,2)]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotation.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotation.m new file mode 100644 index 0000000..9fc7f57 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/rotation.m @@ -0,0 +1,34 @@ +function trans = rotation(varargin) +%ROTATION return 3*3 matrix of a rotation +% +% TRANS = rotation(THETA); +% Returns the rotation corresponding to angle THETA (in radians) +% The returned matrix has the form : +% [cos(theta) -sin(theta) 0] +% [sin(theta) cos(theta) 0] +% [0 0 1] +% +% TRANS = rotation(POINT, THETA); +% TRANS = rotation(X0, Y0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-dx, -dy), rotation, and translation(dx, dy). +% +% +% See also: +% transforms2d, transformPoint, translation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 22/04/2009: copy to createRotation and deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''rotation'' is deprecated, use ''createRotation'' instead'); + +% call current implementation +trans = createRotation(varargin{:}); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/scaling.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/scaling.m new file mode 100644 index 0000000..6861b14 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/scaling.m @@ -0,0 +1,32 @@ +function trans = scaling(varargin) +%SCALING return 3*3 matrix of a scaling in 2 dimensions +% +% TRANS = scaling(SX, SY); +% return the matrix corresponding to scaling by SX and SY in the 2 +% main directions. +% The returned matrix has the form: +% [SX 0 0] +% [0 SY 0] +% [0 0 1] +% +% TRANS = scaling(SX); +% Assume SX and SY are equals. +% +% See also: +% transforms2d, transformPoint, createTranslation, createRotation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. + +% HISTORY +% 04/01/2007: rename as scaling +% 22/04/2009: copy to createScaling and deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''scaling'' is deprecated, use ''createScaling'' instead'); + +% call current implementation +trans = createScaling(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/squareGrid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/squareGrid.m new file mode 100644 index 0000000..a5c5699 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/squareGrid.m @@ -0,0 +1,50 @@ +function varargout = squareGrid(bounds, origin, size) +%SQUAREGRID Generate equally spaces points in plane. +% +% usage +% PTS = squareGrid(BOUNDS, ORIGIN, SIZE) +% generate points, lying in the window defined by BOUNDS (=[xmin ymin +% xmax ymax]), starting from origin with a constant step equal to size. +% +% Example +% PTS = squareGrid([0 0 10 10], [3 3], [4 2]) +% will return points : +% [3 1;7 1;3 3;7 3;3 5;7 5;3 7;7 7;3 9;7 9]; +% +% +% +% TODO: add possibility to use rotated grid +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/08/2005. +% + +% find all x coordinate +x1 = bounds(1) + mod(origin(1)-bounds(1), size(1)); +x2 = bounds(3) - mod(bounds(3)-origin(1), size(1)); +lx = (x1:size(1):x2)'; + +% find all y coordinate +y1 = bounds(2) + mod(origin(2)-bounds(2), size(2)); +y2 = bounds(4) - mod(bounds(4)-origin(2), size(2)); +ly = (y1:size(2):y2)'; + +% number of points in each coord, and total number of points +ny = length(ly); +nx = length(lx); +np = nx*ny; + +% create points +pts = zeros(np, 2); +for i=1:ny + pts( (1:nx)'+(i-1)*nx, 1) = lx; + pts( (1:nx)'+(i-1)*nx, 2) = ly(i); +end + +% process output +if nargout>0 + varargout{1} = pts; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformEdge.m new file mode 100644 index 0000000..77e69fe --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformEdge.m @@ -0,0 +1,41 @@ +function dest = transformEdge(edge, trans) +%TRANSFORMEDGE Transform an edge with an affine transform +% +% EDGE2 = transformEdge(EDGE1, TRANS); +% where EDGE1 has the form [x1 y1 x2 y1], and TRANS is a transformation +% matrix, return the edge transformed with affine transform TRANS. +% +% Format of TRANS can be one of : +% [a b] , [a b c] , or [a b c] +% [d e] [d e f] [d e f] +% [0 0 1] +% +% EDGE2 = transformEdge(EDGES, TRANS); +% Also wotk when EDGES is a [N*4] array of double. In this case, EDGE2 +% has the same size as EDGE. +% +% See also: +% edges2d, transforms2d, transformPoint, translation, rotation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% allocate memory +dest = zeros(size(edge)); + +% compute position +dest(:,1) = edge(:,1)*trans(1,1) + edge(:,2)*trans(1,2); +dest(:,2) = edge(:,1)*trans(2,1) + edge(:,2)*trans(2,2); +dest(:,3) = edge(:,3)*trans(1,1) + edge(:,3)*trans(1,2); +dest(:,4) = edge(:,4)*trans(2,1) + edge(:,4)*trans(2,2); + +% add translation vector, if exist +if size(trans, 2)>2 + dest(:,1) = dest(:,1)+trans(1,3); + dest(:,2) = dest(:,2)+trans(2,3); + dest(:,3) = dest(:,3)+trans(1,3); + dest(:,4) = dest(:,4)+trans(2,3); +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformLine.m new file mode 100644 index 0000000..b890bb3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformLine.m @@ -0,0 +1,39 @@ +function dest = transformLine(line, trans) +%TRANSFORMLINE Transform a line with an affine transform +% +% LINE2 = transformLine(LINE1, TRANS); +% returns the line LINE1 transformed with affine transform TRANS. +% LINE1 has the form [x0 y0 dx dy], and TRANS is a transformation +% matrix. +% +% Format of TRANS can be one of : +% [a b] , [a b c] , or [a b c] +% [d e] [d e f] [d e f] +% [0 0 1] +% +% LINE2 = transformLine(LINES, TRANS); +% Also work when LINES is a [N*4] array of double. In this case, LINE2 +% has the same size as LINE. +% +% See also: +% lines2d, transforms2d, transformPoint +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 02/03/2007: rewrite function + + +% isolate points +points1 = line(:, 1:2); +points2 = line(:, 1:2) + line(:, 3:4); + +% transform points +points1 = transformPoint(points1, trans); +points2 = transformPoint(points2, trans); + +dest = createLine(points1, points2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformPoint.m new file mode 100644 index 0000000..2fd8870 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformPoint.m @@ -0,0 +1,66 @@ +function varargout = transformPoint(varargin) +%TRANSFORMPOINT Transform a point with an affine transform +% +% PT2 = transformPoint(PT1, TRANS); +% where PT1 has the form [xp yp], and TRANS is a [2*2], [2*3] or [3*3] +% matrix, returns the point transformed with affine transform TRANS. +% +% Format of TRANS can be one of : +% [a b] , [a b c] , or [a b c] +% [d e] [d e f] [d e f] +% [0 0 1] +% +% PT2 = transformPoint(PT1, TRANS); +% Also works when PTA is a [N*2] array of double. In this case, PT2 has +% the same size as PT1. +% +% [PX2 PY2] = transformPoint(PX1, PY1, TRANS); +% Also works when PX1 and PY1 are arrays the same size. The function +% transform each couple of (PX1, PY1), and return the result in +% (PX2, PY2), which is the same size as (PX1 PY1). +% +% +% See also: +% points2d, transforms2d, translation, rotation +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 25/04/2005 : support for 2D arrays of points (px, py, trans). + + +if length(varargin)==2 + var = varargin{1}; + px = var(:,1); + py = var(:,2); + trans = varargin{2}; +elseif length(varargin)==3 + px = varargin{1}; + py = varargin{2}; + trans = varargin{3}; +else + error('wrong number of arguments in "transformPoint"'); +end + + +% compute position +px2 = px*trans(1,1) + py*trans(1,2); +py2 = px*trans(2,1) + py*trans(2,2); + +% add translation vector, if exist +if size(trans, 2)>2 + px2 = px2 + trans(1,3); + py2 = py2 + trans(2,3); +end + + +if nargout==0 || nargout==1 + varargout{1} = [px2 py2]; +elseif nargout==2 + varargout{1} = px2; + varargout{2} = py2; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformVector.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformVector.m new file mode 100644 index 0000000..d6694fe --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transformVector.m @@ -0,0 +1,60 @@ +function varargout = transformVector(varargin) +%TRANSFORMVECTOR Transform a vector with an affine transform +% +% VECT2 = transformVector(VECT1, TRANS); +% where VECT1 has the form [xv yv], and TRANS is a [2*2], [2*3] or [3*3] +% matrix, returns the vector transformed with affine transform TRANS. +% +% Format of TRANS can be one of : +% [a b] , [a b c] , or [a b c] +% [d e] [d e f] [d e f] +% [0 0 1] +% +% VECT2 = transformVector(VECT1, TRANS); +% Also works when PTA is a [N*2] array of double. In this case, VECT2 has +% the same size as VECT1. +% +% [vx2 vy2] = transformVector(vx1, vy1, TRANS); +% Also works when vx1 and vy1 are arrays the same size. The function +% transform each couple of (vx1, vy1), and return the result in +% (vx2, vy2), which is the same size as (vx1 vy1). +% +% +% See also: +% vectors2d, transforms2d, rotateVector, transformPoint +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 12/03/2007. +% + +% HISTORY + + +if length(varargin)==2 + var = varargin{1}; + vx = var(:,1); + vy = var(:,2); + trans = varargin{2}; +elseif length(varargin)==3 + vx = varargin{1}; + vy = varargin{2}; + trans = varargin{3}; +else + error('wrong number of arguments in "transformVector"'); +end + + +% compute new position of vector +vx2 = vx*trans(1,1) + vy*trans(1,2); +vy2 = vx*trans(2,1) + vy*trans(2,2); + +% format output +if nargout==0 || nargout==1 + varargout{1} = [vx2 vy2]; +elseif nargout==2 + varargout{1} = vx2; + varargout{2} = vy2; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transforms2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transforms2d.m new file mode 100644 index 0000000..c8ee43e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/transforms2d.m @@ -0,0 +1,28 @@ +function transforms2d(varargin) +%TRANSFORMS2D Description of functions operating on transforms +% +% By 'transform' we mean an affine transform. A planar affine transform +% can be represented by a 3x3 matrix. +% +% Example +% % create a translation by the vector [10 20]: +% T = createTranslation([10 20]) +% T = +% 1 0 10 +% 0 1 20 +% 0 0 1 +% +% +% See also: +% createTranslation, createRotation, createScaling, createBasisTransform +% createHomothecy, createLineReflection, fitAffineTransform2d +% transformPoint, transformVector, transformLine, transformEdge +% rotateVector +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +help('transforms2d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/translation.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/translation.m new file mode 100644 index 0000000..54fa73c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/translation.m @@ -0,0 +1,32 @@ +function trans = translation(varargin) +%TRANSLATION return 3*3 matrix of a translation +% +% TRANS = translation(DX, DY); +% Returns the translation corresponding to DX and DY. +% The returned matrix has the form : +% [1 0 DX] +% [0 1 DY] +% [0 0 1] +% +% TRANS = translation(POINT); +% Returns the translation corresponding to the given point [x y]. +% +% +% See also: +% transforms2d, transformPoint, rotation, scaling +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 22/04/2009: copy to createTranslation and deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''translation'' is deprecated, use ''createTranslation'' instead'); + +% call current implementation +trans = createTranslation(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleArea.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleArea.m new file mode 100644 index 0000000..e680e35 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleArea.m @@ -0,0 +1,45 @@ +function area = triangleArea(pt1, pt2, pt3) +%TRIANGLEAREA Signed area of a triangle +% +% AREA = triangleArea(P1, P2, P3) +% Computes area of the triangle whose vertices are given by P1, P2 and +% P3. Each vertex is a 1-by-2 row vector. +% +% AREA = triangleArea(PTS) +% Concatenates vertex coordinates in a 3-by-2 array. Each row of the +% array contains coordinates of one vertex. +% +% +% Example +% % Compute area of a Counter-Clockwise (CCW) oriented triangle +% triangleArea([10 10], [30 10], [10 40]) +% ans = +% 300 +% +% % Compute area of a Clockwise (CW) oriented triangle +% triangleArea([10 40], [30 10], [10 10]) +% ans = +% -300 +% +% See also +% polygonArea, triangleArea3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-08-23, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% if data is given as one array, split vertices +if nargin == 1 + pt2 = pt1(2,:); + pt3 = pt1(3,:); + pt1 = pt1(1,:); +end + +% compute individual vectors +v12 = bsxfun(@minus, pt2, pt1); +v13 = bsxfun(@minus, pt3, pt1); + +% compute area from cross product +area = (v13(:,2) .* v12(:,1) - v13(:,1) .* v12(:,2)) / 2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleGrid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleGrid.m new file mode 100644 index 0000000..46c1126 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/triangleGrid.m @@ -0,0 +1,35 @@ +function varargout = triangleGrid(bounds, origin, size, varargin) +%TRIANGLEGRID Generate triangular grid of points in the plane. +% +% usage +% PTS = triangleGrid(BOUNDS, ORIGIN, SIZE) +% generate points, lying in the window defined by BOUNDS, given in form +% [xmin ymin xmax ymax], starting from origin with a constant step equal +% to size. +% SIZE is constant and is equals to the length of the sides of each +% triangles. +% +% TODO: add possibility to use rotated grid +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/08/2005. +% + +dx = size(1); +dy = size(1)*sqrt(3); + +% consider two square grids with different centers +pts1 = squareGrid(bounds, origin, [dx dy], varargin{:}); +pts2 = squareGrid(bounds, origin + [dx dy]/2, [dx dy], varargin{:}); + +% gather points +pts = [pts1;pts2]; + + +% process output +if nargout>0 + varargout{1} = pts; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vecnorm.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vecnorm.m new file mode 100644 index 0000000..c7c790e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vecnorm.m @@ -0,0 +1,75 @@ +function n = vecnorm(v, varargin) +%VECNORM compute norm of vector or of set of vectors +% +% N = vecnorm(V); +% Returns the euclidean norm of vector V. +% +% N = vecnorm(V, N); +% Specifies the norm to use. N can be any value greater than 0. +% N=1 -> city lock norm +% N=2 -> euclidean norm +% N=inf -> compute max coord. +% +% When V is a MxN array, compute norm for each vector of the array. +% Vector are given as rows. Result is then a [M*1] array. +% +% See Also: +% vectors2d, vectorAngle +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 02/05/2006 manage several norms +% 18/09/2007 use 'isempty' +% 15/10/2008 add comments +% 22/05/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''vecnorm'' is deprecated, use ''vectorNorm'' instead'); + +dim = size(v); + +d = 2; +if ~isempty(varargin) + d = varargin{1}; +end + +if d==2 + % euclidean norm: sum of squared coordinates, and take square root + if dim(1)==1 || dim(2)==1 + n = sqrt(sum(v.*v)); + else + n = sqrt(sum(v.*v, 2)); + end + return; +elseif d==1 + % absolute norm: sum of absolute coordinates + if dim(1)==1 || dim(2)==1 + n = sum(abs(v)); + else + n = sum(abs(v), 2); + end + return; +elseif d==inf + % infinite norm: uses the maximal corodinate + if dim(1)==1 || dim(2)==1 + n = max(v); + else + n = max(v, 2); + end + return; +else + % Other norms, use explicit but slower expression + if dim(1)==1 || dim(2)==1 + n = power(sum(power(v, d)), 1/d); + else + n = power(sum(power(v, d), 2), 1/d); + end + return; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorAngle.m new file mode 100644 index 0000000..4914fc9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorAngle.m @@ -0,0 +1,104 @@ +function alpha = vectorAngle(v1, varargin) +%VECTORANGLE Angle of a vector, or between 2 vectors +% +% A = vectorAngle(V); +% Returns angle between Ox axis and vector direction, in Counter +% clockwise orientation. +% The result is normalised between 0 and 2*PI. +% +% A = vectorAngle(V1, V2); +% Returns the angle from vector V1 to vector V2, in counter-clockwise +% order, and in radians. +% +% A = vectorAngle(..., 'cutAngle', CUTANGLE); +% A = vectorAngle(..., CUTANGLE); % (deprecated syntax) +% Specifies convention for angle interval. CUTANGLE is the center of the +% 2*PI interval containing the result. See normalizeAngle for details. +% +% Example: +% rad2deg(vectorAngle([2 2])) +% ans = +% 45 +% rad2deg(vectorAngle([1 sqrt(3)])) +% ans = +% 60 +% rad2deg(vectorAngle([0 -1])) +% ans = +% 270 +% +% See also: +% vectors2d, angles2d, normalizeAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-18 +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY +% 2010-04-16 add psb to specify center interval +% 2011-04-10 add support for angle between two vectors + + +%% Initializations + +% default values +v2 = []; +cutAngle = pi; + +% process input arguments +while ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) && isscalar(var) + % argument is normalization constant + cutAngle = varargin{1}; + varargin(1) = []; + + elseif isnumeric(var) && size(var, 2) == 2 + % argument is second vector + v2 = varargin{1}; + varargin(1) = []; + + elseif ischar(var) && length(varargin) >= 2 + % argument is option given as string + value + if strcmpi(var, 'cutAngle') + cutAngle = varargin{2}; + varargin(1:2) = []; + + else + error(['Unknown option: ' var]); + end + + else + error('Unable to parse inputs'); + end +end + + +%% Case of one vector + +% If only one vector is provided, computes its angle +if isempty(v2) + % compute angle and format result in a 2*pi interval + alpha = atan2(v1(:,2), v1(:,1)); + + % normalize within a 2*pi interval + alpha = normalizeAngle(alpha + 2*pi, cutAngle); + + return; +end + + +%% Case of two vectors + +% compute angle of each vector +alpha1 = atan2(v1(:,2), v1(:,1)); +alpha2 = atan2(v2(:,2), v2(:,1)); + +% difference +alpha = bsxfun(@minus, alpha2, alpha1); + +% normalize within a 2*pi interval +alpha = normalizeAngle(alpha + 2*pi, cutAngle); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorNorm.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorNorm.m new file mode 100644 index 0000000..a61695a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectorNorm.m @@ -0,0 +1,80 @@ +function n = vectorNorm(v, varargin) +%VECTORNORM Compute norm of a vector, or of a set of vectors +% +% N = vectorNorm(V); +% Returns the euclidean norm of vector V. +% +% N = vectorNorm(V, N); +% Specifies the norm to use. N can be any value greater than 0. +% N=1 -> city lock norm +% N=2 -> euclidean norm +% N=inf -> compute max coord. +% +% When V is a MxN array, compute norm for each vector of the array. +% Vector are given as rows. Result is then a [M*1] array. +% +% Example +% n1 = vectorNorm([3 4]) +% n1 = +% 5 +% +% n2 = vectorNorm([1, 10], inf) +% n2 = +% 10 +% +% See Also: +% vectors2d, vectorAngle +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 02/05/2006 manage several norms +% 18/09/2007 use 'isempty' +% 15/10/2008 add comments +% 22/05/2009 rename as vectorNorm +% 01/03/2010 fix bug for inf norm + + +% size of vector +dim = size(v); + +% extract the type of norm to compute +d = 2; +if ~isempty(varargin) + d = varargin{1}; +end + +if d==2 + % euclidean norm: sum of squared coordinates, and take square root + if dim(1)==1 || dim(2)==1 + n = sqrt(sum(v.*v)); + else + n = sqrt(sum(v.*v, 2)); + end +elseif d==1 + % absolute norm: sum of absolute coordinates + if dim(1)==1 || dim(2)==1 + n = sum(abs(v)); + else + n = sum(abs(v), 2); + end +elseif d==inf + % infinite norm: uses the maximal corodinate + if dim(1)==1 || dim(2)==1 + n = max(v); + else + n = max(v, [], 2); + end +else + % Other norms, use explicit but slower expression + if dim(1)==1 || dim(2)==1 + n = power(sum(power(v, d)), 1/d); + else + n = power(sum(power(v, d), 2), 1/d); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectors2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectors2d.m new file mode 100644 index 0000000..b2538f9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom2d/vectors2d.m @@ -0,0 +1,23 @@ +function vectors2d +%VECTORS2D Description of functions operating on plane vectors +% +% A vector is defined by its two cartesian coordinates, put into a row +% vector of 2 elements: +% V = [vx vy]; +% +% Several vectors are stored in a matrix with two columns, one for the +% x-coordinate, one for the y-coordinate. +% VS = [vx1 vy1 ; vx2 vy2 ; vx3 vy3]; +% +% See also: +% vectorNorm, vectorAngle, isPerpendicular, isParallel +% normalizeVector, transformVector, rotateVector +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +help('vectors2d'); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/Contents.m new file mode 100644 index 0000000..08373ce --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/Contents.m @@ -0,0 +1,198 @@ +% GEOM3D Geometry 3D Toolbox +% Version 1.0 21-Mar-2011 . +% +% Creation, transformations, algorithms and visualization of geometrical +% 3D primitives, such as points, lines, planes, polyhedra, circles and +% spheres. +% +% Euler Angles are defined as follow: +% PHI is the azimut, i.e. the angle of the projection on horizontal plane +% with the Ox axis, with value beween 0 and 180 degrees. +% THETA is the latitude, i.e. the angle with the Oz axis, with value +% between -90 and +90 degrees. +% PSI is the 'roll', i.e. the rotation around the (PHI, THETA) direction, +% with value in degrees +% See also the 'angles3d' page. +% +% Base format for primitives: +% Point: [x0 y0 z0] +% Vector: [dx dy dz] +% Line: [x0 y0 z0 dx dy dz] +% Edge: [x1 y1 z1 x2 y2 z2] +% Plane: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% Sphere: [x0 y0 z0 R] +% Circle: [x0 y0 z0 R PHI THETA PSI] (origin+center+normal+'roll'). +% Cylinder: [X1 Y1 Z1 X2 Y2 Z2 R] +% Box: [xmin xmax ymin ymax zmin zmax]. Used for clipping shapes. +% +% Polygons are represented by N-by-3 array of points, the last point is +% not necessarily the same as the first one. Points must be coplanar. +% +% +% 3D Points +% points3d - Description of functions operating on 3D points +% midPoint3d - Middle point of two 3D points or of a 3D edge +% isCoplanar - Tests input points for coplanarity in 3-space. +% transformPoint3d - Transform a point with a 3D affine transform +% distancePoints3d - Compute euclidean distance between pairs of 3D Points +% clipPoints3d - Clip a set of points by a box +% drawPoint3d - Draw 3D point on the current axis. +% +% 3D Vectors +% vectors3d - Description of functions operating on 3D vectors +% transformVector3d - Transform a vector with a 3D affine transform +% normalizeVector3d - Normalize a 3D vector to have norm equal to 1 +% vectorNorm3d - Norm of a 3D vector or of set of 3D vectors +% vectorCross3d - Vector cross product faster than inbuilt MATLAB cross. +% vectorAngle3d - Angle between two 3D vectors +% isParallel3d - Check parallelism of two 3D vectors +% isPerpendicular3d - Check orthogonality of two 3D vectors +% drawVector3d - Draw vector at a given position +% +% Angles +% angles3d - Conventions for manipulating angles in 3D +% anglePoints3d - Compute angle between three 3D points +% sphericalAngle - Compute angle between points on the sphere +% angleSort3d - Sort 3D coplanar points according to their angles in plane +% randomAngle3d - Return a 3D angle uniformly distributed on unit sphere +% +% Coordinate transforms +% sph2cart2 - Convert spherical coordinates to cartesian coordinates +% cart2sph2 - Convert cartesian coordinates to spherical coordinates +% cart2sph2d - Convert cartesian coordinates to spherical coordinates in degrees +% sph2cart2d - Convert spherical coordinates to cartesian coordinates in degrees +% cart2cyl - Convert cartesian to cylindrical coordinates +% cyl2cart - Convert cylindrical to cartesian coordinates +% +% 3D Lines and Edges +% lines3d - Description of functions operating on 3D lines +% createLine3d - Create a line with various inputs. +% transformLine3d - Transform a 3D line with a 3D affine transform +% clipLine3d - Clip a line with a box and return an edge +% midPoint3d - Middle point of two 3D points or of a 3D edge +% distancePointLine3d - Euclidean distance between 3D point and line +% distanceLines3d - Minimal distance between two 3D lines +% linePosition3d - Return the position of a 3D point on a 3D line +% drawEdge3d - Draw 3D edge in the current Window +% drawLine3d - Draw a 3D line on the current axis +% +% Planes +% planes3d - Description of functions operating on 3D planes +% createPlane - Create a plane in parametrized form +% normalizePlane - Normalize parametric representation of a plane +% intersectPlanes - Return intersection line between 2 planes in space +% intersectLinePlane - Intersection point between a 3D line and a plane +% intersectEdgePlane - Return intersection point between a plane and a edge +% distancePointPlane - Signed distance betwen 3D point and plane +% projPointOnPlane - Return the orthogonal projection of a point on a plane +% isBelowPlane - Test whether a point is below or above a plane +% medianPlane - Create a plane in the middle of 2 points +% planeNormal - Compute the normal to a plane +% planePosition - Compute position of a point on a plane +% planePoint - Compute 3D position of a point in a plane +% dihedralAngle - Compute dihedral angle between 2 planes +% drawPlane3d - Draw a plane clipped in the current window +% +% 3D Polygons and curves +% polygons3d - Description of functions operating on 3D polygons +% polygonCentroid3d - Centroid (or center of mass) of a polygon +% triangleArea3d - Area of a 3D triangle +% polygon3dNormalAngle - Normal angle at a vertex of the 3D polygon +% intersectLinePolygon3d - Intersection point of a 3D line and a 3D polygon +% intersectLineTriangle3d - Intersection point of a 3D line and a 3D triangle +% intersectRayPolygon3d - Intersection point of a 3D ray and a 3D polygon +% clipConvexPolygon3dHP - Clip a convex 3D polygon with Half-space +% drawPolygon3d - Draw a 3D polygon specified by a list of vertices +% drawPolyline3d - Draw a 3D polyline specified by a list of vertices +% fillPolygon3d - Fill a 3D polygon specified by a list of points +% +% 3D circles and ellipses +% circles3d - Description of functions operating on 3D circles +% circle3dPosition - Return the angular position of a point on a 3D circle +% circle3dPoint - Coordinates of a point on a 3D circle from its position +% circle3dOrigin - Return the first point of a 3D circle +% drawCircle3d - Draw a 3D circle +% drawCircleArc3d - Draw a 3D circle arc +% drawEllipse3d - Draw a 3D ellipse +% +% Spheres +% spheres - Description of functions operating on 3D spheres +% createSphere - Create a sphere containing 4 points +% intersectLineSphere - Return intersection points between a line and a sphere +% intersectPlaneSphere - Return intersection circle between a plane and a sphere +% drawSphere - Draw a sphere as a mesh +% drawSphericalTriangle - Draw a triangle on a sphere +% +% Smooth surfaces +% inertiaEllipsoid - Inertia ellipsoid of a set of 3D points +% intersectLineCylinder - Compute intersection points between a line and a cylinder +% revolutionSurface - Create a surface of revolution from a planar curve +% surfaceCurvature - Curvature on a surface from angle and principal curvatures +% drawEllipsoid - Draw a 3D ellipsoid +% drawTorus - Draw a torus (3D ring) +% drawCylinder - Draw a cylinder +% drawSurfPatch - Draw a 3D surface patch, with 2 parametrized surfaces +% +% Bounding boxes management +% boxes3d - Description of functions operating on 3D boxes +% point3dBounds - Bounding box of a set of 3D points +% intersectBoxes3d - Intersection of two 3D bounding boxes +% mergeBoxes3d - Merge 3D boxes, by computing their greatest extent +% box3dVolume - Volume of a 3-dimensional box +% randomPointInBox3d - Generate random point(s) within a 3D box +% drawBox3d - Draw a 3D box defined by coordinate extents +% +% Geometric transforms +% transforms3d - Conventions for manipulating 3D affine transforms +% createTranslation3d - Create the 4x4 matrix of a 3D translation +% createScaling3d - Create the 4x4 matrix of a 3D scaling +% createRotationOx - Create the 4x4 matrix of a 3D rotation around x-axis +% createRotationOy - Create the 4x4 matrix of a 3D rotation around y-axis +% createRotationOz - Create the 4x4 matrix of a 3D rotation around z-axis +% createBasisTransform3d - Compute matrix for transforming a basis into another basis +% eulerAnglesToRotation3d - Convert 3D Euler angles to 3D rotation matrix +% rotation3dToEulerAngles - Extract Euler angles from a rotation matrix +% createRotation3dLineAngle - Create rotation around a line by an angle theta +% rotation3dAxisAndAngle - Determine axis and angle of a 3D rotation matrix +% recenterTransform3d - Change the fixed point of an affine 3D transform +% composeTransforms3d - Concatenate several space transformations +% +% Various drawing Functions +% drawGrid3d - Draw a 3D grid on the current axis +% drawAxis3d - Draw a coordinate system and an origin +% drawAxisCube - Draw a colored cube representing axis orientation +% drawCube - Draw a 3D centered cube, eventually rotated +% drawCuboid - Draw a 3D cuboid, eventually rotated +% +% +% Credits: +% * function isCoplanar was originally written by Brett Shoelson. +% * Songbai Ji enhanced file intersectPlaneLine (6/23/2006). +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-07 +% Homepage: http://matgeom.sourceforge.net/ +% http://www.pfl-cepia.inra.fr/index.php?page=geom3d +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% In development: +% clipPolygon3dHP - clip a 3D polygon with Half-space +% drawPartialPatch - draw surface patch, with 2 parametrized surfaces + + +% Deprecated: +% intersectPlaneLine - return intersection between a plane and a line +% translation3d - return 4x4 matrix of a 3D translation +% scale3d - return 4x4 matrix of a 3D scaling +% rotationOx - return 4x4 matrix of a rotation around x-axis +% rotationOy - return 4x4 matrix of a rotation around y-axis +% rotationOz - return 4x4 matrix of a rotation around z-axis +% scaling3d - return 4x4 matrix of a 3D scaling +% vecnorm3d - compute norm of vector or of set of 3D vectors +% normalize3d - normalize a 3D vector +% drawCurve3d - draw a 3D curve specified by a list of points +% createEulerAnglesRotation - Create a rotation matrix from 3 euler angles + +% Others diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/anglePoints3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/anglePoints3d.m new file mode 100644 index 0000000..d2769ed --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/anglePoints3d.m @@ -0,0 +1,76 @@ +function alpha = anglePoints3d(varargin) +%ANGLEPOINTS3D Compute angle between three 3D points +% +% ALPHA = anglePoints3d(P1, P2) +% Computes angle (P1, O, P2), in radians, between 0 and PI. +% +% ALPHA = anglePoints3d(P1, P2, P3) +% Computes angle (P1, P2, P3), in radians, between 0 and PI. +% +% ALPHA = anglePoints3d(PTS) +% PTS is a 3x3 or 2x3 array containing coordinate of points. +% +% See also +% points3d, angles3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 20/09/2005 : add case of single argument for all points +% 04/01/2007: check typo + +p2 = [0 0 0]; +if length(varargin)==1 + pts = varargin{1}; + if size(pts, 1)==2 + p1 = pts(1,:); + p0 = [0 0 0]; + p2 = pts(2,:); + else + p1 = pts(1,:); + p0 = pts(2,:); + p2 = pts(3,:); + end +elseif length(varargin)==2 + p1 = varargin{1}; + p0 = [0 0 0]; + p2 = varargin{2}; +elseif length(varargin)==3 + p1 = varargin{1}; + p0 = varargin{2}; + p2 = varargin{3}; +end + +% ensure all data have same size +n1 = size(p1, 1); +n2 = size(p2, 1); +n0 = size(p0, 1); +if n1~=n2 + if n1==1 + p1 = repmat(p1, [n2 1]); + elseif n2==1 + p2 = repmat(p2, [n1 1]); + else + error('Arguments P1 and P2 must have the same size'); + end +end +if n1~=n0 + if n1==1 + p1 = repmat(p1, [n0 1]); + elseif n0==1 + p0 = repmat(p0, [n1 1]); + else + error('Arguments P1 and P0 must have the same size'); + end +end + +% normalized vectors +p1 = normalizeVector3d(p1-p0); +p2 = normalizeVector3d(p2-p0); + +% compute angle +alpha = acos(dot(p1, p2, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angleSort3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angleSort3d.m new file mode 100644 index 0000000..a56560e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angleSort3d.m @@ -0,0 +1,76 @@ +function varargout = angleSort3d(pts, varargin) +%ANGLESORT3D Sort 3D coplanar points according to their angles in plane +% +% PTS2 = angleSort3d(PTS); +% Considers all points are located on the same plane, and sort them +% according to the angle on plane. PTS is a [Nx2] array. Note that the +% result depend on plane orientation: points can be in reverse order +% compared to expected. The reference plane is computed besed on the 3 +% first points. +% +% PTS2 = angleSort3d(PTS, PTS0); +% Computes angles between each point of PTS and PT0. By default, uses +% centroid of points. +% +% PTS2 = angleSort3d(PTS, PTS0, PTS1); +% Specifies the point which will be used as a start. +% +% [PTS2, I] = angleSort3d(...); +% Also return in I the indices of PTS, such that PTS2 = PTS(I, :); +% +% See also: +% points3d, angles3d, angleSort +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-24 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +% HISTORY : +% 04/01/2007: remove unused variables + +% default values +pt0 = mean(pts, 1); +pt1 = pts(1,:); + +if length(varargin)==1 + pt0 = varargin{1}; +elseif length(varargin)==2 + pt0 = varargin{1}; + pt1 = varargin{2}; +end + +% create support plane +plane = createPlane(pts(1:3, :)); + +% project points onto the plane +pts2d = planePosition(pts, plane); +pt0 = planePosition(pt0, plane); +pt1 = planePosition(pt1, plane); + +% compute origin angle +theta0 = atan2(pt1(2)-pt0(2), pt1(1)-pt0(1)); +theta0 = mod(theta0 + 2*pi, 2*pi); + +% translate to reference point +n = size(pts, 1); +pts2d = pts2d - repmat(pt0, [n 1]); + +% compute angles +angle = atan2(pts2d(:,2), pts2d(:,1)); +angle = mod(angle - theta0 + 4*pi, 2*pi); + +% sort points according to angles +[angle, I] = sort(angle); %#ok + + +% format output +if nargout<2 + varargout{1} = pts(I, :); +elseif nargout==2 + varargout{1} = pts(I, :); + varargout{2} = I; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angles3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angles3d.m new file mode 100644 index 0000000..c3ec354 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/angles3d.m @@ -0,0 +1,48 @@ +function angles3d(varargin) +%ANGLES3D Conventions for manipulating angles in 3D +% +% The library uses both radians and degrees angles; +% Results of angle computation between shapes usually returns angles in +% radians. +% Representation of 3D shapes use angles in degrees (easier to manipulate +% and to save). +% +% Contrary to the plane, there are no oriented angles in 3D. Angles +% between lines or between planes are comprised between 0 and PI. +% +% Spherical angles +% Spherical angles are defined by 2 angles: +% * THETA, the colatitude, representing angle with Oz axis (between 0 and +% PI) +% * PHI, the azimut, representing angle with Ox axis of horizontal +% projection of the direction (between 0 and 2*PI) +% +% Spherical coordinates can be represented by THETA, PHI, and the +% distance RHO to the origin. +% +% Euler angles +% Some functions for creating rotations use Euler angles. They follow the +% ZYX convention in the global reference system, that is eqivalent to the +% XYZ convention ine a local reference system. +% Euler angles are given by a triplet of angles [PHI THETA PSI] that +% represents the succession of 3 rotations: +% * rotation around X by angle PSI ("roll") +% * rotation around Y by angle THETA ("pitch") +% * rotation around Z by angle PHI ("yaw") +% +% In this library, euler angles are given in degrees. The functions that +% use euler angles use the keyword 'Euler' in their name. +% +% +% See also +% cart2sph2, sph2cart2, cart2sph2d, sph2cart2d +% anglePoints3d, angleSort3d, sphericalAngle, randomAngle3d +% dihedralAngle, polygon3dNormalAngle, eulerAnglesToRotation3d +% rotation3dAxisAndAngle, rotation3dToEulerAngles +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/box3dVolume.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/box3dVolume.m new file mode 100644 index 0000000..19a5972 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/box3dVolume.m @@ -0,0 +1,26 @@ +function vol = box3dVolume(box) +%BOX3DVOLUME Volume of a 3-dimensional box +% +% V = box3dVolume(BOX) +% +% A box is represented as a set of limits in each direction: +% BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. +% +% Example +% [n e f] = createCubeOctahedron; +% box = point3dBounds(n); +% vol = box3dVolume(box) +% vol = +% 8 +% +% +% See also +% boxes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +vol = prod(box(:,2:2:end)-box(:, 1:2:end), 2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/boxes3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/boxes3d.m new file mode 100644 index 0000000..1c51dc8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/boxes3d.m @@ -0,0 +1,24 @@ +function boxes3d(varargin) +%BOXES3D Description of functions operating on 3D boxes +% +% A box defined by its coordinate extents: +% BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. +% +% Example +% % Draw a polyhedron together with its bounding box +% [n e f]= createIcosahedron; +% drawPolyhedron(n, f); +% hold on; +% drawBox3d(point3dBounds(n)) +% +% +% See also +% point3dBounds, box3dVolume, drawBox3d +% intersectBoxes3d, mergeBoxes3d, randomPointInBox3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2cyl.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2cyl.m new file mode 100644 index 0000000..772ab26 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2cyl.m @@ -0,0 +1,57 @@ +function varargout = cart2cyl(varargin) +%CART2CYL Convert cartesian to cylindrical coordinates +% +% CYL = cart2cyl(POINT) +% convert the 3D cartesian coordinates of points POINT (given by [X Y Z] +% where X, Y, Z have the same size) into cylindrical coordinates CYL, +% given by [THETA R Z]. +% THETA is the arctangent of the ratio Y/X (between 0 and 2*PI) +% R can be computed using sqrt(X^2+Y^2) +% Z keeps the same value. +% The size of THETA, and R is the same as the size of X, Y and Z. +% +% CYL = cart2cyl(X, Y, Z) +% provides coordinates as 3 different parameters +% +% Example +% cart2cyl([-1 0 2]) +% gives : 4.7124 1.0000 2.0000 +% +% See also agles3d, cart2pol, cart2sph2 +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-03-23 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% process input parameters +if length(varargin)==1 + var = varargin{1}; + x = var(:,1); + y = var(:,2); + z = var(:,3); +elseif length(varargin)==3 + x = varargin{1}; + y = varargin{2}; + z = varargin{3}; +end + +% convert coordinates +dim = size(x); +theta = reshape(mod(atan2(y(:), x(:))+2*pi, 2*pi), dim); +r = reshape(sqrt(x(:).*x(:) + y(:).*y(:)), dim); + +% process output parameters +if nargout==0 ||nargout==1 + if length(dim)>2 || dim(2)>1 + varargout{1} = {theta r z}; + else + varargout{1} = [theta r z]; + end +elseif nargout==3 + varargout{1} = theta; + varargout{2} = r; + varargout{3} = z; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2.m new file mode 100644 index 0000000..4e36fb8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2.m @@ -0,0 +1,57 @@ +function varargout = cart2sph2(varargin) +%CART2SPH2 Convert cartesian coordinates to spherical coordinates +% +% [THETA PHI RHO] = cart2sph2([X Y Z]) +% [THETA PHI RHO] = cart2sph2(X, Y, Z) +% +% The following convention is used: +% THETA is the colatitude, in radians, 0 for north pole, +pi for south +% pole, pi/2 for points with z=0. +% PHI is the azimuth, in radians, defined as matlab cart2sph: angle from +% Ox axis, counted counter-clockwise. +% RHO is the distance of the point to the origin. +% Discussion on choice for convention can be found at: +% http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf +% +% Example: +% cart2sph2([1 0 0]) returns [pi/2 0 1]; +% cart2sph2([1 1 0]) returns [pi/2 pi/4 sqrt(2)]; +% cart2sph2([0 0 1]) returns [0 0 1]; +% +% See also: +% angles3d, sph2cart2, cart2sph, cart2sph2d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 02/11/2006: update doc, and manage case RHO is empty +% 03/11/2006: change convention for angle : uses order [THETA PHI RHO] +% 27/06/2007: manage 2 output arguments + +if length(varargin)==1 + var = varargin{1}; +elseif length(varargin)==3 + var = [varargin{1} varargin{2} varargin{3}]; +end + +if size(var, 2)==2 + var(:,3)=1; +end + +[p t r] = cart2sph(var(:,1), var(:,2), var(:,3)); + +if nargout == 1 || nargout == 0 + varargout{1} = [pi/2-t p r]; +elseif nargout==2 + varargout{1} = pi/2-t; + varargout{2} = p; +else + varargout{1} = pi/2-t; + varargout{2} = p; + varargout{3} = r; +end + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2d.m new file mode 100644 index 0000000..7b86515 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cart2sph2d.m @@ -0,0 +1,69 @@ +function varargout = cart2sph2d(x, y, z) +%CART2SPH2D Convert cartesian coordinates to spherical coordinates in degrees +% +% [THETA PHI RHO] = cart2sph2d([X Y Z]) +% [THETA PHI RHO] = cart2sph2d(X, Y, Z) +% +% The following convention is used: +% THETA is the colatitude, in degrees, 0 for north pole, 180 degrees for +% south pole, 90 degrees for points with z=0. +% PHI is the azimuth, in degrees, defined as matlab cart2sph: angle from +% Ox axis, counted counter-clockwise. +% RHO is the distance of the point to the origin. +% Discussion on choice for convention can be found at: +% http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf +% +% Example: +% cart2sph2d([1 0 0]) +% ans = +% 90 0 1 +% +% cart2sph2d([1 1 0]) +% ans = +% 90 45 1.4142 +% +% cart2sph2d([0 0 1]) +% ans = +% 0 0 1 +% +% +% See also: +% angles3d, sph2cart2d, cart2sph, cart2sph2 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% if data are grouped, extract each coordinate +if nargin == 1 + y = x(:, 2); + z = x(:, 3); + x = x(:, 1); +end + +% cartesian to spherical conversion +hxy = hypot(x, y); +rho = hypot(hxy, z); +theta = 90 - atan2(z, hxy) * 180 / pi; +phi = atan2(y, x) * 180 / pi; + +% % convert to degrees and theta to colatitude +% theta = 90 - rad2deg(theta); +% phi = rad2deg(phi); + +% format output +if nargout <= 1 + varargout{1} = [theta phi rho]; + +elseif nargout == 2 + varargout{1} = theta; + varargout{2} = phi; + +else + varargout{1} = theta; + varargout{2} = phi; + varargout{3} = rho; +end + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changelog.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changelog.txt new file mode 100644 index 0000000..ff0f31e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changelog.txt @@ -0,0 +1,123 @@ +change log for geom3d + +geom3d release 2011.10.13 +========================= + +New Features +- added function vectorCross3d (thanks to Sven Holcombe) +- added function triangleArea3d +- added function trimeshSurfaceArea +- added drawPolygon3d (mostly the same as drawPolyline3d) + +Several bug fixes and improvements in code speed, thanks to Sven Holcombe + + +geom3d release 2011.06.30 +========================= + +Important changes: +- Package has been splitted up into 'geom3d' and 'meshes3d'. +- Representation of geometrical shapes (3D circles, ellipsoids...) now uses + degrees for angles + +New features +- added function distanceLine3d +- added functions inertiaEllipsoid and drawEllipsoid +- added functions intersectLinePolygon3d, intersectRayPolygon3d, and + intersectLineTriangle3d +- added function eulerAngleToRotation3d +- added drawing functions: drawTorus, drawCube, drawCuboid +- added function randomPointInBox3d +- added functions sph2cart2d and cart2sph2d, that work with degrees + +Bug fixes +- fixed bugs in intersectEdgePlanes +- fixed bugs in isPerpendicular3d +- enhanced createPlane + + +geom3d release 2011.01.10 +========================= + +New features +- new functions for meshes and polyhedra: + + meshEdgeLength + + meshDihedralAngles + + meshEdgeFaces + + meshSurfaceArea + + polyhedronMeanBreadth + + checkMeshAdjacentFaces + + drawFaceNormals + + meshFace + +- new function createBasisTransform3d to compute coordinate changes between + basis + +- added vectorAngle3d, to compute angle between 2 3D vectors + +- added midPoint3d, to compute middle points of either 2 points or a 3D edge + +- added functions for 3D rotations: + + createRotation3dLineAngle + + rotation3dAxisAndAngle + + rotation3dToEulerAngles + +Regressions +- function 'local2global3d' moved to private directory + +Bug fixes +- most meshes now have their faces oriented with normals pointing outwards of + the meshes +- fix bug in drawPlane for planes touching current axis at one corner +- fix bug in faceNormal for cell array of faces +- fix bug in transformPoint3d for large arrays + +Code +- creation of private directory, for utilitary functions + + +geom3d release 2010.07.28 +========================= + +New features +- added createEulerAnglesRotation +- added functions for management of 3D boxes (isothetic cuboids) +- added drawPolyline3d +- added drawAxisCube function +- added recenterTransform3d, to change invariant point of 3D transforms. + +Enhancements +- added support for several lines in clipLine3d +- added support for multiple inputs in distancePointPlane +- updated doc for polyhedra, for function localToGlobal3d +- updated several drawing functions + +Bug fixes +- fixed several bugs in 3D rotations +- fixed bugs in drawCircle3d, drawCircleArc3d, drawEllipse3d. +- fixed bugs in drawCylinder + + +geom3d release 2009-06-17 +========================= + +* new features +- added transform functions: + + transformLine3d, transformVector3d +- added intersectLineCylinder +- added 'localToGlobal3d': transform from local coordinates to global + coordinates, using a translation vector and 3 rotation angles + +* Changes +- renamed some functions to avoid name conflicts and ambiguities + translation3d -> createTranslation3d + rotationOx -> createRotationOx + rotationOy -> createRotationOy + rotationOz -> createRotationOz + scale3d -> createScaling3d + vecnorm3d -> vectorNorm3d + normalize3d -> normalizeVector3d + +* Compatibility considerations +- changed convention for angle in rotationOx, rotationOy and rotationOz. +- changed convention for dihedral angle, to be consistent with other references diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changes.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changes.txt new file mode 100644 index 0000000..e4ba88e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/changes.txt @@ -0,0 +1,19 @@ +changes in geom3d + +New features +- added createEulerAnglesRotation +- added drawPolyline3d +- added functions for management of 3D boxes (isothetic cuboids) +- added drawAxisCube function +- added recenterTransform3d, to change invariant point of 3D transforms. + +Enhancements +- added support for several lines in clipLine3d +- added support for multiple inputs in distancePointPlane +- updated doc for polyhedra, for function localToGlobal3d +- updated several drawing functions + +Bug fixes +- fixed several bugs in 3D rotations +- fixed bugs in drawCircle3d, drawCircleArc3d, drawEllipse3d. +- fixed bugs in drawCylinder diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dOrigin.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dOrigin.m new file mode 100644 index 0000000..786466e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dOrigin.m @@ -0,0 +1,45 @@ +function ori = circle3dOrigin(varargin) +%CIRCLE3DORIGIN Return the first point of a 3D circle +% +% P = circle3dOrigin([XC YC ZC R THETA PHI]) +% P = circle3dOrigin([XC YC ZC R THETA PHI PSI]) +% Returns the origin point of the circle, i.e. the first point used for +% drawing circle. +% +% See also: +% circles3d, points3d, circle3dPosition +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005 +% + +% HISTORY + +% get center and radius +circle = varargin{1}; +xc = circle(:,1); +yc = circle(:,2); +zc = circle(:,3); +r = circle(:,4); + +% get angle of normal +theta = circle(:,5); +phi = circle(:,6); + +% get roll +if size(circle, 2)==7 + psi = circle(:,7); +else + psi = zeros(size(circle, 1), 1); +end + +% create origin point +pt0 = [r 0 0]; + +% compute transformation from local basis to world basis +trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); + +% transform the point +ori = transformPoint3d(pt0, trans); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPoint.m new file mode 100644 index 0000000..d9568de --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPoint.m @@ -0,0 +1,53 @@ +function point = circle3dPoint(circle, pos) +%CIRCLE3DPOINT Coordinates of a point on a 3D circle from its position +% +% output = circle3dPoint(input) +% +% Example +% % Draw some points on a 3D circle +% figure; hold on; +% % origin point +% pos1 = 0; +% drawPoint3d(circle3dPoint(circle, pos1), 'ro') +% % few points regularly spaced +% for i = 10:10:40 +% drawPoint3d(circle3dPoint(circle, i)) +% end +% % Draw point opposite to origin +% drawPoint3d(circle3dPoint(circle, 180), 'k*') + +% +% See also +% circles3d, circle3dPosition +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-21, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% extract circle coordinates +xc = circle(1); +yc = circle(2); +zc = circle(3); +r = circle(4); + +theta = circle(5); +phi = circle(6); +psi = circle(7); + +% convert position to angle +t = pos * pi / 180; + +% compute position on base circle +x = r * cos(t); +y = r * sin(t); +z = 0; +pt0 = [x y z]; + +% compute transformation from local basis to world basis +trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); + +% compute points of transformed circle +point = transformPoint3d(pt0, trans); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPosition.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPosition.m new file mode 100644 index 0000000..78451c3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circle3dPosition.m @@ -0,0 +1,52 @@ +function theta = circle3dPosition(point, circle) +%CIRCLE3DPOSITION Return the angular position of a point on a 3D circle +% +% POS = circle3dPosition(POINT, CIRCLE) +% Returns angular position of point on the circle, in degrees, between 0 +% and 360. +% with POINT: [xp yp zp] +% and CIRCLE: [X0 Y0 Z0 R THETA PHI] or [X0 Y0 Z0 R THETA PHI PSI] +% (THETA being the colatitude, and PHI the azimut) +% +% See also: +% circles3d, circle3dOrigin, circle3dPoint +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005 +% + +% HISTORY +% 27/06/2007: change 3D angle convention +% 2011-06-21 use degrees for angles + + +% get center and radius +xc = circle(:,1); +yc = circle(:,2); +zc = circle(:,3); + +% get angle of normal +theta = circle(:,5); +phi = circle(:,6); + +% find origin of the circle +ori = circle3dOrigin(circle); + +% normal vector of the supporting plane (cartesian coords) +vn = sph2cart2d([theta phi]); + +% create plane containing the circle +plane = createPlane([xc yc zc], vn); + +% find position of point on the circle plane +pp0 = planePosition(ori, plane); +pp = planePosition(point, plane); + +% compute angles in the planes +theta0 = mod(atan2(pp0(:,2), pp0(:,1)) + 2*pi, 2*pi); +theta = mod(atan2(pp(:,2), pp(:,1)) + 2*pi - theta0, 2*pi); + +% convert to degrees +theta = theta * 180 / pi; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circles3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circles3d.m new file mode 100644 index 0000000..a463990 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/circles3d.m @@ -0,0 +1,21 @@ +function circles3d(varargin) +%CIRCLES3D Description of functions operating on 3D circles +% +% Circles are represented by a center, a radius and a 3D angle +% representing the normal of the plane containing the circle. +% C = [xc yc zc R theta phi psi]. +% THETA is the colatitude of the normal, in degrees, between 0 and 180 +% PHI is the azimut of the normal, in degrees, between 0 and 360 +% PSI is the proper rotation of the circle around the normal, between 0 +% and 360 degrees +% The parameter PSI is used to locate a point on the 3D circle. +% +% See also +% circle3dOrigin, circle3dPosition, circle3dPoint, intersectPlaneSphere +% drawCircle3d, drawCircleArc3d, drawEllipse3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipConvexPolygon3dHP.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipConvexPolygon3dHP.m new file mode 100644 index 0000000..e82973a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipConvexPolygon3dHP.m @@ -0,0 +1,66 @@ +function poly2 = clipConvexPolygon3dHP(poly, plane) +%CLIPCONVEXPOLYGON3DHP Clip a convex 3D polygon with Half-space +% +% POLY2 = clipConvexPolygon3dHP(POLY, PLANE) +% POLY is a N-by-3 array of points, and PLANE is given as: +% [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2]. +% The result POLY2 is also an array of 3d points, sometimes smaller than +% poly, and that can be 0-by-3 (empty polygon). +% +% POLY2 = clipConvexPolygon3dHP(POLY, PT0, NORMAL) +% uses plane with normal NORMAL and containing point PT0. +% +% +% See also: +% polygons3d, polyhedra +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-05 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 2007/14/09 fix postprocessing of last point + +% ensure last point is the same as the first one +if sum(poly(end, :) == poly(1,:)) ~= 3 + poly = [poly; poly(1,:)]; +end + +% initialize empty polygon +poly2 = zeros(0, 2); + +% compute visible points +below = isBelowPlane(poly, plane); + +% case of empty polygon +if sum(below) == 0 + return; +end + +% case of totally clipped polygon +if sum(below) == length(below) + poly2 = poly; + return; +end + +% indices of edges intersecting the plane +ind = find(below ~= below([2:end 1])); + +% compute intersection points: they are 2 for a convex polygon +lines = createLine3d(poly(ind, :), poly(ind+1, :)); +pInt = intersectLinePlane(lines, plane); + +% insert intersection points and remove invisible points +if below(1) + poly2 = [poly(1:ind(1), :); pInt; poly(ind(2)+1:end, :)]; +else + poly2 = [pInt(1, :); poly(ind(1)+1:ind(2), :); pInt(2, :)]; +end + +% remove last point if it is the same as the first one +if sum(poly2(end, :) == poly2(1,:)) == 3 + poly2(end, :) = []; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipLine3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipLine3d.m new file mode 100644 index 0000000..6e23fb6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipLine3d.m @@ -0,0 +1,105 @@ +function edge = clipLine3d(line, box) +%CLIPLINE3D Clip a line with a box and return an edge +% +% EDGE = clipLine3d(LINE, BOX); +% Clips the line LINE with the bounds given in BOX, and returns the +% corresponding edge. +% +% If the line lies totally outside of the box, returns a 1-by-6 row array +% containing only NaN's. +% +% If LINE is a N-by-6 array, with one line by row, returns the clipped +% edge coresponding to each line in a N-by-6 array. +% +% See also: +% lines3d, edges3d, createLine3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 30/10/2008 from drawLine3d + +% HISTORY +% 30/10/2008 replace intersectPlaneLine by intersectLinePlane +% 25/11/2008 improve test for bounds, and use more explicit code +% 22/06/2009 fig bug, add support for several lines +% 16/11/2010 use middle point for checking edge bounds + +% get box limits +xmin = box(1); xmax = box(2); +ymin = box(3); ymax = box(4); +zmin = box(5); zmax = box(6); + +% extreme corners of the box +p000 = [xmin ymin zmin]; +p111 = [xmax ymax zmax]; + +% main vectors +ex = [1 0 0]; +ey = [0 1 0]; +ez = [0 0 1]; + +% box faces parallel to Oxy +planeZ0 = [p000 ex ey]; +planeZ1 = [p111 ex ey]; + +% box faces parallel to Oxz +planeY0 = [p000 ex ez]; +planeY1 = [p111 ex ez]; + +% box faces parallel to Oyz +planeX0 = [p000 ey ez]; +planeX1 = [p111 ey ez]; + +% number of lines +Nl = size(line, 1); + +% allocate memory for result +edge = zeros(Nl, 6); + + +% process each line +for i=1:Nl + + % compute intersection point with each plane + ipZ0 = intersectLinePlane(line(i,:), planeZ0); + ipZ1 = intersectLinePlane(line(i,:), planeZ1); + ipY0 = intersectLinePlane(line(i,:), planeY0); + ipY1 = intersectLinePlane(line(i,:), planeY1); + ipX1 = intersectLinePlane(line(i,:), planeX1); + ipX0 = intersectLinePlane(line(i,:), planeX0); + + % concatenate resulting points + points = [ipX0;ipX1;ipY0;ipY1;ipZ0;ipZ1]; + + % compute position of each point on the line + pos = linePosition3d(points, line(i,:)); + + % keep only defined points + ind = find(~isnan(pos)); + pos = pos(ind); + points = points(ind,:); + + % sort points with respect to their position + [pos ind] = sort(pos); %#ok + points = points(ind, :); + + % keep median points wrt to position. These points define the limit of + % the clipped edge. + nv = length(ind)/2; + + % create resulting edge. + edge(i,:) = [points(nv, :) points(nv+1, :)]; +end + +% check that middle point of the edge is contained in the box +midX = mean(edge(:, [1 4]), 2); +xOk = xmin <= midX & midX <= xmax; +midY = mean(edge(:, [2 5]), 2); +yOk = ymin <= midY & midY <= ymax; +midZ = mean(edge(:, [3 6]), 2); +zOk = zmin <= midZ & midZ <= zmax; + +% if one of the bounding condition is not met, set edge to NaN +edge (~(xOk & yOk & zOk), :) = NaN; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPoints3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPoints3d.m new file mode 100644 index 0000000..37e8be9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPoints3d.m @@ -0,0 +1,41 @@ +function varargout = clipPoints3d(points, box) +%CLIPPOINTS3D Clip a set of points by a box +% +% CLIP = clipPoints3d(POINTS, BOX); +% Returns the set of points which are located inside of the box BOX. +% +% [CLIP IND] = clipPoints2d(POINTS, BOX); +% Also returns the indices of clipepd points. +% +% See also +% points3d, boxes3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% get bounding box limits +xmin = box(1); +xmax = box(2); +ymin = box(3); +ymax = box(4); +zmin = box(5); +zmax = box(6); + +% compute indices of points inside visible area +xOk = points(:,1) >= xmin & points(:,1) <= xmax; +yOk = points(:,2) >= ymin & points(:,2) <= ymax; +zOk = points(:,3) >= zmin & points(:,3) <= zmax; + +% keep only points inside box +ind = find(xOk & yOk & zOk); +points = points(ind, :); + +% process output arguments +varargout{1} = points; +if nargout == 2 + varargout{2} = ind; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPolygon3dHP.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPolygon3dHP.m new file mode 100644 index 0000000..5abd405 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/clipPolygon3dHP.m @@ -0,0 +1,123 @@ +function poly2 = clipPolygon3dHP(poly, plane) +%CLIPPOLYGON3DHP clip a 3D polygon with Half-space +% +% usage +% POLY2 = clipPolygon3dHP(POLY, PLANE) +% POLY is a [Nx3] array of points, and PLANE is given as : +% [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2]. +% The result POLY2 is also an array of 3d points, sometimes smaller than +% poly, and that can be [0x3] (empty polygon). +% +% POLY2 = clipPolygon3dHP(POLY, PT0, NORMAL) +% uses plane with normal NORMAL and containing point PT0. +% +% TODO: not yet implemented +% +% There is a problem for non-convex polygons, as they can be clipped in +% several polygons. Possible solutions: +% * create another function 'clipConvexPolygon3dPlane' or +% 'clipConvexPolygon3d', using a simplified algorithm +% * returns a list of polygons instead of a single polygon, +% * in the case of one polygon as return decide what to return +% * and rename this function to 'clipPolygon3d' +% +% See also: +% poygons3d, polyhedra, clipConvexPolygon3dHP +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 02/08/2005. +% + +% HISTORY +% 2007-01-04 add todo flag +% 2011-08-17 rewrite algo, that works for convex polygons, but is slower +% than function clipConvexPolgon3dHP + + +%% Pre-Processing + +% ensure last point is the same as the first one (makes computation easier) +if sum(poly(end, :) == poly(1,:)) ~= 3 + poly = [poly; poly(1,:)]; +end + +% compute index of position wrt plane for each vertex +below = isBelowPlane(poly, plane); + +% in the case of a polygon totally over the plane, return empty array +if sum(below) == 0 + poly2 = zeros(0, 3); + return; +end + +% in the case of a polygon totally over the plane, return original polygon +if sum(~below) == 0 + poly2 = poly; + return; +end + +% number of intersections +nInter = sum(abs(diff(below))); + +% number of vertices of new polygon +N = size(poly, 1); +% N2 = sum(below(1:end-1)) + nInter; +N2 = sum(below) + nInter; +poly2 = zeros(N2, 3); + + +%% Iteration on polygon vertices + +% vertex index in current polygon +% initialized with first vertex below the plane (vertices before are drop) +i = find(below, 1, 'first'); + +% vertex index in result polygon +j = 1; + +while i <= N + + if below(i) + % keep points located below the plane + poly2(j, :) = poly(i,:); + i = i + 1; + j = j + 1; + + else + % current vertex is above the plane. We know that previous vertex + % was below. We compute intersection of supporting line, find the + % next vertex below, and find next intersection. + + % compute intersection of current edge with plane + line = createLine3d(poly(i-1, :), poly(i, :)); + inter1 = intersectLinePlane(line, plane); + poly2(j, :) = inter1; + j = j + 1; + + % find index of next vertex below the plane, possibily re-starting + % from the beginning of the polygon + while ~below(mod(i - 1, N) + 1) + i = i + 1; + end + + % compute intersection of current line with plane + i2 = mod(i - 1, N) + 1; + line = createLine3d(poly(i2-1, :), poly(i2, :)); + inter2 = intersectLinePlane(line, plane); + poly2(j, :) = inter2; + j = j + 1; + + % add also the current vertex + poly2(j, :) = poly(i2, :); + j = j + 1; + i = i + 1; + end +end + +% remove last point if it is the same as the first one +if sum(poly2(end, :) == poly2(1,:)) == 3 + poly2(end, :) = []; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/composeTransforms3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/composeTransforms3d.m new file mode 100644 index 0000000..d961b6d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/composeTransforms3d.m @@ -0,0 +1,33 @@ +function trans = composeTransforms3d(varargin) +%COMPOSETRANSFORMS3D Concatenate several space transformations +% +% TRANS = composeTransforms3d(TRANS1, TRANS2, ...); +% Computes the affine transform equivalent to performing successively +% TRANS1, TRANS2, ... +% +% Example: +% PTS = rand(20, 3); +% ROT1 = createRotationOx(pi/3); +% ROT2 = createRotationOy(pi/4); +% ROT3 = createRotationOz(pi/5); +% ROTS = composeTransforms3d(ROT1, ROT2, ROT3); +% Then: +% PTS2 = transformPoint3d(PTS, ROTS); +% will give the same result as: +% PTS3 = transformPoint3d(transformPoint3d(transformPoint3d(PTS, ... +% ROT1), ROT2), ROT3); +% +% See also: +% transforms3d, transformPoint3d +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/29/2006. +% + +trans = varargin{nargin}; +for i=length(varargin)-1:-1:1 + trans = trans * varargin{i}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createBasisTransform3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createBasisTransform3d.m new file mode 100644 index 0000000..be51581 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createBasisTransform3d.m @@ -0,0 +1,53 @@ +function transfo = createBasisTransform3d(source, target) +%CREATEBASISTRANSFORM3D Compute matrix for transforming a basis into another basis +% +% TRANSFO = createBasisTransform3d(SOURCE, TARGET) will create a 4-by-4 +% transformation matrix representing the transformation from SOURCE basis +% to TARGET basis. +% SOURCE and TARGET are either standard 1-by-9 geom3d PLANE +% representations of the form: [x0 y0 z0 ex1 ey1 ez1 ex2 ey2 ez2] +% OR +% SOURCE and TARGET may be any string such as 'global' or 'g' in which +% case they represent the global plane [0 0 0 1 0 0 0 1 0]. +% +% The resulting TRANSFO matrix is such that a point expressed with +% coordinates of the first basis will be represented by new coordinates +% P2 = transformPoint3d(P1, TRANSFO) in the target basis. +% +% Example: +% % Calculate local plane coords. of a point given in global coords +% Plane = [5 50 500 1 0 0 0 1 0]; +% Tform = createBasisTransform3d('global', Plane); +% PT_WRT_PLANE = transformPoint3d([3 8 2], Tform); +% +% See also +% transforms3d, transformPoint3d, createPlane +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-12-03, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% init basis transform to identity +t1 = eye(4); +t2 = eye(4); + +% Place source and target planes into t1 and t2 t-form matrices. If either +% input is non-numeric it is assumed to mean 'global', or identity t-form. +if isnumeric(source) + t1(1:3, 1) = source(4:6); + t1(1:3, 2) = source(7:9); + t1(1:3, 3) = cross(source(4:6), source(7:9)); + t1(1:3, 4) = source(1:3); +end +if isnumeric(target) + t2(1:3, 1) = target(4:6); + t2(1:3, 2) = target(7:9); + t2(1:3, 3) = cross(target(4:6), target(7:9)); + t2(1:3, 4) = target(1:3); +end + +% compute transfo +% same as: transfo = inv(t2)*t1; +transfo = t2 \ t1; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createEulerAnglesRotation.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createEulerAnglesRotation.m new file mode 100644 index 0000000..b56d654 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createEulerAnglesRotation.m @@ -0,0 +1,52 @@ +function mat = createEulerAnglesRotation(phi, theta, psi) +%CREATEEULERANGLESROTATION Create a rotation matrix from 3 euler angles +% +% ROT = createEulerAnglesRotation(PHI, THETA, PSI) +% Create a rotation matrix from the 3 euler angles PHI THETA and PSI, +% in radians, using the 'XYZ' convention. These angles correspond to the +% "Roll-Pitch-Yaw" convention, also known as "Tait–Bryan angles". +% PHI: rotation angle around X-axis, in radians, corresponding to the +% 'Roll'. PHI is between -pi and +pi. +% THETA: rotation angle around Y-axis, in radians, corresponding to the +% 'Pitch'. THETA is between -pi/2 and pi/2. +% PSI: rotation angle around Z-axis, in radians, corresponding to the +% 'Yaw'. PSI is between -pi and +pi. +% +% The resulting rotation is equivalent to a rotation around X-axis by an +% angle PHI, followed by a rotation around the Y-axis by an angle THETA, +% followed by a rotation around the Z-axis by an angle PSI. +% That is: +% ROT = Rz * Ry * Rx; +% +% Example +% [n e f] = createCube; +% phi = 20*pi/180; +% theta = 30*pi/180; +% psi = 10*pi/180; +% rot = createEulerAnglesRotation(phi, theta, psi); +% n2 = transformPoint3d(n, rot); +% drawPolyhedron(n2, f); +% +% See also +% transforms3d, createRotationOx, createRotationOy, createRotationOz +% rotation3dAxisAndAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2011-06-20 deprecate + +warning('MatGeom:deprecation', ... + 'Deprecated function, use ''eulerAnglesToRotation3d'' instead'); + +% create individual rotation matrices +rotX = createRotationOx(phi); +rotY = createRotationOy(theta); +rotZ = createRotationOz(psi); + +% concatenate matrices +mat = rotZ * rotY * rotX; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createLine3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createLine3d.m new file mode 100644 index 0000000..4d402f6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createLine3d.m @@ -0,0 +1,144 @@ +function line = createLine3d(varargin) +%CREATELINE3D Create a line with various inputs. +% +% Line is represented in a parametric form : [x0 y0 z0 dx dy dz] +% x = x0 + t*dx +% y = y0 + t*dy; +% z = z0 + t*dz; +% +% +% L = createLine3d(P1, P2); +% Returns the line going through the two given points P1 and P2. +% +% L = createLine3d(X0, Y0, Z0, DX, DY, DZ); +% Returns the line going through the point [x0, y0, z0], and with +% direction vector given by [DX DY DZ]. +% +% L = createLine3d(P0, DX, DY, DZ); +% Returns the line going through point P0 given by [x0, y0, z0] and with +% direction vector given by [DX DY DZ]. +% +% L = createLine3d(THETA, PHI); +% Create a line originated at (0,0) and with angles theta and phi. +% +% L = createLine3d(P0, THETA, PHI); +% Create a line with direction given by theta and phi, and which contains +% point P0. +% +% +% Note : in all cases, parameters can be vertical arrays of the same +% dimension. The result is then an array of lines, of dimensions [N*6]. +% +% See also: +% lines3d +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 30/11/2005 add more cases +% 04/01/2007 remove unused variables + +% NOTE : A 3d line can also be represented with a 1*7 array : +% [x0 y0 z0 dx dy dz t]. +% whith 't' being one of the following : +% - t=0 : line is a singleton (x0,y0) +% - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx, +% y0+dy). +% - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity +% in the direction(dx,dy). +% - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity +% in the direction(-dx,-dy). +% - t=NaN : line is a real straight line, and contains all points +% verifying the above equation. +% This seems to be a convenient way to represent uniformly all kind of +% lines (including edges, rays, and even point). +% +% NOTE2 : Another form is the 1*8 array : +% [x0 y0 z0 dx dy dz t1 t2]. +% with t1 and t2 giving first and last position of the edge on the +% supporting straight line, and with t2>t1. + +if length(varargin)==1 + error('Wrong number of arguments in ''createLine'' '); + +elseif length(varargin)==2 + % 2 input parameters. They can be : + % - 2 points, then 2 arrays of 1*2 double. + v1 = varargin{1}; + v2 = varargin{2}; + if size(v1, 2)==3 + % first input parameter is first point, and second input is the + % second point. + line = [v1(:,1) v1(:,2) v1(:,3) v2(:,1)-v1(:,1) v2(:,2)-v1(:,2) v2(:,3)-v1(:,3)]; + elseif size(v1, 2)==1 + % first parameter is angle with the vertical + % second parameter is horizontal angle with Ox axis + theta = varargin{1}; + phi = varargin{2}; + + sit = sin(theta); + p0 = zeros([size(theta, 1) 3]); + + line = [p0 cos(phi)*sit sin(phi)*sit cos(theta)]; + end + +elseif length(varargin)==3 + % 3 input parameters : + % first parameter is a point of the line + % second parameter is angle with the vertical + % third parameter is horizontal angle with Ox axis + p0 = varargin{1}; + theta = varargin{2}; + phi = varargin{3}; + + if size(p0, 2)~=3 + error('first argument should be a 3D point'); + end + + sit = sin(theta); + line = [p0 cos(phi)*sit sin(phi)*sit cos(theta)]; + +elseif length(varargin)==4 + % 4 input parameters : + p0 = varargin{1}; + dx = varargin{2}; + dy = varargin{3}; + dz = varargin{4}; + + if size(p0, 2)~=3 + error('first argument should be a 3D point'); + end + + line = [p0 dx dy dz]; +elseif length(varargin)==5 + % 5 input parameters : + % first parameter is distance of lin to origin + % second parameter is angle with the vertical + % third parameter is horizontal angle with Ox axis + x0 = varargin{1}; + y0 = varargin{1}; + z0 = varargin{1}; + theta = varargin{2}; + phi = varargin{3}; + + sit = sin(theta); + line = [x0 y0 z0 cos(phi)*sit sin(phi)*sit cos(theta)]; + +elseif length(varargin)==6 + % 6 input parameters, given as separate arguments for x0, y0, z0 and + % dx, dy and dz + % (not very useful, but anyway...) + x0 = varargin{1}; + y0 = varargin{2}; + z0 = varargin{3}; + dx = varargin{4}; + dy = varargin{5}; + dz = varargin{6}; + + line = [x0 y0 z0 dx dy dz]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createPlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createPlane.m new file mode 100644 index 0000000..fbbf406 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createPlane.m @@ -0,0 +1,116 @@ +function plane = createPlane(varargin) +%CREATEPLANE Create a plane in parametrized form +% +% PLANE = createPlane(P1, P2, P3) +% creates a plane containing the 3 points +% +% PLANE = createPlane(PTS) +% The 3 points are packed into a single 3x3 array. +% +% PLANE = createPlane(P0, N); +% Creates a plane from a point and from a normal to the plane. The +% parameter N is given either as a 3D vector (1-by-3 row vector), or as +% [THETA PHI], where THETA is the colatitute (angle with the vertical +% axis) and PHI is angle with Ox axis, counted counter-clockwise (both +% given in radians). +% +% The created plane data has the following format: +% PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], with +% - (X0, Y0, Z0) is a point belonging to the plane +% - (DX1, DY1, DZ1) is a first direction vector +% - (DX2, DY2, DZ2) is a second direction vector +% The 2 direction vectors are normalized and orthogonal. +% +% See also: +% planes3d, medianPlane +% +% --------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 24/11/2005 add possibility to pack points for plane creation +% 21/08/2006 return normalized planes +% 06/11/2006 update doc for planes created from normal + +if length(varargin) == 1 + var = varargin{1}; + + if iscell(var) + plane = zeros([length(var) 9]); + for i=1:length(var) + plane(i,:) = createPlane(var{i}); + end + elseif size(var, 1) >= 3 + % 3 points in a single array + p1 = var(1,:); + p2 = var(2,:); + p3 = var(3,:); + + % create direction vectors + v1 = p2 - p1; + v2 = p3 - p1; + + % create plane + plane = normalizePlane([p1 v1 v2]); + return; + end + +elseif length(varargin) == 2 + % plane origin + p0 = varargin{1}; + + % second parameter is either a 3D vector or a 3D angle (2 params) + var = varargin{2}; + if size(var, 2) == 2 + % normal is given in spherical coordinates + n = sph2cart2([var ones(size(var, 1))]); + elseif size(var, 2)==3 + % normal is given by a 3D vector + n = normalizeVector3d(var); + else + error ('wrong number of parameters in createPlane'); + end + + % ensure same dimension for parameters + if size(p0, 1)==1 + p0 = repmat(p0, [size(n, 1) 1]); + end + if size(n, 1)==1 + n = repmat(n, [size(p0, 1) 1]); + end + + % find a vector not colinear to the normal + v0 = repmat([1 0 0], [size(p0, 1) 1]); + inds = vectorNorm(cross(n, v0, 2))<1e-14; + v0(inds, :) = repmat([0 1 0], [sum(inds) 1]); +% if abs(cross(n, v0, 2))<1e-14 +% v0 = repmat([0 1 0], [size(p0, 1) 1]); +% end + + % create direction vectors + v1 = normalizeVector3d(cross(n, v0, 2)); + v2 = -normalizeVector3d(cross(v1, n, 2)); + + % concatenate result in the array representing the plane + plane = [p0 v1 v2]; + return; + +elseif length(varargin)==3 + p1 = varargin{1}; + p2 = varargin{2}; + p3 = varargin{3}; + + % create direction vectors + v1 = p2 - p1; + v2 = p3 - p1; + + plane = normalizePlane([p1 v1 v2]); + return; + +else + error('Wrong number of arguments in "createPlane".'); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotation3dLineAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotation3dLineAngle.m new file mode 100644 index 0000000..5082781 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotation3dLineAngle.m @@ -0,0 +1,49 @@ +function mat = createRotation3dLineAngle(line, theta) +%CREATEROTATION3DLINEANGLE Create rotation around a line by an angle theta +% +% MAT = createRotation3dLineAngle(LINE, ANGLE) +% +% Example +% origin = [1 2 3]; +% direction = [4 5 6]; +% line = [origin direction]; +% angle = pi/3; +% rot = createRotation3dLineAngle(line, angle); +% [axis angle2] = rotation3dAxisAndAngle(rot); +% angle2 +% angle2 = +% 1.015 +% +% See also +% transforms3d, rotation3dAxisAndAngle, rotation3dToEulerAngles, +% createEulerAnglesRotation +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% determine rotation center and direction +center = [0 0 0]; +if size(line, 2)==6 + center = line(1:3); + vector = line(4:6); +else + vector = line; +end + +% normalize vector +v = normalizeVector3d(vector); + +% compute projection matrix P and anti-projection matrix +P = v'*v; +Q = [0 -v(3) v(2) ; v(3) 0 -v(1) ; -v(2) v(1) 0]; +I = eye(3); + +% compute vectorial part of the transform +mat = eye(4); +mat(1:3, 1:3) = P + (I - P)*cos(theta) + Q*sin(theta); + +% add translation coefficient +mat = recenterTransform3d(mat, center); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOx.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOx.m new file mode 100644 index 0000000..4093b68 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOx.m @@ -0,0 +1,72 @@ +function trans = createRotationOx(varargin) +%CREATEROTATIONOX Create the 4x4 matrix of a 3D rotation around x-axis +% +% TRANS = createRotationOx(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Ox axis. A rotation by an angle of PI/2 +% would transform the vector [0 1 0] into the vector [0 0 1]. +% +% The returned matrix has the form: +% [1 0 0 0] +% [0 cos(THETA) -sin(THETA) 0] +% [0 sin(THETA) cos(THETA) 0] +% [0 0 0 1] +% +% TRANS = createRotationOx(ORIGIN, THETA); +% TRANS = createRotationOx(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% See also: +% transforms3d, transformPoint3d, createRotationOy, createRotationOz +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 24/11/2008 changed convention for angle +% 22/04/2009 rename as createRotationOx + + +% default values +dx = 0; +dy = 0; +dz = 0; +theta = 0; + +% get input values +if length(varargin)==1 + % only angle + theta = varargin{1}; +elseif length(varargin)==2 + % origin point (as array) and angle + var = varargin{1}; + dx = var(1); + dy = var(2); + dz = var(3); + theta = varargin{2}; +elseif length(varargin)==3 + % origin (x and y) and angle + dx = varargin{1}; + dy = varargin{2}; + dz = varargin{3}; + theta = varargin{3}; +end + +% compute coefs +cot = cos(theta); +sit = sin(theta); + +% create transformation +trans = [... + 1 0 0 0;... + 0 cot -sit 0;... + 0 sit cot 0;... + 0 0 0 1]; + +% add the translation part +t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; +trans = t*trans/t; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOy.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOy.m new file mode 100644 index 0000000..9e7c5b6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOy.m @@ -0,0 +1,79 @@ +function trans = createRotationOy(varargin) +%CREATEROTATIONOY Create the 4x4 matrix of a 3D rotation around y-axis +% +% TRANS = createRotationOy(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Oy axis. A rotation by an angle of PI/2 +% would transform the vector [0 0 1] into the vector [1 0 0]. +% +% The returned matrix has the form: +% [ cos(THETA) 0 sin(THETA) 0 ] +% [ 0 1 0 0 ] +% [-sin(THETA) 0 cos(THETA) 0 ] +% [ 0 0 0 1 ] +% +% TRANS = createRotationOy(ORIGIN, THETA); +% TRANS = createRotationOy(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% +% See also: +% transforms3d, transformPoint3d, createRotationOx, createRotationOz +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2008/11/24 changed convention for angle +% 22/04/2009 rename as createcreateRotationOy + + +% default values +dx = 0; +dy = 0; +dz = 0; +theta = 0; + +% get input values +if length(varargin)==1 + % only angle + theta = varargin{1}; +elseif length(varargin)==2 + % origin point (as array) and angle + var = varargin{1}; + dx = var(1); + dy = var(2); + dz = var(3); + theta = varargin{2}; +elseif length(varargin)==3 + % origin (x and y) and angle + dx = varargin{1}; + dy = 0; + dz = varargin{2}; + theta = varargin{3}; +elseif length(varargin)==4 + % origin (x and y) and angle + dx = varargin{1}; + dy = varargin{2}; + dz = varargin{3}; + theta = varargin{4}; +end + +% compute coefs +cot = cos(theta); +sit = sin(theta); + +% create transformation +trans = [... + cot 0 sit 0;... + 0 1 0 0;... + -sit 0 cot 0;... + 0 0 0 1]; + +% add the translation part +t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; +trans = t*trans/t; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOz.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOz.m new file mode 100644 index 0000000..c9869c1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createRotationOz.m @@ -0,0 +1,74 @@ +function trans = createRotationOz(varargin) +%CREATEROTATIONOZ Create the 4x4 matrix of a 3D rotation around z-axis +% +% TRANS = createRotationOz(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Oz axis. A rotation by an angle of PI/2 +% would transform the vector [1 0 0] into the vector [0 1 0]. +% +% The returned matrix has the form: +% [cos(THETA) -sin(THETA) 0 0] +% [sin(THETA) cos(THETA) 0 0] +% [ 0 0 1 0] +% [ 0 0 0 1] +% +% TRANS = createRotationOz(ORIGIN, THETA); +% TRANS = createRotationOz(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% +% See also: +% transforms3d, transformPoint3d, createRotationOx, createRotationOy +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 2008/11/24 changed convention for angle +% 22/04/2009 rename as createcreateRotationOz + + +% default values +dx = 0; +dy = 0; +dz = 0; +theta = 0; + +% get input values +if length(varargin)==1 + % only angle + theta = varargin{1}; +elseif length(varargin)==2 + % origin point (as array) and angle + var = varargin{1}; + dx = var(1); + dy = var(2); + dz = var(3); + theta = varargin{2}; +elseif length(varargin)==3 + % origin (x and y) and angle + dx = varargin{1}; + dy = varargin{2}; + dz = varargin{3}; + theta = varargin{3}; +end + +% compute coefs +cot = cos(theta); +sit = sin(theta); + +% create transformation +trans = [... + cot -sit 0 0;... + sit cot 0 0;... + 0 0 1 0;... + 0 0 0 1]; + +% add the translation part +t = [1 0 0 dx;0 1 0 dy;0 0 1 dz;0 0 0 1]; +trans = t*trans/t; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createScaling3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createScaling3d.m new file mode 100644 index 0000000..f3f24e8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createScaling3d.m @@ -0,0 +1,67 @@ +function trans = createScaling3d(varargin) +%CREATESCALING3D Create the 4x4 matrix of a 3D scaling +% +% TRANS = createScaling3d(S); +% returns the scaling transform corresponding to a scaling factor S in +% each direction. S can be a scalar, or a 1x3 vector containing the +% scaling factor in each direction. +% +% TRANS = createScaling3d(SX, SY, SZ); +% returns the scaling transform corresponding to a different scaling +% factor in each direction. +% +% The returned matrix has the form : +% [SX 0 0 0] +% [ 0 SY 0 0] +% [ 0 0 SZ 0] +% [ 0 0 0 0] +% +% See also: +% transforms3d, transformPoint3d, transformVector3d, createTranslation3d, +% createRotationOx, createRotationOy, createRotationOz +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/04/2006. +% + +% HISTORY +% 25/11/2008 rename from scale3d to scaling3d +% 30/04/2009 rename to createScaling3d + + +% process input parameters +if isempty(varargin) + % assert uniform scaling in each direction + sx = 1; + sy = 1; + sz = 1; +elseif length(varargin)==1 + % only one argument + var = varargin{1}; + if length(var)==1 + % same scaling factor in each direction + sx = var; + sy = var; + sz = var; + elseif length(var)==3 + % scaling is a vector, giving different scaling in each direction + sx = var(1); + sy = var(2); + sz = var(3); + else + error('wrong size for first parameter of "createScaling3d"'); + end +elseif length(varargin)==3 + % 3 arguments, giving scaling in each direction + sx = varargin{1}; + sy = varargin{2}; + sz = varargin{3}; +else + error('wrong number of arguments for "createScaling3d"'); +end + +% create the scaling matrix +trans = [sx 0 0 0;0 sy 0 0;0 0 sz 0;0 0 0 1]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createSphere.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createSphere.m new file mode 100644 index 0000000..1695623 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createSphere.m @@ -0,0 +1,42 @@ +function sphere = createSphere(varargin) +%CREATESPHERE Create a sphere containing 4 points +% +% s = createSphere(p1, p2, p3, p4); +% return in s the sphere common to the 4 pointsp1, p2, p3 and p4. +% +% Ref: P. Bourke +% http://astronomy.swin.edu.au/~pbourke/geometry/spherefrom4/ +% +% See also +% spheres, circles3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 22/03/2005. +% + + +if length(varargin)==4 + pts = [varargin{1};varargin{2};varargin{3};varargin{4}]; +elseif length(varargin)==1 + pts = varargin{1}; +else + error('wrong number of arguments in createSphere'); +end + + +m1 = det([pts ones(4,1)]); +s2 = sum(pts.*pts, 2); +m2 = det([s2 pts(:,2) pts(:,3) ones(4,1)]); +m3 = det([pts(:,1) s2 pts(:,3) ones(4,1)]); +m4 = det([pts(:,1) pts(:,2) s2 ones(4,1)]); + +m5 = det([s2 pts]); + +x0 = m2*.5/m1; +y0 = m3*.5/m1; +z0 = m4*.5/m1; +r = sqrt(x0*x0 + y0*y0 + z0*z0 - m5/m1); + +sphere = [x0 y0 z0 r]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createTranslation3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createTranslation3d.m new file mode 100644 index 0000000..f09b290 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/createTranslation3d.m @@ -0,0 +1,51 @@ +function trans = createTranslation3d(varargin) +%CREATETRANSLATION3D Create the 4x4 matrix of a 3D translation +% +% usage: +% TRANS = createTranslation3d(DX, DY, DZ); +% return the translation corresponding to DX and DY. +% The returned matrix has the form : +% [1 0 0 DX] +% [0 1 0 DY] +% [0 0 1 DZ] +% [0 0 0 1] +% +% TRANS = createTranslation3d(VECT); +% return the translation corresponding to the given vector [x y z]. +% +% +% See also: +% transforms3d, transformPoint3d, transformVector3d, +% createRotationOx, createRotationOy, createRotationOz, createScaling3d +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 22/04/2009 rename as createTranslation3d + + +if isempty(varargin) + % assert translation with null vector + dx = 0; + dy = 0; + dz = 0; +elseif length(varargin)==1 + % translation vector given in a single argument + var = varargin{1}; + dx = var(1); + dy = var(2); + dz = var(3); +else + % translation vector given in 3 arguments + dx = varargin{1}; + dy = varargin{2}; + dz = varargin{3}; +end + +% create the translation matrix +trans = [1 0 0 dx ; 0 1 0 dy ; 0 0 1 dz; 0 0 0 1]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cyl2cart.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cyl2cart.m new file mode 100644 index 0000000..89f955f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/cyl2cart.m @@ -0,0 +1,57 @@ +function varargout = cyl2cart(varargin) +%CYL2CART Convert cylindrical to cartesian coordinates +% +% CART = cyl2cart(CYL) +% convert the 3D cylindrical coordinates of points CYL (given by +% [THETA R Z] where THETA, R, and Z have the same size) into cartesian +% coordinates CART, given by [X Y Z]. +% The transforms is the following : +% X = R*cos(THETA); +% Y = R*sin(THETA); +% Z remains inchanged. +% +% CART = cyl2cart(THETA, R, Z) +% provides coordinates as 3 different parameters +% +% Example +% cyl2cart([-1 0 2]) +% gives : 4.7124 1.0000 2.0000 +% +% See also angles3d, cart2pol, cart2sph2, cart2cyl +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-03-23 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% process input parameters +if length(varargin)==1 + var = varargin{1}; + theta = var(:,1); + r = var(:,2); + z = var(:,3); +elseif length(varargin)==3 + theta = varargin{1}; + r = varargin{2}; + z = varargin{3}; +end + +% convert coordinates +dim = size(theta); +x = reshape(r(:).*cos(theta(:)), dim); +y = reshape(r(:).*sin(theta(:)), dim); + +% process output parameters +if nargout==0 ||nargout==1 + if length(dim)>2 || dim(2)>1 + varargout{1} = {x y z}; + else + varargout{1} = [x y z]; + end +elseif nargout==3 + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/dihedralAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/dihedralAngle.m new file mode 100644 index 0000000..dcfce4d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/dihedralAngle.m @@ -0,0 +1,54 @@ +function theta = dihedralAngle(plane1, plane2) +%DIHEDRALANGLE Compute dihedral angle between 2 planes +% +% THETA = dihedralAngle(PLANE1, PLANE2) +% PLANE1 and PLANE2 are plane representations given in the following +% format: +% [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% THETA is the angle between the two vectors given by plane normals, +% given between 0 and PI. +% +% References +% http://en.wikipedia.org/wiki/Dihedral_angle +% http://mathworld.wolfram.com/DihedralAngle.html +% +% See also: +% planes3d, lines3d, angles3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 2009-06-19 change convention for dihedral angle +% 2011-03-20 improve computation precision + +% compute plane normals +v1 = planeNormal(plane1); +v2 = planeNormal(plane2); + +% number of vectors +n1 = size(v1, 1); +n2 = size(v2, 1); + +% ensures vectors have same dimension +if n1~=n2 + if n1==1 + v1 = repmat(v1, [n2 1]); + elseif n2==1 + v2 = repmat(v2, [n1 1]); + else + error('Arguments V1 and V2 must have the same size'); + end +end + +% compute dihedral angle(s) +theta = atan2(vectorNorm3d(cross(v1, v2, 2)), dot(v1, v2, 2)); + +% % equivalent to: +% n1 = normalizeVector3d(planeNormal(plane1)); +% n2 = normalizeVector3d(planeNormal(plane2)); +% theta = acos(dot(n1, n2, 2)); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distanceLines3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distanceLines3d.m new file mode 100644 index 0000000..395843f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distanceLines3d.m @@ -0,0 +1,53 @@ +function d = distanceLines3d(line1, line2) +%DISTANCELINES3D Minimal distance between two 3D lines +% +% D = distanceLines3d(LINE1, LINE2); +% Returns the distance between line LINE1 and the line LINE2, given as: +% LINE1 : [x0 y0 z0 dx dy dz] (or M-by-6 array) +% LINE2 : [x0 y0 z0 dx dy dz] (or N-by-6 array) +% D : (positive) array M-by-N +% +% Example +% line1 = [2 3 4 0 1 0]; +% line2 = [8 8 8 0 0 1]; +% distanceLines3d(line1, line2) +% ans = +% 6.0000 +% +% See also: +% lines3d +% +% --------- +% author: Brandon Baker +% created January 19, 2011 +% + +% number of points of each array +n1 = size(line1, 1); +n2 = size(line2, 1); + +% compute difference of coordinates for each pair of point ([n1*n2] array) +v1x = repmat(line1(:,4), [1 n2]); +v1y = repmat(line1(:,5), [1 n2]); +v1z = repmat(line1(:,6), [1 n2]); +p1x = repmat(line1(:,1), [1 n2]); +p1y = repmat(line1(:,2), [1 n2]); +p1z = repmat(line1(:,3), [1 n2]); + +v2x = repmat(line2(:,4)', [n1 1]); +v2y = repmat(line2(:,5)', [n1 1]); +v2z = repmat(line2(:,6)', [n1 1]); +p2x = repmat(line2(:,1)', [n1 1]); +p2y = repmat(line2(:,2)', [n1 1]); +p2z = repmat(line2(:,3)', [n1 1]); + +% This calculates distance for each set of lines + +vcross = cross([v1x(:) v1y(:) v1z(:)], [v2x(:) v2y(:) v2z(:)]); + +num = ([p1x(:) p1y(:) p1z(:)] - [p2x(:) p2y(:) p2z(:)]) .* vcross; + +t1 = sum(num,2); +d = (t1) ./ (vectorNorm3d(vcross) + eps); + +d = reshape(abs(d),n1,n2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointLine3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointLine3d.m new file mode 100644 index 0000000..7f839a1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointLine3d.m @@ -0,0 +1,27 @@ +function d = distancePointLine3d(point, line) +%DISTANCEPOINTLINE3D Euclidean distance between 3D point and line +% +% D = distancePointLine3d(POINT, LINE); +% Returns the distance between point POINT and the line LINE, given as: +% POINT : [x0 y0 z0] +% LINE : [x0 y0 z0 dx dy dz] +% D : (positive) scalar +% +% See also: +% lines3d, points3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 23/05/2005. +% + +% HISTORY +% 15/01/2007 unify size of input data +% 31/01/2007 typo in data formatting, and replace norm by vecnorm3d +% 12/12/2010 changed to bsxfun implementation - Sven Holcombe + +% cf. Mathworld (distance point line 3d) for formula +d = bsxfun(@rdivide, vectorNorm3d( ... + vectorCross3d(line(:,4:6), bsxfun(@minus, line(:,1:3), point)) ), ... + vectorNorm3d(line(:,4:6))); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointPlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointPlane.m new file mode 100644 index 0000000..b28bc10 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePointPlane.m @@ -0,0 +1,29 @@ +function d = distancePointPlane(point, plane) +%DISTANCEPOINTPLANE Signed distance betwen 3D point and plane +% +% D = distancePointPlane(POINT, PLANE) +% Returns the euclidean distance between point POINT and the plane PLANE, +% given by: +% POINT : [x0 y0 z0] +% PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% D : scalar +% +% See also: +% planes3d, points3d, intersectLinePlane +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY + + +% normalized plane normal +n = normalizeVector3d(cross(plane(:,4:6), plane(:, 7:9), 2)); + + +% Uses Hessian form, ie : N.p = d +% I this case, d can be found as : -N.p0, when N is normalized +d = -sum(bsxfun(@times, n, bsxfun(@minus, plane(:,1:3), point)), 2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePoints3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePoints3d.m new file mode 100644 index 0000000..dbddc11 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/distancePoints3d.m @@ -0,0 +1,49 @@ +function dist = distancePoints3d(p1, p2, varargin) +%DISTANCEPOINTS3D Compute euclidean distance between pairs of 3D Points +% +% D = distancePoints3d(P1, P2) return distance between points P1 and +% P2, given as [X Y Z]. +% +% If P1 and P2 are two arrays of points, result is a N1*N2 array +% containing distance between each point of P1 and each point of P2. +% +% +% D = distancePoints3d(P1, P2, NOR) +% with NOR being 1, 2, or Inf, corresponfing to the norm used. Default is +% 2 (euclidean norm). 1 correspond to manhattan (or taxi driver) distance +% and Inf to maximum difference in each coordinate. +% +% +% See also: +% points3d, minDistancePoints, distancePoints +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 21/02/2005: add different norms +% 28/08/2007: deprecate + +norm = 2; +if length(varargin)==1 + norm = varargin{1}; +end + +% compute difference of coordinate for each pair of points +ptsDiff = bsxfun(@minus, p2, p1); + +% Return dist based on the type of measurement requested +switch(norm) + case 1 + dist = sum(abs(ptsDiff),2); + case 2 + dist = vectorNorm3d(ptsDiff); + case Inf + dist = max(abs(ptsDiff), [], 2); + otherwise + dist = power(sum(power(ptsDiff, norm),2), 1/norm); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxis3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxis3d.m new file mode 100644 index 0000000..0cb4c98 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxis3d.m @@ -0,0 +1,52 @@ +function drawAxis3d(varargin) +%DRAWAXIS3D Draw a coordinate system and an origin +% +% drawAxis3d +% Adds 3 cylinders to the current axis, corresponding to the directions +% of the 3 basis vectors Ox, Oy and Oz. +% Ox vector is red, Oy vector is green, and Oz vector is blue. +% +% drawAxis3d(L, R) +% Specifies the length L and the radius of the cylinders representing the +% different axes. +% +% Example +% drawAxis +% +% figure; +% drawAxis(20, 1); +% +% See also +% drawAxisCube +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% geometrical data +origin = [0 0 0]; +v1 = [1 0 0]; +v2 = [0 1 0]; +v3 = [0 0 1]; + +% default parameters +L = 1; +r = L/10; + +% extract parameters from input +if ~isempty(varargin) + L = varargin{1}; +end +if length(varargin)>1 + r = varargin{2}; +end + +% draw 3 cylinders and a ball +hold on; +drawCylinder([origin origin+v1*L r], 16, 'facecolor', 'r', 'edgecolor', 'none'); +drawCylinder([origin origin+v2*L r], 16, 'facecolor', 'g', 'edgecolor', 'none'); +drawCylinder([origin origin+v3*L r], 16, 'facecolor', 'b', 'edgecolor', 'none'); +drawSphere([origin 2*r], 'faceColor', 'black'); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxisCube.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxisCube.m new file mode 100644 index 0000000..160557f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawAxisCube.m @@ -0,0 +1,31 @@ +function p = drawAxisCube(varargin) +%DRAWAXISCUBE Draw a colored cube representing axis orientation +% +% output = drawAxisCube(input) +% +% Example +% drawAxisCube +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +[n e f] = createCube; %#ok + +faceColors = [ ... + 1 1 0; ... + 0 0 1; ... + 1 0 0; ... + 0 1 1; ... + 1 0 1; ... + 0 1 0; ... + ]; + +p = patch('vertices', n, 'faces', f, ... + 'facecolor', 'flat', 'FaceVertexCData', faceColors); + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawBox3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawBox3d.m new file mode 100644 index 0000000..9c18a79 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawBox3d.m @@ -0,0 +1,54 @@ +function drawBox3d(box, varargin) +%DRAWBOX3D Draw a 3D box defined by coordinate extents +% +% drawBox3d(BOX); +% Draw a box defined by its coordinate extents: +% BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. +% The function draws only the outline edges of the box. +% +% See Also: +% boxes3d, drawRect2, drawRect +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/12/2003. +% + +% HISTORY +% 2010-02-22 creation + + +% default values + +xmin = box(:,1); +xmax = box(:,2); +ymin = box(:,3); +ymax = box(:,4); +zmin = box(:,5); +zmax = box(:,6); + +nBoxes = size(box, 1); + +for i=1:length(nBoxes) + % lower face (z=zmin) + drawEdge3d([xmin(i) ymin(i) zmin(i) xmax(i) ymin(i) zmin(i)], varargin{:}); + drawEdge3d([xmin(i) ymin(i) zmin(i) xmin(i) ymax(i) zmin(i)], varargin{:}); + drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); + drawEdge3d([xmin(i) ymax(i) zmin(i) xmax(i) ymax(i) zmin(i)], varargin{:}); + + % front face (y=ymin) + drawEdge3d([xmin(i) ymin(i) zmin(i) xmin(i) ymin(i) zmax(i)], varargin{:}); + drawEdge3d([xmax(i) ymin(i) zmin(i) xmax(i) ymin(i) zmax(i)], varargin{:}); + drawEdge3d([xmin(i) ymin(i) zmax(i) xmax(i) ymin(i) zmax(i)], varargin{:}); + + % left face (x=xmin) + drawEdge3d([xmin(i) ymax(i) zmin(i) xmin(i) ymax(i) zmax(i)], varargin{:}); + drawEdge3d([xmin(i) ymin(i) zmax(i) xmin(i) ymax(i) zmax(i)], varargin{:}); + + % the last 3 remaining edges + drawEdge3d([xmin(i) ymax(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); + drawEdge3d([xmax(i) ymax(i) zmin(i) xmax(i) ymax(i) zmax(i)], varargin{:}); + drawEdge3d([xmax(i) ymin(i) zmax(i) xmax(i) ymax(i) zmax(i)], varargin{:}); + +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircle3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircle3d.m new file mode 100644 index 0000000..02cd927 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircle3d.m @@ -0,0 +1,229 @@ +function varargout = drawCircle3d(varargin) +%DRAWCIRCLE3D Draw a 3D circle +% +% Possible calls for the function: +% drawCircle3d([XC YC ZC R THETA PHI]) +% drawCircle3d([XC YC ZC R], [THETA PHI]) +% +% where XC, YC, ZY are coordinates of circle center, R is the circle +% radius, PHI and THETA are 3D angles in degrees of the normal to the +% plane containing the circle: +% * THETA between 0 and 180 degrees, corresponding to the colatitude +% (angle with Oz axis). +% * PHI between 0 and 360 degrees corresponding to the longitude (angle +% with Ox axis) +% +% drawCircle3d([XC YC ZC R THETA PHI PSI]) +% drawCircle3d([XC YC ZC R], [THETA PHI PSI]) +% drawCircle3d([XC YC ZC R], THETA, PHI) +% drawCircle3d([XC YC ZC], R, THETA, PHI) +% drawCircle3d([XC YC ZC R], THETA, PHI, PSI) +% drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) +% drawCircle3d(XC, YC, ZC, R, THETA, PHI) +% drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) +% Are other possible syntaxes for this function. +% +% H = drawCircle3d(...) +% return handle on the created LINE object +% +% Example +% % display 3 mutually orthogonal 3D circles +% figure; hold on; +% drawCircle3d([10 20 30 50 0 0], 'LineWidth', 2, 'Color', 'b'); +% drawCircle3d([10 20 30 50 90 0], 'LineWidth', 2, 'Color', 'r'); +% drawCircle3d([10 20 30 50 90 90], 'LineWidth', 2, 'Color', 'g'); +% axis equal; +% axis([-50 100 -50 100 -50 100]); +% view([-10 20]) +% +% % Draw several circles at once +% center = [10 20 30]; +% circ1 = [center 50 0 0]; +% circ2 = [center 50 90 0]; +% circ3 = [center 50 90 90]; +% figure; hold on; +% drawCircle3d([circ1 ; circ2 ; circ3]); +% axis equal; +% +% See also: +% circles3d, drawCircleArc3d, drawEllipse3d, drawSphere +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-02-17 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 14/12/2006 allows unspecified PHI and THETA +% 04/01/2007 update doc, add todo for angle convention +% 19/06/2009 use localToGlobal3d, add drawing options +% 08/03/2010 use drawPolyline3d +% 2011-06-20 use angles in degrees, support several circles, update doc + + +% Possible calls for the function, with number of arguments : +% drawCircle3d([XC YC ZC R THETA PHI]) 1 +% drawCircle3d([XC YC ZC R THETA PHI PSI]) 1 +% drawCircle3d([XC YC ZC R], [THETA PHI]) 2 +% drawCircle3d([XC YC ZC R], [THETA PHI PSI]) 2 +% drawCircle3d([XC YC ZC R], THETA, PHI) 3 +% drawCircle3d([XC YC ZC], R, THETA, PHI) 4 +% drawCircle3d([XC YC ZC R], THETA, PHI, PSI) 4 +% drawCircle3d([XC YC ZC], R, THETA, PHI, PSI) 5 +% drawCircle3d(XC, YC, ZC, R, THETA, PHI) 6 +% drawCircle3d(XC, YC, ZC, R, THETA, PHI, PSI) 7 + + +% extract drawing options +ind = find(cellfun(@ischar, varargin), 1, 'first'); +options = {}; +if ~isempty(ind) + options = varargin(ind:end); + varargin(ind:end) = []; +end + +% Extract circle data +if length(varargin) == 1 + % get center and radius + circle = varargin{1}; + xc = circle(:,1); + yc = circle(:,2); + zc = circle(:,3); + r = circle(:,4); + + % get colatitude of normal + if size(circle, 2) >= 5 + theta = circle(:,5); + else + theta = zeros(size(circle, 1), 1); + end + + % get azimut of normal + if size(circle, 2)>=6 + phi = circle(:,6); + else + phi = zeros(size(circle, 1), 1); + end + + % get roll + if size(circle, 2)==7 + psi = circle(:,7); + else + psi = zeros(size(circle, 1), 1); + end + +elseif length(varargin) == 2 + % get center and radius + circle = varargin{1}; + xc = circle(:,1); + yc = circle(:,2); + zc = circle(:,3); + r = circle(:,4); + + % get angle of normal + angle = varargin{2}; + theta = angle(:,1); + phi = angle(:,2); + + % get roll + if size(angle, 2)==3 + psi = angle(:,3); + else + psi = zeros(size(angle, 1), 1); + end + +elseif length(varargin) == 3 + % get center and radius + circle = varargin{1}; + xc = circle(:,1); + yc = circle(:,2); + zc = circle(:,3); + r = circle(:,4); + + % get angle of normal and roll + theta = varargin{2}; + phi = varargin{3}; + psi = zeros(size(phi, 1), 1); + +elseif length(varargin) == 4 + % get center and radius + circle = varargin{1}; + xc = circle(:,1); + yc = circle(:,2); + zc = circle(:,3); + + if size(circle, 2)==4 + r = circle(:,4); + theta = varargin{2}; + phi = varargin{3}; + psi = varargin{4}; + else + r = varargin{2}; + theta = varargin{3}; + phi = varargin{4}; + psi = zeros(size(phi, 1), 1); + end + +elseif length(varargin) == 5 + % get center and radius + circle = varargin{1}; + xc = circle(:,1); + yc = circle(:,2); + zc = circle(:,3); + r = varargin{2}; + theta = varargin{3}; + phi = varargin{4}; + psi = varargin{5}; + +elseif length(varargin) == 6 + xc = varargin{1}; + yc = varargin{2}; + zc = varargin{3}; + r = varargin{4}; + theta = varargin{5}; + phi = varargin{6}; + psi = zeros(size(phi, 1), 1); + +elseif length(varargin) == 7 + xc = varargin{1}; + yc = varargin{2}; + zc = varargin{3}; + r = varargin{4}; + theta = varargin{5}; + phi = varargin{6}; + psi = varargin{7}; + +else + error('drawCircle3d: please specify center and radius'); +end + +% circle parametrisation (by using N=60, some vertices are located at +% special angles like 45°, 30°...) +Nt = 60; +t = linspace(0, 2*pi, Nt+1); + +nCircles = length(xc); +h = zeros(nCircles, 1); + +for i = 1:nCircles + % compute position of circle points + x = r(i) * cos(t)'; + y = r(i) * sin(t)'; + z = zeros(length(t), 1); + circle0 = [x y z]; + + % compute transformation from local basis to world basis + trans = localToGlobal3d(xc(i), yc(i), zc(i), theta(i), phi(i), psi(i)); + + % compute points of transformed circle + circle = transformPoint3d(circle0, trans); + + % draw the curve of circle points + h(i) = drawPolyline3d(circle, options{:}); +end + + +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircleArc3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircleArc3d.m new file mode 100644 index 0000000..4030bfb --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCircleArc3d.m @@ -0,0 +1,89 @@ +function varargout = drawCircleArc3d(arc, varargin) +%DRAWCIRCLEARC3D Draw a 3D circle arc +% +% drawCircleArc3d([XC YC ZC R THETA PHI PSI START EXTENT]) +% [XC YC ZC] : coordinate of arc center +% R : arc radius +% [THETA PHI] : orientation of arc normal, in degrees (theta: 0->180). +% PSI : roll of arc (rotation of circle origin) +% START : starting angle of arc, from arc origin, in degrees +% EXTENT : extent of circle arc, in degrees (can be negative) +% +% Drawing options can be specified, as for the plot command. +% +% See also +% angles3, circles3d, drawCircle3d, drawCircleArc +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005 +% + +% HISTORY +% 2007-06-27 change 3D angle convention +% 2010-03-08 use drawPolyline3d +% 2011-06-21 use angles in degrees + + +if iscell(arc) + h = []; + for i = 1:length(arc) + h = [h drawCircleArc3d(arc{i}, varargin{:})]; %#ok + end + if nargout > 0 + varargout = {h}; + end + return; +end + +if size(arc, 1) > 1 + h = []; + for i = 1:size(arc, 1) + h = [h drawCircleArc3d(arc(i,:), varargin{:})]; %#ok + end + if nargout > 0 + varargout = {h}; + end + return; +end + +% get center and radius +xc = arc(:,1); +yc = arc(:,2); +zc = arc(:,3); +r = arc(:,4); + +% get angle of normal +theta = arc(:,5); +phi = arc(:,6); +psi = arc(:,7); + +% get starting angle and angle extent of arc +start = arc(:,8); +extent = arc(:,9); + +% positions on circle arc +N = 60; +t = linspace(start, start+extent, N+1) * pi / 180; + +% compute coordinate of points +x = r*cos(t)'; +y = r*sin(t)'; +z = zeros(length(t), 1); +curve = [x y z]; + +% compute transformation from local basis to world basis +trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); + +% transform circle arc +curve = transformPoint3d(curve, trans); + +% draw the curve with specified options +h = drawPolyline3d(curve, varargin{:}); + +if nargout > 0 + varargout = {h}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCube.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCube.m new file mode 100644 index 0000000..97c4902 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCube.m @@ -0,0 +1,102 @@ +function varargout = drawCube(cube, varargin) +%DRAWCUBE Draw a 3D centered cube, eventually rotated +% +% drawCube(CUBE) +% Displays a 3D cube on current axis. CUBE is given by: +% [XC YC ZC SIDE THETA PHI PSI] +% where (XC, YC, ZC) is the CUBE center, SIDE is the length of the cube +% main sides, and THETA PHI PSI are angles representing the cube +% orientation, in degrees. THETA is the colatitude of the cube, between 0 +% and 90 degrees, PHI is the longitude, and PSI is the rotation angle +% around the axis of the normal. +% +% CUBE can be axis aligned, in this case it should only contain center +% and side information: +% CUBE = [XC YC ZC SIDE] +% +% The function drawCuboid is closely related, but uses a different angle +% convention, and allows for different sizes along directions. +% +% Example +% % Draw a cube with small rotations +% figure; hold on; +% drawCube([10 20 30 50 10 20 30], 'FaceColor', 'g'); +% axis equal; +% view(3); +% +% See also +% meshes3d, polyhedra, createCube, drawCuboid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + + +% default values +theta = 0; +phi = 0; +psi = 0; + +%% Parses the input +if nargin == 0 + % no input: assumes cube with default shape + xc = 0; yc = 0; zc = 0; + a = 1; + +else + % one argument: parses elements + xc = cube(:,1); + yc = cube(:,2); + zc = cube(:,3); + a = cube(:,4); + + % parses orientation if present + k = pi / 180; + if size(cube, 2) >= 6 + theta = cube(:,5) * k; + phi = cube(:,6) * k; + end + if size(cube, 2) >= 7 + psi = cube(:,7) * k; + end +end + + +%% Compute cube coordinates + +% create unit centered cube +[v f] = createCube; +v = bsxfun(@minus, v, mean(v, 1)); + +% convert unit basis to cube basis +sca = createScaling3d(a); +rot1 = createRotationOz(psi); +rot2 = createRotationOy(theta); +rot3 = createRotationOz(phi); +tra = createTranslation3d([xc yc zc]); + +% concatenate transforms +trans = tra * rot3 * rot2 * rot1 * sca; + +% transform mesh vertices +[x y z] = transformPoint3d(v, trans); + + +%% Process output +if nargout == 0 + % no output: draw the cube + drawMesh([x y z], f, varargin{:}); + +elseif nargout == 1 + % one output: draw the cube and return handle + varargout{1} = drawMesh([x y z], f, varargin{:}); + +elseif nargout == 3 + % 3 outputs: return computed coordinates + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCuboid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCuboid.m new file mode 100644 index 0000000..4fe4999 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCuboid.m @@ -0,0 +1,101 @@ +function varargout = drawCuboid(cuboid, varargin) +%DRAWCUBOID Draw a 3D cuboid, eventually rotated +% +% drawCuboid(CUBOID) +% Displays a 3D cuboid on current axis. CUBOID is given by: +% [XC YC ZC L W D YAW PITCH ROLL], +% where (XC, YC, ZC) is the cuboid center, L, W and H are the lengths of +% the cuboid main axes, and YAW PITCH ROLL are Euler angles representing +% the cuboid orientation, in degrees. +% +% If cuboid is axis-aligned, it can be specified using only center and +% side lengths: +% CUBOID = [XC YC ZC L W H] +% +% Example +% % Draw a basic rotated cuboid +% figure; hold on; +% drawCuboid([10 20 30 90 40 10 10 20 30], 'FaceColor', 'g'); +% axis equal; +% view(3); +% +% % Draw three "borromean" cuboids +% figure; hold on; +% drawCuboid([10 20 30 90 50 10], 'FaceColor', 'r'); +% drawCuboid([10 20 30 50 10 90], 'FaceColor', 'g'); +% drawCuboid([10 20 30 10 90 50], 'FaceColor', 'b'); +% view(3); axis equal; +% set(gcf, 'renderer', 'opengl') +% +% See also +% meshes3d, polyhedra, createCube, drawEllipsoid, drawCube +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +phi = 0; +theta = 0; +psi = 0; + +%% Parses the input +if nargin == 0 + % no input: assumes cuboid with default shape + xc = 0; yc = 0; zc = 0; + a = 5; b = 4; c = 3; + +else + % one argument: parses elements + xc = cuboid(:,1); + yc = cuboid(:,2); + zc = cuboid(:,3); + a = cuboid(:,4); + b = cuboid(:,5); + c = cuboid(:,6); + if size(cuboid, 2) >= 9 + k = pi / 180; + phi = cuboid(:,7) * k; + theta = cuboid(:,8) * k; + psi = cuboid(:,9) * k; + end +end + + +%% Compute cuboid coordinates + +% create unit centered cube +[v f] = createCube; +v = bsxfun(@minus, v, mean(v, 1)); + +% convert unit basis to ellipsoid basis +sca = createScaling3d(a, b, c); +rotZ = createRotationOz(phi); +rotY = createRotationOy(theta); +rotX = createRotationOx(psi); +tra = createTranslation3d([xc yc zc]); + +% concatenate transforms +trans = tra * rotZ * rotY * rotX * sca; + +% transform mesh vertices +[x y z] = transformPoint3d(v, trans); + + +%% Process output +if nargout == 0 + % no output: draw the cuboid + drawMesh([x y z], f, varargin{:}); + +elseif nargout == 1 + % one output: draw the cuboid and return handle + varargout{1} = drawMesh([x y z], f, varargin{:}); + +elseif nargout == 3 + % 3 outputs: return computed coordinates + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCurve3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCurve3d.m new file mode 100644 index 0000000..af3a4bc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCurve3d.m @@ -0,0 +1,87 @@ +function varargout = drawCurve3d(varargin) +%DRAWCURVE3D draw a 3D curve specified by a list of points +% +% drawCurve3d(COORD) packs coordinates in a single [N*3] array. +% +% drawCurve3d(PX, PY, PZ) specify coordinates in separate arrays. +% +% H = drawCurve3d(...) also return a handle to the list of line objects. +% +% See Also : +% drawPolygon +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2010-03-08 rename to drawPolyline3d + +% deprecation warning +warning('geom3d:deprecated', ... + '''drawCurve3d'' is deprecated, use ''drawPolyline3d'' instead'); + +% default value for closed or open curve +closed = false; + +% check case we want to draw several curves, stored in a cell array +var = varargin{1}; +if iscell(var) + hold on; + h = []; + for i=1:length(var(:)) + h = [h; drawCurve3d(var{i}, varargin{2:end})]; + end + if nargout>0 + varargout{1}=h; + end + return; +end + +% extract curve coordinate +if size(var, 2)==1 + % first argument contains x coord, second argument contains y coord + % and third one the z coord + px = var; + if length(varargin)<3 + error('Wrong number of arguments in drawCurve3d'); + end + py = varargin{2}; + pz = varargin{3}; + varargin = varargin(4:end); +else + % first argument contains both coordinate + px = var(:, 1); + py = var(:, 2); + pz = var(:, 3); + varargin = varargin(2:end); +end + +% check if curve is closed or open +if ~isempty(varargin) + var = varargin{1}; + if strncmpi(var, 'close', 5) + closed = true; + varargin = varargin(2:end); + elseif strncmpi(var, 'open', 4) + closed = false; + varargin = varargin(2:end); + end +end + +% for closed curve, add the first point at the end to close curve +if closed + px = [px; px(1)]; + py = [py; py(1)]; + pz = [pz; pz(1)]; +end + +%% draw the curve ! !! ! ! +h = plot3(px, py, pz, varargin{:}); + +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCylinder.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCylinder.m new file mode 100644 index 0000000..ec05df6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawCylinder.m @@ -0,0 +1,161 @@ +function varargout = drawCylinder(cyl, varargin) +%DRAWCYLINDER Draw a cylinder +% +% drawCylinder(CYL) +% where CYL is a cylinder defined by [x1 y1 z1 x2 y2 z2 r]: +% [x1 y2 z1] are coordinates of starting point, [x2 y2 z2] are +% coordinates of ending point, and R is the radius of the cylinder, +% draws the corresponding cylinder on the current axis. +% +% drawCylinder(CYL, N) +% uses N points for discretisation of angle. Default value is 32. +% +% drawCylinder(..., OPT) +% with OPT = 'open' (default) or 'closed', specify if bases of the +% cylinder should be drawn. +% +% drawCylinder(..., 'FaceColor', COLOR) +% Specifies the color of the cylinder. Any couple of parameters name and +% value can be given as argument, and will be transfered to the 'surf' +% matlab function +% +% H = drawCylinder(...) +% returns a handle to the patch representing the cylinder. +% +% +% Example: +% figure;drawCylinder([0 0 0 10 20 30 5]); +% +% figure;drawCylinder([0 0 0 10 20 30 5], 'open'); +% +% figure;drawCylinder([0 0 0 10 20 30 5], 'FaceColor', 'r'); +% +% figure; +% h = drawCylinder([0 0 0 10 20 30 5]); +% set(h, 'facecolor', 'b'); +% +% % Draw three mutually intersecting cylinders +% p0 = [30 30 30]; +% p1 = [90 30 30]; +% p2 = [30 90 30]; +% p3 = [30 30 90]; +% figure; +% drawCylinder([p0 p1 25], 'FaceColor', 'r'); +% hold on +% drawCylinder([p0 p2 25], 'FaceColor', 'g'); +% drawCylinder([p0 p3 25], 'FaceColor', 'b'); +% axis equal +% set(gcf, 'renderer', 'opengl') +% view([60 30]) +% +% See Also: +% drawSphere, drawLine3d, surf +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/09/2005 +% + +% HISTORY +% 2006/12/14 bug for coordinate conversion, vectorize transforms +% 04/01/2007 better input processing, manage end caps of cylinder +% 19/06/2009 use function localToGlobal3d, add docs +% 2011-06-29 use sph2cart2d, code cleanup + + +%% Input argument processing + +if iscell(cyl) + res = zeros(length(cyl), 1); + for i=1:length(cyl) + res(i) = drawCylinder(cyl{i}, varargin{:}); + end + + if nargout>0 + varargout{1} = res; + end + return; +end + +% default values +N = 32; +closed = true; + +% check number of discretization steps +if ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) + N = var; + varargin = varargin(2:end); + end +end + +% check if cylinder must be closed or open +if ~isempty(varargin) + var = varargin{1}; + if ischar(var) + if strncmpi(var, 'open', 4) + closed = false; + varargin = varargin(2:end); + elseif strncmpi(var, 'closed', 5) + closed = true; + varargin = varargin(2:end); + end + end +end + + +%% Computation of mesh coordinates + +% extreme points of cylinder +p1 = cyl(1:3); +p2 = cyl(4:6); + +% radius of cylinder +r = cyl(7); + +% compute orientation angle of cylinder +[theta phi rho] = cart2sph2d(p2 - p1); +dphi = linspace(0, 2*pi, N+1); + +% generate a cylinder oriented upwards +x = repmat(cos(dphi) * r, [2 1]); +y = repmat(sin(dphi) * r, [2 1]); +z = repmat([0 ; rho], [1 length(dphi)]); + +% transform points +trans = localToGlobal3d(p1, theta, phi, 0); +pts = transformPoint3d([x(:) y(:) z(:)], trans); + +% reshape transformed points +x2 = reshape(pts(:,1), size(x)); +y2 = reshape(pts(:,2), size(x)); +z2 = reshape(pts(:,3), size(x)); + + +%% Display cylinder mesh + +% add default drawing options +varargin = [{'FaceColor', 'g', 'edgeColor', 'none'} varargin]; + +% plot the cylinder as a surface +hSurf = surf(x2, y2, z2, varargin{:}); + +% eventually plot the ends of the cylinder +if closed + ind = find(strcmpi(varargin, 'facecolor'), 1, 'last'); + if isempty(ind) + color = 'k'; + else + color = varargin{ind+1}; + end + + patch(x2(1,:)', y2(1,:)', z2(1,:)', color, 'edgeColor', 'none'); + patch(x2(2,:)', y2(2,:)', z2(2,:)', color, 'edgeColor', 'none'); +end + +% format ouptut +if nargout == 1 + varargout{1} = hSurf; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEdge3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEdge3d.m new file mode 100644 index 0000000..01da636 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEdge3d.m @@ -0,0 +1,48 @@ +function varargout = drawEdge3d(varargin) +%DRAWEDGE3D Draw 3D edge in the current Window +% +% drawEdge(EDGE) +% draw the edge EDGE on the current axis. EDGE has the form: +% [x1 y1 z1 x2 y2 z2]. +% No clipping is performed. +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. + +% HISTORY +% 04/01/2007 remove unused variables +% 15/12/2009 "reprecate", and add processing of input arguments + +% extract edges from input arguments +nCol = size(varargin{1}, 2); +if nCol==6 + % all parameters in a single array + edges = varargin{1}; + options = varargin(2:end); +elseif nCol==3 + % parameters are two points, or two arrays of points, of size N*3. + edges = [varargin{1} varargin{2}]; + options = varargin(3:end); +elseif nCol==6 + % parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2 + edges = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}]; + options = varargin(7:end); +end + +% draw edges +h = line( [edges(:, 1) edges(:, 4)]', ... + [edges(:, 2) edges(:, 5)]', ... + [edges(:, 3) edges(:, 6)]', 'color', 'b'); + +% apply optional drawing style +if ~isempty(options) + set(h, options{:}); +end + +% return handle to created Edges +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipse3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipse3d.m new file mode 100644 index 0000000..499d204 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipse3d.m @@ -0,0 +1,204 @@ +function varargout = drawEllipse3d(varargin) +%DRAWELLIPSE3D Draw a 3D ellipse +% +% Possible calls for the function : +% drawEllipse3d([XC YC ZC A B THETA PHI]) +% drawEllipse3d([XC YC ZC A B THETA PHI PSI]) +% drawEllipse3d([XC YC ZC A B], [THETA PHI]) +% drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) +% drawEllipse3d([XC YC ZC A B], THETA, PHI) +% drawEllipse3d([XC YC ZC], A, B, THETA, PHI) +% drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) +% drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) +% drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) +% drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) +% +% where XC, YC, ZY are coordinate of ellipse center, A and B are the +% half-lengths of the major and minor axes of the ellipse, +% PHI and THETA are 3D angle (in degrees) of the normal to the plane +% containing the ellipse (PHI between 0 and 380 corresponding to +% longitude, and THETA from 0 to 180, corresponding to angle with +% vertical). +% +% H = drawEllipse3d(...) +% return handle on the created LINE object +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-05-07 +% Copyright 2008 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY + +% Possible calls for the function, with number of arguments : +% drawEllipse3d([XC YC ZC A B THETA PHI]) 1 +% drawEllipse3d([XC YC ZC A B THETA PHI PSI]) 1 +% drawEllipse3d([XC YC ZC A B], [THETA PHI]) 2 +% drawEllipse3d([XC YC ZC A B], [THETA PHI PSI]) 2 +% drawEllipse3d([XC YC ZC A B], THETA, PHI) 3 +% drawEllipse3d([XC YC ZC A B], THETA, PHI, PSI) 4 +% drawEllipse3d([XC YC ZC], A, B, THETA, PHI) 5 +% drawEllipse3d([XC YC ZC], A, B, THETA, PHI, PSI) 6 +% drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI) 7 +% drawEllipse3d(XC, YC, ZC, A, B, THETA, PHI, PSI) 8 + + +% extract drawing options +ind = find(cellfun(@ischar, varargin), 1, 'first'); +options = {}; +if ~isempty(ind) + options = varargin(ind:end); + varargin(ind:end) = []; +end + +if length(varargin)==1 + % get center and radius + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + a = ellipse(:,4); + b = ellipse(:,5); + + % get colatitude of normal + if size(ellipse, 2)>=6 + theta = ellipse(:,6); + else + theta = zeros(size(ellipse, 1), 1); + end + + % get azimut of normal + if size(ellipse, 2)>=7 + phi = ellipse(:,7); + else + phi = zeros(size(ellipse, 1), 1); + end + + % get roll + if size(ellipse, 2)==8 + psi = ellipse(:,8); + else + psi = zeros(size(ellipse, 1), 1); + end + +elseif length(varargin)==2 + % get center and radius + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + a = ellipse(:,4); + b = ellipse(:,5); + + % get angle of normal + angle = varargin{2}; + theta = angle(:,1); + phi = angle(:,2); + + % get roll + if size(angle, 2)==3 + psi = angle(:,3); + else + psi = zeros(size(angle, 1), 1); + end + +elseif length(varargin)==3 + % get center and radius + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + a = ellipse(:,4); + b = ellipse(:,5); + + % get angle of normal and roll + theta = varargin{2}; + phi = varargin{3}; + psi = zeros(size(phi, 1), 1); + +elseif length(varargin)==4 + % get center and radius + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + + if size(ellipse, 2)==5 + a = ellipse(:,4); + b = ellipse(:,5); + end + + theta = varargin{2}; + phi = varargin{3}; + psi = varargin{4}; + +elseif length(varargin)==5 + % get center and radius + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + a = varargin{2}; + b = varargin{3}; + theta = varargin{4}; + phi = varargin{5}; + psi = zeros(size(phi, 1), 1); + +elseif length(varargin)==6 + ellipse = varargin{1}; + xc = ellipse(:,1); + yc = ellipse(:,2); + zc = ellipse(:,3); + a = varargin{2}; + b = varargin{3}; + theta = varargin{4}; + phi = varargin{5}; + psi = varargin{6}; + +elseif length(varargin)==7 + xc = varargin{1}; + yc = varargin{2}; + zc = varargin{3}; + a = varargin{4}; + b = varargin{5}; + theta = varargin{6}; + phi = varargin{7}; + psi = zeros(size(phi, 1), 1); + +elseif length(varargin)==8 + xc = varargin{1}; + yc = varargin{2}; + zc = varargin{3}; + a = varargin{4}; + b = varargin{5}; + theta = varargin{6}; + phi = varargin{7}; + psi = varargin{8}; + +else + error('drawEllipse3d: please specify center and radius'); +end + +% uses 60 intervals +t = linspace(0, 2*pi, 61)'; + +% polyline approximation of ellipse, centered and parallel to main axes +x = a * cos(t); +y = b * sin(t); +z = zeros(length(t), 1); +base = [x y z]; + +% compute transformation from local basis to world basis +trans = localToGlobal3d(xc, yc, zc, theta, phi, psi); + +% transform points composing the ellipse +ellipse = transformPoint3d(base, trans); + +% draw the curve +h = drawPolyline3d(ellipse, options{:}); + +if nargout > 0 + varargout = {h}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipsoid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipsoid.m new file mode 100644 index 0000000..8d8a677 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawEllipsoid.m @@ -0,0 +1,134 @@ +function varargout = drawEllipsoid(varargin) +%DRAWELLIPSOID Draw a 3D ellipsoid +% +% drawEllipsoid(ELLI) +% Displays a 3D ellipsoid on current axis. ELLI is given by: +% [XC YC ZC A B C PHI THETA PSI], +% where (XC, YC, ZC) is the ellipsoid center, A, B and C are the half +% lengths of the ellipsoid main axes, and PHI THETA PSI are Euler angles +% representing ellipsoid orientation, in degrees. +% +% Example +% figure; hold on; +% drawEllipsoid([10 20 30 50 30 10 5 10 0], 'FaceColor', 'g'); +% axis equal; +% +% See also +% spheres, drawSphere, inertiaEllipsoid, ellipsoid +% drawTorus, drawCuboid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + + +% process input options: when a string is found, assumes this is the +% beginning of options +options = {'FaceColor', 'g', 'linestyle', 'none'}; +for i = 1:length(varargin) + if ischar(varargin{i}) + options = [options(1:end) varargin(i:end)]; + varargin = varargin(1:i-1); + break; + end +end + +% default ellipsoid orientation +ellPhi = 0; +ellTheta = 0; +ellPsi = 0; + +% Parse the input (try to extract center coordinates and radius) +if isempty(varargin) + % no input: assumes ellipsoid with defualt shape + xc = 0; yc = 0; zc = 0; + a = 5; b = 4; c = 3; + +elseif length(varargin) == 1 + % one argument: concatenates center and radius + elli = varargin{1}; + xc = elli(:,1); + yc = elli(:,2); + zc = elli(:,3); + a = elli(:,4); + b = elli(:,5); + c = elli(:,6); + k = pi / 180; + ellPhi = elli(:,7) * k; + ellTheta = elli(:,8) * k; + ellPsi = elli(:,9) * k; + +elseif length(varargin) == 2 + % two arguments, corresponding to center and radius vector + center = varargin{1}; + xc = center(:,1); + yc = center(:,2); + zc = center(:,3); + r = varargin{2}; + a = r(:,1); + b = r(:,2); + c = r(:,3); + +else + error('drawEllipsoid: incorrect input arguments'); +end + +% number of meridians +nPhi = 32; +ind = strmatch('nphi', lower(options(1:2:end))); +if ~isempty(ind) + ind = ind(1); + nPhi = options{2*ind}; + options(2*ind-1:2*ind) = []; +end + +% number of parallels +nTheta = 16; +ind = strmatch('ntheta', lower(options(1:2:end))); +if ~isempty(ind) + ind = ind(1); + nTheta = options{2*ind}; + options(2*ind-1:2*ind) = []; +end + +% compute spherical coordinates +theta = linspace(0, pi, nTheta+1); +phi = linspace(0, 2*pi, nPhi+1); + +% convert to cartesian coordinates +sintheta = sin(theta); +x = cos(phi') * sintheta; +y = sin(phi') * sintheta; +z = ones(length(phi),1) * cos(theta); + +% convert unit basis to ellipsoid basis +sca = createScaling3d(a, b, c); +rotZ = createRotationOz(ellPhi); +rotY = createRotationOy(ellTheta); +rotX = createRotationOx(ellPsi); +tra = createTranslation3d([xc yc zc]); + +% concatenate transforms +trans = tra * rotZ * rotY * rotX * sca; + +% transform mesh vertices +[x y z] = transformPoint3d(x, y, z, trans); + +% Process output +if nargout == 0 + % no output: draw the ellipsoid + surf(x, y, z, options{:}); + +elseif nargout == 1 + % one output: draw the ellipsoid and return handle + varargout{1} = surf(x, y, z, options{:}); + +elseif nargout == 3 + % 3 outputs: return computed coordinates + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawGrid3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawGrid3d.m new file mode 100644 index 0000000..de57caa --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawGrid3d.m @@ -0,0 +1,117 @@ +function varargout = drawGrid3d(varargin) +%DRAWGRID3D Draw a 3D grid on the current axis +% +% drawGrid3d +% draws a 3D square grid, with origin (0,0,0) and spacing 1 in each +% direction, with bounds corresponding to the bounds of current axis. +% +% drawGrid3d(SPACING) +% where spacing is either a scalar or a [1x3] matrix, specifies the size +% of the unit cell. +% +% drawGrid3d(ORIGIN, SPACING) +% Also specify origin of grid. ORIGIN is a [1x3] array. +% +% drawGrid3d(..., EDGE) +% specifies whether function should draw edges touching edges of axis. +% EDGE is a characheter string, which can be : +% - 'OPEN' : each line start from one face of window to the opposite +% face. This results in a 'spiky' grid. +% - 'CLOSED' (default value) : each line stops at the last visible point +% of the grid for this line. The result looks like a box (no free spikes +% around the grid). +% +% H = drawGrid3d(...); +% return a vector of handles for each LINE object which was crated. +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-17 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +%% initialize variables ----- + +% default values +closed = true; +origin = [0 0 0]; +spacing = [1 1 1]; + +% check if grid is open or not +str = ''; +if ~isempty(varargin) + str = varargin{end}; +end +if ischar(str) + if strmatch(lower(str), 'open') + closed = false; + end + varargin = varargin(1:end-1); +end + +% check origin and grid spacing +if length(varargin)==1 + spacing = varargin{1}; +elseif length(varargin)==2 + origin = varargin{1}; + spacing = varargin{2}; +end + +%% Compute internam data ----- + +% get axis limits +ax = axis; +x0 = ax(1); x1 = ax(2); +y0 = ax(3); y1 = ax(4); +z0 = ax(5); z1 = ax(6); + +% get first and last coordinates of the grid in each direction +dx = spacing(1); dy = spacing(2); dz = spacing(3); +xe = x0 + mod(origin(1) - x0, dx); +xf = x1 - mod(x1 - origin(1), dx); +ye = y0 + mod(origin(2) - y0, dy); +yf = y1 - mod(y1 - origin(2), dy); +ze = z0 + mod(origin(1) - z0, dz); +zf = z1 - mod(z1 - origin(1), dz); + +% update first and last coordinate if grid is 'closed' +if closed + x0 = xe; x1 = xf; + y0 = ye; y1 = yf; + z0 = ze; z1 = zf; +end + + +%% Draw the grid ----- + +h = []; +%TODO: rewrite code, avoiding loops + +% draw lines parallel to x axis +for y=ye:dy:yf + for z=ze:dz:zf + h = [h; drawEdge3d([x0 y z x1 y z])]; + end +end + +% draw lines parallel to y axis +for x=xe:dx:xf + for z=ze:dz:zf + h = [h; drawEdge3d([x y0 z x y1 z])]; + end +end + +% draw lines parallel to z axis +for x=xe:dx:xf + for y=ye:dy:yf + h = [h; drawEdge3d([x y z0 x y z1])]; + end +end + + +%% Check output arguments ----- + +if nargout>0 + varargout{1} = h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawLine3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawLine3d.m new file mode 100644 index 0000000..38dcfd7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawLine3d.m @@ -0,0 +1,61 @@ +function varargout = drawLine3d(lin, varargin) +%DRAWLINE3D Draw a 3D line on the current axis +% +% drawline3d(LINE); +% Draws the line LINE on the current axis, by clipping with the current +% axis. If line is not clipepd by the axis, function return -1. +% +% drawLine3d(LINE, PARAM, VALUE) +% Accepts parameter/value pairs, like for plot function. +% Color of the line can also be given as a single parameter. +% +% H = drawLine3d(...) +% Returns a handle to the created graphic line object. +% +% +% See also: +% lines3d, createLine3d, clipLine3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 30/10/2008 replace intersectPlaneLine by intersectLinePlane + + +% ensure color is given as name-value pair +if length(varargin)==1 + varargin = {'color', varargin{1}}; +end + +% extract limits of the bounding box +lim = get(gca, 'xlim'); +xmin = lim(1); +xmax = lim(2); +lim = get(gca, 'ylim'); +ymin = lim(1); +ymax = lim(2); +lim = get(gca, 'zlim'); +zmin = lim(1); +zmax = lim(2); + +% clip the ine with the limits of the current axis +edge = clipLine3d(lin, [xmin xmax ymin ymax zmin zmax]); + +% draw the clipped line +if sum(isnan(edge))==0 + h = drawEdge3d(edge); + if ~isempty(varargin) + set(h, varargin{:}); + end +else + h = -1; +end + +% process output +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPartialPatch.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPartialPatch.m new file mode 100644 index 0000000..f51a9cd --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPartialPatch.m @@ -0,0 +1,44 @@ +function drawPartialPatch(u, v, z, varargin) +%DRAWPARTIALPATCH draw surface patch, with 2 parametrized surfaces +% +% usage : +% drawSurfPatch(u, v, zuv) +% where u, v, and zuv are three matrices the same size, u and +% corresponding to each parameter, and zuv being equal to a function of u +% and v. +% +% drawSurfPatch(u, v, zuv, p0) +% If p0 is specified, two lines with u(p0(1)) and v(p0(2)) are drawn on +% the surface +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 24/05/2005. +% + +% HISTORY +% 2005-06-08 add doc. +% 2007-01-04 remove unused variables and change function name +% 2010-03-08 code cleanup, use drawPolyline3d + +% prepare figure +hold on; + +% draw the surface interior +surf(u, v, z, 'FaceColor', 'g', 'EdgeColor', 'none'); + +% draw the surface boundaries +drawPolyline3d(u(1,:), v(1,:), z(1,:)) +drawPolyline3d(u(end,:), v(end,:), z(end,:)) +drawPolyline3d(u(:,end), v(:,end), z(:,end)) +drawPolyline3d(u(:,1), v(:,1), z(:,1)) + +% eventually draw two perpendicular lines on the surface +if ~isempty(varargin) + pos = varargin{1}; + drawPolyline3d(u(pos(1),:), v(pos(1),:), z(pos(1),:)); + drawPolyline3d(u(:,pos(2)), v(:,pos(2)), z(:,pos(2))); +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPlane3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPlane3d.m new file mode 100644 index 0000000..5500b40 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPlane3d.m @@ -0,0 +1,116 @@ +function varargout = drawPlane3d(plane, varargin) +%DRAWPLANE3D Draw a plane clipped in the current window +% +% drawPlane3d(plane) +% plane = [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2]; +% +% See also +% planes3d, createPlane +% +% Example +% p0 = [1 2 3]; +% v1 = [1 0 1]; +% v2 = [0 -1 1]; +% plane = [p0 v1 v2]; +% axis([-10 10 -10 10 -10 10]); +% drawPlane3d(plane) +% drawLine3d([p0 v1]) +% drawLine3d([p0 v2]) +% set(gcf, 'renderer', 'zbuffer'); +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 2008-10-30 replace intersectPlaneLine by intersectLinePlane, add doc +% 2010-10-04 fix a bug for planes touching box by one corner + +param = 'm'; +if ~isempty(varargin) + param = varargin{:}; +end + +lim = get(gca, 'xlim'); +xmin = lim(1); +xmax = lim(2); +lim = get(gca, 'ylim'); +ymin = lim(1); +ymax = lim(2); +lim = get(gca, 'zlim'); +zmin = lim(1); +zmax = lim(2); + + +% line corresponding to cube edges +lineX00 = [xmin ymin zmin 1 0 0]; +lineX01 = [xmin ymin zmax 1 0 0]; +lineX10 = [xmin ymax zmin 1 0 0]; +lineX11 = [xmin ymax zmax 1 0 0]; + +lineY00 = [xmin ymin zmin 0 1 0]; +lineY01 = [xmin ymin zmax 0 1 0]; +lineY10 = [xmax ymin zmin 0 1 0]; +lineY11 = [xmax ymin zmax 0 1 0]; + +lineZ00 = [xmin ymin zmin 0 0 1]; +lineZ01 = [xmin ymax zmin 0 0 1]; +lineZ10 = [xmax ymin zmin 0 0 1]; +lineZ11 = [xmax ymax zmin 0 0 1]; + + +% compute intersection points with each plane +piX00 = intersectLinePlane(lineX00, plane); +piX01 = intersectLinePlane(lineX01, plane); +piX10 = intersectLinePlane(lineX10, plane); +piX11 = intersectLinePlane(lineX11, plane); +piY00 = intersectLinePlane(lineY00, plane); +piY01 = intersectLinePlane(lineY01, plane); +piY10 = intersectLinePlane(lineY10, plane); +piY11 = intersectLinePlane(lineY11, plane); +piZ00 = intersectLinePlane(lineZ00, plane); +piZ01 = intersectLinePlane(lineZ01, plane); +piZ10 = intersectLinePlane(lineZ10, plane); +piZ11 = intersectLinePlane(lineZ11, plane); + +% concatenate points into one array +points = [... + piX00;piX01;piX10;piX11; ... + piY00;piY01;piY10;piY11; ... + piZ00;piZ01;piZ10;piZ11;]; + +% check validity: keep only points inside window +ac = 1e-14; +vx = points(:,1)>=xmin-ac & points(:,1)<=xmax+ac; +vy = points(:,2)>=ymin-ac & points(:,2)<=ymax+ac; +vz = points(:,3)>=zmin-ac & points(:,3)<=zmax+ac; +valid = vx & vy & vz; +pts = unique(points(valid, :), 'rows'); + +% If there is no intersection point, escape. +if size(pts, 1)<3 + disp('plane is outside the drawing window'); + return; +end + +% the two spanning lines of the plane +d1 = plane(:, [1:3 4:6]); +d2 = plane(:, [1:3 7:9]); + +% position of intersection points in plane coordinates +u1 = linePosition3d(pts, d1); +u2 = linePosition3d(pts, d2); + +% reorder vertices in the correct order +ind = convhull(u1, u2); +ind = ind(1:end-1); + +% draw the patch +h = patch(pts(ind, 1), pts(ind, 2), pts(ind, 3), param); + +% return handle to plane if needed +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPoint3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPoint3d.m new file mode 100644 index 0000000..17b6e58 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPoint3d.m @@ -0,0 +1,61 @@ +function varargout = drawPoint3d(varargin) +%DRAWPOINT3D Draw 3D point on the current axis. +% +% drawPoint3d(X, Y, Z) +% will draw points defined by coordinates X and Y. +% X and Y are N*1 array, with N being number of points to be drawn. +% +% drawPoint3d(COORD) +% packs coordinates in a single [N*3] array. +% +% drawPoint3d(..., OPT) +% will draw each point with given option. OPT is a string compatible with +% 'plot' model. +% +% H = drawPoint3d(...) +% Also return a handle to each of the drawn points. +% +% +% See also +% points3d, clipPoints3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables, and enhance support for plot +% options +% 12/02/2010 does not clip points anymore + + +var = varargin{1}; +if size(var, 2)==3 + % points are given as one single array with 3 columns + px = var(:, 1); + py = var(:, 2); + pz = var(:, 3); + varargin = varargin(2:end); +elseif length(varargin)<3 + error('wrong number of arguments in drawPoint3d'); +else + % points are given as 3 columns with equal length + px = varargin{1}; + py = varargin{2}; + pz = varargin{3}; + varargin = varargin(4:end); +end + +% default draw style: no line, marker is 'o' +if length(varargin)~=1 + varargin = ['linestyle', 'none', 'marker', 'o', varargin]; +end + +% plot only points inside the axis. +h = plot3(px, py, pz, varargin{:}); + +if nargout>0 + varargout{1} = h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolygon3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolygon3d.m new file mode 100644 index 0000000..05c5c5b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolygon3d.m @@ -0,0 +1,76 @@ +function varargout = drawPolygon3d(varargin) +%DRAWPOLYGON3D Draw a 3D polygon specified by a list of vertices +% +% drawPolygon3d(POLY); +% packs coordinates in a single N-by-3 array. +% +% drawPolygon3d(PX, PY, PZ); +% specifies coordinates in separate arrays. +% +% drawPolygon3d(..., PARAM, VALUE); +% Specifies style options to draw the polyline, see plot for details. +% +% H = drawPolygon3d(...); +% also return a handle to the list of line objects. +% +% See Also: +% polygons3d, fillPolygon3d, drawPolyline3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-08-17 from drawPolyline3d, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% HISTORY + + +% check case we want to draw several curves, stored in a cell array +var = varargin{1}; +if iscell(var) + hold on; + h = []; + for i = 1:length(var(:)) + h = [h; drawPolygon3d(var{i}, varargin{2:end})]; %#ok + end + if nargout > 0 + varargout{1} = h; + end + return; +end + +% extract curve coordinate +if size(var, 2) == 1 + % first argument contains x coord, second argument contains y coord + % and third one the z coord + px = var; + if length(varargin) < 3 + error('Wrong number of arguments in drawPolygon3d'); + end + py = varargin{2}; + pz = varargin{3}; + varargin = varargin(4:end); +else + % first argument contains both coordinate + px = var(:, 1); + py = var(:, 2); + pz = var(:, 3); + varargin = varargin(2:end); +end + + +%% draw the polygon + +% check that the polygon is closed +if px(1) ~= px(end) || py(1) ~= py(end) || pz(1) ~= pz(end) + px = [px; px(1)]; + py = [py; py(1)]; + pz = [pz; pz(1)]; +end + +% draw the closed curve +h = plot3(px, py, pz, varargin{:}); + +if nargout > 0 + varargout = {h}; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolyline3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolyline3d.m new file mode 100644 index 0000000..1fcbdb3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawPolyline3d.m @@ -0,0 +1,108 @@ +function varargout = drawPolyline3d(varargin) +%DRAWPOLYLINE3D Draw a 3D polyline specified by a list of vertices +% +% drawPolyline3d(POLY); +% packs coordinates in a single N-by-3 array. +% +% drawPolyline3d(PX, PY, PZ); +% specify coordinates in separate arrays. +% +% drawPolyline3d(..., CLOSED); +% Specifies if the polyline is closed or open. CLOSED can be one of: +% - 'closed' +% - 'open' (the default) +% - a boolean variable with value TRUE for closed polylines. +% +% drawPolyline3d(..., PARAM, VALUE); +% Specifies style options to draw the polyline, see plot for details. +% +% H = drawPolyline3d(...); +% also return a handle to the list of line objects. +% +% See Also: +% polygons3d, drawPolygon3d, fillPolygon3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2010-03-08 rename as drawPolyline3d + + +%% Process input arguments + +% check case we want to draw several curves, stored in a cell array +var = varargin{1}; +if iscell(var) + hold on; + h = []; + for i = 1:length(var(:)) + h = [h; drawPolyline3d(var{i}, varargin{2:end})]; %#ok + end + if nargout > 0 + varargout = {h}; + end + return; +end + +% extract curve coordinates +if size(var, 2) == 1 + % first argument contains x coord, second argument contains y coord + % and third one the z coord + px = var; + if length(varargin) < 3 + error('Wrong number of arguments in drawPolyline3d'); + end + py = varargin{2}; + pz = varargin{3}; + varargin = varargin(4:end); + +else + % all coordinates are grouped in the first argument + px = var(:, 1); + py = var(:, 2); + pz = var(:, 3); + varargin = varargin(2:end); +end + +% check if curve is closed or open (default is open) +closed = false; +if ~isempty(varargin) + var = varargin{1}; + if islogical(var) + % check boolean flag + closed = var; + varargin = varargin(2:end); + + elseif ischar(var) + % check string indicating close or open + if strncmpi(var, 'close', 5) + closed = true; + varargin = varargin(2:end); + + elseif strncmpi(var, 'open', 4) + closed = false; + varargin = varargin(2:end); + end + + end +end + + +%% draw the curve + +% for closed curve, add the first point at the end to close curve +if closed + px = [px; px(1)]; + py = [py; py(1)]; + pz = [pz; pz(1)]; +end + +h = plot3(px, py, pz, varargin{:}); + +if nargout > 0 + varargout = {h}; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphere.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphere.m new file mode 100644 index 0000000..0712620 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphere.m @@ -0,0 +1,157 @@ +function varargout = drawSphere(varargin) +%DRAWSPHERE Draw a sphere as a mesh +% +% drawSphere(SPHERE) +% Where SPHERE = [XC YC ZC R], draw the sphere centered on the point with +% coordinates [XC YC ZC] and with radius R, using a quad mesh. +% +% drawSphere(CENTER, R) +% Where CENTER = [XC YC ZC], specifies the center and the radius with two +% arguments. +% +% drawSphere(XC, YC, ZC, R) +% Specifiy sphere center and radius as four arguments. +% +% drawSphere(..., NAME, VALUE); +% Specifies one or several options using parameter name-value pairs. +% Available options are usual drawing options, as well as: +% 'nPhi' the number of arcs used for drawing the meridians +% 'nTheta' the number of circles used for drawing the parallels +% +% H = drawSphere(...) +% Return a handle to the graphical object created by the function. +% +% [X Y Z] = drawSphere(...) +% Return the coordinates of the vertices used by the sphere. In this +% case, the sphere is not drawn. +% +% Example +% % Draw four spheres with different centers +% figure(1); clf; hold on; +% drawSphere([10 10 30 5]); +% drawSphere([20 30 10 5]); +% drawSphere([30 30 30 5]); +% drawSphere([30 20 10 5]); +% view([-30 20]); axis equal; l = light; +% +% % Draw sphere with different settings +% figure(1); clf; +% drawSphere([10 20 30 10], 'linestyle', ':', 'facecolor', 'r'); +% axis([0 50 0 50 0 50]); axis equal; +% l = light; +% +% % The same, but changes style using graphic handle +% figure(1); clf; +% h = drawSphere([10 20 30 10]); +% set(h, 'linestyle', ':'); +% set(h, 'facecolor', 'r'); +% axis([0 50 0 50 0 50]); axis equal; +% l = light; +% +% % Draw a sphere with high resolution +% figure(1); clf; +% h = drawSphere([10 20 30 10], 'nPhi', 360, 'nTheta', 180); +% l = light; view(3); +% +% +% See also +% spheres, circles3d, sphere, drawEllipsoid +% +% --------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005 +% + +% HISTORY +% 2006-05-19 use centered sphere with radius 1 when no input specified +% 2007-01-04 typo +% 2010-11-08 code cleanup, add doc + + +% process input options: when a string is found, assumes this is the +% beginning of options +options = {'FaceColor', 'g', 'linestyle', 'none'}; +for i=1:length(varargin) + if ischar(varargin{i}) + options = [options(1:end) varargin(i:end)]; + varargin = varargin(1:i-1); + break; + end +end + +% Parse the input (try to extract center coordinates and radius) +if isempty(varargin) + % no input: assumes unit sphere + xc = 0; yc = 0; zc = 0; + r = 1; + +elseif length(varargin) == 1 + % one argument: concatenates center and radius + sphere = varargin{1}; + xc = sphere(:,1); + yc = sphere(:,2); + zc = sphere(:,3); + r = sphere(:,4); + +elseif length(varargin) == 2 + % two arguments, corresponding to center and radius + center = varargin{1}; + xc = center(1); + yc = center(2); + zc = center(3); + r = varargin{2}; + +elseif length(varargin) == 4 + % four arguments, corresponding to XC, YX, ZC and R + xc = varargin{1}; + yc = varargin{2}; + zc = varargin{3}; + r = varargin{4}; +else + error('drawSphere: please specify center and radius'); +end + +% number of meridians +nPhi = 32; +ind = strmatch('nphi', lower(options(1:2:end))); +if ~isempty(ind) + ind = ind(1); + nPhi = options{2*ind}; + options(2*ind-1:2*ind) = []; +end + +% number of parallels +nTheta = 16; +ind = strmatch('ntheta', lower(options(1:2:end))); +if ~isempty(ind) + ind = ind(1); + nTheta = options{2*ind}; + options(2*ind-1:2*ind) = []; +end + +% compute spherical coordinates +theta = linspace(0, pi, nTheta+1); +phi = linspace(0, 2*pi, nPhi+1); + +% convert to cartesian coordinates +sintheta = sin(theta); +x = xc + cos(phi')*sintheta*r; +y = yc + sin(phi')*sintheta*r; +z = zc + ones(length(phi),1)*cos(theta)*r; + +% Process output +if nargout == 0 + % no output: draw the sphere + surf(x, y, z, options{:}); + +elseif nargout == 1 + % one output: compute + varargout{1} = surf(x, y, z, options{:}); + +elseif nargout == 3 + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphericalTriangle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphericalTriangle.m new file mode 100644 index 0000000..899882d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSphericalTriangle.m @@ -0,0 +1,63 @@ +function varargout = drawSphericalTriangle(sphere, p1, p2, p3, varargin) +%DRAWSPHERICALTRIANGLE Draw a triangle on a sphere +% +% drawsphericaltriangle(SPHERE, PT1, PT2, PT3); +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 22/02/2005 +% + +% HISTORY +% 27/06/2007 manage spheres other than origin +% 30/10/2008 replace intersectPlaneLine by intersectLinePlane + +% extract data of the sphere +ori = sphere(:, 1:3); +r = sphere(4); + +% extract direction vectors for each point +v1 = normalizeVector3d(p1 - ori); +v2 = normalizeVector3d(p2 - ori); +v3 = normalizeVector3d(p3 - ori); + +% create a plane tangent to the sphere containing first point +plane = createPlane(v1, v1); + +% position on the plane of the direction vectors +pp2 = planePosition(intersectLinePlane([ori v2], plane), plane); +pp3 = planePosition(intersectLinePlane([ori v3], plane), plane); + +% create rough parametrization with 2 variables +s = 0:.2:1; +t = 0:.2:1; +ns = length(s); +nt = length(t); +s = repmat(s, [nt, 1]); +t = repmat(t', [1, ns]); + +% convert to plane coordinates +xp = s * pp2(1) + t .* (1-s) * pp3(1); +yp = s * pp2(2) + t .* (1-s) * pp3(2); + +% convert to 3D coordinates (still on the 3D plane) +x = plane(1) * ones(size(xp)) + plane(4) * xp + plane(7) * yp - ori(1); +y = plane(2) * ones(size(xp)) + plane(5) * xp + plane(8) * yp - ori(2); +z = plane(3) * ones(size(xp)) + plane(6) * xp + plane(9) * yp - ori(3); + +% project on the sphere +norm = hypot(hypot(x, y), z); +xn = x ./ norm * r + ori(1); +yn = y ./ norm * r + ori(2); +zn = z ./ norm * r + ori(3); + + +if nargout == 0 + surf(xn, yn, zn, 'FaceColor', 'g', 'EdgeColor', 'none', varargin{:}); +else + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSurfPatch.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSurfPatch.m new file mode 100644 index 0000000..60d093f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawSurfPatch.m @@ -0,0 +1,44 @@ +function drawSurfPatch(u, v, z, varargin) +%DRAWSURFPATCH Draw a 3D surface patch, with 2 parametrized surfaces +% +% usage: +% drawSurfPatch(u, v, zuv) +% where u, v, and zuv are three matrices the same size, u and +% corresponding to each parameter, and zuv being equal to a function of u +% and v. +% +% drawSurfPatch(u, v, zuv, p0) +% If p0 is specified, two lines with u(p0(1)) and v(p0(2)) are drawn on +% the surface, and corresponding tangent are also shown. +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 24/05/2005. +% + +% HISTORY +% 2005-06-08 add doc. +% 2007-01-04 remove unused variables and change function name +% 2010-03-08 code cleanup, use drawPolyline3d + +% prepare figure +hold on; + +% draw the surface interior +surf(u, v, z, 'FaceColor', 'g', 'EdgeColor', 'none'); + +% draw the surface boundaries +drawPolyline3d(u(1,:), v(1,:), z(1,:)) +drawPolyline3d(u(end,:), v(end,:), z(end,:)) +drawPolyline3d(u(:,end), v(:,end), z(:,end)) +drawPolyline3d(u(:,1), v(:,1), z(:,1)) + +% eventually draw two perpendicular lines on the surface +if ~isempty(varargin) + pos = varargin{1}; + drawPolyline3d(u(pos(1),:), v(pos(1),:), z(pos(1),:)); + drawPolyline3d(u(:,pos(2)), v(:,pos(2)), z(:,pos(2))); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawTorus.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawTorus.m new file mode 100644 index 0000000..b405d10 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawTorus.m @@ -0,0 +1,49 @@ +function varargout = drawTorus(torus, varargin) +%DRAWTORUS Draw a torus (3D ring) +% +% drawTorus(TORUS) +% Draws the torus on the current axis. TORUS is given by +% [XC YC ZY R1 R2 THETA PHI] +% where (XC YZ ZC) is the center of the torus, R1 is the main radius, R2 +% is the radius of the torus section, and (THETA PHI) is the angle of the +% torus normal vector (both in degrees). +% +% Example +% figure; +% drawTorus([50 50 50 30 10 30 45]); +% axis equal; +% +% See also +% drawEllipsoid, revolutionSurface +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +center = torus(1:3); +r1 = torus(4); +r2 = torus(5); + +if size(torus, 2) >= 7 + normal = torus(6:7); +end + +% default drawing options +varargin = [{'FaceColor', 'g'}, varargin]; + +% create base torus +circle = circleAsPolygon([r1 0 r2], 60); +[x y z] = revolutionSurface(circle, linspace(0, 2*pi, 60)); + +% transform torus +trans = localToGlobal3d([center normal]); +[x y z] = transformPoint3d(x, y, z, trans); + +% draw the surface +hs = surf(x, y, z, varargin{:}); + +if nargout > 0 + varargout = {hs}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawVector3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawVector3d.m new file mode 100644 index 0000000..ff5f060 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/drawVector3d.m @@ -0,0 +1,28 @@ +function varargout = drawVector3d(pos, vect, varargin) +%DRAWVECTOR3D Draw vector at a given position +% +% drawVector3d(POS, VECT) +% +% Example +% figure; hold on; +% drawVector3d([2 3 4], [1 0 0]); +% drawVector3d([2 3 4], [0 1 0]); +% drawVector3d([2 3 4], [0 0 1]); +% view(3); +% +% See also +% quiver3 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-19, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +h = quiver3(pos(:, 1), pos(:, 2), pos(:, 3), ... + vect(:, 1), vect(:, 2), vect(:, 3), varargin{:}); + +% format output +if nargout > 0 + varargout{1} = h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/eulerAnglesToRotation3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/eulerAnglesToRotation3d.m new file mode 100644 index 0000000..c507bcf --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/eulerAnglesToRotation3d.m @@ -0,0 +1,66 @@ +function mat = eulerAnglesToRotation3d(phi, theta, psi, varargin) +%EULERANGLESTOROTATION3D Convert 3D Euler angles to 3D rotation matrix +% +% MAT = eulerAnglesToRotation3d(PHI, THETA, PSI) +% Creates a rotation matrix from the 3 euler angles PHI THETA and PSI, +% given in degrees, using the 'XYZ' convention (local basis), or the +% 'ZYX' convention (global basis). The result MAT is a 4-by-4 rotation +% matrix in homogeneous coordinates. +% +% PHI: rotation angle around Z-axis, in degrees, corresponding to the +% 'Yaw'. PHI is between -180 and +180. +% THETA: rotation angle around Y-axis, in degrees, corresponding to the +% 'Pitch'. THETA is between -90 and +90. +% PSI: rotation angle around X-axis, in degrees, corresponding to the +% 'Roll'. PSI is between -180 and +180. +% These angles correspond to the "Yaw-Pitch-Roll" convention, also known +% as "Tait–Bryan angles". +% +% The resulting rotation is equivalent to a rotation around X-axis by an +% angle PSI, followed by a rotation around the Y-axis by an angle THETA, +% followed by a rotation around the Z-axis by an angle PHI. +% That is: +% ROT = Rz * Ry * Rx; +% +% MAT = eulerAnglesToRotation3d(ANGLES) +% Concatenates all angles in a single 1-by-3 array. +% +% Example +% [n e f] = createCube; +% phi = 20; +% theta = 30; +% psi = 10; +% rot = eulerAnglesToRotation3d(phi, theta, psi); +% n2 = transformPoint3d(n, rot); +% drawPolyhedron(n2, f); +% +% See also +% transforms3d, createRotationOx, createRotationOy, createRotationOz +% rotation3dAxisAndAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2011-06-20 rename and use degrees + + +% Process input arguments +if size(phi, 2) == 3 + % manages arguments given as one array + theta = phi(:, 2); + psi = phi(:, 3); + phi = phi(:, 1); +end + +% create individual rotation matrices +k = pi / 180; +rotX = createRotationOx(psi * k); +rotY = createRotationOy(theta * k); +rotZ = createRotationOz(phi * k); + +% concatenate matrices +mat = rotZ * rotY * rotX; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/fillPolygon3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/fillPolygon3d.m new file mode 100644 index 0000000..b6cc6a9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/fillPolygon3d.m @@ -0,0 +1,80 @@ +function varargout = fillPolygon3d(varargin) +%FILLPOLYGON3D Fill a 3D polygon specified by a list of points +% +% fillPolygon3d(COORD, COLOR) +% packs coordinates in a single [N*3] array. +% COORD can also be a cell array of polygon, in this case each polygon is +% drawn using the same color. +% +% fillPolygon3d(PX, PY, PZ, COLOR) +% specify coordinates in separate arrays. +% +% fillPolygon3d(..., PARAM, VALUE) +% allow to specify some drawing parameter/value pairs as for the plot +% function. +% +% H = fillPolygon3d(...) also return a handle to the list of line objects. +% +% See Also: +% polygons3d, drawPolygon, drawPolyline3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-01-05 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +% check case we want to draw several curves, stored in a cell array +var = varargin{1}; +if iscell(var) + hold on; + h = []; + for i=1:length(var(:)) + h = [h; fillPolygon3d(var{i}, varargin{2:end})]; + end + if nargout>0 + varargout{1}=h; + end + return; +end + +% extract curve coordinate +if size(var, 2)==1 + % first argument contains x coord, second argument contains y coord + % and third one the z coord + px = var; + if length(varargin)<3 + error('Wrong number of arguments in fillPolygon3d'); + end + py = varargin{2}; + pz = varargin{3}; + varargin = varargin(4:end); +else + % first argument contains both coordinate + px = var(:, 1); + py = var(:, 2); + pz = var(:, 3); + varargin = varargin(2:end); +end + +% extract color information +if isempty(varargin) + color = 'c'; +else + color = varargin{1}; + varargin = varargin(2:end); +end + +% ensure polygon is closed +px = [px; px(1)]; +py = [py; py(1)]; +pz = [pz; pz(1)]; + +% fill the polygon +h = fill3(px, py, pz, color, varargin{:}); + +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/inertiaEllipsoid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/inertiaEllipsoid.m new file mode 100644 index 0000000..172d8a4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/inertiaEllipsoid.m @@ -0,0 +1,55 @@ +function ell = inertiaEllipsoid(points) +%INERTIAELLIPSOID Inertia ellipsoid of a set of 3D points +% +% ELL = inertiaEllipsoid(PTS) +% Compute the inertia ellipsoid of the set of points PTS. The result is +% an ellispoid defined by: +% ELL = [XC YC ZC A B C PHI THETA PSI] +% where [XC YC ZY] is the centern [A B C] are length of semi-axes (in +% decreasing order), and [PHI THETA PSI] are euler angles representing +% the ellipsoid orientation, in degrees. +% +% Example +% inertiaEllipsoid +% +% See also +% spheres, drawEllipsoid, inertiaEllipse +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-03-12, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% number of points +n = size(points, 1); + +% compute centroid +center = mean(points); + +% compute the covariance matrix +covPts = cov(points)/n; + +% perform a principal component analysis with 2 variables, +% to extract inertia axes +[U S] = svd(covPts); + +% extract length of each semi axis +radii = 2 * sqrt(diag(S)*n)'; + +% sort axes from greater to lower +[radii ind] = sort(radii, 'descend'); + +% format U to ensure first axis points to positive x direction +U = U(ind, :); +if U(1,1) < 0 + U = -U; + % keep matrix determinant positive + U(:,3) = -U(:,3); +end + +% convert axes rotation matrix to Euler angles +angles = rotation3dToEulerAngles(U); + +% concatenate result to form an ellipsoid object +ell = [center radii angles]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectBoxes3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectBoxes3d.m new file mode 100644 index 0000000..deef95c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectBoxes3d.m @@ -0,0 +1,38 @@ +function box = intersectBoxes3d(box1, box2) +%INTERSECTBOXES3D Intersection of two 3D bounding boxes +% +% RES = intersectBoxes3d(BOX1, BOX2) +% +% Example +% box1 = [5 20 5 30 10 50]; +% box2 = [0 15 0 15 0 20]; +% intersectBoxes3d(box1, box2) +% ans = +% 5 15 5 15 10 20 +% +% See also +% boxes3d, drawBox3d, mergeBoxes3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% unify sizes of data +if size(box1,1) == 1 + box1 = repmat(box1, size(box2,1), 1); +elseif size(box2, 1) == 1 + box2 = repmat(box2, size(box1,1), 1); +elseif size(box1,1) ~= size(box2,1) + error('Bad size for inputs'); +end + +% compute extreme coords +mini = min(box1(:,2:2:end), box2(:,2:2:end)); +maxi = max(box1(:,1:2:end), box2(:,1:2:end)); + +% concatenate result into a new box structure +box = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2) maxi(:,3) mini(:,3)]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectEdgePlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectEdgePlane.m new file mode 100644 index 0000000..d28cc0f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectEdgePlane.m @@ -0,0 +1,86 @@ +function point = intersectEdgePlane(edge, plane, varargin) +%INTERSECTEDGEPLANE Return intersection point between a plane and a edge +% +% PT = intersectEdgePlane(edge, PLANE) return the intersection point of +% the given edge and the given plane. +% PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% edge : [x1 y1 z1 x2 y2 z2] +% PT : [xi yi zi] +% If EDGE and PLANE are parallel, return [NaN NaN NaN]. +% If EDGE (or PLANE) is a matrix with 6 (or 9) columns and N rows, result +% is an array of points with N rows and 3 columns. +% +% Example: +% edge = [5 5 -1 5 5 1]; +% plane = [0 0 0 1 0 0 0 1 0]; +% intersectEdgePlane(edge, plane) % should return [5 5 0]. +% ans = +% 5 5 0 +% +% See Also: +% planes3d, intersectLinePlane, createLine3d, createPlane +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 24/04/2007 from intersectLinePlane. +% + +% HISTORY +% +% 17/06/2011 E. J. Payton - fixed indexing error that caused incorrect +% points to be returned + +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +np = size(plane, 1); +ne = size(edge, 1); + +% unify sizes of data +if np ~= ne + if ne == 1; + % one edge and many planes + edge = edge(ones(np, 1), :); + elseif np == 1 + % one plane possible many edges + plane = plane(ones(ne, 1), :); + else + % N planes and M edges, not allowed for now. + error('Should have the same number of planes and edges'); + end +end + +% initialize empty arrays +point = zeros(size(plane, 1), 3); +t = zeros(size(plane,1),3); + +% plane normal +n = cross(plane(:,4:6), plane(:,7:9), 2); + +% create line supporting edge +line = createLine3d(edge(:,1:3), edge(:,4:6)); + +% get indices of edge and plane which are parallel +par = abs(dot(n, line(:,4:6), 2)) < tol; +point(par,:) = NaN; +t(par) = NaN; + +% difference between origins of plane and edge +dp = plane(:, 1:3) - line(:, 1:3); + +% relative position of intersection on line +%t = dot(n(~par,:), dp(~par,:), 2)./dot(n(~par,:), line(~par,4:6), 2); +t(~par) = dot(n(~par,:), dp(~par,:), 2) ./ dot(n(~par,:), line(~par,4:6), 2); + +% compute coord of intersection point +%point(~par, :) = line(~par,1:3) + repmat(t,1,3).*line(~par,4:6); +point(~par, :) = line(~par,1:3) + repmat(t(~par),1,3) .* line(~par,4:6); + +% set points outside of edge to [NaN NaN NaN] +point(t<0, :) = NaN; +point(t>1, :) = NaN; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineCylinder.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineCylinder.m new file mode 100644 index 0000000..3e61da3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineCylinder.m @@ -0,0 +1,150 @@ +function points = intersectLineCylinder(line, cylinder, varargin) +%INTERSECTLINECYLINDER Compute intersection points between a line and a cylinder +% +% POINTS = intersectLineCylinder(LINE, CYLINDER) +% Returns intersection points between a line and a cylinder. +% +% Input parameters: +% LINE = [x0 y0 z0 dx dy dz] +% CYLINDER = [x1 y1 z1 x2 y2 z2 R] +% +% Output: +% POINTS = [x1 y1 z1 ; x2 y2 z2] +% +% POINTS = intersectLineCylinder(LINE, CYLINDER, 'checkBounds', B) +% Where B is a boolean (TRUE by default), check if the points are within +% the bounds defined by the two extreme points. If B is false, the +% cylinder is considered as infinite. +% +% Example +% % Compute intersection between simple cylinder and line +% line = [60 60 60 1 2 3]; +% cylinder = [20 50 50 80 50 50 30]; +% points = intersectLineCylinder(line, cylinder); +% % Display the different shapes +% figure; +% drawCylinder(cylinder); +% hold on; light; +% axis([0 100 0 100 0 100]); +% drawLine3d(line); +% drawPoint3d(points, 'ko'); +% +% +% % Compute intersections when one of the points is outside the +% % cylinder +% line = [80 60 60 1 2 3]; +% cylinder = [20 50 50 80 50 50 30]; +% intersectLineCylinder(line, cylinder) +% ans = +% 67.8690 35.7380 23.6069 +% +% +% See also +% lines3d, intersectLinePlane +% +% References +% See the link: +% http://www.gamedev.net/community/forums/topic.asp?topic_id=467789 +% +% --- +% Author: David Legland, from a file written by Daniel Trauth (RWTH) +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-27 + +% HISTORY +% 2010-10-21 change cylinder argument convention, add bounds check and doc +% 2010-10-21 add check for points on cylinders, update doc + + +%% Parse input arguments + +% default arguments +checkBounds = true; + +% parse inputs +while length(varargin)>1 + var = varargin{1}; + if strcmpi(var, 'checkbounds') + checkBounds = varargin{2}; + else + error(['Unkown argument: ' var]); + end + varargin(1:2) = []; +end + + +%% Parse cylinder parameters + +% Starting point of the line +l0 = line(1:3)'; + +% Direction vector of the line +dl = line(4:6)'; + +% Starting position of the cylinder +c0 = cylinder(1:3)'; + +% Direction vector of the cylinder +dc = cylinder(4:6)' - c0; + +% Radius of the cylinder +r = cylinder(7); + + +%% Resolution of a quadratic equation to find the increment + +% Substitution of parameters +e = dl - (dot(dl,dc)/dot(dc,dc))*dc; +f = (l0-c0) - (dot(l0-c0,dc)/dot(dc,dc))*dc; + +% Coefficients of 2-nd order equation +A = dot(e, e); +B = 2*dot(e,f); +C = dot(f,f) - r^2; + +% compute discriminant +delta = B^2 - 4*A*C; + +% check existence of solution(s) +if delta<0 + points = zeros(0, 3); + return; +end + +% extract roots +x1 = (-B + sqrt(delta))/(2*A); +x2 = (-B - sqrt(delta))/(2*A); +x = [x1;x2]; + + +%% Estimation of points position + +% process the smallest position +x1 = min((x)); + +% Point on the line: l0 + x*dl = p +point1 = l0 + x1*dl; + +% process the greatest position +x2 = max((x)); + +% Point on the line: l0 + x*dl = p +point2 = l0 + x2*dl; + +% Format result +points = [point1' ; point2']; + + +%% Check if points are located between bounds + +if checkBounds + % cylinder axis + axis = [c0' dc']; + + % compute position on axis + ts = linePosition3d(points, axis); + + % check bounds + ind = ts>=0 & ts<=1; + points = points(ind, :); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePlane.m new file mode 100644 index 0000000..cf6f84e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePlane.m @@ -0,0 +1,54 @@ +function point = intersectLinePlane(line, plane) +%INTERSECTLINEPLANE Intersection point between a 3D line and a plane +% +% PT = intersectLinePlane(LINE, PLANE) +% Returns the intersection point of the given line and the given plane. +% LINE: [x0 y0 z0 dx dy dz] +% PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% PT: [xi yi zi] +% If LINE and PLANE are parallel, return [NaN NaN NaN]. +% If LINE (or PLANE) is a matrix with 6 (or 9) columns and N rows, result +% is an array of points with N rows and 3 columns. +% +% See also: +% lines3d, planes3d, points3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 24/11/2005 add support for multiple input +% 23/06/2006 correction from Songbai Ji +% 14/12/2006 correction for parallel lines and plane normals +% 05/01/2007 fixup for parallel lines and plane normals +% 24/04/2007 rename as 'intersectLinePlane' +% 11/19/2010 Added bsxfun functionality for improved speed (Sven Holcombe) + +% Songbai Ji (6/23/2006). Bug fixed; also allow one plane, many lines; +% many planes one line; or N planes and N lines configuration in the input. + +% unify sizes of data +plCnt = size(plane,1); +lnCnt = size(line,1); +if plCnt>1 && lnCnt>1 && plCnt~=lnCnt % N planes and M lines, not allowed for now. + error('input size not correct, either one/many plane and many/one line, or same # of planes and lines!'); +end + +% plane normal +n = vectorCross3d(plane(:,4:6), plane(:,7:9)); + +% difference between origins of plane and line +dp = bsxfun(@minus, plane(:, 1:3), line(:, 1:3)); + +% relative position of intersection on line +t = sum(bsxfun(@times,n,dp),2) ./ sum(bsxfun(@times,n,line(:,4:6)),2); + +% compute coord of intersection point +point = bsxfun(@plus, line(:,1:3), bsxfun(@times, [t t t], line(:,4:6))); + +% set indices of line and plane which are parallel to NaN +par = abs( sum(bsxfun(@times, n, line(:,4:6)), 2) ) < 1e-14; +point(par,:) = NaN; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePolygon3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePolygon3d.m new file mode 100644 index 0000000..4e4a412 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLinePolygon3d.m @@ -0,0 +1,60 @@ +function [inter inside]= intersectLinePolygon3d(line, poly) +%INTERSECTLINEPOLYGON3D Intersection point of a 3D line and a 3D polygon +% +% INTER = intersectLinePolygon3d(LINE, POLY) +% Compute coordinates of intersection point between the 3D line LINE and +% the 3D polygon POLY. LINE is a 1-by-6 row vector containing origin and +% direction vector of the line, POLY is a Np-by-3 array containing +% coordinates of 3D polygon vertices. +% INTER is a 1-by-3 row vector containing coordinates of intersection +% point, or [NaN NaN NaN] if line and polygon do not intersect. +% +% INTERS = intersectLinePolygon3d(LINES, POLY) +% If LINES is a N-by-6 array representing several lines, the result +% INTERS is a N-by-3 array containing coordinates of intersection of each +% line with the polygon. +% +% [INTER INSIDE] = intersectLinePolygon3d(LINE, POLY) +% Also return a N-by-1 boolean array containing TRUE if the corresponding +% polygon contains the intersection point. +% +% Example +% % Compute intersection between a 3D line and a 3D triangle +% pts3d = [3 0 0; 0 6 0;0 0 9]; +% line1 = [0 0 0 3 6 9]; +% inter = intersectLinePolygon3d(line1, pts3d) +% inter = +% 1 2 3 +% +% % keep only valid intersections with several lines +% pts3d = [3 0 0; 0 6 0;0 0 9]; +% lines = [0 0 0 1 2 3;10 0 0 1 2 3]; +% [inter inside] = intersectLinePolygon3d(line1, pts3d); +% inter(inside, :) +% ans = +% 1 2 3 +% +% See Also +% intersectLinePlane, intersectRayPolygon3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% supporting plane of polygon vertices +plane = createPlane(poly(1:3, :)); + +% intersection of 3D line with the plane +inter = intersectLinePlane(line, plane); + +% project all points on reference plane +pts2d = planePosition(poly, plane); +pInt2d = planePosition(inter, plane); + +% need to check polygon orientation +inside = xor(isPointInPolygon(pInt2d, pts2d), polygonArea(pts2d) < 0); + +% intersection points outside the polygon are set to NaN +inter(~inside, :) = NaN; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineSphere.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineSphere.m new file mode 100644 index 0000000..5165c20 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineSphere.m @@ -0,0 +1,57 @@ +function point = intersectLineSphere(line, sphere, varargin) +%INTERSECTLINESPHERE Return intersection points between a line and a sphere +% +% GC = intersectLineSphere(LINE, SPHERE); +% Returns the two points which are the intersection of the given line and +% sphere. +% LINE : [x0 y0 z0 dx dy dz] +% SPHERE : [xc yc zc R] +% GC : [x1 y1 z1 ; x2 y2 z2] +% +% See also +% spheres, circles3d, intersectPlaneSphere +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2011-06-21 bug for tangent lines, add tolerance + +% check if user-defined tolerance is given +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% difference between centers +dc = line(1:3) - sphere(1:3); + +% equation coefficients +a = sum(line(:, 4:6) .* line(:, 4:6), 2); +b = 2*sum(dc.*line(4:6), 2); +c = sum(dc.*dc, 2) - sphere(:,4).*sphere(:,4); + +% solve equation +delta = b.*b - 4*a.*c; + +if delta > tol + % delta positive: find two roots of second order equation + u1 = (-b -sqrt(delta)) / 2 / a; + u2 = (-b +sqrt(delta)) / 2 / a; + + % convert into 3D coordinate + point = [line(1:3)+u1*line(4:6) ; line(1:3)+u2*line(4:6)]; + +elseif abs(delta) < tol + % delta around zero: find unique root, and convert to 3D coord. + u = -b/2./a; + point = line(1:3) + u*line(4:6); + +else + % delta negative: no solution + point = ones(2, 3); + point(:) = NaN; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineTriangle3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineTriangle3d.m new file mode 100644 index 0000000..f95371d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectLineTriangle3d.m @@ -0,0 +1,139 @@ +function [point isInside pos] = intersectLineTriangle3d(line, triangle, varargin) +%INTERSECTLINETRIANGLE3D Intersection point of a 3D line and a 3D triangle +% +% POINT = intersectLineTriangle3d(LINE, TRI) +% Compute coordinates of the intersection point between the line LINE and +% the triangle TRI. +% LINE is a 1-by-6 row vector given as: [X0 Y0 Z0 DX DY DZ] +% TRI is given either as a row vector [X1 Y1 Z1 X2 Y2 Z2 X3 Y3 Z3], or as +% a 3-by-3 array, each row containing coordinates of one of the triangle +% vertices. +% The result is a 1-by-3 array containing coordinates of the intesection +% point, or [NaN NaN NaN] if the line and the triangle do not intersect. +% +% [POINT POS] = intersectLineTriangle3d(LINE, TRI) +% Also returns the position of the intersection point on the line, or NaN +% if the line and the supporting plane of the triangle are parallel. +% +% [POINT POS ISINSIDE] = intersectLineTriangle3d(LINE, TRI) +% Also returns a boolean value, set to true if the line and the triangle +% intersect each other. Can be used for testing validity of result. +% +% Example +% line = [1 1 0 0 0 1]; +% tri = [0 0 5;5 0 0;0 5 0]; +% intersectLineTriangle3d(line, tri) +% ans = +% 1 1 3 +% +% See also +% points3d, lines3d, polygons3d +% +% References +% Algorithm adapted from SoftSurfer Ray/Segment-Triangle intersection +% http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + + +%% Default values + +% default return value +point = [NaN NaN NaN]; +pos = NaN; +isInside = false; + +tol = 1e-13; +if ~isempty(varargin) + tol = varargin{1}; +end + + +%% Process inputs + +% triangle edge vectors +if size(triangle, 2) > 3 + % triangle is given as a 1-by-9 row vector + t0 = triangle(1:3); + u = triangle(4:6) - t0; + v = triangle(7:9) - t0; +else + % triangle is given as a 3-by-3 array + t0 = triangle(1, 1:3); + u = triangle(2, 1:3) - t0; + v = triangle(3, 1:3) - t0; +end + + +%% Compute intersection + +% triangle normal +n = cross(u, v); + +% test for degenerate case of flat triangle +if vectorNorm(n) < tol + return; +end + + +% line direction vector +dir = line(4:6); + +% vector between triangle origin and line origin +w0 = line(1:3) - t0; + +a = -dot(n, w0); +b = dot(n, dir); + +% test case of line parallel to the triangle +if abs(b) < tol + return; +end + +% compute intersection point of line with supporting plane +% If r < 0: point before ray +% IF r > 1: point after edge +pos = a / b; + +% coordinates of intersection point +point = line(1:3) + pos * dir; + + +%% test if intersection point is inside triangle + +% normalize direction vectors of triangle edges +uu = dot(u, u); +uv = dot(u, v); +vv = dot(v, v); + +% coordinates of vector v in triangle basis +w = point - t0; +wu = dot(w, u); +wv = dot(w, v); + +% normalization constant +D = uv^2 - uu * vv; + +% test first coordinate +s = (uv * wv - vv * wu) / D; +if s < 0.0 || s > 1.0 + point = [NaN NaN NaN]; + pos = NaN; + return; +end + +% test second coordinate, and third triangle edge +t = (uv * wu - uu * wv) / D; +if t < 0.0 || (s + t) > 1.0 + point = [NaN NaN NaN]; + pos = NaN; + return; +end + +% set the validity flag +isInside = true; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneLine.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneLine.m new file mode 100644 index 0000000..9c18513 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneLine.m @@ -0,0 +1,76 @@ +function point = intersectPlaneLine(plane, line) +%INTERSECTPLANELINE return intersection between a plane and a line +% +% PT = intersectPlaneLine(PLANE, LINE) return the intersection point of +% the given line and the given plane. +% PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% LINE : [x0 y0 z0 dx dy dz] +% PT : [xi yi zi] +% +% Note: deprecated. Replaced by function 'intersectLinePlane' +% +% Songbai Ji (6/23/2006). Bug fixed; also allow one plane, many lines; +% many planes one line; or N planes and N lines configuration in the input. +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 24/11/2005 add support for multiple input +% 23/06/2006 correction from Songbai Ji +% 14/12/2006 correction for parallel lines and plane normals +% 05/01/2007 fixup for parallel lines and plane normals +% 17/10/2008 add warning for deprecation + + +warning('IMAEL:deprecatedFunction', ... + 'This function is deprecated, use ''intersectLinePlane'' instead'); + + +% unify sizes of data +if size(plane, 1) == 1; % one plane possible many lines + plane = repmat(plane, size(line,1), 1); +elseif size(line,1) == 1; % one line and many planes + line = repmat(line, size(plane,1), 1); +elseif (size(plane,1) ~= size(line,1)) ; % N planes and M lines, not allowed for now. + error('input size not correct, either one/many plane and many/one line, or same # of planes and lines!'); +end + +% initialize empty array +point = zeros(size(plane, 1), 3); + +% plane normal +n = cross(plane(:,4:6), plane(:, 7:9), 2); + +% get indices of line and plane which are parallel +par = abs(dot(n, line(:,4:6), 2))<1e-14; +point(par,:) = NaN; +% old version: +% II = find(abs(dot(n, line(:,4:6), 2))<1e-14); +% if ~isempty(II) +% point(II,:) = [NaN NaN NaN]; +% end + +% difference between origins of plane and line +dp = plane(:,1:3) - line(:,1:3); + +% relative position of intersection on line +% Should be Array multiply, original file had a bug. (songbai ji +% 6/23/2006). +% Divide only for non parallel vectors (DL, +t = dot(n(~par,:), dp(~par,:), 2)./dot(n(~par,:), line(~par,4:6), 2); +%t = dot(n, dp, 2)./dot(n, line(:,4:6), 2); + + +% compute coord of intersection point +% point = line(:,1:3) + t*line(:,4:6); +% NOTE: original m file had a bug (in the above line). It should be +% corrected as follows. (Songbai Ji 6/23/2006). +%point = line(~par,1:3) + repmat(t,1,3).*line(~par,4:6); +%point = line(:,1:3) + repmat(t,1,3).*line(:,4:6); +point(~par, :) = line(~par,1:3) + repmat(t,1,3).*line(~par,4:6); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneSphere.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneSphere.m new file mode 100644 index 0000000..d5ff715 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlaneSphere.m @@ -0,0 +1,76 @@ +function circle = intersectPlaneSphere(plane, sphere) +%INTERSECTPLANESPHERE Return intersection circle between a plane and a sphere +% +% CIRC = intersectPlaneSphere(PLANE, SPHERE) +% Returns the circle which is the intersection of the given plane +% and sphere. +% PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% SPHERE : [XS YS ZS RS] +% CIRC : [XC YC ZC RC THETA PHI PSI] +% [x0 y0 z0] is the origin of the plane, [dx1 dy1 dz1] and [dx2 dy2 dz2] +% are two direction vectors, +% [XS YS ZS] are coordinates of the sphere center, RS is the sphere +% radius, +% [XC YC ZC] are coordinates of the circle center, RC is the radius of +% the circle, [THETA PHI] is the normal of the plane containing the +% circle (THETA being the colatitude, and PHI the azimut), and PSI is a +% rotation angle around the normal (equal to zero in this function, but +% kept for compatibility with other functions). All angles are given in +% degrees. +% +% See Also: +% planes3d, spheres, circles3d, intersectLinePlane, intersectLineSphere +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 27/06/2007: change output format of circle, add support for multiple +% data +% 2011-06-21 use degrees for angles + +% number of inputs of each type +Ns = size(sphere, 1); +Np = size(plane, 1); + +% unify data dimension +if Ns ~= Np + if Ns == 1 + sphere = sphere(ones(Np, 1), :); + elseif Np == 1 + plane = plane(ones(Ns, 1), :); + else + error('data should have same length, or one data should have length 1'); + end +end +% center of the spheres +center = sphere(:,1:3); + +% radius of spheres +if size(sphere, 2) == 4 + Rs = sphere(:,4); +else + % assume default radius equal to 1 + Rs = ones(size(sphere, 1), 1); +end + +% projection of sphere center on plane -> gives circle center +circle0 = projPointOnPlane(center, plane); + +% radius of circles +d = distancePoints3d(center, circle0); +Rc = sqrt(Rs.*Rs - d.*d); + +% normal of planes = normal of circles +nor = planeNormal(plane); + +% convert to angles +[theta phi] = cart2sph2(nor(:,1), nor(:,2), nor(:,3)); +psi = zeros(Np, 1); + +% create structure for circle +k = 180 / pi; +circle = [circle0 Rc [theta phi psi]*k]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlanes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlanes.m new file mode 100644 index 0000000..057f533 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectPlanes.m @@ -0,0 +1,51 @@ +function line = intersectPlanes(plane1, plane2) +%INTERSECTPLANES Return intersection line between 2 planes in space +% +% LINE = intersectPlanes(PLANE1, PLANE2) +% Returns the straight line belonging to both planes +% PLANE: [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% LINE: [x0 y0 z0 dx dy dz] +% +% See also: +% planes3d, lines3d, intersectLinePlane +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY + + +% plane normal +n1 = normalizeVector3d(cross(plane1(:,4:6), plane1(:, 7:9), 2)); +n2 = normalizeVector3d(cross(plane2(:,4:6), plane2(:, 7:9), 2)); + +% test if planes are parallel +if abs(cross(n1, n2, 2))<1e-14 + line = [NaN NaN NaN NaN NaN NaN]; + return; +end + +% Uses Hessian form, ie : N.p = d +% I this case, d can be found as : -N.p0, when N is normalized +d1 = dot(n1, plane1(:,1:3), 2); +d2 = dot(n2, plane2(:,1:3), 2); + +% compute dot products +dot1 = dot(n1, n1, 2); +dot2 = dot(n2, n2, 2); +dot12 = dot(n1, n2, 2); + +% intermediate computations +det = dot1*dot2 - dot12*dot12; +c1 = (d1*dot2 - d2*dot12)./det; +c2 = (d2*dot1 - d1*dot12)./det; + +% compute line origin and direction +p0 = c1*n1 + c2*n2; +dp = cross(n1, n2, 2); + +% concatenate result to form a new line +line = [p0 dp]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectRayPolygon3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectRayPolygon3d.m new file mode 100644 index 0000000..9d6bbe4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/intersectRayPolygon3d.m @@ -0,0 +1,62 @@ +function [inter inside]= intersectRayPolygon3d(ray, poly) +%INTERSECTRAYPOLYGON3D Intersection point of a 3D ray and a 3D polygon +% +% INTER = intersectRayPolygon3d(RAY, POLY) +% Compute coordinates of intersection point between the 3D ray RAY and +% the 3D polygon POLY. RAY is a 1-by-6 row vector containing origin and +% direction vector of the ray, POLY is a Np-by-3 array containing +% coordinates of 3D polygon vertices. +% INTER is a 1-by-3 row vector containing coordinates of intersection +% point, or [NaN NaN NaN] if ray and polygon do not intersect. +% +% INTERS = intersectRayPolygon3d(RAYS, POLY) +% If RAYS is a N-by-6 array representing several rays, the result +% INTERS is a N-by-3 array containing coordinates of intersection of each +% ray with the polygon. +% +% [INTER INSIDE] = intersectRayPolygon3d(RAY, POLY) +% Also return a N-by-1 boolean array containing TRUE if both the polygon +% and the corresponding ray contain the intersection point. +% +% Example +% % Compute intersection between a 3D ray and a 3D triangle +% pts3d = [3 0 0; 0 6 0;0 0 9]; +% ray1 = [0 0 0 3 6 9]; +% inter = intersectRayPolygon3d(ray1, pts3d) +% inter = +% 1 2 3 +% +% % keep only valid intersections with several rays +% pts3d = [3 0 0; 0 6 0;0 0 9]; +% rays = [0 0 0 3 6 9;10 0 0 1 2 3;3 6 9 3 6 9]; +% [inter inside] = intersectRayPolygon3d(rays, pts3d); +% inter(inside, :) +% ans = +% 1 2 3 +% +% See Also +% intersectLinePlane, intersectLinePolygon3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% supporting plane of polygon vertices +plane = createPlane(poly(1:3, :)); + +% intersection of 3D ray with the plane +inter = intersectLinePlane(ray, plane); + +% project all points on reference plane +pts2d = projPointOnPlane(poly, plane); +pInt2d = projPointOnPlane(inter, plane); + +% need to check polygon orientation +inPoly = xor(isPointInPolygon(pInt2d, pts2d), polygonArea(pInt2d) < 0); +onRay = linePosition3d(inter, ray) >= 0; +inside = inPoly & onRay; + +% intersection points outside the polygon are set to NaN +inter(~inside, :) = NaN; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isBelowPlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isBelowPlane.m new file mode 100644 index 0000000..7d7fd9a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isBelowPlane.m @@ -0,0 +1,42 @@ +function below = isBelowPlane(point, varargin) +%ISBELOWPLANE Test whether a point is below or above a plane +% +% BELOW = isBelowPlane(POINT, PLANE) +% where POINT is given as coordinate row vector [XP YP ZP], and PLANE is +% given as a row containing initial point and 2 direction vectors, +% return TRUE if POINT lie below PLANE. +% +% Example +% isBelowPlane([1 1 1], createPlane([1 2 3], [1 1 1])) +% ans = +% 1 +% isBelowPlane([3 3 3], createPlane([1 2 3], [1 1 1])) +% ans = +% 0 +% +% See also +% planes3d, points3d, linePosition3d, planePosition +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-05 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +if length(varargin)==1 + plane = varargin{1}; +elseif length(varargin)==2 + plane = createPlane(varargin{1}, varargin{2}); +end + +% ensure same dimension for parameters +if size(point, 1)==1 + point = repmat(point, [size(plane, 1) 1]); +end +if size(plane, 1)==1 + plane = repmat(plane, [size(point, 1) 1]); +end + +% compute position of point projected on 3D line corresponding to plane +% normal, and returns true for points locatd below the plane (pos<=0). +below = linePosition3d(point, [plane(:, 1:3) planeNormal(plane)]) <= 0; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isCoplanar.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isCoplanar.m new file mode 100644 index 0000000..a087f83 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isCoplanar.m @@ -0,0 +1,72 @@ +function copl = isCoplanar(x,y,z,tolerance) +%ISCOPLANAR Tests input points for coplanarity in 3-space. +% +% COPL = isCoplanar(X,Y,Z,TOLERANCE) takes input arguments x,y, and z as column vectors; +% TOLERANCE is optional. +% COPL = isCoplanar(x) takes an n x 3 input argument in the form [x1 y1 z1;x2 y2 z2;...;xn yn zn] +% +% The optional argument TOLERANCE allows for roundoff error; if each combination of four points is +% truly coplanar, the volume of the tetrahedron they define is zero. When computational round-off +% error is introduced, this volume can be close to, but not equal to zero. Setting the tolerance +% to a value greater than zero enables the algorithm to return a "correct" finding of coplanarity +% within the tolerance specified. +% +% EXAMPLES: iscoplanar([1 2 -2;-3 1 -14;-1 2 -6;1 -2 -8],eps) +% copl = iscoplanar([1 -3 -1 1]',[2 1 2 -2]',[-2 -14 -6 -8]') + +% +% Written by Brett Shoelson, Ph.D. +% brett.shoelson@joslin.harvard.edu +% +% Thanks to Roger Stafford, roger.ellie@mindspring.com for his dilligence +% in uncovering problems with my original code. +% +% Completed 6/10/01. +% Written and tested under MATLAB V6 (R12). +% Modified 2/10/04; now uses determinant discrimination, which is much +% faster (on the order of ten times) than previous way. Also, old version +% had a typo; should have (but didn't) compared ABSOLUTE VALUE of error +% +% 04/01/2007: clean up input processing (DL) + +if nargin == 0 + error('Requires at least one input argument.'); +elseif nargin == 1 + if size(x,2) == 3 + % Matrix of all x,y,z is input + allpoints = x; + tolerance = 0; + else + error('Invalid input.') + end +elseif nargin == 2 + if size(x,2) == 3 + % Matrix of all x,y,z is input + allpoints = x; + tolerance = y; + else + error('Invalid input.') + end +elseif nargin == 3 + % Compile a matrix of all x,y,z + allpoints = [x y z]; + tolerance = 0; +else + allpoints = [x y z]; +end + +if length(x)<=3 +% disp('Three or fewer points are necessarily coplanar.'); + copl=1; + return; +end + +%Compare all 4-tuples of point combinations; {P1:P4} are coplanar iff +%det([x1 y1 z1 1;x2 y2 z2 1;x3 y3 z3 1;x4 y4 z4 1])==0 +tmp = nchoosek(1:size(allpoints,1),4); +for ii = 1:size(tmp,1) + copl = abs(det([allpoints(tmp(ii, :), :) ones(4,1)])) <= tolerance; + if ~copl + break + end +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isParallel3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isParallel3d.m new file mode 100644 index 0000000..1060a82 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isParallel3d.m @@ -0,0 +1,45 @@ +function b = isParallel3d(v1, v2, varargin) +%ISPARALLEL3D Check parallelism of two 3D vectors +% +% B = isParallel3d(V1, V2) +% where V1 and V2 are 2 [1x3] arrays, returns 1 if the vectors are +% parallels, and 0 otherwise. +% +% Also works when V1 and V2 are two [Nx3] arrays with same number of +% rows. In this case, return a [Nx1] array containing 1 at the positions +% of parallel vectors. +% +% Also works when one of V1 or V2 is scalar and the other one is [Nx3] +% array, in this case return [Nx1] results. +% +% B = isPerpendicular3d(V1, V2, TOL) +% Specifies the absolute tolerance (default is 1e-14). +% +% Example +% isParallel3d([1 2 1], [2 4 2]) +% ans = +% 1 +% +% isParallel3d([1 2 1], [1 3 2]) +% ans = +% 0 +% +% See also +% vectors3d, isPerpendicular3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-04-25 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% 2011.03.20 fix bug for set of 3 vectors + +% check if tolerance is specified +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% compute +b = vectorNorm3d(vectorCross3d(v1, v2)) < tol; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isPerpendicular3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isPerpendicular3d.m new file mode 100644 index 0000000..edd5810 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/isPerpendicular3d.m @@ -0,0 +1,46 @@ +function b = isPerpendicular3d(v1, v2, varargin) +%ISPERPENDICULAR3D Check orthogonality of two 3D vectors +% +% B = isPerpendicular3d(V1, V2) +% where V1 and V2 are 2 [1x3] arrays, returns 1 if the vectors are +% orthogonal, and 0 otherwise. +% +% Also works when V1 and V2 are two [Nx3] arrays with same number of +% rows. In this case, return a [Nx1] array containing 1 at the positions +% of parallel vectors. +% +% Also works when one of V1 or V2 is scalar and the other one is [Nx3] +% array, in this case return [Nx1] results. +% +% B = isPerpendicular3d(V1, V2, TOL) +% Specifies the absolute tolerance (default is 1e-14). +% +% +% Example +% isPerpendicular3d([1 0 0], [0 1 0]) +% ans = +% 1 +% +% isPerpendicular3d([1 0 1], [1 0 0]) +% ans = +% 0 +% +% See also +% vectors3d, isParallel3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-04-25 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% 2011.03.20 add support for tolerance, fix computation + +% check if tolerance is specified +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% compute perpendicularity test +b = abs(sum(bsxfun(@times, v1, v2), 2)) < tol; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/linePosition3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/linePosition3d.m new file mode 100644 index 0000000..af1c8e1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/linePosition3d.m @@ -0,0 +1,41 @@ +function d = linePosition3d(point, line) +%LINEPOSITION3D Return the position of a 3D point on a 3D line +% +% L = linePosition3d(POINT, LINE) +% compute position of point POINT on the line LINE, relative to origin +% point and direction vector of the line. +% LINE has the form [x0 y0 z0 dx dy dy], +% POINT has the form [x y z], and is assumed to belong to line. +% If POINT does not belong to LINE, the position of its orthogonal +% projection is computed instead. +% +% L = linePosition3d(POINT, LINES) +% if LINES is an array of NL lines, return NL positions, corresponding to +% each line. +% +% L = linePosition3d(POINTS, LINE) +% if POINTS is an array of NP points, return NP positions, corresponding +% to each point. +% +% See also: +% lines3d, points3d, createLine3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY +% 05/01/2007 update doc +% 28/10/2010 change to bsxfun calculation for arbitrary input sizes +% (Thanks to Sven Holcombe) + +% vector from line origin to point +dp = bsxfun(@minus, point, line(:,1:3)); + +% direction vector of the line +dl = line(:, 4:6); + +% compute position using dot product normalized with norm of line vector. +d = bsxfun(@rdivide, sum(bsxfun(@times, dp, dl), 2), sum(dl.^2, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/lines3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/lines3d.m new file mode 100644 index 0000000..e11aa03 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/lines3d.m @@ -0,0 +1,16 @@ +function lines3d(varargin) +%LINES3D Description of functions operating on 3D lines +% +% A 3D Line is represented by a 3D point (its origin) and a 3D vector +% (its direction): +% LINE = [X0 Y0 Z0 DX DY DZ]; +% +% See also: +% createLine3d, transformLine3d, distancePointLine3d, linePosition3d +% intersectLinePlane, distanceLines3d, clipLine3d, drawLine3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/medianPlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/medianPlane.m new file mode 100644 index 0000000..f172c0f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/medianPlane.m @@ -0,0 +1,39 @@ +function plane = medianPlane(p1, p2) +%MEDIANPLANE Create a plane in the middle of 2 points +% +% PLANE = medianPlane(P1, P2) +% Creates a plane in the middle of 2 points. +% PLANE is perpendicular to line (P1 P2) and contains the midpoint of P1 +% and P2. +% The direction of the normal of PLANE is the same as the vector from P1 +% to P2. +% +% See also: +% planes3d, createPlane +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 28/06/2007: add doc, and manage multiple inputs + +% unify data dimension +if size(p1, 1)==1 + p1 = repmat(p1, [size(p2, 1) 1]); +elseif size(p2, 1)==1 + p2 = repmat(p2, [size(p1, 1) 1]); +elseif size(p1, 1)~=size(p2, 1) + error('data should have same length, or one data should have length 1'); +end + +% middle point +p0 = (p1 + p2)/2; + +% normal to plane +n = p2-p1; + +% create plane from point and normal +plane = createPlane(p0, n); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/mergeBoxes3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/mergeBoxes3d.m new file mode 100644 index 0000000..079ff42 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/mergeBoxes3d.m @@ -0,0 +1,39 @@ +function box = mergeBoxes3d(box1, box2) +%MERGEBOXES3D Merge 3D boxes, by computing their greatest extent +% +% BOX = mergeBoxes3d(BOX1, BOX2); +% +% Example +% box1 = [5 20 5 30 10 50]; +% box2 = [0 15 0 15 0 20]; +% mergeBoxes3d(box1, box2) +% ans = +% 0 20 0 30 0 50 +% +% +% See also +% boxes3d, drawBox3d, intersectBoxes3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% unify sizes of data +if size(box1,1) == 1 + box1 = repmat(box1, size(box2,1), 1); +elseif size(box2, 1) == 1 + box2 = repmat(box2, size(box1,1), 1); +elseif size(box1,1) ~= size(box2,1) + error('Bad size for inputs'); +end + +% compute extreme coords +mini = min(box1(:,1:2:end), box2(:,1:2:end)); +maxi = max(box1(:,2:2:end), box2(:,2:2:end)); + +% concatenate result into a new box structure +box = [mini(:,1) maxi(:,1) mini(:,2) maxi(:,2) mini(:,3) maxi(:,3)]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/midPoint3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/midPoint3d.m new file mode 100644 index 0000000..f1f3c66 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/midPoint3d.m @@ -0,0 +1,82 @@ +function varargout = midPoint3d(varargin) +%MIDPOINT3D Middle point of two 3D points or of a 3D edge +% +% MID = midPoint3d(P1, P2) +% Compute the middle point of the two points P1 and P2. +% +% MID = midPoint3d(EDGE) +% Compute the middle point of the edge given by EDGE. +% EDGE has the format: [X1 Y1 Z1 X2 Y2 Z2], and MID has the format +% [XMID YMID ZMID], +% with XMID = (X1+X2)/2, YMID = (Y1+Y2)/2 and ZMID = (Z1+Z2)/2. +% +% [MIDX MIDY] = midPoint3d(...) +% Return the result as two separate variables or arrays. +% +% Works also when EDGE is a N-by-6 array, in this case the result is a +% N-by-3 array containing the midPoint3d of each edge. +% +% +% Example +% P1 = [10 20 30]; +% P2 = [30 40 50]; +% % edge input +% midPoint3d([P1 P2]) +% ans = +% 20 30 40 +% +% % two points input +% midPoint3d(P1, P2) +% ans = +% 20 30 40 +% +% % three outputs +% [xm ym zm] = midPoint3d(P1, P2) +% xm = +% 20 +% ym = +% 30 +% zm = +% 40 +% +% See also +% edges3d, points3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-08-08, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +if nargin == 1 + % input is a 3D edge + edge = varargin{1}; + mid = [mean(edge(:, [1 4]), 2) mean(edge(:, [2 5]), 2) mean(edge(:, [3 6]), 2)]; + +elseif nargin == 2 + % input are two points + p1 = varargin{1}; + p2 = varargin{2}; + + % assert inputs are equal + n1 = size(p1, 1); + n2 = size(p2, 1); + if n1>1 && n2==1 + p2 = repmat(p2, n1, 1); + elseif n2>1 && n1==1 + p1 = repmat(p1, n2, 1); + elseif n1~=n2 + error('geom3d:midPoint3d', ... + 'Inputs must have same size, or one must have length 1'); + end + + % compute middle point + mid = (p1 + p2) / 2; +end + +% process output arguments +if nargout<=1 + varargout{1} = mid; +else + varargout = {mid(:,1), mid(:,2), mid(:,3)}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalize3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalize3d.m new file mode 100644 index 0000000..202bec0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalize3d.m @@ -0,0 +1,29 @@ +function vn = normalize3d(v) +%NORMALIZE3D normalize a 3D vector +% +% V2 = normalize3d(V); +% Returns the normalization of vector V, such that ||V|| = 1. Vector V is +% given as a row vector. +% +% When V is a Nx3 array, normalization is performed for each row of the +% array. +% +% See also: +% vectors3d, vecnorm3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/11/2004. +% + +% HISTORY +% 30/11/2005 correct a bug +% 19/06/2009 deprecate and replace by normalizeVector3d + +% deprecation warning +warning('geom3d:deprecated', ... + '''normalize3d'' is deprecated, use ''normalizeVector3d'' instead'); + +n = sqrt(v(:,1).*v(:,1) + v(:,2).*v(:,2) + v(:,3).*v(:,3)); +vn = v./[n n n]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizePlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizePlane.m new file mode 100644 index 0000000..574ec2a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizePlane.m @@ -0,0 +1,40 @@ +function plane2 = normalizePlane(plane1) +%NORMALIZEPLANE Normalize parametric representation of a plane +% +% PLANE2 = normalizePlane(PLANE1); +% Transforms the plane PLANE1 in the following format: +% [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where: +% - (X0, Y0, Z0) is a point belonging to the plane +% - (DX1, DY1, DZ1) is a first direction vector +% - (DX2, DY2, DZ2) is a second direction vector +% into another plane, with the same format, but with: +% - (x0 y0 z0) is the closest point of plane to the origin +% - (DX1 DY1 DZ1) has norm equal to 1 +% - (DX2 DY2 DZ2) has norm equal to 1 and is orthogonal to (DX1 DY1 DZ1) +% +% See also: +% planes3d, createPlane +% +% --------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 21/08/2009 compute origin after computation of vectors (more precise) +% and add support for several planes. + +% compute first direction vector +d1 = normalizeVector3d(plane1(:,4:6)); + +% compute second direction vector +n = normalizeVector3d(planeNormal(plane1)); +d2 = -normalizeVector3d(cross(d1, n)); + +% compute origin point of the plane +origins = repmat([0 0 0], [size(plane1, 1) 1]); +p0 = projPointOnPlane(origins, [plane1(:,1:3) d1 d2]); + +% create the resulting plane +plane2 = [p0 d1 d2]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizeVector3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizeVector3d.m new file mode 100644 index 0000000..979e814 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/normalizeVector3d.m @@ -0,0 +1,25 @@ +function vn = normalizeVector3d(v) +%NORMALIZEVECTOR3D Normalize a 3D vector to have norm equal to 1 +% +% V2 = normalizeVector3d(V); +% Returns the normalization of vector V, such that ||V|| = 1. Vector V is +% given as a row vector. +% +% If V is a N-by-3 array, normalization is performed for each row of the +% input array. +% +% See also: +% vectors3d, vectorNorm3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/11/2004. +% + +% HISTORY +% 2005-11-30 correct a bug +% 2009-06-19 rename as normalizeVector3d +% 2010-11-16 use bsxfun (Thanks to Sven Holcombe) + +vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2))); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planeNormal.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planeNormal.m new file mode 100644 index 0000000..d6152c1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planeNormal.m @@ -0,0 +1,22 @@ +function n = planeNormal(plane) +%PLANENORMAL Compute the normal to a plane +% +% N = planeNormal(PLANE) +% compute the normal of the given plane +% PLANE : [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% N : [dx dy dz] +% +% See also +% planes3d, createPlane +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/02/2005. +% + +% HISTORY + + +% plane normal +n = cross(plane(:,4:6), plane(:, 7:9), 2); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePoint.m new file mode 100644 index 0000000..9de850b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePoint.m @@ -0,0 +1,37 @@ +function coord = planePoint(plane, point) +%PLANEPOINT Compute 3D position of a point in a plane +% +% POINT = planePoint(PLANE, POS) +% PLANE is a 9 element row vector [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2] +% POS is the coordinate of a point in the plane basis, +% POINT is the 3D coordinate in global basis. +% +% Example +% planePoint +% +% See also +% planes3d, planePosition +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-09-18, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% adapt size of input arguments +npl = size(plane, 1); +npt = size(point, 1); +if npl~=npt + if npl==1 + plane = repmat(plane, npt, 1); + elseif npt==1 + point = repmat(point, npl, 1); + else + error('plane and point should have same size'); + end +end + +% compute 3D coordinate +coord = plane(:,1:3) + ... + plane(:,4:6).*repmat(point(:,1), 1, 3) + ... + plane(:,7:9).*repmat(point(:,2), 1, 3); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePosition.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePosition.m new file mode 100644 index 0000000..c2a5778 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planePosition.m @@ -0,0 +1,50 @@ +function pos = planePosition(point, plane) +%PLANEPOSITION Compute position of a point on a plane +% +% PT2 = planePosition(POINT, PLANE) +% POINT has format [X Y Z], and plane has format +% [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2], where : +% - (X0, Y0, Z0) is a point belonging to the plane +% - (DX1, DY1, DZ1) is a first direction vector +% - (DX2, DY2, DZ2) is a second direction vector +% +% Result PT2 has the form [XP YP], with [XP YP] coordinate of the point +% in the coordinate system of the plane. +% +% +% CAUTION: +% WORKS ONLY FOR PLANES WITH ORTHOGONAL DIRECTION VECTORS +% +% See also: +% planes3d, points3d, planePoint +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 24/11/2005 add support for multiple input + +% unify size of data +if size(point, 1)~=size(plane, 1) + if size(point, 1)==1 + point = repmat(point, [size(plane, 1) 1]); + elseif size(plane, 1)==1 + plane = repmat(plane, [size(point, 1) 1]); + else + error('point and plane do not have the same dimension'); + end +end + + +p0 = plane(:, 1:3); +d1 = plane(:, 4:6); +d2 = plane(:, 7:9); + +s = dot(point-p0, d1, 2) ./ vectorNorm3d(d1); +t = dot(point-p0, d2, 2) ./ vectorNorm3d(d2); + +pos = [s t]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planes3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planes3d.m new file mode 100644 index 0000000..0f149a8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/planes3d.m @@ -0,0 +1,21 @@ +function planes3d(varargin) +%PLANES3D Description of functions operating on 3D planes +% +% Planes are represented by a 3D point (the plane origin) and 2 direction +% vectors, which should not be colinear. +% PLANE = [X0 Y0 Z0 DX1 DY1 DZ1 DX2 DY2 DZ2]; +% +% See also +% createPlane, medianPlane, normalizePlane +% planeNormal, planePosition, dihedralAngle +% intersectPlanes, projPointOnPlane, isBelowPlane +% intersectLinePlane, intersectEdgePlane, distancePointPlane +% drawPlane3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +help('planes3d'); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/point3dBounds.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/point3dBounds.m new file mode 100644 index 0000000..af00e95 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/point3dBounds.m @@ -0,0 +1,33 @@ +function box = point3dBounds(points) +%POINT3DBOUNDS Bounding box of a set of 3D points +% +% BOX = point3dBounds(POINTS); +% POINTS is a N-by-3 array of points, each coordinate being given in a +% column. The result BOX contains extreme coordinates in the form: +% BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. +% +% +% Example +% % compute bounding box of a cubeoctehedron +% [n e f] = createCubeOctahedron; +% box = point3dBounds(n) +% box = +% -1 1 -1 1 -1 1 +% +% +% See also +% points3d, boxes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% comput extreme coords +mini = min(points, [], 1); +maxi = max(points, [], 1); + +% format to obtain have box format +box = [mini ; maxi]; +box = box(:)'; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/points3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/points3d.m new file mode 100644 index 0000000..bb1545f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/points3d.m @@ -0,0 +1,20 @@ +function points3d(varargin) +%POINTS3D Description of functions operating on 3D points +% +% Points are represented by their 3 Cartesian coordinates: +% P = [X Y Z]; +% +% Arrays of points consist in N*3 arrays, each row being a point. +% +% See also +% isCoplanar, distancePoints +% anglePoints3d, angleSort3d, sphericalAngle +% sph2cart2, cart2sph2, cart2cyl, cyl2cart +% transformPoint3d, clipPoints3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygon3dNormalAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygon3dNormalAngle.m new file mode 100644 index 0000000..8c0f3c6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygon3dNormalAngle.m @@ -0,0 +1,55 @@ +function theta = polygon3dNormalAngle(points, ind) +%POLYGON3DNORMALANGLE Normal angle at a vertex of the 3D polygon +% +% THETA = polygon3DNormalAngle(POLYGON, IND) +% where POLYGON is a set of points, and IND is index of a point in +% polygon. The function compute the angle of the normal cone localized at +% this vertex. +% If IND is a vector of indices, normal angle is computed for each vertex +% specified by IND. +% +% Example +% % create an equilateral triangle in space +% poly3d = [1 1 0;-1 0 1;0 -1 -1]; +% % compute each normal angle +% theta = polygon3dNormalAngle(poly3d, 1:size(poly3d, 1)); +% % sum of normal angles must be equal to 2*PI for simple polygons +% sum(theta) +% +% IMPORTANT NOTE: works only for convex angles ! ! ! ! +% +% See also +% polygons3d, faceNormalAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-30 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +% number of points +np = size(points, 1); + +% number of angles to compute +nv = length(ind); + +theta = zeros(nv, 1); + +for i=1:nv + p0 = points(ind(i), :); + + if ind(i)==1 + p1 = points(np, :); + else + p1 = points(ind(i)-1, :); + end + + if ind(i)==np + p2 = points(1, :); + else + p2 = points(ind(i)+1, :); + end + + theta(i) = pi - anglePoints3d(p1, p0, p2); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygonCentroid3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygonCentroid3d.m new file mode 100644 index 0000000..498f5a4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygonCentroid3d.m @@ -0,0 +1,50 @@ +function centroid = polygonCentroid3d(varargin) +%POLYGONCENTROID3D Centroid (or center of mass) of a polygon +% +% PTC = polygonCentroid3d(POLY) +% Computes center of mass of a polygon defined by POLY. POLY is a N-by-3 +% array of double containing coordinates of polygon vertices. +% +% PTC = polygonCentroid3d(VX, VY, VZ) +% Specifies vertex coordinates as three separate arrays. +% +% Example +% % compute centroid of a basic polygon +% poly = [0 0 0; 10 0 10;10 10 20;0 10 10]; +% centro = polygonCentroid3d(poly) +% centro = +% 5.0000 5.0000 10.0000 +% +% See also +% polygons3d, polygonCentroid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-09-18 +% Copyright 2007 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if nargin==1 + % polygon is given as a single argument + pts = varargin{1}; + +elseif nargin==2 + % polygon is given as 3 corodinate arrays + px = varargin{1}; + py = varargin{2}; + pz = varargin{3}; + pts = [px py pz]; +end + +% create supporting plane (assuming first 3 points are not colinear...) +plane = createPlane(pts(1:3, :)); + +% project points onto the plane +pts = planePosition(pts, plane); + +% compute centroid in 2D +centro2d = polygonCentroid(pts); + +% project back in 3D +centroid = planePoint(plane, centro2d); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygons3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygons3d.m new file mode 100644 index 0000000..17c2f65 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/polygons3d.m @@ -0,0 +1,18 @@ +function polygons3d(varargin) +%POLYGONS3D Description of functions operating on 3D polygons +% +% A 3D polygon is simply a set of 3D points (called vertices) which are +% assumed to be located in the same plane. +% Several functions are provided for computing basic geometrical +% parameters (centroid, angles), or intersections with lines or planes. +% +% See also: +% polygon3dNormalAngle, polygonCentroid3d, clipConvexPolygon3dHP +% intersectLinePolygon3d, intersectLineTriangle3d, intersectRayPolygon3d +% drawPolygon3d, drawPolyline3d, fillPolygon3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/private/localToGlobal3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/private/localToGlobal3d.m new file mode 100644 index 0000000..0425654 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/private/localToGlobal3d.m @@ -0,0 +1,92 @@ +function trans = localToGlobal3d(varargin) +%LOCALTOGLOBAL3D Transformation matrix from local to global coordinate system +% +% TRANS = localToGlobal3d(CENTER, THETA, PHI, PSI) +% Compute the transformation matrix from a local (or modelling) +% coordinate system to the global (or world) coordinate system. +% This is a low-level function, used by several drawing functions. +% +% The transform is defined by: +% - CENTER: the position of the local origin into the World coordinate +% system +% - THETA: colatitude, defined as the angle with the Oz axis (between 0 +% and 180 degrees), positive in the direction of the of Oy axis. +% - PHI: azimut, defined as the angle of the normal with the Ox axis, +% between 0 and 360 degrees +% - PSI: intrinsic rotation, corresponding to the rotation of the object +% around the direction vector, between 0 and 360 degrees +% +% The resulting transform is obtained by applying (in that order): +% - Rotation by PSI around he Z-axis +% - Rotation by THETA around the Y-axis +% - Rotation by PHI around the Z-axis +% - Translation by vector CENTER +% This corresponds to Euler ZYZ rotation, using angles PHI, THETA and +% PSI. +% +% The 'createEulerAnglesRotation' function may better suit your needs as +% it is more 'natural'. +% +% Example +% localToGlobal3d +% +% See also +% transforms3d, createEulerAnglesRotation +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% HISTORY +% 19/08/2009 fix bug in parsing center with 4 args +% 2011-06-21 use degrees + +% extract the components of the transform +if nargin == 1 + % all components are bundled in the first argument + var = varargin{1}; + center = var(1:3); + theta = var(4); + phi = var(5); + psi = 0; + if length(var) > 5 + psi = var(6); + end + +elseif nargin == 4 + % arguments = center, then the 3 angles + center = varargin{1}; + theta = varargin{2}; + phi = varargin{3}; + psi = varargin{4}; + +elseif nargin > 4 + % center is given in 3 arguments, then 3 angles + center = [varargin{1} varargin{2} varargin{3}]; + theta = varargin{4}; + phi = varargin{5}; + psi = 0; + if nargin > 5 + psi = varargin{6}; + end +end + +% conversion from degrees to radians +k = pi / 180; + +% rotation around normal vector axis +rot1 = createRotationOz(psi * k); + +% colatitude +rot2 = createRotationOy(theta * k); + +% longitude +rot3 = createRotationOz(phi * k); + +% shift center +tr = createTranslation3d(center); + +% create final transform by concatenating transforms +trans = tr * rot3 * rot2 * rot1; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/projPointOnPlane.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/projPointOnPlane.m new file mode 100644 index 0000000..f9de3d6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/projPointOnPlane.m @@ -0,0 +1,35 @@ +function point = projPointOnPlane(point, plane) +%PROJPOINTONPLANE Return the orthogonal projection of a point on a plane +% +% PT2 = projPointOnPlane(PT1, PLANE); +% Compute the (orthogonal) projection of point PT1 onto the line PLANE. +% +% Function works also for multiple points and planes. In this case, it +% returns multiple points. +% Point PT1 is a [N*3] array, and PLANE is a [N*9] array (see createPlane +% for details). Result PT2 is a [N*3] array, containing coordinates of +% orthogonal projections of PT1 onto planes PLANE. +% +% See also: +% planes3d, points3d, planePosition, intersectLinePlane +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 21/08/2006: debug support for multiple points or planes + +if size(point, 1)==1 + point = repmat(point, [size(plane, 1) 1]); +elseif size(plane, 1)==1 + plane = repmat(plane, [size(point, 1) 1]); +elseif size(plane, 1) ~= size(point, 1) + error('projPointOnPlane: size of inputs differ'); +end + +n = planeNormal(plane); +line = [point n]; +point = intersectLinePlane(line, plane); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomAngle3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomAngle3d.m new file mode 100644 index 0000000..ae3af9f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomAngle3d.m @@ -0,0 +1,54 @@ +function varargout = randomAngle3d(varargin) +%RANDOMANGLE3D Return a 3D angle uniformly distributed on unit sphere +% +% usage +% [THETA PHI] = randomAngle3d +% Generate an angle unformly distributed on the surface of the unit +% sphere. +% +% "Mathematical" convention is used: theta is the colatitude (angle with +% vertical axis, 0 for north pole, +pi for south pole, pi/2 for points at +% equator) with z=0. +% phi is the same as matlab cart2sph: angle from Ox axis, counted +% positively counter-clockwise. +% +% [THETA PHI] = randomAngle3d(N) +% generates N random angles (N is a scalar). The result is a N-by-2 +% array. +% +% Example: +% % Draw some points on the surface of a sphere +% figure; +% drawSphere; hold on; +% drawPoint3d(pts, '.'); +% axis equal; +% +% See also: +% angles3d, sph2cart2, cart2sph2 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 18/02/2005. +% Copyright INRA - Cepia Software platform + +% HISTORY +% 2007-01-04 change angle order, update doc +% 2011-06-27 fix bug in input parsing, add doc + + +N = 1; +if ~isempty(varargin) + N = varargin{1}; +end + +phi = 2*pi*rand(N, 1); +theta = asin(2*rand(N, 1)-1) + pi/2; + +if nargout<2 + var = [theta phi]; + varargout{1} = var; +else + varargout{1} = theta; + varargout{2} = phi; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomPointInBox3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomPointInBox3d.m new file mode 100644 index 0000000..b1b2cb5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/randomPointInBox3d.m @@ -0,0 +1,50 @@ +function points = randomPointInBox3d(box, N, varargin) +%RANDOMPOINTINBOX3D Generate random point(s) within a 3D box +% +% PTS = randomPointInBox3d(BOX) +% Generate a random point within the 3D box BOX. The result is a 1-by-3 +% row vector. +% +% PTS = randomPointInBox3d(BOX, N) +% Generates N points within the box. The result is a N-by-3 array. +% +% BOX has the format: +% BOX = [XMIN XMAX YMIN YMAX ZMIN ZMAX]. +% +% Example +% % draw points within a box +% box = [10 40 20 60 30 50]; +% pts = randomPointInBox3d(box, 500); +% figure(1); hold on; +% drawBox3d(box); +% drawPoint3d(pts, '.'); +% axis('equal'); +% axis([0 100 0 100 0 100]); +% view(3); +% +% See also +% points3d, boxes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-27, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +if nargin < 2 + N = 1; +end + +% extract box bounds +xmin = box(1); +ymin = box(3); +zmin = box(5); + +% compute size of box +dx = box(2) - xmin; +dy = box(4) - ymin; +dz = box(6) - zmin; + +% compute point coordinates +points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin , rand(N, 1)*dz+zmin]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/readme.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/readme.txt new file mode 100644 index 0000000..fc35e46 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/readme.txt @@ -0,0 +1,35 @@ +Description of the geom3d library. + +The aim of geom3d library is to handle and visualize 3D geometric primitives +such as points, lines, planes, polyhedra... It provides low-level functions +for manipulating 3D geometric primitives, making easier the development of more +complex geometric algorithms. + +Some features of the library are: + +- creation of various shapes (3D points, 3D lines, planes, polyhedra...) + through an intuitive syntax. + Ex: createPlane(p1, p2, p3) to create a plane through 3 points. + +- derivation of new shapes: intersection between 2 planes, intersection between + a plane and a line, between a sphere and a line... + +- functions for 3D polygons and polyhedra. Polyhedra use classical vertex-faces + arrays (face array contain indices of vertices), and support faces with any + number of vertices. Some basic models are provided (createOctaedron, + createCubeoctaedron...), as well as some computation (like faceNormal or + centroid) + +- manipulation of planar transformation. Ex.: + ROT = createRotationOx(THETA); + P2 = transformPoint3d(P1, ROT); + +- direct drawing of shapes with specialized functions. Clipping is performed + automatically for infinite shapes such as lines or rays. Ex: + drawPoint3d([50 50 25; 20 70 10], 'ro'); % draw some points + drawLine3d([X0 Y0 Z0 DX DY DZ]); % clip and draw straight line + +Some functions require the geom2d package. + +Additional help is provided in geom3d/Contents.m file, as well as summary files + like 'points3d.m' or 'lines3d.m'. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/recenterTransform3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/recenterTransform3d.m new file mode 100644 index 0000000..699abb3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/recenterTransform3d.m @@ -0,0 +1,39 @@ +function res = recenterTransform3d(transfo, center) +%RECENTERTRANSFORM3D Change the fixed point of an affine 3D transform +% +% TRANSFO2 = recenterTransform3d(TRANSFO, CENTER) +% where TRANSFO is a 4x4 transformation matrix, and CENTER is a 1x3 row +% vector, computes the new transformations that uses the same linear part +% (defined by the upper-left 3x3 corner of the transformation matrix) as +% the initial transform, and that will leave the point CENTER unchanged. +% +% +% +% Example +% % creating a re-centered rotation using: +% rot1 = createRotationOx(pi/3); +% rot2 = recenterTransform3d(rot1, [3 4 5]); +% % will give the same result as: +% rot3 = createRotationOx([3 4 5], pi/3); +% +% +% See also +% transforms3d, createRotationOx, createRotationOy, createRotationOz +% createTranslation3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-27, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% remove former translation part +res = eye(4); +res(1:3, 1:3) = transfo(1:3, 1:3); + +% create translations +t1 = createTranslation3d(-center); +t2 = createTranslation3d(center); + +% compute translated transform +res = t2*res*t1; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/revolutionSurface.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/revolutionSurface.m new file mode 100644 index 0000000..065e556 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/revolutionSurface.m @@ -0,0 +1,147 @@ +function varargout = revolutionSurface(varargin) +%REVOLUTIONSURFACE Create a surface of revolution from a planar curve +% +% usage +% [X Y Z] = revolutionSurface(C1, C2, N); +% create the surface of revolution of parametrized function (xt, yt), +% with N+1 equally spaced slices, around the Oz axis. +% It assumed that C1 corresponds to the x coordinate, and that C2 +% corresponds to the Oz coordinate. +% +% [X Y Z] = revolutionSurface(CURVE, N); +% is the same, but generating curve is given in a single parameter CURVE, +% which is a [Nx2] array of 2D points. +% +% [X Y Z] = revolutionSurface(..., THETA) +% where THETA is a vector, uses values of THETA for computing revolution +% angles. +% +% [X Y Z] = revolutionSurface(..., LINE); +% where LINE is a 1x4 array, specifes the revolution axis in the +% coordinate system of the curve. LINE is a row vector of 4 parameters, +% containing [x0 y0 dx dy], where (x0,y0) is the origin of the line and +% (dx,dy) is a direction vector of the line. +% The resulting revolution surface still has Oz axis as symmetry axis. It +% can be transformed using transformPoint3d function. +% Surface can be displayed using : +% H = surf(X, Y, Z); +% H is a handle to the created patch. +% +% revolutionSurface(...); +% by itself, directly shows the created patch. +% +% Example +% % draws a piece of torus +% circle = circleAsPolygon([10 0 3], 50); +% [x y z] = revolutionSurface(circle, linspace(0, 4*pi/3, 50)); +% surf(x, y, z); +% axis equal; +% +% +% +% See also +% surf, transformPoint3d, drawSphere, drawTorus, drawEllipsoid +% surfature (on Matlab File Exchange) +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2004-04-09 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ Jouy-en-Josas. + +% based on function cylinder from matlab +% 31/06/2006 fix bug when passing 3 parameters +% 20/04/2007 rewrite processing of input parameters, add psb to specify +% revolution axis +% 24/10/2008 fix angle vector +% 29/07/2010 doc update + + +%% Initialisations + +% default values + +% use revolution using the full unit circle, decomposed into 24 angular +% segments (thus, some vertices correspond to particular angles 30°, +% 45°...) +theta = linspace(0, 2*pi, 25); + +% use planar vertical axis as default revolution axis +revol = [0 0 0 1]; + +% extract the generating curve +var = varargin{1}; +if size(var, 2)==1 + xt = var; + yt = varargin{2}; + varargin(1:2) = []; +else + xt = var(:,1); + yt = var(:,2); + varargin(1) = []; +end + +% extract optional parameters: angles, axis of revolution +% parameters are identified from their length +while ~isempty(varargin) + var = varargin{1}; + + if length(var) == 4 + % axis of rotation in the base plane + revol = var; + + elseif length(var) == 1 + % number of points -> create row vector of angles + theta = linspace(0, 2*pi, var); + + else + % use all specified angle values + theta = var(:)'; + + end + varargin(1) = []; +end + + +%% Create revolution surface + +% ensure length is enough +m = length(xt); +if m==1 + xt = [xt xt]; +end + +% ensure x and y are vertical vectors +xt = xt(:); +yt = yt(:); + +% transform xt and yt to replace in the reference of the revolution axis +tra = createTranslation(-revol(1:2)); +rot = createRotation(pi/2 - lineAngle(revol)); +[xt yt] = transformPoint(xt, yt, tra*rot); + +% compute surface vertices +x = xt * cos(theta); +y = xt * sin(theta); +z = yt * ones(size(theta)); + + +%% Process output arguments + +% format output depending on how many output parameters are required +if nargout == 0 + % draw the revolution surface + surf(x, y, z); + +elseif nargout == 1 + % draw the surface and return a handle to the shown structure + h = surf(x, y, z); + varargout{1} = h; + +elseif nargout == 3 + % return computed mesh + varargout = {x, y, z}; +end + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dAxisAndAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dAxisAndAngle.m new file mode 100644 index 0000000..c6af3fc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dAxisAndAngle.m @@ -0,0 +1,65 @@ +function [axis theta] = rotation3dAxisAndAngle(mat) +%ROTATION3DAXISANDANGLE Determine axis and angle of a 3D rotation matrix +% +% [AXIS ANGLE] = rotation3dAxisAndAngle(MAT) +% Where MAT is a 4-by-4 matrix representing a rotation, compute the +% rotation axis (containing the points that remain invariant under the +% rotation), and the rotation angle around that axis. +% AXIS has the format [DX DY DZ], constrained to unity, and ANGLE is the +% rotation angle in radians. +% +% This method use eigen vector extraction. It would be more precise to +% use quaternions, see: +% http://www.mathworks.cn/matlabcentral/newsreader/view_thread/160945 +% +% +% Example +% origin = [1 2 3]; +% direction = [4 5 6]; +% line = [origin direction]; +% angle = pi/3; +% rot = createRotation3dLineAngle(line, angle); +% [axis angle2] = rotation3dAxisAndAngle(rot); +% angle2 +% angle2 = +% 1.0472 +% +% See also +% transforms3d, vectors3d, angles3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% extract the linear part of the rotation matrix +A = mat(1:3, 1:3); + +% extract eigen values and eigen vectors +[V D] = eig(A - eye(3)); + +% we need the eigen vector corresponding to eigenvalue==1 +[dummy ind] = min(abs(diag(D)-1)); %#ok + +% extract corresponding eigen vector +vector = V(:, ind)'; + +% compute rotation angle +t = [A(3,2)-A(2,3) , A(1,3)-A(3,1) , A(2,1)-A(1,2)]; +theta = atan2(dot(t, vector), trace(A)-1); + +% If angle is negative, invert both angle and vector direction +if theta<0 + theta = -theta; + vector = -vector; +end + +% try to get a point on the line +% seems to work, but not sure about stability +[V D] = eig(mat-eye(4)); %#ok +origin = V(1:3,4)'/V(4, 4); + +% create line corresponding to rotation axis +axis = [origin vector]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dToEulerAngles.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dToEulerAngles.m new file mode 100644 index 0000000..4eed507 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotation3dToEulerAngles.m @@ -0,0 +1,61 @@ +function varargout = rotation3dToEulerAngles(mat) +%ROTATION3DTOEULERANGLES Extract Euler angles from a rotation matrix +% +% [PHI, THETA, PSI] = rotation3dToEulerAngles(MAT) +% Computes Euler angles PHI, THETA and PSI (in degrees) from a 3D 4-by-4 +% or 3-by-3 rotation matrix. +% +% ANGLES = rotation3dToEulerAngles(MAT) +% Concatenates results in a single 1-by-3 row vector. This format is used +% for representing some 3D shapes like ellipsoids. +% +% Example +% rotation3dToEulerAngles +% +% References +% Code from Graphics Gems IV on euler angles +% http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/EulerAngles.c +% Modified using explanations in: +% http://www.gregslabaugh.name/publications/euler.pdf +% +% See also +% transforms3d, rotation3dAxisAndAngle, createRotation3dLineAngle, +% eulerAnglesToRotation3d +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-08-11, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + + +% conversion from radians to degrees +k = 180 / pi; + +% extract |cos(theta)| +cy = hypot(mat(1, 1), mat(2, 1)); + +% avoid dividing by 0 +if cy > 16*eps + % normal case: theta <> 0 +% psi = k * atan2( mat(3, 2) / cy, mat(3, 3) / cy); + psi = k * atan2( mat(3, 2), mat(3, 3)); + theta = k * atan2(-mat(3, 1), cy); +% psi = k * atan2( mat(2, 1) / cy, mat(1, 1) / cy); + phi = k * atan2( mat(2, 1), mat(1, 1)); +else + % + psi = k * atan2(-mat(2, 3), mat(2, 2)); + theta = k * atan2(-mat(3, 1), cy); + phi = 0; +end + +% format output arguments +if nargout <= 1 + % one array + varargout{1} = [phi theta psi]; +else + % three separate arrays + varargout = {phi, theta, psi}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOx.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOx.m new file mode 100644 index 0000000..1b5dd9e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOx.m @@ -0,0 +1,38 @@ +function trans = rotationOx(varargin) +%ROTATIONOX return 4x4 matrix of a rotation around x-axis +% +% TRANS = rotationOx(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Ox axis. A rotation by an angle of PI/2 +% would transform the vector [0 1 0] into the vector [0 0 1]. +% +% The returned matrix has the form: +% [1 0 0 0] +% [0 cos(THETA) -sin(THETA) 0] +% [0 sin(THETA) cos(THETA) 0] +% [0 0 0 1] +% +% TRANS = rotationOx(ORIGIN, THETA); +% TRANS = rotationOx(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% See also: +% transforms3d, transformPoint3d, rotationOy, rotationOz +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2008/11/24 changed convention for angle +% 30/04/2009 deprecate: use createRotationOx instead + +% deprecation warning +warning('geom3d:deprecated', ... + [mfilename ' is deprecated, use ''createRotationOx'' instead']); + +% call current implementation +trans = createRotationOx(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOy.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOy.m new file mode 100644 index 0000000..38230ff --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOy.m @@ -0,0 +1,39 @@ +function trans = rotationOy(varargin) +%ROTATIONOY return 4x4 matrix of a rotation around y-axis +% +% TRANS = rotationOy(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Oy axis. A rotation by an angle of PI/2 +% would transform the vector [0 0 1] into the vector [1 0 0]. +% +% The returned matrix has the form: +% [ cos(THETA) 0 sin(THETA) 0 ] +% [ 0 1 0 0 ] +% [-sin(THETA) 0 cos(THETA) 0 ] +% [ 0 0 0 1 ] +% +% TRANS = rotationOy(ORIGIN, THETA); +% TRANS = rotationOy(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% +% See also: +% transforms3d, transformPoint3d, rotationOx, rotationOz +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 2008/11/24 changed convention for angle +% 30/04/2009 deprecate: use createRotationOy instead + +% deprecation warning +warning('geom3d:deprecated', ... + [mfilename ' is deprecated, use ''createRotationOy'' instead']); + +% call current implementation +trans = createRotationOy(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOz.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOz.m new file mode 100644 index 0000000..72af433 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/rotationOz.m @@ -0,0 +1,40 @@ +function trans = rotationOz(varargin) +%ROTATIONOZ return 4x4 matrix of a rotation around z-axis +% +% TRANS = rotationOz(THETA); +% Returns the transform matrix corresponding to a rotation by the angle +% THETA (in radians) around the Oz axis. A rotation by an angle of PI/2 +% would transform the vector [1 0 0] into the vector [0 1 0]. +% +% The returned matrix has the form: +% [cos(THETA) -sin(THETA) 0 0] +% [sin(THETA) cos(THETA) 0 0] +% [ 0 0 1 0] +% [ 0 0 0 1] +% +% TRANS = rotationOz(ORIGIN, THETA); +% TRANS = rotationOz(X0, Y0, Z0, THETA); +% Also specifies origin of rotation. The result is similar as performing +% translation(-X0, -Y0, -Z0), rotation, and translation(X0, Y0, Z0). +% +% +% See also: +% transforms3d, transformPoint3d, rotationOx, rotationOy +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 2008/11/24 changed convention for angle +% 30/04/2009 deprecate: use createRotationOz instead + +% deprecation warning +warning('geom3d:deprecated', ... + [mfilename ' is deprecated, use ''createRotationOz'' instead']); + +% call current implementation +trans = createRotationOz(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scale3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scale3d.m new file mode 100644 index 0000000..0de052c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scale3d.m @@ -0,0 +1,60 @@ +function trans = scale3d(varargin) +%SCALE3D return 4x4 matrix of a 3D scaling +% +% TRANS = scale3d(S); +% return the scaling transform corresponding to a scaling factor S in +% each direction. S can be a scalar, or a 1x3 vector containing the +% scaling factor in each direction. +% +% TRANS = scale3d(SX, SY, SZ); +% return the scaling transform corresponding to a different scaling +% factor in each direction. +% +% The returned matrix has the form : +% [SX 0 0 0] +% [ 0 SY 0 0] +% [ 0 0 SZ 0] +% [ 0 0 0 0] +% +% Note: +% deprecated, use 'scaling3d' instead. +% +% See also : +% scaling3d, transforms3d, transformPoint3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/04/2006. +% + +% HISTORY +% 25/11/2008 deprecate + +warning('geom3d:deprecated', ... + 'deprecated: call ''scaling3d'' instead'); + +if isempty(varargin) + sx = 1; + sy = 1; + sz = 1; +elseif length(varargin)==1 + var = varargin{1}; + if length(var)==1 + sx = var; + sy = var; + sz = var; + elseif length(var)==3 + sx = var(1); + sy = var(2); + sz = var(3); + else + error('wrong size for first parameter of "scale3d"'); + end +else + sx = varargin{1}; + sy = varargin{2}; + sz = varargin{3}; +end + +trans = [sx 0 0 0;0 sy 0 0;0 0 sz 0;0 0 0 1]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scaling3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scaling3d.m new file mode 100644 index 0000000..21b53c2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/scaling3d.m @@ -0,0 +1,39 @@ +function trans = scaling3d(varargin) +%SCALING3D return 4x4 matrix of a 3D scaling +% +% TRANS = scaling3d(S); +% returns the scaling transform corresponding to a scaling factor S in +% each direction. S can be a scalar, or a 1x3 vector containing the +% scaling factor in each direction. +% +% TRANS = scaling3d(SX, SY, SZ); +% returns the scaling transform corresponding to a different scaling +% factor in each direction. +% +% The returned matrix has the form : +% [SX 0 0 0] +% [ 0 SY 0 0] +% [ 0 0 SZ 0] +% [ 0 0 0 0] +% +% +% See also: +% transforms3d, transformPoint3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 20/04/2006. +% + +% HISTORY +% 25/11/2008 rename from scale3d to scaling3d +% HISTORY +% 30/04/2009 deprecate: use createScaling3d instead + +% deprecation warning +warning('geom3d:deprecated', ... + [mfilename ' is deprecated, use ''createScaling3d'' instead']); + +% call current implementation +trans = createScaling3d(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2.m new file mode 100644 index 0000000..0871ae9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2.m @@ -0,0 +1,63 @@ +function varargout = sph2cart2(theta, phi, rho) +%SPH2CART2 Convert spherical coordinates to cartesian coordinates +% +% C = SPH2CART2(S) +% C = SPH2CART2(THETA, PHI) (assume rho = 1) +% C = SPH2CART2(THETA, PHI, RHO) +% [X, Y, Z] = SPH2CART2(THETA, PHI, RHO); +% +% S = [phi theta rho] (spherical coordinate). +% C = [X Y Z] (cartesian coordinate) +% +% The following convention is used: +% THETA is the colatitude, in radians, 0 for north pole, +pi for south +% pole, pi/2 for points with z=0. +% PHI is the azimuth, in radians, defined as matlab cart2sph: angle from +% Ox axis, counted counter-clockwise. +% RHO is the distance of the point to the origin. +% Discussion on choice for convention can be found at: +% http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf +% +% See also: +% angles3d, cart2sph2, sph2cart, sph2cart2d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 18/02/2005. +% + +% HISTORY +% 22/03/2005: make test for 2 args, and add radius if not specified for +% 1 arg. +% 03/11/2006: change convention for angle: uses order [THETA PHI RHO] + +% Process input arguments +if nargin == 1 + phi = theta(:, 2); + if size(theta, 2) > 2 + rho = theta(:, 3); + else + rho = ones(size(phi)); + end + theta = theta(:, 1); + +elseif nargin == 2 + rho = ones(size(theta)); + +end + +% conversion +rz = rho .* sin(theta); +x = rz .* cos(phi); +y = rz .* sin(phi); +z = rho .* cos(theta); + +if nargout <= 1 + varargout{1} = [x, y, z]; +else + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2d.m new file mode 100644 index 0000000..72cbd7c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sph2cart2d.m @@ -0,0 +1,60 @@ +function varargout = sph2cart2d(theta, phi, rho) +%SPH2CART2D Convert spherical coordinates to cartesian coordinates in degrees +% +% C = SPH2CART2(THETA, PHI, RHO) +% C = SPH2CART2(THETA, PHI) (assume rho = 1) +% C = SPH2CART2(S) +% [X, Y, Z] = SPH2CART2(THETA, PHI, RHO); +% +% S = [phi theta rho] (spherical coordinate). +% C = [X Y Z] (cartesian coordinate) +% +% The following convention is used: +% THETA is the colatitude, in degrees, 0 for north pole, +180 degrees for +% south pole, +90 degrees for points with z=0. +% PHI is the azimuth, in degrees, defined as matlab cart2sph: angle from +% Ox axis, counted counter-clockwise. +% RHO is the distance of the point to the origin. +% Discussion on choice for convention can be found at: +% http://www.physics.oregonstate.edu/bridge/papers/spherical.pdf +% +% See also: +% angles3d, cart2sph2d, sph2cart2 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-29, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% Process input arguments +if nargin == 1 + phi = theta(:, 2); + if size(theta, 2) > 2 + rho = theta(:, 3); + else + rho = ones(size(phi)); + end + theta = theta(:, 1); + +elseif nargin == 2 + rho = ones(size(theta)); + +end + +% conversion +rz = rho .* sind(theta); +x = rz .* cosd(phi); +y = rz .* sind(phi); +z = rho .* cosd(theta); + +% Process output arguments +if nargout == 1 || nargout == 0 + varargout{1} = [x, y, z]; + +else + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/spheres.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/spheres.m new file mode 100644 index 0000000..cb5a584 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/spheres.m @@ -0,0 +1,22 @@ +function spheres(varargin) +%SPHERES Description of functions operating on 3D spheres +% +% Spheres are represented by their center and their radius: +% S = [xc yc zc r]; +% +% An ellipsoid is defined by: +% ELL = [XC YC ZC A B C PHI THETA PSI] +% where [XC YC ZY] is the center, [A B C] are length of semi-axes (in +% decreasing order), and [PHI THETA PSI] are euler angles representing +% the ellipsoid orientation. +% +% See also +% createSphere, inertiaEllipsoid +% intersectLineSphere, intersectPlaneSphere +% drawSphere, drawEllipsoid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sphericalAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sphericalAngle.m new file mode 100644 index 0000000..a4a54f7 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/sphericalAngle.m @@ -0,0 +1,57 @@ +function alpha = sphericalAngle(p1, p2, p3) +%SPHERICALANGLE Compute angle between points on the sphere +% +% ALPHA = sphericalAngle(P1, P2, P3) +% Compute angle (P1, P2, P3), i.e. the angle, measured at point P2, +% between the direction P2 P1 and the direction P2 P3. +% The result is given in radians, between 0 and 2*PI. +% +% Points are given either as [x y z] (there will be normalized to lie on +% the unit sphere), or as [phi theta], with phi being the longitude in [0 +% 2*PI] and theta being the elevation on horizontal [-pi/2 pi/2]. +% +% +% NOTE: +% this is an 'oriented' version of the angle computation, that is, the +% result of sphericalAngle(P1, P2, P3) equals +% 2*pi-sphericalAngle(P3,P2,P1). To have the more classical relation +% (with results given betwen 0 and PI), it suffices to take the minimum +% of angle and 2*pi-angle. +% +% See also: +% angles3d, spheres +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 23/05/2006 fix bug for points with angle from center > pi/2 + +% test if points are given as matlab spherical coordinate +if size(p1, 2) ==2 + [x y z] = sph2cart(p1(:,1), p1(:,2)); + p1 = [x y z]; + [x y z] = sph2cart(p2(:,1), p2(:,2)); + p2 = [x y z]; + [x y z] = sph2cart(p3(:,1), p3(:,2)); + p3 = [x y z]; +end + +% normalize points +p1 = normalizeVector3d(p1); +p2 = normalizeVector3d(p2); +p3 = normalizeVector3d(p3); + +% create the plane tangent to the unit sphere and containing central point +plane = createPlane(p2, p2); + +% project the two other points on the plane +pi1 = planePosition(projPointOnPlane(p1, plane), plane); +pi3 = planePosition(projPointOnPlane(p3, plane), plane); + +% compute angle on the tangent plane +alpha = angle3Points(pi1, [0 0], pi3); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/surfaceCurvature.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/surfaceCurvature.m new file mode 100644 index 0000000..d3e7e63 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/surfaceCurvature.m @@ -0,0 +1,28 @@ +function kappa = surfaceCurvature(kappa1, kappa2, theta) +%SURFACECURVATURE Curvature on a surface from angle and principal curvatures +% +% usage: +% KAPPA = surfaceCurvature(KAPPA1, KAPPA2, THETA) +% return the curvature KAPPA of surface with respect to direction THETA. + +% KAPPA1 and KAPPA2 are the principal curvatures of the surface at the +% considered point. THETA is angle of direction relative to angle of +% first principal curvature KAPPA1. +% +% Examples: +% K = surfaceCurvature(KAPPA1, KAPPA2, 0) returns KAPPA1. +% K = surfaceCurvature(KAPPA1, KAPPA2, pi/2) returns KAPPA2. +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2004. +% + +% HISTORY +% 20/04/2004 change name and add doc. +% 14/06/2004 correct creation date + +kappa = kappa1 * cos(theta).^2 + kappa2 * sin(theta).^2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformLine3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformLine3d.m new file mode 100644 index 0000000..c2d99ff --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformLine3d.m @@ -0,0 +1,29 @@ +function res = transformLine3d(line, trans) +%TRANSFORMLINE3D Transform a 3D line with a 3D affine transform +% +% LINE2 = transformLine3d(LINE1, TRANS) +% +% Example +% P1 = [10 20 30]; +% P2 = [30 40 50]; +% L = createLine3d(P1, P2); +% T = createRotationOx(P1, pi/6); +% L2 = transformLine3d(L, T); +% figure; hold on; +% axis([0 100 0 100 0 100]); view(3); +% drawPoint3d([P1;P2]); +% drawLine3d(L, 'b'); +% drawLine3d(L2, 'm'); +% +% See also: +% lines3d, transforms3d, transformPoint3d, transformVector3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-11-25, using Matlab 7.7.0.471 (R2008b) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +res = [... + transformPoint3d(line(:, 1:3), trans) ... % transform origin point + transformVector3d(line(:,4:6), trans)]; % transform direction vect. \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformPoint3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformPoint3d.m new file mode 100644 index 0000000..c5026ae --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformPoint3d.m @@ -0,0 +1,117 @@ +function varargout = transformPoint3d(varargin) +%TRANSFORMPOINT3D Transform a point with a 3D affine transform +% +% PT2 = transformPoint3d(PT1, TRANS); +% PT2 = transformPoint3d(X1, Y1, Z1, TRANS); +% where PT1 has the form [xp yp zp], and TRANS is a [3x3], [3x4], [4x4] +% matrix, return the point transformed according to the affine transform +% specified by TRANS. +% +% Format of TRANS is a 4-by-4 matrix. +% +% The function accepts transforms given using the following formats: +% [a b c] , [a b c j] , or [a b c j] +% [d e f] [d e f k] [d e f k] +% [g h i] [g h i l] [g h i l] +% [0 0 0 1] +% +% PT2 = transformPoint3d(PT1, TRANS) +% also work when PT1 is a [Nx3xMxPxETC] array of double. In this case, +% PT2 has the same size as PT1. +% +% PT2 = transformPoint3d(X1, Y1, Z1, TRANS); +% also work when X1, Y1 and Z1 are 3 arrays with the same size. In this +% case, PT2 will be a 1-by-3 cell containing {X Y Z} outputs of size(X1). +% +% [X2 Y2 Z2] = transformPoint3d(...); +% returns the result in 3 different arrays the same size as the input. +% This form can be useful when used with functions like meshgrid or warp. +% +% +% See also: +% points3d, transforms3d, translation3d +% meshgrid +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% 23/03/2006 add support for non vector point data +% 26/10/2006 better support for large data handling: iterate on points +% in the case of a memory lack. +% 20/04/2007 add link to rotationXX functions +% 29/09/2010 fix bug in catch case +% 12/03/2011 slightly reduce memory usage + +% process input arguments +if length(varargin) == 2 + % Point coordinates are given in a single N-by-3-by-M-by-etc argument. + % Preallocate x, y, and z to size N-by-1-by-M-by-etc, then fill them in + dim = size(varargin{1}); + dim(2) = 1; + [x,y,z] = deal(zeros(dim,class(varargin{1}))); + x(:) = varargin{1}(:,1,:); + y(:) = varargin{1}(:,2,:); + z(:) = varargin{1}(:,3,:); + trans = varargin{2}; + +elseif length(varargin) == 4 + % Point coordinates are given in 3 different arrays + x = varargin{1}; + y = varargin{2}; + z = varargin{3}; + dim = size(x); + trans = varargin{4}; +end + +% eventually add null translation +if size(trans, 2) == 3 + trans = [trans zeros(size(trans, 1), 1)]; +end + +% eventually add normalization +if size(trans, 1) == 3 + trans = [trans;0 0 0 1]; +end + +% convert coordinates +NP = numel(x); +try + % vectorial processing, if there is enough memory + %res = (trans*[x(:) y(:) z(:) ones(NP, 1)]')'; + %res = [x(:) y(:) z(:) ones(NP, 1)]*trans'; + res = [x(:) y(:) z(:) ones(NP,1,class(x))] * trans'; + + % Back-fill x,y,z with new result (saves calling costly reshape()) + x(:) = res(:,1); + y(:) = res(:,2); + z(:) = res(:,3); +catch ME + disp(ME.message) + % process each point one by one, writing in existing array + for i = 1:NP + res = [x(i) y(i) z(i) 1] * trans'; + x(i) = res(1); + y(i) = res(2); + z(i) = res(3); + end +end + +% process output arguments +if nargout <= 1 + % results are stored in a unique array + if length(dim) > 2 && dim(2) > 1 + warning('geom3d:shapeMismatch',... + 'Shape mismatch: Non-vector xyz input should have multiple x,y,z output arguments. Cell {x,y,z} returned instead.') + varargout{1} = {x,y,z}; + else + varargout{1} = [x y z]; + end + +elseif nargout == 3 + varargout{1} = x; + varargout{2} = y; + varargout{3} = z; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformVector3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformVector3d.m new file mode 100644 index 0000000..eb27595 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transformVector3d.m @@ -0,0 +1,45 @@ +function varargout = transformVector3d(varargin) +%TRANSFORMVECTOR3D Transform a vector with a 3D affine transform +% +% V2 = transformVector3d(V1, TRANS); +% Computes the vector obtained by transforming vector V1 with affine +% transform TRANS. +% V1 has the form [x1 y1 z1], and TRANS is a [3x3], [3x4], or [4x4] +% matrix, with one of the forms: +% [a b c] , [a b c j] , or [a b c j] +% [d e f] [d e f k] [d e f k] +% [g h i] [g h i l] [g h i l] +% [0 0 0 1] +% +% V2 = transformVector3d(V1, TRANS) also works when V1 is a [Nx3xMxEtc] +% array of double. In this case, V2 has the same size as V1. +% +% V2 = transformVector3d(X1, Y1, Z1, TRANS); +% Specifies vectors coordinates in three arrays with same size. +% +% [X2 Y2 Z2] = transformVector3d(...); +% Returns the coordinates of the transformed vector separately. +% +% +% See also: +% vectors3d, transforms3d, transformPoint3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 25/11/2008 from transformPoint3d +% + +if length(varargin)==2 % func(PTS_XYZ, PLANE) syntax + vIds = 1:2; +elseif length(varargin)==4 % func(X, Y, Z, PLANE) syntax + vIds = 1:3; +end + +% Extract only the linear part of the affine transform +trans = varargin{vIds(end)}; +trans(1:4, 4) = [0; 0; 0; 1]; + +% Call transformPoint3d using equivalent output arguments +varargout = cell(1, max(1,nargout)); +[varargout{:}] = transformPoint3d(varargin{vIds(1:end-1)}, trans); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transforms3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transforms3d.m new file mode 100644 index 0000000..4d3841e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/transforms3d.m @@ -0,0 +1,32 @@ +function transforms3d(varargin) +%TRANSFORMS3D Conventions for manipulating 3D affine transforms +% +% By 'transform' we mean an affine transform. A 3D affine transform +% is represented by a 4*4 matrix. The last row of the matrix is equal to +% [0 0 0 1]. +% +% +% +% Example: +% % create a translation by the vector [10 20 30]: +% T = createTranslation3d([10 20 30]); +% % Transform a basic point: +% PT1 = [4 5 6]; +% PT2 = transformPoint3d(PT1, T) +% % returns: +% PT2 = +% 14 25 36 +% +% See also +% createTranslation3d, createScaling3d, , createBasisTransform3d +% createRotationOx, createRotationOy, createRotationOz +% rotation3dAxisAndAngle, rotation3dToEulerAngles, +% createRotation3dLineAngle, createEulerAnglesRotation +% transformPoint3d, transformVector3d, transformLine3d +% composeTransforms3d, recenterTransform3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/translation3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/translation3d.m new file mode 100644 index 0000000..61389c8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/translation3d.m @@ -0,0 +1,35 @@ +function trans = translation3d(varargin) +%TRANSLATION3D return 4x4 matrix of a 3D translation +% +% usage : +% TRANS = translation3d(DX, DY, DZ); +% return the translation corresponding to DX and DY. +% The returned matrix has the form : +% [1 0 0 DX] +% [0 1 0 DY] +% [0 0 1 DZ] +% [0 0 0 1] +% +% TRANS = translation3d(VECT); +% return the translation corresponding to the given vector [x y z]. +% +% +% See also: +% vectors3d, transforms3d, transformPoint, rotation +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 30/04/2009 deprecate: use createTranslation instead + +% deprecation warning +warning('geom3d:deprecated', ... + [mfilename ' is deprecated, use ''createTranslation3d'' instead']); + +% call current implementation +trans = createTranslation3d(varargin{:}); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/triangleArea3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/triangleArea3d.m new file mode 100644 index 0000000..de98b03 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/triangleArea3d.m @@ -0,0 +1,39 @@ +function area = triangleArea3d(pt1, pt2, pt3) +%TRIANGLEAREA3D Area of a 3D triangle +% +% AREA = triangleArea3d(P1, P2, P3) +% Computes area of the 3D triangle whose vertices are given by P1, P2 and +% P3. Each vertex is a 1-by-3 row vector. +% +% AREA = triangleArea3d(PTS) +% Concatenates vertex coordinates in a 3-by-3 array. Each row of the +% array contains coordinates of one vertex. +% +% +% Example +% triangleArea3d([10 10 10], [30 10 10], [10 40 10]) +% ans = +% 300 +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-08-23, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% if data is given as one array, split vertices +if nargin == 1 + pt2 = pt1(2,:); + pt3 = pt1(3,:); + pt1 = pt1(1,:); +end + +% compute individual vectors +v12 = bsxfun(@minus, pt2, pt1); +v13 = bsxfun(@minus, pt3, pt1); + +% compute area from cross product +area = vectorNorm(cross(v12, v13, 2)) / 2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vecnorm3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vecnorm3d.m new file mode 100644 index 0000000..957eaa5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vecnorm3d.m @@ -0,0 +1,28 @@ +function n = vecnorm3d(v) +%VECNORM3D compute norm of vector or of set of 3D vectors +% +% N = vecnorm(V); +% Returns norm of vector V. +% +% When V is a Nx3 array, compute norm for each vector of the array. +% Vector are given as rows. Result is then a [N*1] array. +% +% NOTE: compute only euclidean norm. +% +% See Also +% vectors3d, normalize3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. +% + +% HISTORY +% 19/06/2009 deprecate and replace by vectorNorm3d + +% deprecation warning +warning('geom3d:deprecated', ... + '''vecnorm3d'' is deprecated, use ''vectorNorm3d'' instead'); + +n = sqrt(sum(v.*v, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorAngle3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorAngle3d.m new file mode 100644 index 0000000..ecce255 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorAngle3d.m @@ -0,0 +1,39 @@ +function theta = vectorAngle3d(v1, v2) +%VECTORANGLE3D Angle between two 3D vectors +% +% THETA = vectorAngle3d(V1, V2) +% Computes the angle between the 2 3D vectors V1 and V2. The result THETA +% is given in radians, between 0 and PI. +% +% +% Example +% % angle between 2 orthogonal vectors +% vectorAngle3d([1 0 0], [0 1 0]) +% ans = +% 1.5708 +% +% % angle between 2 parallel vectors +% v0 = [3 4 5]; +% vectorAngle3d(3*v0, 5*v0) +% ans = +% 0 +% +% See also +% vectors3d, vectorNorm3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% 2011-03-10 improve computation precision + +% compute angle using arc-tangent to get better precision for angles near +% zero, see the discussion in: +% http://www.mathworks.com/matlabcentral/newsreader/view_thread/151925#381952 +theta = atan2(vectorNorm3d(vectorCross3d(v1, v2)), sum(bsxfun(@times, v1, v2),2)); +% equivalent to: +% v1 = normalizeVector3d(v1); +% v2 = normalizeVector3d(v2); +% theta = acos(dot(v1, v2, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorCross3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorCross3d.m new file mode 100644 index 0000000..e36fc8f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorCross3d.m @@ -0,0 +1,40 @@ +function c = vectorCross3d(a,b) +%VECTORCROSS3D Vector cross product faster than inbuilt MATLAB cross. +% +% C = VECTORCROSS3D(A, B) +% returns the cross product of the 3D vectors A and B, that is: +% C = A x B +% A and B must be N-by-3 element vectors. If either A or B is a 1-by-3 +% row vector, the result C will have the size of the other input and will +% be the concatenation of each row's cross product. +% +% Class support for inputs A,B: +% float: double, single +% +% See also DOT. + +% Sven Holcombe + +% needed_colons = max([3, length(size(a)), length(size(b))]) - 3; +% tmp_colon = {':'}; +% clnSet = tmp_colon(ones(1, needed_colons)); +% +% c = bsxfun(@times, a(:,[2 3 1],clnSet{:}), b(:,[3 1 2],clnSet{:})) - ... +% bsxfun(@times, b(:,[2 3 1],clnSet{:}), a(:,[3 1 2],clnSet{:})); + +sza = size(a); +szb = size(b); + +% Initialise c to the size of a or b, whichever has more dimensions. If +% they have the same dimensions, initialise to the larger of the two +switch sign(numel(sza) - numel(szb)) + case 1 + c = zeros(sza); + case -1 + c = zeros(szb); + otherwise + c = zeros(max(sza, szb)); +end + +c(:) = bsxfun(@times, a(:,[2 3 1],:), b(:,[3 1 2],:)) - ... + bsxfun(@times, b(:,[2 3 1],:), a(:,[3 1 2],:)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorNorm3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorNorm3d.m new file mode 100644 index 0000000..45720d4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectorNorm3d.m @@ -0,0 +1,23 @@ +function n = vectorNorm3d(v) +%VECTORNORM3D Norm of a 3D vector or of set of 3D vectors +% +% N = vectorNorm3d(V); +% Returns the norm of vector V. +% +% When V is a N-by-3 array, compute norm for each vector of the array. +% Vector are given as rows. Result is then a N-by-1 array. +% +% NOTE: compute only euclidean norm. +% +% See Also +% vectors3d, normalizeVector3d, vectorAngle3d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/02/2005. + +% HISTORY +% 19/06/2009 rename as vectorNorm3d + +n = sqrt(sum(v.*v, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectors3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectors3d.m new file mode 100644 index 0000000..ce96158 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/geom3d/vectors3d.m @@ -0,0 +1,20 @@ +function vectors3d(varargin) +%VECTORS3D Description of functions operating on 3D vectors +% +% Vectors are represented by their 3 Cartesian coordinates: +% V = [VX VY VZ]; +% +% List of vectors are represented by N*3 arrays, with the coordinates of +% each vector on a row. +% +% +% See also +% vectorNorm3d, normalizeVector3d, vectorCross3d, vectorAngle3d +% isParallel3d, isPerpendicular3d +% createTranslation3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/Contents.m new file mode 100644 index 0000000..da02102 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/Contents.m @@ -0,0 +1,135 @@ +% GRAPHS Simple Toolbox for manipulating Geometric Graphs +% Version 0.5 11-Apr-2010 . +% +% The aim of this package is to provides functions to easily create, +% modify and display geometric graphs (geometric in a sense position +% of vertices is kept in memory). +% +% Graph structure is represented by at least two arrays: +% * NODES, which contains coordinates of each vertex +% * EDGES, which contains indices of start and end vertex. +% +% Others arrays may sometimes be used: +% * FACES, which contains indices of vertices of each face (either a +% double array, or a cell array) +% * CELLS, which contains indices of faces of each cell. +% +% An alternative representation is to use a structure, with fields: +% * edges +% * faces +% * cells +% corresponding to the data described above. +% +% Note that topological description of 2D graph is entirely contained in +% EDGES array, and that NODES array is used only to display graph +% +% Caution: this type of data structure is easy to create and to manage, +% but may be very inefficient for some algorithms. +% +% Graphs are usually considered as non-oriented in this package. +% +% +% Graph creation +% knnGraph - Create the k-nearest neighbors graph of a set of points +% delaunayGraph - Graph associated to Delaunay triangulation of input points +% gabrielGraph - Gabriel Graph of a set of points +% euclideanMST - Build euclidean minimal spanning tree of a set of points +% prim_mst - Minimal spanning tree by Prim's algorithm +% +% Create graph from images +% imageGraph - Create equivalent graph of a binary image +% boundaryGraph - Get boundary of image as a graph +% gcontour2d - Creates contour graph of a 2D binary image. +% gcontour3d - Create contour graph of a 3D binary image. +% vectorize - Transform a binary skeleton into a graph (nodes and edges) +% +% Graph information +% grNodeDegree - Degree of a node in a (undirected) graph +% grNodeInnerDegree - Inner degree of a node in a graph +% grNodeOuterDegree - Outer degree of a node in a graph +% grNeighborNodes - Find adjacent nodes of a given node +% grNeighborEdges - Find adjacent edges of a given node +% grOppositeNode - Return opposite node in an edge +% grLabel - Associate a label to each connected component of the graph +% +% Graph management (low level operations) +% grRemoveNode - Remove a node in a graph +% grRemoveNodes - Remove several nodes in a graph +% grRemoveEdge - Remove an edge in a graph. +% grRemoveEdges - Remove several edges from a graph +% +% Graph processing (general applications) +% mergeGraphs - Merge two graphs, by adding nodes, edges and faces lists. +% grMergeNodes - Merge two (or more) nodes in a graph. +% grMergeMultipleNodes - Simplify a graph by merging multiple nodes +% grMergeMultipleEdges - Remove all edges sharing the same extremities +% grSimplifyBranches - Replace branches of a graph by single edges +% +% Filtering operations on Graph +% grMean - Compute mean from neihgbours +% grMedian - Compute median from neihgbours +% grDilate - Morphological dilation on graph +% grErode - Morphological erosion on graph +% grClose - Morphological closing on graph +% grOpen - Morphological opening on graph +% +% Geodesic operations +% grPropagateDistance - Propagates distances from a vertex to other vertices +% grVertexEccentricity - Eccentricity of vertices in the graph +% graphDiameter - Diameter of a graph +% graphPeripheralVertices - Peripheral vertices of a graph +% graphCenter - Center of a graph +% graphRadius - Radius of a graph +% grFindGeodesicPath - Find a geodesic path between two nodes in the graph +% grFindMaximalLengthPath - Find a path that maximizes sum of edge weights +% +% Operations for geometric graphs +% grMergeNodeClusters - Merge cluster of connected nodes in a graph +% grMergeNodesMedian - Replace several nodes by their median coordinate +% clipGraph - Clip a graph with a rectangular area +% addSquareFace - Add a (square) face defined from its vertices to a graph +% grFaceToPolygon - Compute the polygon corresponding to a graph face +% graph2Contours - Convert a graph to a set of contour curves +% +% Voronoi Graphs +% voronoi2d - Compute a voronoi diagram as a graph structure +% boundedVoronoi2d - Return a bounded voronoi diagram as a graph structure +% centroidalVoronoi2d - Create a 2D Centroidal Voronoi Tesselation +% cvtUpdate - Update germs of a CVT with given points +% cvtIterate - Update germs of a CVT using random points with given density +% +% Graph display +% drawGraph - Draw a graph, given as a set of vertices and edges +% drawGraphEdges - Draw edges of a graph +% drawGraphFaces - Draw faces of a graph +% drawDigraph - Draw a directed graph, given as a set of vertices and edges +% drawDirectedEdges - Draw edges with arrow indicating direction +% drawEdgeLabels - Draw values associated to graph edges +% drawNodeLabels - Draw values associated to graph nodes +% drawSquareMesh - Draw a 3D square mesh given as a graph +% patchGraph - Transform 3D graph (mesh) into a patch handle +% +% +% ----- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 07/11/2005. +% Copyright INRA - Cepia Software Platform. + + +% HISTORY +% 25/07/2007 remove old functions +% 27/07/2007 integrate headers of other functions +% 27/07/2007 add MST by prim algo, and EuclideanMST +% 24/08/2010 code cleanup +% 07/09/2010 add functions for computing geodesic distances +% 18/05/2011 code re-organisation, add to MatGeom library + +% Deprecated functions +% grSimplifyBranches_old - Replace branches of a graph by single edges +% grRemoveMultiplePoints - Remove groups of close nodes in a graph +% +% Functions that requires further development +% quiverToGraph - Converts quiver data to quad mesh + +% Other functions diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/addSquareFace.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/addSquareFace.m new file mode 100644 index 0000000..dfadf8f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/addSquareFace.m @@ -0,0 +1,75 @@ +function [nodes, edges, faces] = addSquareFace(nodes, edges, faces, faceNodes) +%ADDSQUAREFACE Add a (square) face defined from its vertices to a graph +% +% [N2 E2 F2] = addSquareFace(N, E, F, FN) +% Add a new face, defined by the nodes indices FN, to the graph defined +% by node list N, edge list E, and face list F. +% Edges of the face are also added, if they are not already present in +% the edge list. +% +% See Also +% patchGraph, boundaryGraph +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + + + +n1 = faceNodes(1,:); +n2 = faceNodes(2,:); +n3 = faceNodes(3,:); +n4 = faceNodes(4,:); + +% search indices of each nodes +ind1 = find(ismember(nodes, n1, 'rows')); +ind2 = find(ismember(nodes, n2, 'rows')); +ind3 = find(ismember(nodes, n3, 'rows')); +ind4 = find(ismember(nodes, n4, 'rows')); + +% if nodes are not in the list, we add them +if isempty(ind1) + nodes = [nodes; n1]; + ind1 = size(nodes, 1); +end +if isempty(ind2) + nodes = [nodes; n2]; + ind2 = size(nodes, 1); +end +if isempty(ind3) + nodes = [nodes; n3]; + ind3 = size(nodes, 1); +end +if isempty(ind4) + nodes = [nodes; n4]; + ind4 = size(nodes, 1); +end + +% add current face to the list +faces(size(faces, 1)+1, 1:4) = [ind1(1) ind2(1) ind3(1) ind4(1)]; + +% create edges of the face +% (first index is the smallest one, by convention) +e1 = [min(ind1, ind2) max(ind1, ind2)]; +e2 = [min(ind2, ind3) max(ind2, ind3)]; +e3 = [min(ind3, ind4) max(ind3, ind4)]; +e4 = [min(ind4, ind1) max(ind4, ind1)]; + +% search edge indices in the list +% if nodes are not in the list +if isempty(ismember(edges, e1, 'rows')) + edges = [edges; e1]; +end +if isempty(ismember(edges, e2, 'rows')) + edges = [edges; e2]; +end +if isempty(ismember(edges, e3, 'rows')) + edges = [edges; e3]; +end +if isempty(ismember(edges, e4, 'rows')) + edges = [edges; e4]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundaryGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundaryGraph.m new file mode 100644 index 0000000..8911ec0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundaryGraph.m @@ -0,0 +1,140 @@ +function varargout = boundaryGraph(img) +%BOUNDARYGRAPH Get boundary of image as a graph +% +% [NODES, EDGES] = boundaryGraph(IMG) (2D) +% [NODES, EDGES, FACES] = boundaryGraph(IMG) (3D) +% Create a graph on the boundary of binary image IMG. Each pixel is +% considered as a unit square (or cube), centered on integer coordinates. +% Boundary of the shape is selected as a graph. +% +% Result is a set of nodes with (x,y) or (x,y,z) coordinates, a set of +% edges linking two neighbour nodes, and in 3D also a set of square +% faces, containing reference to each 4-tuple of nodes. +% +% The resulting shell is open if the binary structure touches edges of +% image. +% +% See also : +% imPatch, drawMesh +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + +% HISTORY +% 05/08/2004 : change name and add 2D case. + + +dim = size(img); +nd = length(dim); +if nd==2 && (dim(1)==1 || dim(2)==1) + nd=1; +end + + +nodes = zeros([0 nd]); % coordinates of vertices +edges = zeros([0 2]); % first node and second nodes +faces = zeros([0 4]); % indices of 4 corners of each square face + +if nd==1 + img = img(:)>0; + D1 = size(img,1); + nodes = find(img(1:D1-1)~=img(2:D1))+.5; + + if nargout==1 + varargout{1} = nodes; + end + return + +elseif nd==2 + D1 = size(img, 1); + D2 = size(img, 2); + + px = []; + py = []; + + ind = find(img(1:D1-1, :)~=img(2:D1, :)); + [x y] = ind2sub([D1-1 D2], ind); + px = [px; reshape([x+.5 x+.5]', length(x)*2,1)]; + py = [py; reshape([y-.5 y+.5]', length(x)*2,1)]; + + ind = find(img(:, 1:D2-1)~=img(:, 2:D2)); + [x y] = ind2sub([D1 D2-1], ind); + px = [px; reshape([x-.5 x+.5]', length(x)*2,1)]; + py = [py; reshape([y+.5 y+.5]', length(x)*2,1)]; + + [nodes, i, j] = unique([py px], 'rows'); %#ok + + + ne = floor(size(px, 1)/2); + edges = repmat(1:2, [ne 1]) + repmat((0:2:2*ne-1)', [1 2]); + + for i=1:length(edges(:)) + edges(i) = j(edges(i)); + end + edges = unique(sort(edges, 2), 'rows'); + +elseif nd==3 + D1 = size(img, 1); + D2 = size(img, 2); + D3 = size(img, 3); + + px = []; + py = []; + pz = []; + + ind = find(img(1:D1-1, :, :)~=img(2:D1, :, :)); + [x y z] = ind2sub([D1-1 D2 D3], ind); + px = [px; reshape([x+.5 x+.5 x+.5 x+.5]', length(x)*4,1)]; + py = [py; reshape([y-.5 y+.5 y+.5 y-.5]', length(x)*4,1)]; + pz = [pz; reshape([z-.5 z-.5 z+.5 z+.5]', length(x)*4,1)]; + + + ind = find(img(:, 1:D2-1, :)~=img(:, 2:D2, :)); + [x y z] = ind2sub([D1 D2-1 D3], ind); + px = [px; reshape([x-.5 x-.5 x+.5 x+.5]', length(x)*4,1)]; + py = [py; reshape([y+.5 y+.5 y+.5 y+.5]', length(x)*4,1)]; + pz = [pz; reshape([z-.5 z+.5 z+.5 z-.5]', length(x)*4,1)]; + + ind = find(img(:, :, 1:D3-1)~=img(:, :, 2:D3)); + [x y z] = ind2sub([D1 D2 D3-1], ind); + px = [px; reshape([x-.5 x+.5 x+.5 x-.5]', length(x)*4,1)]; + py = [py; reshape([y-.5 y-.5 y+.5 y+.5]', length(x)*4,1)]; + pz = [pz; reshape([z+.5 z+.5 z+.5 z+.5]', length(x)*4,1)]; + + + [nodes, i, j] = unique([py px pz], 'rows'); %#ok + + nf = floor(size(px, 1)/4); + faces = repmat(1:4, [nf 1]) + repmat((0:4:4*nf-1)', [1 4]); + + for i=1:length(faces(:)) + faces(i) = j(faces(i)); + end + + edges = [edges ; [faces(:,1) faces(:,2)]]; + edges = [edges ; [faces(:,2) faces(:,3)]]; + edges = [edges ; [faces(:,3) faces(:,4)]]; + edges = [edges ; [faces(:,4) faces(:,1)]]; + edges = unique(sort(edges, 2), 'rows'); +end + + +% format output arguments + +if nargout==3 + varargout{1} = nodes; + varargout{2} = edges; + varargout{3} = faces; +elseif nargout==2 + varargout{1} = nodes; + varargout{2} = edges; +elseif nargout==1 + graph.nodes = nodes; + graph.edges = edges; + graph.faces = faces; + varargout{1} = graph; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundedVoronoi2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundedVoronoi2d.m new file mode 100644 index 0000000..49c9762 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/boundedVoronoi2d.m @@ -0,0 +1,54 @@ +function [nodes edges faces] = boundedVoronoi2d(box, germs) +%BOUNDEDVORONOI2D Return a bounded voronoi diagram as a graph structure +% +% [NODES EDGES FACES] = boundedVoronoi2d(BOX, GERMS) +% GERMS an array of points with dimension 2 +% NODES, EDGES, FACES: usual graph representation, FACES as cell array +% +% Example +% [n e f] = boundedVoronoi2d([0 100 0 100], rand(100, 2)*100); +% drawGraph(n, e); +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-12 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% uniformize input for box. +box = box'; +box = box(:); + +% add points far enough +width = box(2)-box(1); +height = box(4)-box(3); +farPoints = [... + box(2)+2*width box(4)+3*height;... + box(1)-3*width box(4)+2*height;... + box(1)-2*width box(3)-3*height;... + box(2)+3*width box(3)-2*height;... + ]; + +% extract voronoi vertices and face structure +[V C] = voronoin([germs;farPoints]); + +% for each germ, determines the different lines + +% initialize graph structure, without edges and without faces +nodes = V(2:end, :); +edges = zeros(0, 2); +faces = {}; + +for i=1:size(germs, 1) + cell = C{i}; + cell = cell-1; + edges = [edges; sort([cell' cell([2:end 1])'], 2)]; %#ok + faces{length(faces)+1} = cell; %#ok +end + +edges = unique(edges, 'rows'); + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/centroidalVoronoi2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/centroidalVoronoi2d.m new file mode 100644 index 0000000..63e3fb2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/centroidalVoronoi2d.m @@ -0,0 +1,74 @@ +function varargout = centroidalVoronoi2d(germs, box, varargin) +%CENTROIDALVORONOI2D Create a 2D Centroidal Voronoi Tesselation +% +% [N E F] = centroidalVoronoi2d(GERMS, BOX) +% GERMS are N-by-2 point array, BOX is given as [xmin xmax ymin ymax]. +% Algorithm is an iteration of voronoi diagram computations, using at +% each steps the centroids of previous diagram as germs for the new +% diagram. +% +% [N E F] = centroidalVoronoi2d(GERMS, BOX, NITER) +% Specifies the number of iterations. +% +% [N E F G] = centroidalVoronoi2d(...) +% also returns the positions of germs/centroids for each face. If the +% number of iteration was sufficient, location of germs should correspond +% to centroids of faces 'fc' computed using: +% fc(i,:) = polygonCentroid(n(f{i}, :)); +% +% Example +% [n e f] = centroidalVoronoi2d(rand(20, 2)*100, [0 100 0 100]); +% drawGraph(n, e, f); +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-12 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 27/07/2007 add doc, and psb to specify number of iterations +% 18/09/2007 add psb to return germs of tessellation + + +% number of iteration +nIter = 10; +if ~isempty(varargin) + nIter = varargin{1}; +end + +% limits and size of the box +x0 = box(1); x1 = box(2); +y0 = box(3); y1 = box(4); +dx = x1-x0; dy = y1-y0; + +% far points to bound the voronoi diagram +farPoints = [... + x1+10*dx y1+10*dy;... + x0-10*dx y1+10*dy;... + x0-10*dx y0-10*dy;... + x1+10*dx y0-10*dy]; + +% iterate bounded voronoi tesselation +for i = 1:nIter + % generate Voronoi diagram, and clip woth the box + [n e f] = voronoi2d([germs ; farPoints]); + [n e f] = clipGraph(n, e, f, box); + + % compute new germs as centroids of of each face + for j = 1:length(f) + face = n(f{j}, :); + germs(j, 1:2) = polygonCentroid(face); + end +end + +% result is given in n, e, and f, eventually germs +varargout{1} = n; +varargout{2} = e; +varargout{3} = f; +if nargout>3 + varargout{4} = germs; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/clipGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/clipGraph.m new file mode 100644 index 0000000..c198845 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/clipGraph.m @@ -0,0 +1,208 @@ +function varargout = clipGraph(nodes, edges, varargin) +%CLIPGRAPH Clip a graph with a rectangular area +% +% [N2 E2] = clipGraph(N, E, BOX); +% [N2 E2 F2] = clipGraph(N, E, F, BOX); +% N is an array ov vertices, E an array of edges, containing indices of +% first ans second vertices, and F (optional) is either a matrice or a +% cell array containing indices of vertices for each face. +% BOX is either a box given as a matrix: [XMIN XMAX;YMIN YMAX], or a row +% vector following matlab axis format: [XMIN XMAX YMIN YMAX]. +% +% Example +% clipGraph +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-18 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% Format inputs + +% extract input arguments +faces = []; +if length(varargin)==1 + box = varargin{1}; +elseif length(varargin)==2 + faces = varargin{1}; + box = varargin{2}; +else + error('Wrong number of arguments in clipGraph'); +end + +% uniformization of input for box. +box = box'; +box = box(:); + +% accuracy of numeric computations +ACC = 1e-14; + + +%% Get bounding lines + +% get bounds of the box +xmin = box(1); +xmax = box(2); +ymin = box(3); +ymax = box(4); + +% create box corners +corners = [ ... + xmin ymin; ... + xmin ymax; ... + xmax ymin; ... + xmax ymax]; ... + +%% Clip the nodes + +% find nodes inside clipping window +insideNodes = ... + nodes(:,1)-xmin>ACC & nodes(:,1)-xmaxACC & nodes(:,2)-ymax no clip + if in1 && in2 + edges2 = [edges2; hashNodes(edges(e, :))']; %#ok + hashEdges(e) = size(edges2, 1); + continue; + end + + % check that edge is not totally clipped -> no edge + if edge(1)-xminACC && edge(3)-xmax>ACC, continue; end + if edge(2)-yminACC && edge(4)-ymax>ACC, continue; end + + % otherwise, we have to clip the edge ! + edge = clipEdge(edge, [box(1) box(2); box(3) box(4)]); + + % display debug info + %disp(sprintf('clip edge n°%2d, from %2d to %2d', e, edges(e,1), edges(e,2))); + + % Node for first vertex + if ~in1 + nodes2 = [nodes2; edge([1 2])]; %#ok + indN1 = size(nodes2, 1); + else + indN1 = hashNodes(edges(e, 1)); + end + + % Node for second vertex + if ~in2 + nodes2 = [nodes2; edge([3 4])]; %#ok + indN2 = size(nodes2, 1); + else + indN2 = hashNodes(edges(e, 2)); + end + + % add clipped edge to the list + edges2 = [edges2; indN1 indN2]; %#ok + hashEdges(e) = size(edges2, 1); +end + + +%% Clip the faces +faces2 = {}; +for f = 1:length(faces) + % indices of vertices of current face + face = faces{f}; + + % if the face is not clipped, use directly new indices of nodes + face2 = hashNodes(face)'; + if ~ismember(0, face2) + faces2 = [faces2, {face2}]; %#ok + continue; + end + + % At least one vertex is clipped. Here is some more special processing + + % edges of current face + faceEdges = sort([face' face([2:end 1])'], 2); + + % indices of face edges in edges array + indEdges = ismember(edges, faceEdges, 'rows'); + + % convert to indices of edges in clipped edges array. indEdges with + % value=0 correspond to totally clipped edges, and can be removed. + indEdges = hashEdges(indEdges); + indEdges = indEdges(indEdges~=0); + + % case of face totally clipped: break and continuue with next face + if isempty(indEdges) + continue; + end + + % extract indices of vertices of the clipped face + face2 = edges2(indEdges, :); + face2 = unique(face2(:)); + + % Test whether one should add one of the corner of the box. + poly = [nodes(face, 1) nodes(face, 2)]; + ind = inpolygon(corners(:,1), corners(:,2), poly(:,1), poly(:,2)); + if sum(ind)>0 + nodes2 = [nodes2; corners(ind, :)]; %#ok + face2 = [face2; size(nodes2, 1)]; %#ok + end + + % vertices of the face, as points + faceNodes = nodes2(face2, :); + + % sort vertices according to their angle around the centroid + [faceNodes I] = angleSort(faceNodes, centroid(faceNodes)); %#ok + + % add current face to list of faces + faces2 = [faces2, {face2(I)'}]; %#ok +end + + +%% Format output arguments + +% clean up nodes to ensure coord correspond to clipping box. +nodes2(:,1) = min(max(nodes2(:,1), box(1)), box(2)); +nodes2(:,2) = min(max(nodes2(:,2), box(3)), box(4)); + +if nargout==2 + varargout{1} = nodes2; + varargout{2} = edges2; +elseif nargout==3 + varargout{1} = nodes2; + varargout{2} = edges2; + varargout{3} = faces2; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtIterate.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtIterate.m new file mode 100644 index 0000000..e95cda0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtIterate.m @@ -0,0 +1,87 @@ +function varargout = cvtIterate(germs, funcPtr, funcArgs, N) +%CVTITERATE Update germs of a CVT using random points with given density +% +% G2 = cvtIterate(G, FPTR, FARGS, N) +% G: inital germs +% FPTR: pointer to a function which accept a scalar M and return M random +% points with a given distribution +% FARGS: arguments to be given to the FPTR function (can be empty) +% N: number of random points to generate +% +% Example +% P = randPointDiscUnif(50); +% P2 = cvtIterate(P, @randPointDiscUnif, [], 1000); +% P3 = cvtIterate(P2, @randPointDiscUnif, [], 1000); +% +% See also +% +% +% Rewritten from programs found in +% http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html +% +% Reference: +% Qiang Du, Vance Faber, and Max Gunzburger, +% Centroidal Voronoi Tessellations: Applications and Algorithms, +% SIAM Review, Volume 41, 1999, pages 637-676. +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% Init + +% format input +if isempty(funcArgs) + funcArgs = {}; +end + +% number of germs +Ng = size(germs, 1); + +% initialize centroids with values of germs +centroids = germs; + +% number of updates of each centroid +count = ones(Ng, 1); + + +%% random points + +% generate N random points +pts = feval(funcPtr, N, funcArgs{:}); + +% for each point, determines which germ is the closest ones +[dist ind] = minDistancePoints(pts, germs); %#ok + +h = zeros(Ng, 1); +for i = 1:Ng + h(i) = sum(ind==i); +end + + +%% Centroids update + +% add coordinate of each point to closest centroid +energy = 0; +for j = 1:N + centroids(ind(j), :) = centroids(ind(j), :) + pts(j, :); + energy = energy + sum ( ( centroids(ind(j), :) - pts(j, :) ).^2); + count(ind(j)) = count(ind(j)) + 1; +end + +% estimate coordinate by dividing by number of counts +centroids = centroids ./ repmat(count, 1, size(germs, 2)); + +% normalizes energy by number of sample points +energy = energy / N; + + +%% format output + +varargout{1} = centroids; +if nargout > 1 + varargout{2} = energy; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtUpdate.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtUpdate.m new file mode 100644 index 0000000..9f91a67 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/cvtUpdate.m @@ -0,0 +1,80 @@ +function varargout = cvtUpdate(germs, points) +%CVTUPDATE Update germs of a CVT with given points +% +% G2 = cvtUpdate(G, PTS) +% G: inital germs +% PTS: the points +% +% Example +% G = randPointDiscUnif(50); +% P = randPointDiscUnif(10000); +% G2 = cvtUpdate(G, P); +% +% See also +% +% +% Rewritten from programs found in +% http://people.scs.fsu.edu/~burkardt/m_src/cvt/cvt.html +% +% Reference: +% Qiang Du, Vance Faber, and Max Gunzburger, +% Centroidal Voronoi Tessellations: Applications and Algorithms, +% SIAM Review, Volume 41, 1999, pages 637-676. +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-10, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% Init + +% number of germs and of points +Ng = size(germs, 1); +N = size(points, 1); + +% initialize centroids with values of germs +centroids = germs; + +% number of updates of each centroid +count = ones(Ng, 1); + + +%% Generate random points + +% for each point, determines which germ is the closest ones +[dist ind] = minDistancePoints(points, germs); %#ok + +h = zeros(Ng, 1); +for i = 1:Ng + h(i) = sum(ind==i); +end + + +%% Centroids update + +% add coordinate of each point to closest centroid +energy = 0; +for j = 1:N + centroids(ind(j), :) = centroids(ind(j), :) + points(j, :); + energy = energy + sum ( ( centroids(ind(j), :) - points(j, :) ).^2); + count(ind(j)) = count(ind(j)) + 1; +end + +% estimate coordinate by dividing by number of counts +centroids = centroids ./ repmat(count, 1, size(germs, 2)); + +% normalizes energy by number of sample points +energy = energy / N; + + +%% Format output + +varargout{1} = centroids; +if nargout > 1 + varargout{2} = energy; +end + + + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/delaunayGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/delaunayGraph.m new file mode 100644 index 0000000..de9f418 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/delaunayGraph.m @@ -0,0 +1,49 @@ +function [points edges] = delaunayGraph(points, varargin) +%DELAUNAYGRAPH Graph associated to Delaunay triangulation of input points +% +% [NODES EDGES] = delaunayGraph(POINTS) +% Compute the Delaunay triangulation of the set of input points, and +% convert to a set of edges. The output NODES is the same as the input +% POINTS. +% +% Example +% % Draw a planar graph correpspionding to Delaunay triangulation +% points = rand(30, 2) * 100; +% [nodes edges] = delaunayGraph(points); +% figure; +% drawGraph(nodes, edges); +% +% % Draw a 3Dgraph corresponding to Delaunay tetrahedrisation +% points = rand(20, 3) * 100; +% [nodes edges] = delaunayGraph(points); +% figure; +% drawGraph(nodes, edges); +% view(3); +% +% See Also +% delaunay, delaunayn +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-19, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% compute triangulation +tri = delaunayn(points, varargin{:}); + +% number of simplices (triangles), and of vertices by simplex (3 in 2D) +nt = size(tri, 1); +nv = size(tri, 2); + +% allocate memory +edges = zeros(nt * nv, 2); + +% compute edges of each simplex +for i = 1:nv-1 + edges((1:nt) + (i-1)*nt, :) = sort([tri(:, i) tri(:, i+1)], 2); +end +edges((1:nt) + (nv-1)*nt, :) = sort([tri(:, end) tri(:, 1)], 2); + +% remove multiple edges +edges = unique(edges, 'rows'); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDigraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDigraph.m new file mode 100644 index 0000000..c5ee0e6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDigraph.m @@ -0,0 +1,94 @@ +function varargout = drawDigraph(varargin) +%DRAWDIGRAPH Draw a directed graph, given as a set of vertices and edges +% +% drawDigraph(NODES1, NODES2, EDGES) +% NODES1 are originating vertices +% NODES2 are destination vertices +% EDGES is an array, with first column containing index of origin vertex +% (index in NODES1), and second column containing index of destination +% vertex (index in NODES2). +% Edges are drawn with arrows. +% +% H = drawDigraph(...) +% return handle to the set of edges. +% +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/08/2004. +% + + +%% Initialisations + +% check number of arguments +if nargin < 3 + help drawDigraph; + return; +end + +% initialisations +sn1 = 'bo'; % nodes are red circles +sn2 = 'ro'; % nodes are red circles + + +%% process input arguments + + +% First extract the graph structure +n1 = varargin{1}; +n2 = varargin{2}; +e = varargin{3}; +varargin = varargin(4:length(varargin)); + +% extract drawing style +if ~isempty(varargin) + sn1 = varargin{1}; +end + +if length(varargin)>1 + sn2 = varargin{2}; +end + + +%% main drawing processing + +hold on; + +nodes = [n1 ; n2]; +e(:,2) = e(:,2)+length(n1); + +% Draw a 2 dimensional directed graph ---------------------- + + +% Draw 2D Edges ---------------------- +%if ~strcmp(se, 'none') & size(e, 1)>0 +% he = plot([n1(e(:,1),1) n2(e(:,2),1)]', [n1(e(:,1),2) n2(e(:,2),2)]', se); +%end +he = drawDirectedEdges(nodes, e); + +hn = []; +% Draw 2D nodes ---------------------- +if ~strcmp(sn1, 'none') + hn = plot(n1(:,1), n1(:,2), sn1); +end + + % Draw 2D nodes ---------------------- +if ~strcmp(sn2, 'none') + hn = plot(n2(:,1), n2(:,2), sn2); +end + + +%% format output arguments + +if nargout==1 + varargout{1} = he; +end + +if nargout==2 + varargout{1} = hn; + varargout{2} = he; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDirectedEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDirectedEdges.m new file mode 100644 index 0000000..c202053 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawDirectedEdges.m @@ -0,0 +1,72 @@ +function varargout = drawDirectedEdges(p, e, varargin) +%DRAWDIRECTEDEDGES Draw edges with arrow indicating direction +% +% usage: +% drawDirectedEdges(NODES, EDGES); +% +% drawDirectedEdges(NODES, EDGES, STYLE); +% specifies style of arrrows. Can be one of: +% 'left' +% 'right' +% 'arrow' +% 'triangle' +% 'fill' +% +% drawDirectedEdges(NODES, EDGES, STYLE, DIRECT) : also specify the base +% direction of all edges. DIRECT is true by default. If DIRECT is false +% all edges are inverted. +% +% H = drawDirectedEdges(NODES, EDGES) : return handles to each of the +% lines created. +% +% TODO: now only style 'arrow' is implemented ... +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 12/03/2003. +% + +% HISTORY + + +b=1; + +if ~isempty(varargin) + b = varargin{1}; +end + +h = zeros(length(e),1); +hold on; +for l=1:length(e) + p1 = e(l, 1); + p2 = e(l, 2); + h(l*4) = line([p(p1,1) p(p2,1)], [p(p1,2) p(p2,2)]); + + % position of middles of edge + xm = (p(p1,1) + p(p2,1))/2; + ym = (p(p1,2) + p(p2,2))/2; + + % orientation of edge + theta = atan2(p(p2,2) - p(p1,2), p(p2,1) - p(p1,1)) + (b==0)*pi; + + % pin of the arrow + xa0 = xm + 10*cos(theta); + ya0 = ym + 10*sin(theta); + + % right side of the arrow + xa1 = xm + 3*cos(theta-pi/2); + ya1 = ym + 3*sin(theta-pi/2); + + % left side of the arrow + xa2 = xm + 3*cos(theta+pi/2); + ya2 = ym + 3*sin(theta+pi/2); + + h(l*4+1) = line([xa1 xa0], [ya1 ya0]); + h(l*4+2) = line([xa2 xa0], [ya2 ya0]); +end + +if nargout==1 + varargout(1) = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawEdgeLabels.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawEdgeLabels.m new file mode 100644 index 0000000..cdd7820 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawEdgeLabels.m @@ -0,0 +1,56 @@ +function varargout = drawEdgeLabels(p, e, value) +%DRAWEDGELABELS Draw values associated to graph edges +% +% usage: +% drawEdgeLabels(NODES, EDGES, VALUES); +% NODES: array of double, containing x and y values of nodes +% EDGES: array of int, containing indices of in and out nodes +% VALUES is an array the same length of EDGES, containing values +% associated to each edges of the graph. +% +% The function computes the center of each edge, and puts the text with +% associated value. +% +% H = drawEdgeLabels(...) return array of handles to each text structure, +% making possible to change font, color, size +% +% +% ----- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2003. +% + +% HISTORY +% 10/03/2004 included into lib/graph library + + +if length(p) > 1 && length(e) > 1 + h = zeros(length(e), 1); + hold on; + for l=1:length(e) + % indices of source and target nodes + n1 = e(l, 1); + n2 = e(l, 2); + + % node coordinates + x1 = p(n1, 1); + y1 = p(n1, 2); + x2 = p(n2, 1); + y2 = p(n2, 2); + + % display the edge + line([x1 x2], [y1 y2]); + + % coordinates of edge label + xm = (x1 + x2)/2; + ym = (y1 + y2)/2; + + % display label + h(l) = text(xm, ym, sprintf('%3d', floor(value(l)))); + end +end + +if nargout == 1 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraph.m new file mode 100644 index 0000000..f9b0ea4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraph.m @@ -0,0 +1,274 @@ +function varargout = drawGraph(varargin) +%DRAWGRAPH Draw a graph, given as a set of vertices and edges +% +% DRAWGRAPH(NODES, EDGES) +% draw a graph specified by a set of nodes (array N*2 or N*3, +% corresponding to coordinate of each node), and a set of edges (an array +% Ne*2, containing for each edge the first and the second node). +% Default drawing is a red circle for nodes and a blue line for edges. +% +% DRAWGRAPH(NODES, EDGES, FACES) +% also draw faces of the graph as patches. +% +% DRAWGRAPH(GRAPH) +% passes argument in a srtucture with at least 2 fields named 'nodes' and +% 'edges', and possibly one field 'faces', corresponding to previously +% described parameters. +% GRAPH can also be a cell array, whose first element is node array, +% second element is edges array, and third element, if present, is faces +% array. +% +% +% DRAWGRAPH(..., SNODES) +% DRAWGRAPH(..., SNODES, SEDGES) +% DRAWGRAPH(..., SNODES, SEDGES, SFACES) +% specify the draw mode for each element, as in the classical 'plot' +% function. To not display some elements, uses 'none'. +% +% +% H = DRAWGRAPH(...) +% return handle to the set of edges. +% +% [HN, HE] = DRAWGRAPH(...) +% return handle to the set of nodes and to the set of edges. +% +% [HN, HE, HF] = DRAWGRAPH(...) +% Also return handle to the set of faces. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/07/2003. +% + +% HISTORY +% 10/02/2004 : documentation +% 06/04/2004 : change name +% 09/07/2004 : add faces +% 05/08/2004 : correct bug when drawing 2D graph +% 06/08/2004 : small bug for drawing poins (length instead of size(.,1)) +% 09/08/2004 : rewrite code (separate 2D and 3D, use of plot instead of +% line, manage faces if present in 2D and 3D, ...), add style +% management, various input types, and documentation +% 22/09/2004 : correct bug in drawing faces +% 11/11/2005 : forgot a loop index for faces stored as cells +% 22/05/2009 add more drawing options + + +%% initialisations + +% uses empty arrays by default for edges and faces +e = []; +f = []; + +% default styles for nodes, edges, and faces + +% nodes are drawn as red circles +sn = {'linestyle', 'none', 'color', 'r', 'marker', 'o'}; + +% edges are drawn as blue lines +se = {'linestyle', '-', 'color', 'b'}; + +% faces are cyan, their edges are not drawn +sf = {'EdgeColor', 'none', 'Facecolor', 'c'}; + + +%% Process input arguments + +% case of a call without arguments +if nargin==0 + help drawGraph; + return; +end + +% --------------------------------------------------------------- +% First extract the graph structure + +var = varargin{1}; +if iscell(var) + % graph is stored as a cell array: first cell is nodes, second one is + % edges, and third is faces + n = var{1}; + if length(var)>1 + e = var{2}; + end + if length(var)>2 + f = var{3}; + end + varargin(1) = []; +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges', and + % eventually 'faces'. + n = var.nodes; + e = var.edges; + if isfield(var, 'faces') + f = var.faces; + end + varargin(1) = []; +else + % graph is stored as set of variables: nodes, edges, and eventually + % faces + n = varargin{1}; + e = varargin{2}; + varargin(1:2) = []; + + if ~isempty(varargin) + var = varargin{1}; + if isnumeric(var) + % faces are stored in a numeric array of indices + f = var; + varargin(1) = []; + elseif iscell(var) + if ~ischar(var{1}) + % faces are stored in a cell array, each cell containing a + % row vector of indices + f = var; + varargin(1) = []; + end + end + end +end + +% extract drawing style + +if ~isempty(varargin) + sn = concatArguments(sn, varargin{1}); +end + +if length(varargin)>1 + se = concatArguments(se, varargin{2}); +end + +if length(varargin)>2 + sf = concatArguments(sf, varargin{3}); +end + + + +%% main drawing processing + +hold on; + +if size(n, 2)==2 + % Draw a 2 dimensional graph ---------------------- + + % Draw faces of the graph ------------ + if ~strcmp(sf{1}, 'none') && ~isempty(f) + if iscell(f) + % each face is contained in a cell. + hf = zeros(size(f)); + for fi=1:length(f) + hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); + end + else + % process faces as an Nf*N array. Nf is the number of faces, + % and all faces have the same number of vertices (nodes). + hf = patch('Faces', f, 'Vertices', n, sf{:}); + end + end + + % Draw 2D Edges ---------------------- + if ~strcmp(se{1}, 'none') && size(e, 1)>0 + he = plot([n(e(:,1),1) n(e(:,2),1)]', [n(e(:,1),2) n(e(:,2),2)]', se{:}); + end + + % Draw 2D nodes ---------------------- + if ~strcmp(sn{1}, 'none') + hn = plot(n(:,1), n(:,2), sn{:}); + end + + +elseif size(n, 2)==3 + % Draw a 3 dimensional graph ---------------------- + + % use a zbuffer to avoid display pbms. + set(gcf, 'renderer', 'zbuffer'); + + % Draw 3D Faces ---------------------- + if ~strcmp(sf{1}, 'none') + if iscell(f) + % each face is contained in a cell. + hf = zeros(size(f)); + for fi=1:length(f) + hf(fi) = patch('Faces', f{fi}, 'Vertices', n, sf{:}); + end + else + % process faces as an Nf*N array. Nf i the number of faces, + % and all faces have the same number of vertices (nodes). + hf = patch('Faces', f, 'Vertices', n, sf{:}); + end + end + + % Draw 3D edges ---------------------- + if ~strcmp(se{1}, 'none') && size(e, 1)>0 +% he = plot3(... +% [n(e(:,1),1) n(e(:,2),1)]', ... +% [n(e(:,1),2) n(e(:,2),2)]', ... +% [n(e(:,1),3) n(e(:,2),3)]', ... +% se{:}); + he = line(... + [n(e(:,1),1) n(e(:,2),1)]', ... + [n(e(:,1),2) n(e(:,2),2)]', ... + [n(e(:,1),3) n(e(:,2),3)]', ... + se{:}); + end + + % Draw 3D nodes ---------------------- + if ~strcmp(sn{1}, 'none'); + hn = plot3(n(:,1), n(:,2), n(:,3), sn{:}); + end + +end + + +%% Format output arguments + +% return handle to edges +if nargout==1 + varargout{1} = he; +end + +% return handle to nodes and edges +if nargout==2 + varargout{1} = hn; + varargout{2} = he; +end + +% return handle to nodes, edges and faces +if nargout==3 + varargout{1} = hn; + varargout{2} = he; + varargout{3} = hf; +end + + + +end + +function res = concatArguments(in1, in2) +% in1 is a cell array already initialized +% in2 is an argument that can be: +% - empty +% - the string 'none' +% - another cell array + +if isempty(in2) + res = in1; + return; +end + +if ischar(in2) + if strcmp('none', in2) + res = {'none'}; + return; + end +end + +if iscell(in1) + res = [in1(:)' in2(:)']; +else + res = [{in1} in2(:)]; +end + +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphEdges.m new file mode 100644 index 0000000..f97bb39 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphEdges.m @@ -0,0 +1,99 @@ +function varargout = drawGraphEdges(varargin) +%DRAWGRAPHEDGES Draw edges of a graph +% +% drawGraphEdges(NODES, EDGES) +% Draws a graph specified by a set of nodes (array N-by-2 or N-by-3, +% corresponding to coordinate of each node), and a set of edges (an array +% Ne-by-2, containing to the first and the second node of each edge). +% +% drawGraphEdges(..., SEDGES) +% Specifies the draw mode for each element, as in the classical 'plot' +% function. +% Default drawing is a blue line for edges. +% +% +% H = drawGraphEdges(...) +% return handle to the set of edges. +% +% See also +% drawGraph +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-24 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY + + +%% Input argument processing + +% initialisations +e = []; + +% check input arguments number +if nargin == 0 + help drawGraphEdges; + return; +end + +% First extract the graph structure +var = varargin{1}; +if iscell(var) + % TODO: should consider array of graph structures. + % graph is stored as a cell array : first cell is nodes, second one is + % edges, and third is faces + n = var{1}; + if length(var) > 1 + e = var{2}; + end + varargin(1) = []; + +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges' + n = var.nodes; + e = var.edges; + varargin(1) = []; + +else + % graph is stored as set of variables: nodes + edges + n = varargin{1}; + e = varargin{2}; + varargin(1:2) = []; +end + +% check if there are edges to draw +if size(e, 1) == 0 + return; +end + +% setup default drawing style if not specified +if isempty(varargin) + varargin = {'-b'}; +end + + +%% main drawing processing + +if size(n, 2) == 2 + % Draw 2D edges + x = [n(e(:,1), 1) n(e(:,2), 1)]'; + y = [n(e(:,1), 2) n(e(:,2), 2)]'; + he = plot(x, y, varargin{:}); + +elseif size(n, 2) == 3 + % Draw 3D edges + x = [n(e(:,1), 1) n(e(:,2), 1)]'; + y = [n(e(:,1), 2) n(e(:,2), 2)]'; + z = [n(e(:,1), 3) n(e(:,2), 3)]'; + he = plot3(x, y, z, varargin{:}); + +end + + +%% format output arguments + +if nargout == 1 + varargout = {he}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphFaces.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphFaces.m new file mode 100644 index 0000000..e6b733a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawGraphFaces.m @@ -0,0 +1,144 @@ +function varargout = drawGraphFaces(varargin) +%DRAWGRAPHFACES Draw faces of a graph +% +% DRAWGRAPHFACES(NODES, EDGES) +% draw a graph specified by a set of nodes (array N*2 or N*3, +% corresponding to coordinate of each node), and a set of edges (an array +% Ne*2, containing for each edge the first and the second node). +% Default drawing is a red circle for nodes and a blue line for edges. +% +% DRAWGRAPHFACES(NODES, EDGES, FACES) +% also draw faces of the graph as patches. +% +% DRAWGRAPHFACES(GRAPH) +% passes argument in a srtucture with at least 3 fields named 'nodes', +% 'edges', and 'faces', corresponding to previously described parameters. +% GRAPH can also be a cell array, whose first element is node array, +% second element is edges array, and third element, if present, is faces +% array. +% +% +% DRAWGRAPHFACES(..., SFACES) +% specify the draw mode for each element, as in the classical 'plot' +% function. To not display some elements, uses 'none'. +% +% +% H = DRAWGRAPHFACES(...) +% return handle to the set of faces. +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2005-11-24 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY + +%% initialisations + +f = []; + +sf = 'c'; % faces are cyan + + +%% process input arguments + +if nargin==0 + help drawGraphFaces; + return; +end + +% First extract the graph structure + +var = varargin{1}; +if iscell(var) + % graph is stored as a cell array : first cell is nodes, second one is + % edges, and third is faces + n = var{1}; + if length(var) > 2 + f = var{3}; + end + varargin = varargin(2:length(varargin)); + +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges', and + % eventually 'faces'. + n = var.nodes; + if isfield(var, 'faces') + f = var.faces; + end + varargin = varargin(2:length(varargin)); + +else + % graph is stored as set of variables : nodes, edges, and eventually + % faces + n = varargin{1}; + if length(varargin) > 2 + var = varargin{3}; + if isnumeric(var) || iscell(var) + f = var; + varargin = varargin(4:length(varargin)); + else + varargin = varargin(3:length(varargin)); + end + else + varargin = varargin(3:length(varargin)); + end + +end + +% extract drawing style +if ~isempty(varargin) + sf = varargin{1}; +end + + +%% main drawing processing + +hold on; + +if size(n, 2) == 2 + % Draw faces of a 2D graph ------------ + if ~strcmp(sf, 'none') + if iscell(f) + % each face is contained in a cell. + for fi=1:length(f) + hf(fi) = patch('Faces', f{fi}, 'Vertices', n, 'FaceColor', sf, 'EdgeColor', 'none'); %#ok + end + else + % process faces as an Nf*N array. Nf i the number of faces, + % and all faces have the same number of vertices (nodes). + hf = patch('Faces', f, 'Vertices', n, 'FaceColor', sf, 'EdgeColor', 'none'); + end + end + +elseif size(n, 2) == 3 + % Draw faces of a 3D graph ---------------------- + + % use a zbuffer to avoid display pbms. + set(gcf, 'renderer', 'zbuffer'); + + % Draw 3D Faces ---------------------- + if ~strcmp(sf, 'none') + if iscell(f) + % each face is contained in a cell. + for fi=1:length(f) + hf(fi) = patch('Faces', f{fi}, 'Vertices', n, 'FaceColor', sf, 'EdgeColor', 'none'); %#ok + end + else + % process faces as an Nf*N array. Nf i the number of faces, + % and all faces have the same number of vertices (nodes). + hf = patch('Faces', f, 'Vertices', n, 'FaceColor', sf, 'EdgeColor', 'none'); + end + end + +end + + +%% format output arguments + +if nargout==1 + varargout{1} = hf; +end + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawNodeLabels.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawNodeLabels.m new file mode 100644 index 0000000..d1d841f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawNodeLabels.m @@ -0,0 +1,58 @@ +function varargout = drawNodeLabels(nodes, value) +%DRAWNODELABELS Draw values associated to graph nodes +% +% Usage: +% drawNodeLabels(NODES, VALUES); +% NODES: array of double, containing x and y values of nodes +% VALUES is an array the same length of EDGES, containing values +% associated to each edges of the graph. +% +% H = drawNodeLabels(...) +% Returns array of handles to each text structure, making it possible to +% change font, color, size +% +% ----- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2003. +% + +% HISTORY +% 10/03/2004 included into lib/graph library + +% number and dimension of nodes +Nn = size(nodes, 1); +Nd = size(nodes, 2); + +% check input size +if length(value) ~= Nn + error('Value array must have same length as node number'); +end + +% allocate memory +h = zeros(Nn, 1); + +if Nd == 2 + % Draw labels of 2D nodes + for i = 1:Nn + x = nodes(i, 1); + y = nodes(i, 2); + h(i) = text(x, y, sprintf('%3d', floor(value(i)))); + end + +elseif Nd == 3 + % Draw labels of 3D nodes + for i = 1:Nn + x = nodes(i, 1); + y = nodes(i, 2); + z = nodes(i, 3); + h(i) = text(x, y, z, sprintf('%3d', floor(value(i)))); + end + +else + error('Node dimension must be 2 or 3'); +end + +if nargout == 1 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawSquareMesh.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawSquareMesh.m new file mode 100644 index 0000000..ce91e1f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/drawSquareMesh.m @@ -0,0 +1,42 @@ +function varargout = drawSquareMesh(nodes, edges, faces, varargin) %#ok +%DRAWSQUAREMESH Draw a 3D square mesh given as a graph +% +% drawSquareMesh(NODES, EDGES, FACES) +% Draw the mesh defined by NODES, EDGES and FACES. FACES must be a N-by-4 +% array of vertex indices. +% +% See Also +% boundaryGraph, drawGraph +% +% --------- +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + +% input size check up +if size(faces, 2) ~= 4 + error('Requires a face array with 4 columns'); +end + +% number of faces +Nf = size(faces, 1); + +% allocate memory for vertex coordinates +px = zeros(4, Nf); +py = zeros(4, Nf); +pz = zeros(4, Nf); + +% initialize vertex coordinates of each face +for f = 1:Nf + face = faces(f, 1:4); + px(1:4, f) = nodes(face, 1); + py(1:4, f) = nodes(face, 2); + pz(1:4, f) = nodes(face, 3); +end + +p = patch(px, py, pz, 'r'); + +if nargout > 0 + varargout = {p}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/euclideanMST.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/euclideanMST.m new file mode 100644 index 0000000..3a18a71 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/euclideanMST.m @@ -0,0 +1,80 @@ +function varargout = euclideanMST(points) +%EUCLIDEANMST Build euclidean minimal spanning tree of a set of points +% +% EDGES = euclideanMST(POINTS) +% POINTS is a [NxP] array, N being the number of points and P being the +% dimension. +% Result EDGES is a [Mx2] array, containing indices of each vertex for +% each edges. +% +% [EDGES DISTS] = euclideanMST(POINTS) +% Also returns the lengths of edges computed by MST algorithm. +% +% Algorithm first computes Delaunay triangulation of the set of points, +% then computes euclidean length of each edge of triangulation, and +% finally uses prim algorithm to simplify the graph. +% +% Example +% % choose random points in the plane and display their Euclidean MST +% pts = rand(50, 2)*100; +% edges = euclideanMST(pts); +% drawGraph(pts, edges) +% +% See also +% prim_mst, distancePoints, delaunayn +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-07-27, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% dimension +D = size(points, 2); +Df = factorial(D); + +% compute all couples of vertices in unit triangle, tetrahedron, or n-dim +% simplex +subs = zeros(Df, 2); +k = 1; +for i = 1:D + for j = i+1:D+1 + subs(k, 1) = i; + subs(k, 2) = j; + k = k + 1; + end +end + +% compute delaunay triangulation in D dimensions +tri = delaunayn(points); +Nt = size(tri, 1); + +% compute all possible edges +edges = zeros(Nt*Df, 2); +for t = 1:Nt + for i = 1:Df + edges((t-1)*Df+i, 1) = tri(t, subs(i, 1)); + edges((t-1)*Df+i, 2) = tri(t, subs(i, 2)); + end +end + +% simplify edges +edges = unique(sort(edges, 2), 'rows'); + +% compute euclidean length of each edge +val = zeros(size(edges, 1), 1); +for i = 1:size(edges,1) + val(i) = distancePoints(points(edges(i,1), :), points(edges(i,2), :)); +end + +% compute MST of created graph +[edges2 vals2] = prim_mst(edges, val); + +% process output arguments +if nargout == 1 + varargout{1} = edges2; +elseif nargout==2 + varargout{1} = edges2; + varargout{2} = vals2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gabrielGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gabrielGraph.m new file mode 100644 index 0000000..2d6a871 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gabrielGraph.m @@ -0,0 +1,56 @@ +function varargout = gabrielGraph(pts) +%GABRIELGRAPH Gabriel Graph of a set of points +% +% EDGES = gabrielGraph(PTS) +% Computes the Gabriel graph of the input set of points PTS. The Gabriel +% graph is based on the euclidean Delaunay triangulation, and keeps only +% edges whose circumcircle does not contain any other input point than +% the edge extremities. +% +% [NODES EDGES] = gabrielGraph(PTS) +% Also returns the initial set of points; +% +% Example +% pts = rand(100, 2); +% edges = gabrielGraph(pts); +% figure; drawPoint(pts); +% hold on; axis([0 1 0 1]); axis equal; +% drawGraph(pts, edges); +% +% See also +% drawGraph, delaunayGraph +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2012-01-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2012 INRA - Cepia Software Platform. + +% compute delaunay triangulation +dt = DelaunayTri(pts); + +% extract edges (N-by-2 array) +eds = dt.edges(); + +% radius of the circule circumscribed to each edge +rads = edgeLength([pts(eds(:,1), :) pts(eds(:,2), :)]) / 2; + +% extract middle point of each edge +midPts = midPoint(pts(eds(:,1), :), pts(eds(:,2), :)); + +% distance between midpoints and all points +% closest points should be edge vertices +dists = minDistancePoints(midPts, pts); + +% geometric tolerance (adapted to point set extent) +tol = max(max(pts) - min(pts)) * eps; + +% keep only edges whose circumcircle does not contain any other point +keep = dists >= rads - tol; +edges = eds(keep, :); + +if nargout < 2 + varargout = {edges}; +else + varargout = {pts, edges}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour2d.m new file mode 100644 index 0000000..091a8a5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour2d.m @@ -0,0 +1,75 @@ +function [nodes, edges] = gcontour2d(img) +%GCONTOUR2D Creates contour graph of a 2D binary image. +% +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 25/06/2004. +% + +nodes = zeros([0 2]); +edges = zeros([0 2]); + +D1 = size(img, 1); +D2 = size(img, 2); + +% first direction for image +for i=1:D1 + + % find transitions between the two phases + ind = find(img(i, 1:D2-1)~=img(i, 2:D2)); + + % process each transition in direction 1 + for i2 = 1:length(ind) + + n1 = [i-.5 ind(i2)+.5]; + n2 = [i+.5 ind(i2)+.5]; + + ind1 = find(ismember(nodes, n1, 'rows')); + ind2 = find(ismember(nodes, n2, 'rows')); + if isempty(ind1) + nodes = [nodes; n1]; + ind1 = size(nodes, 1); + end + if isempty(ind2) + nodes = [nodes; n2]; + ind2 = size(nodes, 1); + end + + edges(size(edges, 1)+1, 1:2) = [ind1(1) ind2(1)]; + + end +end + + +% second direction for image +for i=1:D2 + + % find transitions between the two phases + ind = find(img(1:D1-1, i)~=img(2:D1, i)); + + % process each transition in direction 1 + for i2 = 1:length(ind) + + n1 = [ind(i2)+.5 i-.5]; + n2 = [ind(i2)+.5 i+.5]; + + ind1 = find(ismember(nodes, n1, 'rows')); + ind2 = find(ismember(nodes, n2, 'rows')); + if isempty(ind1) + nodes = [nodes; n1]; + ind1 = size(nodes, 1); + end + if isempty(ind2) + nodes = [nodes; n2]; + ind2 = size(nodes, 1); + end + + edges(size(edges, 1)+1, 1:2) = [ind1(1) ind2(1)]; + + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour3d.m new file mode 100644 index 0000000..7ade5f5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/gcontour3d.m @@ -0,0 +1,145 @@ +function [nodes, edges, faces] = gcontour3d(img) +%GCONTOUR3D Create contour graph of a 3D binary image. +% +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + +nodes = zeros([0 3]); % 3 coordinates vertices +edges = zeros([0 2]); % first node and second nodes +faces = zeros([0 4]); % indices of 4 corners of each square face + +D1 = size(img, 1); +D2 = size(img, 2); +D3 = size(img, 3); + +% first direction for image +for y=1:D2 + for z=1:D3 + % find transitions between the two phases + ind = find(img(1:D1-1, y, z)~=img(2:D1, y, z)); + + % process each transition in direction 1 + for i2 = 1:length(ind) + + % coordinates of each node + n1 = [ind(i2)+.5 y-.5 z-.5]; + n2 = [ind(i2)+.5 y-.5 z+.5]; + n3 = [ind(i2)+.5 y+.5 z+.5]; + n4 = [ind(i2)+.5 y+.5 z-.5]; + + % add the face (and edges) with the 4 given nodes + [nodes edges faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); + end + end +end + +% second direction for image +for x=1:D1 + for z=1:D3 + % find transitions between the two phases + ind = find(img(x, 1:D2-1, z)~=img(x, 2:D2, z)); + + % process each transition in direction 1 + for i2 = 1:length(ind) + + % coordinates of each node + n1 = [x-.5 ind(i2)+.5 z-.5]; + n2 = [x-.5 ind(i2)+.5 z+.5]; + n3 = [x+.5 ind(i2)+.5 z+.5]; + n4 = [x+.5 ind(i2)+.5 z-.5]; + + % add the face (and edges) with the 4 given nodes + [nodes edges faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); + end + end +end + +% third direction for image +for x=1:D1 + for y=1:D2 + % find transitions between the two phases + ind = find(img(x, y, 1:D3-1)~=img(x, y, 2:D3)); + + % process each transition in direction 1 + for i2 = 1:length(ind) + + % coordinates of each node + n1 = [x-.5 y-.5 ind(i2)+.5]; + n2 = [x-.5 y+.5 ind(i2)+.5]; + n3 = [x+.5 y+.5 ind(i2)+.5]; + n4 = [x+.5 y-.5 ind(i2)+.5]; + + % add the face (and edges) with the 4 given nodes + [nodes edges faces] = addFace(nodes, edges, faces, [n1; n2; n3; n4]); + end + end +end + + + +return; + + + +function [nodes, edges, faces] = addFace(nodes, edges, faces, faceNodes) +% add given nodes and coresponding face to the graph. + + +n1 = faceNodes(1,:); +n2 = faceNodes(2,:); +n3 = faceNodes(3,:); +n4 = faceNodes(4,:); + +% search indices of each nodes +ind1 = find(ismember(nodes, n1, 'rows')); +ind2 = find(ismember(nodes, n2, 'rows')); +ind3 = find(ismember(nodes, n3, 'rows')); +ind4 = find(ismember(nodes, n4, 'rows')); + +% if nodes are not in the list, we add them +if isempty(ind1) + nodes = [nodes; n1]; + ind1 = size(nodes, 1); +end +if isempty(ind2) + nodes = [nodes; n2]; + ind2 = size(nodes, 1); +end +if isempty(ind3) + nodes = [nodes; n3]; + ind3 = size(nodes, 1); +end +if isempty(ind4) + nodes = [nodes; n4]; + ind4 = size(nodes, 1); +end + +% add current face to the list +faces(size(faces, 1)+1, 1:4) = [ind1(1) ind2(1) ind3(1) ind4(1)]; + +% create edges of the face +% (first index is the smallest one, by convention) +e1 = [min(ind1, ind2) max(ind1, ind2)]; +e2 = [min(ind2, ind3) max(ind2, ind3)]; +e3 = [min(ind3, ind4) max(ind3, ind4)]; +e4 = [min(ind4, ind1) max(ind4, ind1)]; + + % if nodes are not in the list, we add them +if isempty(find(ismember(edges, e1, 'rows'), 1)) + edges = [edges; e1]; +end +if isempty(find(ismember(edges, e2, 'rows'), 1)) + edges = [edges; e2]; +end +if isempty(find(ismember(edges, e3, 'rows'), 1)) + edges = [edges; e3]; +end +if isempty(find(ismember(edges, e4, 'rows'), 1)) + edges = [edges; e4]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grClose.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grClose.m new file mode 100644 index 0000000..cbf4245 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grClose.m @@ -0,0 +1,45 @@ +function varargout = grClose(varargin) +%GRCLOSE Morphological closing on graph +% +% LBL2 = grClose(EDGES, LBL1) +% First performs dilatation, then erosion. +% +% Example +% grOpen +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grOpen"'); +end + +uni = unique(edges(:)); + +% performs dilation +lbl2 = zeros(size(lbl)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = max(lbl([uni(n); neigh])); +end + +% performs erosion +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl(uni(n)) = min(lbl2([uni(n); neigh])); +end + +varargout{1} = lbl; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grDilate.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grDilate.m new file mode 100644 index 0000000..d9fd3a3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grDilate.m @@ -0,0 +1,41 @@ +function varargout = grDilate(varargin) +%GRDILATE Morphological dilation on graph +% +% LBL2 = grDilate(EDGES, LBL1) +% Each label of the graph is assigned the highest label of its +% neighbours, or it keeps the same label this one is bigger. +% +% Example +% grDilate +% +% See also +% grErode, grOpen, grClose +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grDilate"'); +end + + +lbl2 = zeros(size(lbl)); + +uni = unique(edges(:)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = max(lbl([uni(n); neigh])); +end + +varargout{1} = lbl2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grErode.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grErode.m new file mode 100644 index 0000000..5ba9f45 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grErode.m @@ -0,0 +1,39 @@ +function varargout = grErode(varargin) +%GRERODE Morphological erosion on graph +% +% LBL2 = grErode(EDGES, LBL1) +% Each label of the graph is assigned the smallest label of its +% neighbours, or it keeps the same label this one is smaller. +% +% Example +% grErode +% +% See also +% grDilate, grOpen, grClose +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grErode"'); +end + +lbl2 = zeros(size(lbl)); + +uni = unique(edges(:)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = min(lbl([uni(n); neigh])); +end + +varargout{1} = lbl2; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFaceToPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFaceToPolygon.m new file mode 100644 index 0000000..dd9bd27 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFaceToPolygon.m @@ -0,0 +1,76 @@ +function pts2 = grFaceToPolygon(varargin) +%GRFACETOPOLYGON Compute the polygon corresponding to a graph face +% +% PTS2 = grFaceToPolygon(NODES, EDGES, FACES, INDF) +% PTS2 = grFaceToPolygon(NODES, FACES, INDF) +% Where NODES, EDGES, and FACES are internal data of graph, and INDF is +% the index of the face to extract. The result is the (ordered) set of +% points composing the face. +% +% +% PTS2 = grFaceToPolygon(GRAPH, INDF) +% use structure representation for graph. The structure GRAPH must +% contain data for fields 'nodes' and 'faces'. +% +% If several indices face indices are specified, result is a cell array +% of polygons. +% +% The number of columns of PTS2 is the same as for NODES. +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-30 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 27/07/2007: cleanup code + +if length(varargin)==2 + % argument is a graph structure + graph = varargin{1}; + nodes = graph.nodes; + faces = graph.faces; + indf = varargin{2}; + +elseif length(varargin)==3 + % arguments are nodes, faces and indices + nodes = varargin{1}; + faces = varargin{2}; + indf = varargin{3}; + +elseif length(varargin)==4 + % arguments are nodes, edges, faces and indices, we forget edges + nodes = varargin{1}; + faces = varargin{3}; + indf = varargin{4}; +end + + +if iscell(faces) + % faces is a cell array + if length(indf)==1 + face = faces{indf}; + pts2 = nodes(face, :); + else + pts2 = cell(length(indf), 1); + for i=1:length(indf) + face = faces{indf(i)}; + pts2{i} = nodes(face, :); + end + end +else + % faces is an indices array: all faces have same number of vertices + if length(indf)==1 + face = faces(indf, :); + pts2 = nodes(face, :); + else + pts2 = cell(length(indf), 1); + for i=1:length(indf) + face = faces(indf(i), :); + pts2{i} = nodes(face, :); + end + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindGeodesicPath.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindGeodesicPath.m new file mode 100644 index 0000000..80a0e31 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindGeodesicPath.m @@ -0,0 +1,65 @@ +function path = grFindGeodesicPath(nodes, edges, ind0, ind1, edgeWeights) +%GRFINDGEODESICPATH Find a geodesic path between two nodes in the graph +% +% PATH = grFindGeodesicPath(NODES, EDGES, NODE1, NODE2, WEIGHTS) +% NODES and EDGES defines the graph, NODE1 and NODE2 are indices of the +% node extremities, and WEIGHTS is the set of weights associated to each +% edge. +% The function returns a set of edge indices. +% +% +% See also +% grFindMaximalLengthPath +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% ensure weights are defined +if ~exist('edgeWeights', 'var') + edgeWeights = ones(size(edges, 1), 1); +end + +% check indices limits +nNodes = size(nodes, 1); +if max(ind0) > nNodes + error('Start index exceed number of nodes in the graph'); +end +if max(ind1) > nNodes + error('End index exceed number of nodes in the graph'); +end + +% find a vertex opposite to the first extremity +dists = grPropagateDistance(nodes, edges, ind0, edgeWeights); + +% iterate on neighbors of current node: choose next neighbor with smallest +% cumulated weight, until we are back on source node +path = []; +while true + % find neighbor with lowest cumulated distance + neighs = grNeighborNodes(edges, ind1); + neighDists = dists(neighs); + indN = find(neighDists == min(neighDists), 1); + ind2 = neighs(indN); + + if isempty(ind2) + warning('graphs:grFindGeodesicPath', ... + 'No neighbor node found for node %d, graph may be not connected', ind1); + break; + end + + % add edge index to the path + indE = find(sum(ismember(edges, [ind1 ind2]), 2) == 2, 1); + path = [path indE]; %#ok + + % test if path is finished or not + if ind2 == ind0 + break; + end + ind1 = ind2; +end + +% reverse path direction +path = path(end:-1:1); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindMaximalLengthPath.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindMaximalLengthPath.m new file mode 100644 index 0000000..5733e52 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grFindMaximalLengthPath.m @@ -0,0 +1,60 @@ +function path = grFindMaximalLengthPath(nodes, edges, edgeWeights) +%GRFINDMAXIMALLENGTHPATH Find a path that maximizes sum of edge weights +% +% PATH = grFindMaximalLengthPath(NODES, EDGES, EDGE_WEIGHTS); +% Finds a greatest geodesic path in the graph. A path between two nodes +% is a succession of adjacent edges that link the first and last nodes. +% the length of the path is the sum of weights of edges that constitute +% the path. +% A geodesic path is a path that minimizes the length of the path among +% the set of paths between the nodes. +% A maximal length path maximizes the length of the geodesic path between +% couples of nodes in the graph +% +% The result PATH is the list of edge indices that constitutes the path. +% +% PATH = grFindMaximalLengthPath(NODES, EDGES); +% Assumes each edge has a weight equal to 1. +% +% See Also +% grFindGeodesicPath +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-05-22, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% ensure weights are defined +if ~exist('edgeWeights', 'var') + edgeWeights = ones(size(edges, 1), 1); +end + +% find an extremity vertex +inds = graphPeripheralVertices(nodes, edges, edgeWeights); +ind0 = inds(end); + +% find a vertex opposite to the first extremity +dists = grPropagateDistance(nodes, edges, ind0, edgeWeights); +ind1 = find(dists == max(dists), 1, 'first'); + +% iterate on neighbors of current node: choose next neighbor with smallest +% cumulated weight, until we are back on source node +path = []; +while true + % find neighbor with lowest cumulated distance + neighs = grNeighborNodes(edges, ind1); + neighDists = dists(neighs); + indN = find(neighDists == min(neighDists), 1); + ind2 = neighs(indN); + + % add edge index to the path + indE = find(sum(ismember(edges, [ind1 ind2]), 2) == 2, 1); + path = [path indE]; %#ok + + % test if path is finished or not + if ind2 == ind0 + break; + end + ind1 = ind2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grLabel.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grLabel.m new file mode 100644 index 0000000..d171b78 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grLabel.m @@ -0,0 +1,59 @@ +function labels = grLabel(nodes, edges) +%GRLABEL Associate a label to each connected component of the graph +% LABELS = grLabel(NODES, EDGES) +% Returns an array with as many rows as the array NODES, containing index +% number of each connected component of the graph. If the graph is +% totally connected, returns an array of 1. +% +% Example +% nodes = rand(6, 2); +% edges = [1 2;1 3;4 6]; +% labels = grLabel(nodes, edges); +% labels = +% 1 +% 1 +% 1 +% 2 +% 3 +% 2 +% +% See also +% getNeighborNodes +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% init +Nn = size(nodes, 1); +labels = (1:Nn)'; + +% iteration until stability +modif = true; +while modif + modif = false; + + % compute the minimum label in the neighborhood of each node + for i = 1:Nn + neigh = grNeighborNodes(edges, i); + neighLabels = labels([i;neigh]); + + % check for a modification + if length(unique(neighLabels)) > 1 + modif = true; + end + + % put new labels + labels(ismember(labels, neighLabels)) = min(neighLabels); + end +end + +% renumbering to have fewer labels +labels2 = unique(labels); +for i = 1:length(labels2) + labels(labels == labels2(i)) = i; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMean.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMean.m new file mode 100644 index 0000000..b446414 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMean.m @@ -0,0 +1,41 @@ +function varargout = grMean(varargin) +%GRMEAN Compute mean from neihgbours +% +% LBL2 = grMean(EDGES, LBL1) +% new label for each node of the graph is computed as the mean of the +% values of neighbours and of old value. +% +% Example +% grMean +% +% See also +% grMedian, grDilate, grErode +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grMean"'); +end + + +lbl2 = zeros(size(lbl)); + +uni = unique(edges(:)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = mean(lbl([uni(n); neigh])); +end + +varargout{1} = lbl2; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMedian.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMedian.m new file mode 100644 index 0000000..274374a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMedian.m @@ -0,0 +1,41 @@ +function varargout = grMedian(varargin) +%GRMEDIAN Compute median from neihgbours +% +% LBL2 = grMedian(EDGES, LBL1) +% new label for each node of the graph is computed as the median of the +% values of neighbours and of old value. +% +% Example +% grMedian +% +% See also +% grMean, grDilate, grErode +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grMedian"'); +end + + +lbl2 = zeros(size(lbl)); + +uni = unique(edges(:)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = median(lbl([uni(n); neigh])); +end + +varargout{1} = lbl2; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleEdges.m new file mode 100644 index 0000000..2866c45 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleEdges.m @@ -0,0 +1,41 @@ +function varargout = grMergeMultipleEdges(nodes, edges) +%GRMERGEMULTIPLEEDGES Remove all edges sharing the same extremities +% +% [NODES2 EDGES2] = grMergeMultipleEdges(NODES, EDGES) +% Remove configuration with two edges sharing the same 2 nodes. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 doc +% 2011-05-18 rename to grMergeMultipleEdges + +rmedge = []; +for e = 1:length(edges) + edge = edges(e, :); + for e2 = e+1:length(edges) + if (edge(1) == edges(e2, 1) && edge(2) == edges(e2, 2)) || ... + (edge(1) == edges(e2, 2) && edge(2) == edges(e2, 1)) + rmedge(length(rmedge)+1) = e2; %#ok + end + end +end + +[nodes edges] = grRemoveEdges(nodes, edges, rmedge); + +% process output depending on how many arguments are needed +if nargout == 1 + out{1} = nodes; + out{2} = edges; + varargout{1} = out; +end + +if nargout == 2 + varargout = {nodes, edges}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleNodes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleNodes.m new file mode 100644 index 0000000..9948285 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeMultipleNodes.m @@ -0,0 +1,110 @@ +function varargout = grMergeMultipleNodes(varargin) +%GRMERGEMULTIPLENODES Simplify a graph by merging multiple nodes +% +% OUTPUT = grMergeMultipleNodes(INPUT); +% simplify the graph INPUT, and return the result in the graph OUTPUT. +% format for input can be one of +% nodes, edges +% +% Two steps in the procedure : +% * first remove multiple nodes. find all nodes with same coords, and +% keep only one +% * remove edges that link same nodes +% +% ----- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 09/08/2004. +% + + + +%% process input arguments + +n = []; +e = []; +f = []; + +% extract data of the graph +var = varargin{1}; +if iscell(var) + % graph is stored as a cell array : first cell is nodes, second one is + % edges, and third is faces + n = var{1}; + if length(var)>1 + e = var{2}; + end + if length(var)>2 + f = var{3}; + end +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges', and + % eventually 'faces'. + n = var.nodes; + e = var.edges; + if isfield(var, 'faces') + f = var.faces; + end +elseif length(varargin)>1 + % graph is stored as set of variables : nodes, edges, and eventually + % faces + n = varargin{1}; + e = varargin{2}; + + if length(varargin)==3 + f = varargin{3}; + end +end + + +%% Main processing + +% simplify graph to remove multiple nodes, and adapt edges and faces +% indices + +% simplify nodes +[n, i, j] = unique(n, 'rows'); %#ok + +% change edges indices and remove double edges (undirected graph) +for i = 1:length(e(:)) + e(i) = j(e(i)); %#ok +end +e = unique(sort(e, 2), 'rows'); + +% change faces indices +if iscell(f) + % faces stored as cell array (irregular mesh) + for k = 1:length(f) + face = f{k}; + for i = 1:length(face(:)) + face(i) = j(face(i)); + end + f{k} = face; %#ok + end +else + % faces indices stored as regular array (square or triangle mesh). + for i = 1:length(f(:)) + f(i) = j(f(i)); %#ok + end +end + + +%% process output depending on how many arguments are needed + +if nargout == 1 + out{1} = n; + out{2} = e; + varargout{1} = out; +end + +if nargout == 2 + varargout{1} = n; + varargout{2} = e; +end + +if nargout == 3 + varargout{1} = n; + varargout{2} = e; + varargout{3} = f; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodeClusters.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodeClusters.m new file mode 100644 index 0000000..c76bffe --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodeClusters.m @@ -0,0 +1,80 @@ +function [nodes2 edges2] = grMergeNodeClusters(nodes, edges) +%GRMERGENODECLUSTERS Merge cluster of connected nodes in a graph +% +% grMergeNodeClusters(nodes, edges) +% Detects groups of nodes that belongs to the same global node, and +% replace them by a unique node. Coordinates of reference node is given +% by the median coordinates of cluster nodes. +% +% This function is intended to be used as filter after a binary image +% skeletonization and vectorization. +% +% +% See Also +% grMergeNodesMedian +% +% ----- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY + + +%% Initialization + +% intialize result +nodes2 = nodes; +edges2 = edges; + +% compute degree of each node +degrees = grNodeDegree(1:size(nodes, 1), edges)'; + +% find index of multiple nodes +indMul = find(degrees > 2); + +% indices of edges that link several multiple nodes +indEdges = sum(ismember(edges, indMul), 2) == 2; + +% associate a label to each cluster +labels = grLabel(nodes, edges(indEdges, :)); +clusterLabels = unique(labels(indMul)); + + +%% Replace each cluster by median point + +% iterate on clusters +for i = 1:length(clusterLabels) + % indices of nodes of the current cluster + inds = find(labels == clusterLabels(i)); + + % coordinates of new reference node + clusterNodes = nodes(inds, :); + medianNode = median(clusterNodes, 1); + + % replace coordinates of reference node + refNode = min(inds); + nodes2(refNode, :) = medianNode; + + % replace node indices in edge array + edges2(ismember(edges2, inds)) = refNode; +end + + +%% Clean up + +% keep only relevant nodes +inds = unique(edges2(:)); +nodes2 = nodes2(inds, :); + +% relabeling of edges +for i = 1:length(inds) + edges2(edges2 == inds(i)) = i; +end + +% remove double edges +edges2 = unique(sort(edges2, 2), 'rows'); + +% remove 'loops' +edges2(edges2(:,1) == edges2(:,2), :) = []; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodes.m new file mode 100644 index 0000000..803ed13 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodes.m @@ -0,0 +1,38 @@ +function [nodes, edges] = grMergeNodes(nodes, edges, mnodes) +%GRMERGENODES Merge two (or more) nodes in a graph. +% +% usage: +% [NODES2 EDGES2] = grMergeNodes(NODES, EDGES, NODE_INDS) +% NODES and EDGES are wo arrays representing a graph, and NODE_INDS is +% the set of indices of the nodes to merge. +% The nodes corresponding to indices in NODE_INDS are removed from the +% list, and edges between two nodes are removed. +% +% Example: merging of lables 1 and 2 +% Edges: Edges2: +% [1 2] [1 3] +% [1 3] [1 4] +% [1 4] [3 4] +% [2 3] +% [3 4] +% +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 30/06/2004. +% + +refNode = mnodes(1); +mnodes = mnodes(2:length(mnodes)); + +% replace merged nodes references by references to refNode +edges(ismember(edges, mnodes))=refNode; + +% remove "loop edges" from and to reference node +edges = edges(edges(:,1) ~= refNode | edges(:,2) ~= refNode, :); + +% format output +edges = sortrows(unique(sort(edges, 2), 'rows')); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodesMedian.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodesMedian.m new file mode 100644 index 0000000..eb11b28 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grMergeNodesMedian.m @@ -0,0 +1,61 @@ +function [nodes2, edges2] = grMergeNodesMedian(nodes, edges, mnodes) +%GRMERGENODESMEDIAN Replace several nodes by their median coordinate +% +% [NODES2 EDGES2] = grMergeNodesMedian(NODES, EDGES, NODES2MERGE) +% NODES ans EDGES are the graph structure, and NODES2MERGE is the list of +% indices of nodes to be merged. +% The median coordinate of merged nodes is computed, and all nodes are +% merged to this new node. +% +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 : documentation + + +% coordinates of reference node +x = median(nodes(mnodes, 1)); +y = median(nodes(mnodes, 2)); + +% index of reference node +refNode = findPoint([x y], nodes); +mnodes = sort(mnodes(mnodes ~= refNode)); + +for n = 1:length(mnodes) + node = mnodes(n); + + % process each neighbor of the current node + neighbors = grNeighborNodes(edges, node); + for e = 1:length(neighbors) + edge = neighbors(e); + + if edges(edge, 1) == refNode || edges(edge, 2) == refNode + continue; + end + + % find if the node is referenced as 1 or 2 in the edge, + % and replace it with the reference node. + if edges(edge, 1) == node + edges(edge, 1) = refNode; + else + edges(edge, 2) = refNode; + end + + end +end + +% remove nodes from the list, except the reference node. +for n = 1:length(mnodes) + [nodes edges] = grRemoveNode(nodes, edges, mnodes(n)-n+1); +end + +nodes2 = nodes; +edges2 = edges; + + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborEdges.m new file mode 100644 index 0000000..a2f0723 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborEdges.m @@ -0,0 +1,21 @@ +function neigh = grNeighborEdges(edges, node) +%GRNEIGHBOREDGES Find adjacent edges of a given node +% +% NEIGHS = grNeighborEdges(EDGES, NODE) +% EDGES : the complete edges list +% NODE : index of the node +% NEIGHS : the indices of edges containing the node index +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 : documentation +% 13/07/2004 : faster algorithm +% 17/01/2006 : rename and change implementation + +neigh = find(edges(:,1) == node | edges(:,2) == node); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborNodes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborNodes.m new file mode 100644 index 0000000..ab00a7f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNeighborNodes.m @@ -0,0 +1,27 @@ +function nodes2 = grNeighborNodes(edges, node) +%GRNEIGHBORNODES Find adjacent nodes of a given node +% +% NEIGHS = grNeighborNodes(EDGES, NODE) +% EDGES: the complete edges list +% NODE: index of the node +% NEIGHS: the nodes adjacent to the given node. +% +% NODE can also be a vector of node indices, in this case the result is +% the set of neighbors of any input node. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 16/08/2004. +% + +% HISTORY +% 10/02/2004 documentation +% 13/07/2004 faster algorithm +% 03/10/2007 can specify several input nodes + +[i, j] = find(ismember(edges, node)); %#ok +nodes2 = edges(i,1:2); +nodes2 = unique(nodes2(:)); +nodes2 = sort(nodes2(~ismember(nodes2, node))); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeDegree.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeDegree.m new file mode 100644 index 0000000..c69587e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeDegree.m @@ -0,0 +1,34 @@ +function degree = grNodeDegree(node, edges) +%GRNODEDEGREE Degree of a node in a (undirected) graph +% +% DEG = grNodeDegree(NODE_INDEX, EDGES); +% return the degree of a node in the given edge list, that is the number +% of edges connected to it. +% NODE_INDEX is the index of the node, and EDGES is a liste of couples of +% indices (origin and destination node). +% This degree is the sum of inner degree (number of edges arriving on the +% node) and the outer degree (number of emanating edges). +% +% Note: Also works when NODE_INDEX is a vector of indices +% +% To get degrees of all nodes: +% grNodeDegree(1:size(nodes, 1), edges) +% +% See Also: grNodeInnerDegree, grNodeOuterDegree +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2003-08-13 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 10/02/2004 documentation +% 17/01/2006 change name, reimplement, and rewrite doc. + +degree = zeros(size(node)); + +for i = 1:length(node(:)) + degree(i) = sum(edges(:,1) == node(i)) + sum(edges(:,2) == node(i)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeInnerDegree.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeInnerDegree.m new file mode 100644 index 0000000..c85cece --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeInnerDegree.m @@ -0,0 +1,33 @@ +function degree = grNodeInnerDegree(node, edges) +%GRNODEINNERDEGREE Inner degree of a node in a graph +% +% DEG = grNodeInnerDegree(NODE, EDGES); +% Returns the inner degree of a node in the given edge list, i.e. the +% number of edges arriving to it. +% NODE is the index of the node, and EDGES is a liste of couples of +% indices (origin and destination node). +% +% Note: Also works when node is a vector of indices +% +% See Also: +% grNodeDegree, grNodeOuterDegree +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-17 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). +% + +% HISTORY +% 2008-08-07 pre-allocate memory, update doc + +% allocate memory +N = size(node, 1); +degree = zeros(N, 1); + +% compute inner degree of each vertex +for i=1:length(node) + degree(i) = sum(edges(:,2)==node(i)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeOuterDegree.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeOuterDegree.m new file mode 100644 index 0000000..cbdf036 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grNodeOuterDegree.m @@ -0,0 +1,34 @@ +function degree = grNodeOuterDegree(node, edges) +%GRNODEOUTERDEGREE Outer degree of a node in a graph +% +% DEG = grNodeOuterDegree(NODE, EDGES); +% Returns the outer degree of a node in the given edge list, i.e. the +% number of edges emanating from it. +% NODE is the index of the node, and EDGES is a liste of couples of +% indices (origin and destination node). +% +% Note: Also works when node is a vector of indices +% +% See Also: +% grNodeDegree, grNodeInnerDegree +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-17 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). +% + +% HISTORY +% 2008-08-07 pre-allocate memory, update doc + + +% allocate memory +N = size(node, 1); +degree = zeros(N, 1); + +% compute outer degree of each vertex +for i=1:N + degree(i) = sum(edges(:,1)==node(i)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOpen.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOpen.m new file mode 100644 index 0000000..baca4b8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOpen.m @@ -0,0 +1,48 @@ +function varargout = grOpen(varargin) +%GROPEN Morphological opening on graph +% +% LBL2 = grOpen(EDGES, LBL1) +% The labels are the result of a morphological erosion followed by a +% morphological dilation. +% +% Example +% grOpen +% +% See also +% grClose, grErode, grDilate +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-01-20 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin) == 2 + edges = varargin{1}; + lbl = varargin{2}; +elseif length(varargin) == 3 + edges = varargin{2}; + lbl = varargin{3}; +else + error('Wrong number of arguments in "grOpen"'); +end + + +uni = unique(edges(:)); + +% performs erosion +lbl2 = zeros(size(lbl)); +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl2(uni(n)) = min(lbl([uni(n); neigh])); +end + +% performs dilation +for n = 1:length(uni) + neigh = grNeighborNodes(edges, uni(n)); + lbl(uni(n)) = max(lbl2([uni(n); neigh])); +end + +varargout{1} = lbl; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOppositeNode.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOppositeNode.m new file mode 100644 index 0000000..7eaea22 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grOppositeNode.m @@ -0,0 +1,31 @@ +function node2 = grOppositeNode(edges, node) +%GROPPOSITENODE Return opposite node in an edge +% +% NODE2 = grOppositeNode(EDGE, NODE); +% Return the index of the node opposite to NODE in EDGE. +% If the edge does not contain node NODE, result is 0. +% +% Works also if EDGE is a N-by-2 array of source and target vertex +% indices, in this case the result NODE2 has as many rows as the number +% of edges. +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY + +% allocate memory for result +Ne = size(edges, 1); +node2 = zeros(Ne, 1); + +% iterate on edges +for i = 1:Ne + if edges(i,1) == node + node2(i) = edges(i,2); + elseif edges(i,2) == node + node2(i) = edges(i,1); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grPropagateDistance.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grPropagateDistance.m new file mode 100644 index 0000000..a4f65be --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grPropagateDistance.m @@ -0,0 +1,80 @@ +function d = grPropagateDistance(v, e, v0, l) +%GRPROPAGATEDISTANCE Propagates distances from a vertex to other vertices +% +% DISTS = grPropagateDistance(V, E, V0, L) +% V0 is index of initial vertex +% E is array of source and target vertices +% L is the vector of length of each edge. If not specified, length 1 is +% assumed for all edges. +% The result DISTS is a column array with as many rows as the number of +% vertices, containing the geodesic distance of each vertex to the vertex +% of index V0. +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% DISTS = grPropagateDistance(nodes, edges, 2) +% DISTS = +% 1 +% 0 +% 1 +% 1 +% 3 +% 2 +% 3 +% drawNodeLabels(nodes+1, DISTS); +% +% See Also +% graphRadius, graphCenter, graphDiameter, graphPeripheralVertices +% grVertexEccentricity +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + + +% initialize empty array for result +Nv = length(v); +d = ones(Nv, 1)*inf; +d(v0) = 0; + +% ensure there is a valid length array +if nargin < 4 + l = ones(size(e,1), 1); +end + +% iterate from germ vertex until there are no more vertices to process +verticesToProcess = v0; +while ~isempty(verticesToProcess) + % init new iteration + newVerticesToProcess = []; + + % iterate over vertices that need to be updated + for i = 1:length(verticesToProcess) + vertex = verticesToProcess(i); + + % iterate over neighbor edges of current vertex + vertexEdges = grNeighborEdges(e, vertex); + for j = 1:length(vertexEdges) + iEdge = vertexEdges(j); + + % compute distance between current vertex and its neighbor + vertex2 = grOppositeNode(e(iEdge,:), vertex); + newDist = d(vertex) + l(iEdge); + + % update geodesic distance of neighbor node if needed + if newDist < d(vertex2) + d(vertex2) = newDist; + newVerticesToProcess = [newVerticesToProcess ; vertex2]; %#ok + end + end + end + + % update set of vertices for next tieration + verticesToProcess = newVerticesToProcess; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdge.m new file mode 100644 index 0000000..51705b2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdge.m @@ -0,0 +1,22 @@ +function [nodes, edges2] = grRemoveEdge(nodes, edges, edge) +%GRREMOVEEDGE Remove an edge in a graph. +% +% [NODES2 EDGES2] = grRemoveEdge(NODES, EDGES, EDGE2REMOVE) +% Remove an edge in the edges list, and return the modified graph. +% The NODES array is not modified. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 doc + + +dim = size(edges); +edges2 = zeros(dim(1)-1, 2); +edges2(1:edge-1, :) = edges(1:edge-1, :); +edges2(edge:dim(1)-1, :) = edges(edge+1:dim(1), :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdges.m new file mode 100644 index 0000000..a9f73a3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveEdges.m @@ -0,0 +1,51 @@ +function [nodes2, edges2] = grRemoveEdges(nodes, edges, rmEdges) +%GRREMOVEEDGES Remove several edges from a graph +% +% [NODES2 EDGES2] = grRemoveEdges(NODES, EDGES, EDGES2REMOVE) +% Remove some edges in the edges list, and return the modified graph. +% The NODES array is not modified. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY : +% 10/02/2004 : doc + + +rmEdges = sort(rmEdges); + +% do not change the node list +nodes2 = nodes; + +% number of edges +N = size(edges, 1); +NR = length(rmEdges); +N2 = N - NR; + +% allocate memory for new edges list +edges2 = zeros(N2, 2); + +% case of no edge to remove +if NR == 0 + nodes2 = nodes; + edges2 = edges; + return; +end + +% process the first edge +edges2(1:rmEdges(1)-1,:) = edges(1:rmEdges(1)-1,:); + +% process the classical edges +for i = 2:NR + %if rmEdges(i)-i < rmEdges(i-1)-i+2 + % continue; + %end + edges2(rmEdges(i-1)-i+2:rmEdges(i)-i, :) = edges(rmEdges(i-1)+1:rmEdges(i)-1, :); +end + +% process the last edge +edges2(rmEdges(NR)-NR+1:N2, :) = edges(rmEdges(NR)+1:N, :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveMultiplePoints.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveMultiplePoints.m new file mode 100644 index 0000000..67a01ca --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveMultiplePoints.m @@ -0,0 +1,66 @@ +function varargout = grRemoveMultiplePoints(nodes, edges) +%GRREMOVEMULTIPLEPOINTS Remove groups of close nodes in a graph +% +% grRemoveMultiplePoints(nodes, edges) +% Detects groups of nodes that belongs to the same global node. +% This function is intended to be used as filter after a binary image +% skeletonization and vectorization. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 doc +% 27/04/2005 function was not working, due to mergeNode modification. + + +% TODO: accelerate function, by limiting action on nodes with degree>2 +% TODO: algo does not work, it can forget some groups. + +n = 1; +while n <= length(nodes) + + x = nodes(n, 1); + y = nodes(n, 2); + + p1 = findPoint([x-1, y], nodes); + p2 = findPoint([x+1, y], nodes); + p3 = findPoint([x, y-1], nodes); + p4 = findPoint([x, y+1], nodes); + + p = [p1 p2 p3 p4]; + p = p(p ~= 0); + + if length(p) > 1 + [nodes edges] = grMergeNodes(nodes, edges, [n p]); + end + + n = n+1; +end + +% renumerate edges +b = unique(edges(:)); +for i = 1:length(b) + edges(edges == b(i)) = i; +end + +% remove extra nodes +nodes = nodes(b, :); + + +% process output depending on how many arguments are needed +if nargout == 1 + out{1} = nodes; + out{2} = edges; + varargout{1} = out; +end + +if nargout == 2 + varargout{1} = nodes; + varargout{2} = edges; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNode.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNode.m new file mode 100644 index 0000000..a70ba5b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNode.m @@ -0,0 +1,41 @@ +function [nodes2, edges2] = grRemoveNode(nodes, edges, node) +%GRREMOVENODE Remove a node in a graph +% +% usage: +% [NODES2 EDGES2] = grRemoveNode(NODES, EDGES, NODE2REMOVE) +% remove the node with index NODE2REMOVE from array NODES, and also +% remove edges containing the node NODE2REMOVE. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004: doc + + +% remove all edges connected to the node +neighbours = grNeighborNodes(edges, node); +[nodes2, edges2] = grRemoveEdges(nodes, edges, neighbours); %#ok + + +% change edges information, due to the node index shift +for i = 1:length(edges2) + if edges2(i,1) > node + edges2(i,1) = edges2(i,1) - 1; + end + if edges2(i,2) > node + edges2(i,2) = edges2(i,2) - 1; + end +end + +% allocate memory +dim = size(nodes); +nodes2 = zeros(dim(1)-1, 2); + +% copy nodes information, except the undesired node +nodes2(1:node-1, :) = nodes(1:node-1, :); +nodes2(node:dim(1)-1, :) = nodes(node+1:dim(1), :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNodes.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNodes.m new file mode 100644 index 0000000..6772079 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grRemoveNodes.m @@ -0,0 +1,64 @@ +function [nodes2, edges2] = grRemoveNodes(nodes, edges, rmNodes) +%GRREMOVENODES Remove several nodes in a graph +% +% usage: +% [NODES2 EDGES2] = grRemoveNodes(NODES, EDGES, NODES2REMOVE) +% remove the nodes with indices NODE2REMOVE from array NODES, and also +% remove edges containing the nodes NODE2REMOVE. +% +% ----- +% +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 doc + + +%% edges processing + +% remove all edges connected to each node +for i = 1:length(rmNodes) + neighbours = grNeighborNodes(edges, rmNodes(i)); + if ~isempty(neighbours) + [nodes, edges] = grRemoveEdges(nodes, edges, neighbours); + end +end + +% change edges information, due to the node index shift +for n = 1:length(rmNodes) + for i = 1:length(edges) + if edges(i,1) > rmNodes(n)-n+1 + edges(i,1) = edges(i,1) - 1; + end + if edges(i,2) > rmNodes(n)-n+1 + edges(i,2) = edges(i,2) - 1; + end + end +end + +edges2 = edges; + + +%% nodes processing + +% number of nodes +N = size(nodes, 1); +NR = length(rmNodes); +N2 = N-NR; + +% allocate memory +nodes2 = zeros(N2, 2); + +% process the first node +nodes2(1:rmNodes(1)-1,:) = nodes(1:rmNodes(1)-1,:); + +% process the classical nodes +for i = 2:NR + nodes2(rmNodes(i-1)-i+2:rmNodes(i)-i, :) = nodes(rmNodes(i-1)+1:rmNodes(i)-1, :); +end + +% process the last node +nodes2(rmNodes(NR)-NR+1:N2, :) = nodes(rmNodes(NR)+1:N, :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches.m new file mode 100644 index 0000000..348549c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches.m @@ -0,0 +1,154 @@ +function varargout = grSimplifyBranches(nodes, edges) +%GRSIMPLIFYBRANCHES Replace branches of a graph by single edges +% +% [NODES2 EDGES2] = grSimplifyBranches(NODES, EDGES) +% renvoie une version simplifiee d'un graphe, en ne gardant que les +% points multiples et les aretes reliant les points multiples. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY : +% 10/02/2004 : doc +% 17/01/2006 : uses faster method to find neighbour edges +% 18/01/2006 : replace call to subfunctions by inlining -> faster + +Mnodes = []; % size Nn*2 -> nodes coordinates +Sedges = []; % size Ne*2 -> indices of nodes +Mpoints = []; % size Nn*1 -> indices of Multiple points + % in nodes input array + +branch = []; % size Nb*2 (variable) + +Nn = 0; +Ne = 0; +Nb = 0; + +% look for the first multiple point +p = 1; +while length(find(edges(:,1) == p | edges(:,2) == p)) < 3 + p = p + 1; +end + +Mpoints(1) = p; +Mnodes(1, 1:2) = nodes(p, 1:2); +Nn = Nn + 1; + +% add the branches of the first multiple point +neighbours = find(edges(:,1)==p | edges(:,2)==p); +for b = 1:length(neighbours) + Nb = Nb+1; + edge = edges(neighbours(b),:); + if edge(1) == p + branch(Nb, 1:2) = [p edge(2)]; %#ok + else + branch(Nb, 1:2) = [p edge(1)]; %#ok + end +end + +% process each branch, until there is no more branch to process. +% b is index of current branch +b = 0; +while b < length(branch) + b = b+1; + + % check if the branch is valid + if branch(b, 1) == 0 + continue; + end + + % initialize iteration + pNode = branch(b, 1); + node = branch(b,2); + neighbours = find(edges(:,1) == node | edges(:,2) == node); + +% disp(sprintf('node %3d (%03d ; %03d) -> %3d (%03d ; %03d)', ... +% Mnode, nodes(Mnode, 1), nodes(Mnode, 2), ... +% node, nodes(node, 1), nodes(node, 2))); + + while length(neighbours) < 3 + % look for the next point on the current branch + next = 0; + for n = 1:length(neighbours) + edge = edges(neighbours(n), :); + if edge(1)~= node && edge(1)~= pNode + next = edge(1); + break; + end + if edge(2)~= node && edge(2)~= pNode + next = edge(2); + break; + end + end + + pNode = node; + node = next; + neighbours = find(edges(:,1) == node | edges(:,2) == node); + end + + % node is now the next multiple point, and pNode contains the last + % point of the branch. + + % check if the multiple point has already been processed + index = find(Mpoints==node); + if ~isempty(index) + % find the branch starting with node, and with pNode has + % second point, and set it to [0 0] to avoid it to be + % processed again + %disp('remove branch'); + for b2 = 1:Nb + if branch(b2, 1) == node && branch(b2, 2) == pNode + %disp('find branch'); + branch(b2, 1:2) = 0; %#ok + break; + end + end + + else + % add the multiple point to the list of points + %disp('add point'); + Nn = Nn+1; + Mnodes(Nn, 1:2) = nodes(node, 1:2); %#ok + index = Nn; + Mpoints(Nn) = node; %#ok + + % add each neighbour of the new multiple point (but not + % the neighbour containing pNode) to the list of branches + for n = 1:length(neighbours) + edge = edges(neighbours(n), :); + if edge(1) ~= pNode && edge(2) ~= pNode + %disp('add a branch'); + Nb = Nb + 1; + if edge(1) == node + branch(Nb, 1:2) = [node edge(2)]; %#ok + else + branch(Nb, 1:2) = [node edge(1)]; %#ok + end + end + end + end + + %disp('add new Edge'); + Ne = Ne + 1; + Sedges(Ne, 1:2) = [find(Mpoints == branch(b,1)), index]; %#ok +end + + +% process output depending on how many arguments are needed +if nargout == 1 + out{1} = Mnodes; + out{2} = Sedges; + varargout{1} = out; +end + +if nargout == 2 + varargout{1} = Mnodes; + varargout{2} = Sedges; +end + +return; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches_old.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches_old.m new file mode 100644 index 0000000..73838ee --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grSimplifyBranches_old.m @@ -0,0 +1,56 @@ +function varargout = grSimplifyBranches_old(nodes, edges) +%GRSIMPLIFYBRANCHES_OLD Replace branches of a graph by single edges +% +% [NODES2 EDGES2] = grSimplifyBranches(NODES, EDGES) +% Replaces each branch (composed of a series of edges connected only by +% 2-degree nodes) by a single edge, whose extremities are nodes with +% degree >= 3. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 13/08/2003. +% + +% HISTORY +% 10/02/2004 doc + +n = 1; +while n < length(nodes) + neigh = grNeighborNodes(edges, n); + if length(neigh) == 2 + % find other node of first edge + edge = edges(neigh(1), :); + if edge(1) == n + node1 = edge(2); + else + node1 = edge(1); + end + + % replace current node in the edge by the other node + % of first edge + edge = edges(neigh(2), :); + if edge(1) == n + edges(neigh(2), 1) = node1; + else + edges(neigh(2), 2) = node1; + end + + [nodes edges] = grRemoveNode(nodes, edges, n); + continue + end + + n = n + 1; +end + +% process output depending on how many arguments are needed +if nargout == 1 + out{1} = nodes; + out{2} = edges; + varargout = {out}; +end + +if nargout == 2 + varargout = {nodes, edges}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grVertexEccentricity.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grVertexEccentricity.m new file mode 100644 index 0000000..056c200 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/grVertexEccentricity.m @@ -0,0 +1,48 @@ +function g = grVertexEccentricity(v, e, l, inds) +%GRVERTEXECCENTRICITY Eccentricity of vertices in the graph +% +% G = grVertexEccentricity(V, E, L) +% V is the array of vertices +% E is the array of edges +% L is a column vector containing length of each edge (assumes 1 for each +% edge if not specified). +% G is the maximal geodesic length of each vertex. +% +% G = grVertexEccentricity(V, E, L, INDV) +% Compute eccentricity only for vertices whose index is given in INDV. +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% G = grVertexEccentricity(nodes, edges); +% drawNodeLabels(nodes+2, G); +% +% See Also +% graphRadius, graphCenter, graphDiameter, graphPeripheralVertices +% grPropagateDistance +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% init result +Nv = size(v, 1); +g = zeros(Nv, 1); + +% ensure there is a valid length array +if nargin<3 + l = ones(size(e,1), 1); +end + +if nargin<4 + inds = 1:Nv; +end + +% compuite maximal geodesic length for each vertex +for i=1:Nv + g(i) = max(grPropagateDistance(v, e, inds(i), l)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graph2Contours.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graph2Contours.m new file mode 100644 index 0000000..a689b35 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graph2Contours.m @@ -0,0 +1,73 @@ +function varargout = graph2Contours(nodes, edges) %#ok +%GRAPH2CONTOURS Convert a graph to a set of contour curves +% +% CONTOURS = GRAPH2CONTOURS(NODES, EDGES) +% NODES, EDGES is a graph representation (type "help graphs" for details) +% The algorithm assume every node has degree 2, and the set of edges +% forms only closed loops. The result is a list of indices arrays, each +% array containing consecutive point indices of a contour. +% +% To transform contours into drawable curves, please use : +% CURVES{i} = NODES(CONTOURS{i}, :); +% +% +% NOTE : contours are not oriented. To manage contour orientation, edges +% also need to be oriented. So we must precise generation of edges. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/08/2004. +% + + +curves = {}; +c = 0; + +while size(edges,1)>0 + % find first point of the curve + n0 = edges(1,1); + curve = n0; + + % second point of the curve + n = edges(1,2); + e = 1; + + while true + % add current point to the curve + curve = [curve n]; %#ok + + % remove current edge from the list + edges = edges((1:size(edges,1))~=e,:); + + % find index of edge containing reference to current node + e = find(edges(:,1)==n | edges(:,2)==n); + e = e(1); + + % get index of next current node + % (this is the other node of the current edge) + if edges(e,1)==n + n = edges(e,2); + else + n = edges(e,1); + end + + % if node is same as start node, loop is closed, and we stop + % node iteration. + if n==n0 + break; + end + end + + % remove the last edge of the curve from edge list. + edges = edges((1:size(edges,1))~=e,:); + + % add the current curve to the list, and start a new curve + c = c+1; + curves{c} = curve; %#ok +end + +if nargout == 1 + varargout = {curves}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphCenter.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphCenter.m new file mode 100644 index 0000000..acf46ac --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphCenter.m @@ -0,0 +1,40 @@ +function center = graphCenter(v, e, l) +%GRAPHCENTER Center of a graph +% +% CENTER = graphCenter(V, E) +% Computes the center of the graph given by V and E. The center of the +% graph is the set of vertices whose eccentricity is minimal. The +% function returns indices of center vertices. +% +% CENTER = graphCenter(V, E, L) +% Specifies the weight of each edge for computing the distances. Default +% is to consider a weight of 1 for each edge. +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% C = graphCenter(nodes, edges) +% C = +% 4 +% +% See Also +% grPropagateDistance, grVertexEccentricity +% graphRadius, graphDiameter, graphPeripheralVertices +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% ensure there is a valid length array +if nargin<3 + l = ones(size(e,1), 1); +end + +g = grVertexEccentricity(v, e, l); + +center = find(g==min(g)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphDiameter.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphDiameter.m new file mode 100644 index 0000000..d472b5f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphDiameter.m @@ -0,0 +1,39 @@ +function diam = graphDiameter(v, e, l) +%GRAPHDIAMETER Diameter of a graph +% +% D = graphDiameter(V, E) +% Computes the diameter of the graph given by V and E. The diameter of +% the graph is the greatest eccentricity over all vertices in the graph. +% +% D = graphDiameter(V, E, L) +% Specifies the weight of each edge for computing the distances. Default +% is to consider a weight of 1 for each edge. +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% D = graphDiameter(nodes, edges) +% D = +% 4 +% +% See Also +% grPropagateDistance, grVertexEccentricity +% graphCenter, graphRadius, graphPeripheralVertices +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% ensure there is a valid length array +if nargin<3 + l = ones(size(e,1), 1); +end + +g = grVertexEccentricity(v, e, l); + +diam = max(g); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphPeripheralVertices.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphPeripheralVertices.m new file mode 100644 index 0000000..9505cd8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphPeripheralVertices.m @@ -0,0 +1,42 @@ +function inds = graphPeripheralVertices(v, e, l) +%GRAPHPERIPHERALVERTICES Peripheral vertices of a graph +% +% INDS = graphPeripheralVertices(V, E) +% Return indices of peripheral vertices, that is, vertices whose +% eccentricity is maximal and equal to the diameter of the graph. +% +% INDS = graphPeripheralVertices(V, E, L) +% Specify length of each edge. Default is 1 for each edge. +% +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% INDP = graphPeripheralVertices(nodes, edges); +% INDP = +% 1 +% 3 +% 5 +% 7 +% +% +% See Also +% grPropagateDistance, grVertexEccentricity +% graphCenter, graphDiameter, graphRadius +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% ensure there is a valid length array +if nargin<3 + l = ones(size(e,1), 1); +end + +g = grVertexEccentricity(v, e, l); + +inds = find(g==max(g)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphRadius.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphRadius.m new file mode 100644 index 0000000..bd883d4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/graphRadius.m @@ -0,0 +1,38 @@ +function r = graphRadius(v, e, l) +%GRAPHRADIUS Radius of a graph +% +% R = graphRadius(V, E) +% Computes the radius of the graph given by V and E. The radius of the +% graph is the smallest eccentricity over all vertices in the graph. +% +% R = graphRadius(V, E, L) +% Specifies the weight of each edge for computing the distances. Default +% is to consider a weight of 1 for each edge. +% +% Example +% nodes = [20 20;20 50;20 80;50 50;80 20;80 50;80 80]; +% edges = [1 2;2 3;2 4;4 6;5 6;6 7]; +% figure; drawGraph(nodes, edges); +% axis([0 100 0 100]); axis equal; hold on +% R = graphRadius(nodes, edges) +% R = +% 2 +% +% See Also +% grPropagateDistance, grVertexEccentricity +% graphCenter, graphDiameter, graphPeripheralVertices +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-09-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% ensure there is a valid length array +if nargin<3 + l = ones(size(e,1), 1); +end + +g = grVertexEccentricity(v, e, l); + +r = min(g); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/imageGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/imageGraph.m new file mode 100644 index 0000000..886a436 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/imageGraph.m @@ -0,0 +1,160 @@ +function varargout = imageGraph(img, varargin) +%IMAGEGRAPH Create equivalent graph of a binary image +% +% [N E] = imageGraph(IMG); +% or +% [N E F] = imageGraph(IMG); +% create graph representing adjacencies in image. N is the array of +% nodes, E is the array of edges, and F is a 4-columns array containing +% indices of vertices of each face. +% IMG can be either 2D or 3D image. +% This functions uses only 4 neighbors in 2D, and 6 neighbors in 3D. +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + +% HISTORY + + +%% Initialisations + +nodes = []; +edges = zeros(0, 2); +faces = zeros(0, 4); +cells = []; + +dim = size(img); + + +%% Main processing + +if ndims(img)==2 + N1 = dim(1); + N2 = dim(2); + + % first find nodes, equivalent to pixels + ind = find(img); + [x y] = ind2sub([N1 N2], ind); + nodes = [x y]; + + % find vertical edges + ind = find(img(1:N1, 1:N2-1) & img(1:N1, 2:N2)); + for i=1:length(ind) + [x y] = ind2sub([N1 N2-1], ind(i)); + i1 = find(ismember(nodes, [x y], 'rows')); + i2 = find(ismember(nodes, [x y+1], 'rows')); + edges(size(edges, 1)+1, 1:2) = [i1 i2]; + end + + % find horizontal edges + ind = find(img(1:N1-1, 1:N2) & img(2:N1, 1:N2)); + for i=1:length(ind) + [x y] = ind2sub([N1-1 N2], ind(i)); + i1 = find(ismember(nodes, [x y], 'rows')); + i2 = find(ismember(nodes, [x+1 y], 'rows')); + edges(size(edges, 1)+1, 1:2) = [i1 i2]; + end + + % find faces + ind = find(img(1:N1-1, 1:N2-1) & img(2:N1, 1:N2-1) & ... + img(1:N1-1, 2:N2) & img(2:N1, 2:N2) ); + for i=1:length(ind) + [x y] = ind2sub([N1-1 N2-1], ind(i)); + i1 = find(ismember(nodes, [x y], 'rows')); + i2 = find(ismember(nodes, [x+1 y], 'rows')); + i3 = find(ismember(nodes, [x+1 y+1], 'rows')); + i4 = find(ismember(nodes, [x y+1], 'rows')); + faces(size(faces, 1)+1, 1:4) = [i1 i2 i3 i4]; + end + +elseif ndims(img)==3 + N1 = dim(1); + N2 = dim(2); + N3 = dim(3); + + % first find nodes, equivalent to pixels + ind = find(img); + [x y z] = ind2sub([N1 N2 N3], ind); + nodes = [x y z]; + + % find edges in direction 1 + ind = find(img(1:N1-1, 1:N2, 1:N3) & img(2:N1, 1:N2, 1:N3)); + [x y z] = ind2sub([N1-1 N2 N3], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x+1 y z], 'rows')); + edges = [edges ; [i1 i2]]; + + % find edges in direction 2 + ind = find(img(1:N1, 1:N2-1, 1:N3) & img(1:N1, 2:N2, 1:N3)); + [x y z] = ind2sub([N1 N2-1 N3], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x y+1 z], 'rows')); + edges = [edges ; [i1 i2]]; + + % find edges in direction 3 + ind = find(img(1:N1, 1:N2, 1:N3-1) & img(1:N1, 1:N2, 2:N3)); + [x y z] = ind2sub([N1 N2 N3-1], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x y z+1], 'rows')); + edges = [edges ; [i1 i2]]; + + + % find faces in direction 1 + ind = find(img(1:N1, 1:N2-1, 1:N3-1) & img(1:N1, 1:N2-1, 2:N3) & ... + img(1:N1, 2:N2, 1:N3-1) & img(1:N1, 2:N2, 2:N3) ); + [x y z] = ind2sub([N1 N2-1 N3-1], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x y+1 z], 'rows')); + i3 = find(ismember(nodes, [x y+1 z+1], 'rows')); + i4 = find(ismember(nodes, [x y z+1], 'rows')); + faces = [faces; [i1 i2 i3 i4]]; + + % find faces in direction 2 + ind = find(img(1:N1-1, 1:N2, 1:N3-1) & img(1:N1-1, 1:N2, 2:N3) & ... + img(2:N1, 1:N2, 1:N3-1) & img(2:N1, 1:N2, 2:N3) ); + [x y z] = ind2sub([N1-1 N2 N3-1], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x+1 y z], 'rows')); + i3 = find(ismember(nodes, [x+1 y z+1], 'rows')); + i4 = find(ismember(nodes, [x y z+1], 'rows')); + faces = [faces; [i1 i2 i3 i4]]; + + % find faces in direction 3 + ind = find(img(1:N1-1, 1:N2-1, 1:N3) & img(1:N1-1, 2:N2, 1:N3) & ... + img(2:N1, 1:N2-1, 1:N3) & img(2:N1, 2:N2, 1:N3) ); + [x y z] = ind2sub([N1-1 N2-1 N3], ind); + i1 = find(ismember(nodes, [x y z], 'rows')); + i2 = find(ismember(nodes, [x+1 y z], 'rows')); + i3 = find(ismember(nodes, [x+1 y+1 z], 'rows')); + i4 = find(ismember(nodes, [x y+1 z], 'rows')); + faces = [faces; [i1 i2 i3 i4]]; + +end + + +%% Format output + +if nargout==1 + graph.nodes = nodes; + graph.edges = edges; + graph.faces = faces; + if ndims(img)>2 + graph.cells = cells; + end + varargout{1} = graph; +elseif nargout==2 + varargout{1} = nodes; + varargout{2} = edges; +elseif nargout==3 + varargout{1} = nodes; + varargout{2} = edges; + varargout{3} = faces; +end + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/knnGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/knnGraph.m new file mode 100644 index 0000000..ce41a5b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/knnGraph.m @@ -0,0 +1,40 @@ +function edges = knnGraph(nodes, varargin) +%KNNGRAPH Create the k-nearest neighbors graph of a set of points +% +% EDGES = knnGraph(NODES) +% +% Example +% nodes = rand(10, 2); +% edges = knnGraph(nodes); +% drawGraph(nodes, edges); +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-07-28, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% get number of neighbors for each node +k = 2; +if ~isempty(varargin) + k = varargin{1}; +end + +% init size of arrays +n = size(nodes, 1); +edges = zeros(k*n, 2); + +% iterate on nodes +for i = 1:n + dists = distancePoints(nodes(i,:), nodes); + [dists inds] = sort(dists); %#ok + for j = 1:k + edges(k*(i-1)+j, :) = [i inds(j+1)]; + end +end + +% remove double edges +edges = unique(sort(edges, 2), 'rows'); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/mergeGraphs.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/mergeGraphs.m new file mode 100644 index 0000000..91a2089 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/mergeGraphs.m @@ -0,0 +1,180 @@ +function varargout = mergeGraphs(varargin) +%MERGEGRAPHS Merge two graphs, by adding nodes, edges and faces lists. +% +% +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 09/08/2004. +% + + +simplify = false; + + +edges = {}; edges2 = {}; +faces = {}; faces2 = {}; + + +% =============================================================== +% process input arguments + +% --------------------------------------------------------------- +% extract simplify tag + +var = varargin{nargin}; +if ischar(var) + if strcmp(var, 'simplify'); + simplify = true; + varargin = varargin(1:length(varargin)-1); + end +end + + +% --------------------------------------------------------------- +% extract data of first graph + +var = varargin{1}; +if iscell(var) + % graph is stored as a cell array : first cell is nodes, second one is + % edges, and third is faces + nodes = var{1}; + if length(var)>1 + edges = var{2}; + end + if length(var)>2 + faces = var{3}; + end + varargin = varargin(2:length(varargin)); + +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges', and + % eventually 'faces'. + nodes = var.nodes; + edges = var.edges; + if isfield(var, 'faces') + faces = var.faces; + end + varargin = varargin(2:length(varargin)); + +elseif length(varargin)>2 + % graph is stored as set of variables : nodes, edges, and eventually + % faces + nodes = varargin{1}; + edges = varargin{2}; + + if length(varargin)==3 + % last argument describe graph 2 + varargin = varargin(3); + else + if length(varargin)~=4 || ~isnumeric(varargin{4}) + % third argument is faces of graph 1 + faces = varargin{3}; + varargin = varargin(4:length(varargin)); + else + varargin = varargin(3:length(varargin)); + end + end + +else + error('Error in passing arguments in mergeGraphs'); +end + + +% --------------------------------------------------------------- +% extract data of second graph + +var = varargin{1}; +if iscell(var) + % graph is stored as a cell array : first cell is nodes, second one is + % edges, and third is faces + nodes2 = var{1}; + if length(var)>1 + edges2 = var{2}; + end + if length(var)>2 + faces2 = var{3}; + end + +elseif isstruct(var) + % graph is stored as a structure, with fields 'nodes', 'edges', and + % eventually 'faces'. + nodes2 = var.nodes; + edges2 = var.edges; + if isfield(var, 'faces') + faces2 = var.faces; + end + +elseif length(varargin)>1 + % graph is stored as set of variables : nodes, edges, and eventually + % faces + nodes2 = varargin{1}; + edges2 = varargin{2}; + + if length(varargin)>2 + % last argument describe graph 2 + faces2 = varargin{3}; + end + +else + error('Error in passing arguments in mergeGraphs'); +end + + +% =============================================================== +% Main algorithm + +% eventually convert faces +if ~iscell(faces) + f = cell(size(faces, 1), 1); + for i=1:size(faces, 1) + f{i} = faces(i,:); + end + faces = f; +end + +edges = [edges ; edges2 + size(nodes, 1)]; +if iscell(faces2) + for i=1:length(faces2) + faces{length(faces)+1} = faces2{i} + size(nodes, 1); %#ok + end +else + % TODO +end +nodes = [nodes; nodes2]; + +if simplify + if ~isempty(faces) + [nodes edges faces] = grSimplifyBranches(nodes, edges, faces); + else + [nodes edges] = grSimplifyBranches(nodes, edges); + end +end + + +% =============================================================== +% process output depending on how many arguments are needed + +if nargout == 1 + graph.nodes = nodes; + graph.edges = edges; + if ~isempty(faces) + graph.faces = faces; + end + varargout{1} = graph; +end + +if nargout == 2 + varargout{1} = nodes; + varargout{2} = edges; +end + +if nargout == 3 + varargout{1} = nodes; + varargout{2} = edges; + varargout{3} = faces; +end + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/patchGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/patchGraph.m new file mode 100644 index 0000000..2c387c1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/patchGraph.m @@ -0,0 +1,38 @@ +function varargout = patchGraph(nodes, edges, faces) %#ok +%PATCHGRAPH Transform 3D graph (mesh) into a patch handle +% +% [PX, PY, PZ] = PATCHGRAPH(NODES, EDGES, FACES) +% Transform the graph defined as a set of nodes, edges and faces in a +% patch which can be drawn usind matlab function 'patch'. +% The result is a set of 3 array of size [NV*NF], with NV being the +% number of vertices per face, and NF being the total number of faces. +% each array contains one coordinate of vertices of each patch. +% +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 28/06/2004. +% + +if iscell(faces) + p = zeros(length(faces), 1); + for i = 1:length(faces) + p(i) = patch( ... + 'Faces', faces{i}, ... + 'Vertices', nodes, ... + 'FaceColor', 'r', ... + 'EdgeColor', 'none') ; + end +else + p = patch( ... + 'Faces', faces, ... + 'Vertices', nodes, ... + 'FaceColor', 'r', ... + 'EdgeColor', 'none') ; +end + +if nargout>0 + varargout{1}=p; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/prim_mst.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/prim_mst.m new file mode 100644 index 0000000..f14fc04 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/prim_mst.m @@ -0,0 +1,59 @@ +function varargout = prim_mst(edges, vals) +%PRIM_MST Minimal spanning tree by Prim's algorithm +% +% EDGES2 = prim_mst(EDGES, VALUES) +% Compute the minimal spanning tree (MST) of the graph with edges given +% by EDGES, and whose edges are valuated by VALUES. +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-07-27, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% isolate vertices index +nodes = unique(edges(:)); +N = length(nodes); + +% initialize memory +nodes2 = zeros(N, 1); +edges2 = zeros(N-1, 2); +vals2 = zeros(N-1, 1); + +% initialize with a first node +nodes2(1) = nodes(1); +nodes = nodes(2:end); + +% iterate on edges +for i = 1:N-1 + % find all edges from nodes2 to nodes + ind = unique(find(... + (ismember(edges(:,1), nodes2(1:i)) & ismember(edges(:,2), nodes)) | ... + (ismember(edges(:,1), nodes) & ismember(edges(:,2), nodes2(1:i))) )); + + % choose edge with lowest value + [tmp ind2] = min(vals(ind)); %#ok + ind = ind(ind2(1)); + vals2(i) = vals(ind); + + % index of other vertex + edge = edges(ind, :); + neigh = edge(~ismember(edge, nodes2)); + + % add to list of nodes and list of edges + nodes2(i+1) = neigh; + edges2(i,:) = edge; + + % remove current node from list of old nodes + nodes = nodes(~ismember(nodes, neigh)); +end + + +% process output arguments +if nargout == 1 + varargout{1} = edges2; +elseif nargout==2 + varargout{1} = edges2; + varargout{2} = vals2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/quiverToGraph.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/quiverToGraph.m new file mode 100644 index 0000000..de0b117 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/quiverToGraph.m @@ -0,0 +1,39 @@ +function [v e] = quiverToGraph(x, y, dx, dy) +%QUIVERTOGRAPH Converts quiver data to quad mesh +% +% [V E] = quiverToGraph(x, y, dx, dy) +% x, y, dx and dy are matrices the same dimension, typically ones used +% for display using 'quiver'. +% V and E are vertex coordinates, and edge vertex indices of the graph +% joining end points of vector arrows. +% +% Example +% quiverToGraph +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-06-16, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% compute vertex coordinates +vx = x+dx; +vy = y+dy; +v = [vx(:) vy(:)]; + +% index of vertices +labels = reshape(1:numel(x), size(x)); + +% compute indices of vertical edges +N1 = numel(labels(1:end-1,:)); +vedges = [reshape(labels(1:end-1, :), [N1 1]) reshape(labels(2:end, :), [N1 1])]; + +% compute indices of horizontal edges +N2 = numel(labels(:, 1:end-1)); +hedges = [reshape(labels(:, 1:end-1), [N2 1]) reshape(labels(:, 2:end), [N2 1])]; + +% concatenate horizontal and vertical edges +e = [hedges ; vedges]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/vectorize.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/vectorize.m new file mode 100644 index 0000000..2ae6c38 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/vectorize.m @@ -0,0 +1,166 @@ +function varargout = vectorize(img) +%VECTORIZE Transform a binary skeleton into a graph (nodes and edges) +% +% [NODES EDGES] = vectorize(IMG); +% IMG is a binary image, with structure of width 1 pixel (such as the +% result of sketetonization) +% NODES is a Nnodes*2 array of doubles containing values of vertices +% coordinates +% EDGES is a Nedges*2 array of integers, containing indices of vertices +% of each extremity. +% +% GRAPH = vectorize(IMG); +% return the result as a graph structure, containing fields 'nodes' and +% 'edges'. +% +% +% Example: +% img = imread('circles.png'); +% skel = bwmorph(img, 'shrink', Inf); +% [nodes, edges] = vectorize(skel); +% figure; imshow(skel); hold on; +% drawGraph(nodes, edges); +% +% +% See Also: drawGraph, minGraph, removeMultiplePoints +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/07/2003. +% + +% HISTORY +% 21/07/2003 : uses only one loop to detect nodes and edges +% 26/01/2004 : reverse direction of searching pixels in array : faster +% 10/02/2004 : documentation +% 11/02/2004 : supprime calcul du temps execution +% 18/01/2006 : rewrite by using a label for each point, making it working +% faster + + +%% Initialisations + +% nodes array +[y x] = find(img>0); +points = [x y]; + +% intialize empty edges array. +edges = zeros(0, 2); + + +% adapt datasize of label image to the number of points. +n = length(x); +if n < 256 + typ = 'uint8'; +elseif n < power(2, 16) + typ = 'uint16'; +elseif n < power(2, 32); + typ = 'uint32'; +else + typ = 'uint64'; +end + +% create label image +dim = size(img); +img = zeros(dim, typ); +for i = 1:length(x) + img(y(i), x(i)) = i; +end + +%% detection of edges + +% first line +for x = 2:dim(2) + % continue if no point + if img(1, x) == 0 + continue; + end + + % check the point to the left + if img(1, x-1) > 0 + edges = [edges; img(1, x) img(1, x-1)]; + end +end + +% normal lines +for y = 2:dim(1) + + % first point of the line + if img(y, 1) > 0 + + % check point on the top + if img(y-1,1)>0 + edges = [edges; img(y, 1) img(y-1,1)]; + end + + % check point on the top-right + if img(y-1,2)>0 + edges = [edges; img(y, 1) img(y-1,2)]; + end + end + + % each 'normal' point of the line + for x=2:dim(2)-1 + if ~img(y,x) + continue; + end + + % check point on the left + if img(y, x-1)>0 + edges = [edges; img(y, x) img(y, x-1)]; + end + + % check point on the top-left + if img(y-1, x-1)>0 + edges = [edges; img(y, x) img(y-1, x-1)]; + end + + % check point on the top + if img(y-1, x)>0 + edges = [edges; img(y, x) img(y-1, x)]; + end + + % check point on the top-right + if img(y-1, x+1)>0 + edges = [edges; img(y, x) img(y-1, x+1)]; + end + + end + + % last point of the line + if img(y, dim(2)) + + % check point on the left + if img(y, dim(2)-1)>0 + edges = [edges; img(y, dim(2)) img(y, dim(2)-1)]; + end + + % check point on the top-left + if img(y-1, dim(2)-1)>0 + edges = [edges; img(y, dim(2)) img(y-1, dim(2)-1)]; + end + + % check point on the top + if img(y-1, dim(2))>0 + edges = [edges; img(y, dim(2)) img(y-1, dim(2))]; + end + end +end + + +%% Format output arguments + +% process output depending on how many arguments are needed +if nargout == 1 + out.nodes = points; + out.edges = edges; + varargout{1} = out; +end + +if nargout == 2 + varargout{1} = points; + varargout{2} = edges; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/voronoi2d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/voronoi2d.m new file mode 100644 index 0000000..610a206 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/graphs/voronoi2d.m @@ -0,0 +1,39 @@ +function [nodes edges faces] = voronoi2d(germs) +%VORONOI2D Compute a voronoi diagram as a graph structure +% +% [NODES EDGES FACES] = voronoi2d(GERMS) +% GERMS an array of points with dimension 2 +% NODES, EDGES, FACES: usual graph representation, FACES as cell array +% +% Example +% [n e f] = voronoi2d(rand(100, 2)*100); +% drawGraph(n, e); +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-01-12 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +[V C] = voronoin(germs); + +nodes = V(2:end, :); +edges = zeros(0, 2); +faces = {}; + +for i=1:length(C) + cell = C{i}; + if ismember(1, cell) + continue; + end + + cell = cell-1; + edges = [edges; sort([cell' cell([2:end 1])'], 2)]; %#ok + faces{length(faces)+1} = cell; %#ok +end + +edges = unique(edges, 'rows'); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/license.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/license.txt new file mode 100644 index 0000000..c8d23c2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/license.txt @@ -0,0 +1,29 @@ +Copyright (c) 2011, INRA +All rights reserved. +(simplified BSD License) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of copyright holder. diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/Contents.m new file mode 100644 index 0000000..9e4a592 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/Contents.m @@ -0,0 +1,97 @@ +% MESHES3D 3D Surface Meshes +% Version 1.0 21-Mar-2011 . +% +% Creation, vizualization, and manipulation of 3D surface meshes or +% polyhedra. +% +% Meshes and Polyhedra are represented by a couple of variables {V, F}: +% V: Nv-by-3 array of vertices: [x1 y1 z1; ... ; xn yn zn]; +% F: is either a NF-by-3 or NF-by-4 array containing reference for +% vertices of each face, or a NF-by-1 cell array, where each cell is an +% array containing a variable number of node indices. +% For some functions, the array E of edges is needed. It consists in a +% NE-by-2 array containing indices of source and target vertices. +% +% The library provides function to create basic polyhedric meshes (the 5 +% platonic solids, plus few others), as well as functions to perform +% basic computations (surface area, normal angles, face centroids...). +% The 'MengerSponge' structure is an example of mesh that is not simply +% connected (multiple tunnels in the structure). +% +% The drawMesh function is mainly a wrapper to the Matlab 'patch' +% function, allowing passing arguments more quickly. +% +% Example +% % create a soccer ball mesh and display it +% [n e f] = createSoccerBall; +% drawMesh(n, f, 'faceColor', 'g', 'linewidth', 2); +% axis equal; +% +% +% General functions +% meshFace - Return the vertex indices of a face in a mesh +% computeMeshEdges - Computes edges array from face array +% meshEdgeFaces - Compute index of faces adjacent to each edge of a mesh +% faceCentroids - Compute centroids of a mesh faces +% faceNormal - Compute normal vector of faces in a 3D mesh +% vertexNormal - Compute normals to a mesh vertices +% +% Measures on meshes +% meshSurfaceArea - Surface area of a polyhedral mesh +% trimeshSurfaceArea - Surface area of a triangular mesh +% meshEdgeLength - Lengths of edges of a polygonal or polyhedral mesh +% meshDihedralAngles - Dihedral at edges of a polyhedal mesh +% polyhedronNormalAngle - Compute normal angle at a vertex of a 3D polyhedron +% polyhedronMeanBreadth - Mean breadth of a convex polyhedron +% +% Basic processing +% triangulateFaces - Convert face array to an array of triangular faces +% gridmeshToQuadmesh - Create a quad mesh from a grid mesh +% checkMeshAdjacentFaces - Check if adjacent faces of a mesh have similar orientation +% meshReduce - Merge coplanar faces of a polyhedral mesh +% minConvexHull - Return the unique minimal convex hull of a set of 3D points +% +% Intersections and clipping +% intersectLineMesh3d - Intersection points of a 3D line with a mesh +% polyhedronSlice - Intersect a convex polyhedron with a plane. +% clipMeshVertices - Clip vertices of a surfacic mesh and remove outer faces +% clipConvexPolyhedronHP - Clip a convex polyhedron by a plane +% +% Typical polyhedra +% polyhedra - Index of classical polyhedral meshes +% createCube - Create a 3D mesh representing the unit cube +% createOctahedron - Create a 3D mesh representing an octahedron +% createCubeOctahedron - Create a 3D mesh representing a cube-octahedron +% createIcosahedron - Create a 3D mesh representing an Icosahedron. +% createDodecahedron - Create a 3D mesh representing a dodecahedron +% createTetrahedron - Create a 3D mesh representing a tetrahedron +% createRhombododecahedron - Create a 3D mesh representing a rhombododecahedron +% createTetrakaidecahedron - Create a 3D mesh representing a tetrakaidecahedron +% +% Less typical polyhedra +% createSoccerBall - Create a 3D mesh representing a soccer ball +% createMengerSponge - Create a cube with an inside cross removed +% steinerPolytope - Create a steiner polytope from a set of vectors +% +% Drawing functions +% drawFaceNormals - Draw normal vector of each face in a mesh +% drawMesh - Draw a 3D mesh defined by vertices and faces +% +% Reading from file +% readMesh_off - Read mesh data stord in OFF format +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-07 +% Homepage: http://matgeom.sourceforge.net/ +% http://www.pfl-cepia.inra.fr/index.php?page=geom3d +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +% Deprecated: +% drawPolyhedra - draw polyhedra defined by vertices and faces +% drawPolyhedron - draw polyhedron defined by vertices and faces + +% Others diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/changelog.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/changelog.txt new file mode 100644 index 0000000..55ed8d6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/changelog.txt @@ -0,0 +1,16 @@ +change log for meshes3d + +meshes3d release 2011.06.30 +=========================== + +Important changes: +- Package has been splitted up into 'geom3d' and 'meshes3d'. See changelog of + "geom3d" package for older revisions + +New Functions +- added function clipMeshVertices +- added function computeMeshEdges + +Bug Fixes +- fixed bug in edge labeling of createCubeOctaedron + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/checkMeshAdjacentFaces.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/checkMeshAdjacentFaces.m new file mode 100644 index 0000000..ca6ac86 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/checkMeshAdjacentFaces.m @@ -0,0 +1,65 @@ +function checkMeshAdjacentFaces(vertices, edges, faces) +%CHECKMESHADJACENTFACES Check if adjacent faces of a mesh have similar orientation +% +% checkMeshAdjacentFaces(VERTICES, EDGES, FACES) +% The functions returns no output, but if two faces share a common edge +% with the same direction (meaning that adjacent faces have normals in +% opposite direction), a warning is displayed. +% +% Example +% [v e f] = createCube(); +% checkMeshAdjacentFaces(v, e, f); +% % no output -> all faces have normal outwards of the cube +% +% v = [0 0 0; 10 0 0; 0 10 0; 10 10 0]; +% e = [1 2;1 3;2 3;2 4;3 4]; +% f = [1 2 3; 2 3 4]; +% checkMeshAdjacentFaces(v, e, f); +% Warning: Faces 1 and 2 run through the edge 3 (2-3) in the same direction +% +% See also +% meshes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +pattern = 'Faces %d and %d run through the edge %d (%d-%d) in the same direction'; + +edgeFaces = meshEdgeFaces(vertices, edges, faces); +Ne = size(edgeFaces, 1); + +for i = 1:Ne + % indices of extreimty vertices + v1 = edges(i, 1); + v2 = edges(i, 2); + + % index of adjacent faces + indF1 = edgeFaces(i, 1); + indF2 = edgeFaces(i, 2); + + % if one of the faces has index 0, then the edge is at the boundary + if indF1 == 0 || indF2 == 0 + continue; + end + % vertices of adjacent faces + face1 = meshFace(faces, indF1); + face2 = meshFace(faces, indF2); + + % position of vertices in face vertex array + ind11 = find(face1 == v1); + ind12 = find(face1 == v2); + ind21 = find(face2 == v1); + ind22 = find(face2 == v2); + + % check if edge is traveled forward or backard + direct1 = (ind12 == ind11+1) | (ind12 == 1 & ind11 == length(face1)); + direct2 = (ind22 == ind21+1) | (ind22 == 1 & ind21 == length(face2)); + + % adjacent faces should travel the edge in opposite direction + if direct1 == direct2 + warning(pattern, indF1, indF2, i, v1, v2); %#ok + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipConvexPolyhedronHP.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipConvexPolyhedronHP.m new file mode 100644 index 0000000..7d05423 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipConvexPolyhedronHP.m @@ -0,0 +1,145 @@ +function [nodes2 faces2] = clipConvexPolyhedronHP(nodes, faces, plane) +%CLIPCONVEXPOLYHEDRONHP Clip a convex polyhedron by a plane +% +% [NODES2, FACES2] = clipConvexPolyhedronHP(NODES, FACES, PLANE) +% +% return the new (convex) polyhedron whose vertices are 'below' the +% specified plane, and with faces clipped accordingly. NODES2 contains +% clipped vertices and new created vertices, FACES2 contains references +% to NODES2 vertices. +% +% Example +% [N E F] = createCube; +% P = createPlane([.5 .5 .5], [1 1 1]); +% [N2 F2] = clipConvexPolyhedronHP(N, F, P); +% drawPolyhedra(N2, F2); +% +% See also +% polyhedra, planes +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-09-14, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% Preprocessing + +% if faces is a numeric array, convert it to cell array +if isnumeric(faces) + faces2 = cell(size(faces, 1), 1); + for f=1:length(faces2) + faces2{f} = faces(f,:); + end + faces = faces2; +end + +% find vertices below the plane +b = isBelowPlane(nodes, plane); + +% initialize results +Nn = size(nodes, 1); +nodes2 = zeros(0, 3); % list of new nodes +faces2 = faces; % list of new faces. Start with initial list, and remove some of them + + +%% Main iteration on faces + +% iterate on each face, and test if either: +% - all points below plane -> keep all face +% - all points up plane -> remove face +% - both -> clip the polygon +keep = true(length(faces), 1); +for f=1:length(faces) + % current face + face = faces{f}; + bf = b(face); + + % face totally outside plane + if sum(bf)==0 + keep(f) = false; + continue; + end + + % face totally below plane + if sum(bf==1)==length(bf) + continue; + end + + % clip polygon formed by face + poly = nodes(face, :); + clipped = clipConvexPolygon3dHP(poly, plane); + + % identify indices of polygon vertices + inds = zeros(1, size(clipped, 1)); + faceb = face(bf==1); % indices of vertices still in clipped face + [minDists I] = minDistancePoints(nodes(faceb,:), clipped); + for i=1:length(I) + inds(I(i)) = faceb(i); + end + + % indices of new points in clipped polygon + indNews = find(inds==0); + + if size(nodes2, 1)<2 + nodes2 = [nodes2; clipped(indNews, :)]; + inds(indNews(1)) = Nn + 1; + inds(indNews(2)) = Nn + 2; + faces2{f} = inds; + continue; + end + + % distances from new vertices to already added vertices + [minDists I] = minDistancePoints(clipped(indNews, :), nodes2); + + % compute index of first vertex + if minDists(1)<1e-10 + inds(indNews(1)) = Nn + I(1); + else + nodes2 = [nodes2; clipped(indNews(1), :)]; + inds(indNews(1)) = Nn + size(nodes2, 1); + end + + % compute index of second vertex + if minDists(2)<1e-10 + inds(indNews(2)) = Nn + I(2); + else + nodes2 = [nodes2; clipped(indNews(2), :)]; + inds(indNews(2)) = Nn + size(nodes2, 1); + end + + % stores the modified face + faces2{f} = inds; +end + + +%% Postprocessing + +% creates a new face formed by the added nodes +[tmp I] = angleSort3d(nodes2); +newFace = I'+Nn; + +% remove faces outside plane and add the new face +faces2 = {faces2{keep}, newFace}; + +% remove clipped nodes, and add new nodes to list of nodes +N2 = size(nodes2, 1); +nodes2 = [nodes(b, :); nodes2]; + +% new nodes are inside half-space by definition +b = [b; ones(N2, 1)]; + +% create look up table between old indices and new indices +inds = zeros(size(nodes2, 1), 1); +indb = find(b); +for i=1:length(indb) + inds(indb(i)) = i; +end + +% update indices of faces +for f=1:length(faces2) + face = faces2{f}; + faces2{f} = inds(face); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipMeshVertices.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipMeshVertices.m new file mode 100644 index 0000000..3adebfc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/clipMeshVertices.m @@ -0,0 +1,53 @@ +function [cVertices cFaces] = clipMeshVertices(vertices, faces, box) +%CLIPMESHVERTICES Clip vertices of a surfacic mesh and remove outer faces +% +% output = clipMeshVertices(input) +% +% Example +% clipMeshVertices +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-07, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +if isstruct(vertices) + box = faces; + faces = vertices.faces; + vertices = vertices.vertices; +end + +[cVertices indVertices] = clipPoints3d(vertices, box); + + +% for face indices relabeling +refInds = zeros(size(indVertices)); +for i = 1:length(indVertices) + refInds(indVertices(i)) = i; +end + + +if isnumeric(faces) + % Faces given as numeric array + indFaces = sum(~ismember(faces, indVertices), 2) == 0; + cFaces = refInds(faces(indFaces, :)); + +elseif iscell(faces) + % Faces given as cell array + nFaces = length(faces); + indFaces = false(nFaces, 1); + for i = 1:nFaces + indFaces(i) = sum(~ismember(faces{i}, indVertices), 2) == 0; + end + cFaces = faces(indFaces, :); + + % re-label indices of face vertices + for i = 1:length(cFaces) + cFaces{i} = refInds(cFaces{i}); + end + +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/computeMeshEdges.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/computeMeshEdges.m new file mode 100644 index 0000000..278d1d8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/computeMeshEdges.m @@ -0,0 +1,60 @@ +function edges = computeMeshEdges(faces) +%COMPUTEMESHEDGES Computes edges array from face array +% +% EDGES = computeMeshEdges(FACES); +% +% Example +% computeMeshEdges +% +% See also +% meshes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-06-28, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +if ~iscell(faces) + % faces is given as numeric array, + % all faces have same number of vertices, stored in nVF variable + + % compute total number of edges + nFaces = size(faces, 1); + nVF = size(faces, 2); + nEdges = nFaces * nVF; + + % create all edges (with double ones) + edges = zeros(nEdges, 2); + for i = 1:nFaces + f = faces(i, :); + edges(((i-1)*nVF+1):i*nVF, :) = [f' f([2:end 1])']; + end + +else + % faces are given as a cell array, with possibly different number of + % vertices + nFaces = length(faces); + + % compute number of edges + nEdges = 0; + for i = nFaces + nEdges = nEdges + length(faces{i}); + end + + % allocate memory + edges = zeros(nEdges, 2); + ind = 0; + + % fillup edge array + for i = 1:nFaces + f = faces{i}; + nVF = length(f); + edges(ind+1:ind+nVF, :) = [f' f([2:end 1])']; + ind = ind + nVF; + end + +end + +% keep only unique edges, and return sorted result +edges = sortrows(unique(sort(edges, 2), 'rows')); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCube.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCube.m new file mode 100644 index 0000000..6d2b4ef --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCube.m @@ -0,0 +1,56 @@ +function varargout = createCube() +%CREATECUBE Create a 3D mesh representing the unit cube +% +% [V E F] = createCube +% Create a unit cube, as a polyhedra representation. +% c has the form [V E F], where V is a 8-by-3 array with vertices +% coordinates, E is a 12-by-2 array containing indices of neighbour +% vertices, and F is a 6-by-4 array containing vertices array of each +% face. +% +% [V F] = createCube; +% Returns only the vertices and the face vertex indices. +% +% MESH = createCube; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [n e f] = createCube; +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh +% createOctahedron, createTetrahedron, createDodecahedron +% createIcosahedron, createCubeOctahedron +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +x0 = 0; dx= 1; +y0 = 0; dy= 1; +z0 = 0; dz= 1; + +nodes = [... + x0 y0 z0; ... + x0+dx y0 z0; ... + x0 y0+dy z0; ... + x0+dx y0+dy z0; ... + x0 y0 z0+dz; ... + x0+dx y0 z0+dz; ... + x0 y0+dy z0+dz; ... + x0+dx y0+dy z0+dz]; + +edges = [1 2;1 3;1 5;2 4;2 6;3 4;3 7;4 8;5 6;5 7;6 8;7 8]; + +% faces are oriented such that normals point outwards +faces = [1 3 4 2;5 6 8 7;2 4 8 6;1 5 7 3;1 2 6 5;3 7 8 4]; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCubeOctahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCubeOctahedron.m new file mode 100644 index 0000000..14ab638 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createCubeOctahedron.m @@ -0,0 +1,60 @@ +function varargout = createCubeOctahedron() +%CREATECUBEOCTAHEDRON Create a 3D mesh representing a cube-octahedron +% +% [V E F] = createCubeOctahedron; +% Cubeoctahedron can be seen either as a truncated cube, or as a +% truncated octahedron. +% V is the 12-by-3 array of vertex coordinates +% E is the 27-by-2 array of edge vertex indices +% F is the 1-by-14 cell array of face vertex indices +% +% [V F] = createCubeOctahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createCubeOctahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [n e f] = createCubeOctahedron; +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh, createCube, createOctahedron +% +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +nodes = [... + 0 -1 1;1 0 1;0 1 1;-1 0 1; ... + 1 -1 0;1 1 0;-1 1 0;-1 -1 0;... + 0 -1 -1;1 0 -1;0 1 -1;-1 0 -1]; + +edges = [... + 1 2; 1 4; 1 5; 1 8; ... + 2 3; 2 5; 2 6; ... + 3 4; 3 6; 3 7; ... + 4 7; 4 8; ... + 5 9; 5 10; ... + 6 10; 6 11; ... + 7 11; 7 12; ... + 8 9; 8 12; ... + 9 10; 9 12; ... + 10 11; 11 12]; + +faces = {... + [1 2 3 4], [1 5 2], [2 6 3], [3 7 4], [4 8 1], ... + [5 10 6 2], [3 6 11 7], [4 7 12 8], [1 8 9 5], ... + [5 9 10], [6 10 11], [7 11 12], [8 12 9], [9 12 11 10]}; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createDodecahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createDodecahedron.m new file mode 100644 index 0000000..c4dea6b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createDodecahedron.m @@ -0,0 +1,74 @@ +function varargout = createDodecahedron() +%CREATEDODECAHEDRON Create a 3D mesh representing a dodecahedron +% +% [V E F] = createDodecahedron; +% Create a 3D mesh representing a dodecahedron +% V is the 20-by-3 array of vertex coordinates +% E is the 30-by-2 array of edge vertex indices +% F is the 12-by-5 array of face vertex indices +% +% [V F] = createDodecahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createDodecahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [v e f] = createDodecahedron; +% drawMesh(v, f); +% +% Use values given by P. Bourke, see: +% http://local.wasp.uwa.edu.au/~pbourke/geometry/platonic/ +% faces are re-oriented to have normals pointing outwards. +% +% See also +% meshes3d, drawMesh +% createCube, createOctahedron, createIcosahedron, createTetrahedron +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 29/07/2010. +% + +% HISTORY + +% golden ratio +phi = (1+sqrt(5))/2; + +% coordinates pre-computations +b = 1 / phi ; +c = 2 - phi ; + +% use values given by P. Bourke, see: +% http://local.wasp.uwa.edu.au/~pbourke/geometry/platonic/ +tmp = [ ... + c 0 1 ; b b b ; 0 1 c ; -b b b ; -c 0 1 ; ... +-c 0 1 ; -b -b b ; 0 -1 c ; b -b b ; c 0 1 ; ... + c 0 -1 ; b -b -b ; 0 -1 -c ; -b -b -b ; -c 0 -1 ; ... +-c 0 -1 ; -b b -b ; 0 1 -c ; b b -b ; c 0 -1 ; ... + 0 1 -c ; 0 1 c ; b b b ; 1 c 0 ; b b -b ; ... + 0 1 c ; 0 1 -c ; -b b -b ; -1 c 0 ; -b b b ; ... + 0 -1 -c ; 0 -1 c ; -b -b b ; -1 -c 0 ; -b -b -b ; ... + 0 -1 c ; 0 -1 -c ; b -b -b ; 1 -c 0 ; b -b b ; ... + 1 c 0 ; b b b ; c 0 1 ; b -b b ; 1 -c 0 ; ... + 1 -c 0 ; b -b -b ; c 0 -1 ; b b -b ; 1 c 0 ; ... +-1 c 0 ; -b b -b ; -c 0 -1 ; -b -b -b ; -1 -c 0 ; ... +-1 -c 0 ; -b -b b ; -c 0 1 ; -b b b ; -1 c 0 ; ... +]; + +% extract coordinates of unique vertices +[verts M N] = unique(tmp, 'rows', 'first'); %#ok + +% compute indices of face vertices, put result in a 12-by-5 index array +ind0 = reshape((1:60), [5 12])'; +faces = N(ind0); + +% extract edges from faces +edges = [reshape(faces(:, 1:5), [60 1]) reshape(faces(:, [2:5 1]), [60 1])]; +edges = unique(sort(edges, 2), 'rows'); + + +% format output +varargout = formatMeshOutput(nargout, verts, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createIcosahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createIcosahedron.m new file mode 100644 index 0000000..eebeb99 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createIcosahedron.m @@ -0,0 +1,77 @@ +function varargout = createIcosahedron() +%CREATEICOSAHEDRON Create a 3D mesh representing an Icosahedron. +% +% MESH = createIcosahedron; +% [V E F] = createIcosahedron; +% Create a solid with 12 vertices, and 20 triangular faces. Faces are +% oriented outwards of the mesh. +% +% [V F] = createIcosahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createIcosahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [n e f] = createIcosahedron; +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh +% createCube, createOctahedron, createDodecahedron, createTetrahedron +% +% +% --------- +% author: David Legland +% mail: david.legland@grignon.inra.fr +% INRA - TPV URPOI - BIA IMASTE +% created the 21/03/2005. +% + +% HISTORY +% 2007-01-04 remove unused variables +% 2010-12-06 format output, orient normals outwards + + +%% Initialisations + +theta = 2*pi/5; +l = 1/sin(theta/2)/2; +z1 = sqrt(1-l*l); + +t1 = (0:2*pi/5:2*pi*(1-1/5))'; +x1 = l*cos(t1); +y1 = l*sin(t1); + +t2 = t1 + 2*pi/10; +x2 = l*cos(t2); +y2 = l*sin(t2); + +h = sqrt(l*l-.5*.5); +z2 = sqrt(3/4 - (l-h)*(l-h)); + + +%% Create mesh data + +nodes = [0 0 0;... + [x1 y1 repmat(z1, [5 1])]; ... + [x2 y2 repmat(z1+z2, [5 1])]; ... + 0 0 2*z1+z2]; + +edges = [... + 1 2;1 3;1 4;1 5;1 6; ... + 2 3;3 4;4 5;5 6;6 2; ... + 2 7;7 3;3 8;8 4;4 9;9 5;5 10;10 6;6 11;11 2; ... + 7 8;8 9;9 10;10 11;11 7; ... + 7 12;8 12;9 12;10 12;11 12]; + +% faces are ordered to have normals pointing outside of the mesh +faces = [... + 1 3 2 ; 1 4 3 ; 1 5 4 ; 1 6 5 ; 1 2 6;... + 2 3 7 ; 3 4 8 ; 4 5 9 ; 5 6 10 ; 6 2 11;... + 7 3 8 ; 8 4 9 ; 9 5 10 ; 10 6 11 ; 11 2 7;... + 7 8 12 ; 8 9 12 ; 9 10 12 ; 10 11 12 ; 11 7 12]; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createMengerSponge.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createMengerSponge.m new file mode 100644 index 0000000..13aa3cf --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createMengerSponge.m @@ -0,0 +1,113 @@ +function varargout = createMengerSponge() +%CREATEMENGERSPONGE Create a cube with an inside cross removed +% +% [n e f] = createMengerSponge; +% Main use is to test possibility of drawing polyhedra with complex faces +% (polygonal faces with holes) +% +% Example +% [n e f] = createMengerSponge; +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-10-18 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 2008-10-17 finishes implementation + +nodes =[... + ... % main cube corners (1->8) + 0 0 0; ... + 3 0 0; ... + 0 3 0; ... + 3 3 0; ... + 0 0 3; ... + 3 0 3; ... + 0 3 3; ... + 3 3 3; ... + ... % outer cube inner face corners + 1 1 0; ... % face z=0 (9->12) + 2 1 0; ... + 1 2 0; ... + 2 2 0; ... + 1 1 3; ... % face z=3 (13->16) + 2 1 3; ... + 1 2 3; ... + 2 2 3; ... + 1 0 1; ... % face y=0 (17->20) + 2 0 1; ... + 1 0 2; ... + 2 0 2; ... + 1 3 1; ... % face y=3 (21->24) + 2 3 1; ... + 1 3 2; ... + 2 3 2; ... + 0 1 1; ... % face x=0 (25->28) + 0 2 1; ... + 0 1 2; ... + 0 2 2; ... + 3 1 1; ... % face x=3 (29->32) + 3 2 1; ... + 3 1 2; ... + 3 2 2; ... + ... % inner cube corners (33->40) + 1 1 1; ... + 2 1 1; ... + 1 2 1; ... + 2 2 1; ... + 1 1 2; ... + 2 1 2; ... + 1 2 2; ... + 2 2 2; ... + ]; + +edges = [... + 1 2;1 3;2 4;3 4;5 6;5 7;6 8;7 8;1 5;2 6;3 7;4 8;... % outer cube + 9 10;9 11;10 12;11 12;13 14;13 15;14 16;15 16; ... + 17 18;17 19;18 20;19 20; 21 22;21 23;22 24;23 24; ... + 25 26;25 27;26 28;27 28; 29 30;29 31;30 32;31 32; ... + 33 34;33 35;34 36;35 36; 37 38;37 39;38 40;39 40; ... % inner cube + 33 37;34 38;35 39;36 40; ... + 9 33;10 34;11 35;12 36; ... % parallel to xy + 13 37;14 38;15 39;16 40; ... + 17 33;18 34;19 37;20 38; ... % parallel to yz + 21 35;22 36;23 39;24 40; ... + 25 33;26 35;27 37;28 39; ... % parallel to xz + 29 34;30 36;31 38;32 40; ... + ]; + +% Alternative definition for faces: +% [1 2 4 3 NaN 9 11 12 10], ... +% [5 6 8 7 NaN 13 15 16 14], ... +% [1 5 7 3 NaN 25 26 28 27], .... +% [2 6 8 4 NaN 29 30 32 31], ... +% [1 2 6 5 NaN 17 18 20 19], ... +% [3 4 8 7 NaN 21 22 24 23], ... + +faces = {... + ... % 6 square faces with a square hole + [1 2 4 3 1 9 11 12 10 9], ... + [5 6 8 7 5 13 15 16 14 13], ... + [1 5 7 3 1 25 26 28 27 25], .... + [2 6 8 4 2 29 30 32 31 29], ... + [1 2 6 5 1 17 18 20 19 17], ... + [3 4 8 7 3 21 22 24 23 21], ... + ... % faces orthogonal to XY plane, parallel to Oz axis + [ 9 10 34 33], [ 9 11 35 33], [10 12 36 34], [11 12 36 35], ... + [13 14 38 37], [13 15 39 37], [14 16 40 38], [15 16 40 39], ... + ... % faces orthogonal to YZ plane, parallel to Oy axis + [17 18 34 33], [17 19 37 33], [18 20 38 34], [19 20 38 37], ... + [21 22 36 35], [21 23 39 35], [22 24 40 36], [23 24 40 39], ... + ...% faces orthogonal to the YZ plane, parallel to Ox axis + [25 33 35 26], [25 33 37 27], [26 35 39 28], [27 37 39 28], ... + [29 30 36 34], [29 31 38 34], [30 32 40 36], [31 32 40 38], ... + }; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createOctahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createOctahedron.m new file mode 100644 index 0000000..209be02 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createOctahedron.m @@ -0,0 +1,54 @@ +function varargout = createOctahedron() +%CREATEOCTAHEDRON Create a 3D mesh representing an octahedron +% +% [V E F] = createOctahedron; +% Create a 3D mesh representing an octahedron +% V is a 6-by-3 array with vertices coordinate, E is a 12-by-2 array +% containing indices of neighbour vertices, and F is a 8-by-3 array +% containing array of vertex index for each face. +% +% [V F] = createOctahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createOctahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Vertices are located on grid vertices: +% ( ±1, 0, 0 ) +% ( 0, ±1, 0 ) +% ( 0, 0, ±1 ) +% +% Edge length of returned octahedron is sqrt(2). +% Surface area of octahedron is 2*sqrt(3)*a^2, approximately 6.9282 in +% this case. +% Volume of octahedron is sqrt(2)/3*a^3, approximately 1.3333 in this +% case. +% +% Example +% [v e f] = createOctahedron; +% drawMesh(v, f); +% +% +% See also +% meshes3d, drawMesh +% createCube, createIcosahedron, createDodecahedron, createTetrahedron +% createCubeOctahedron +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +nodes = [1 0 0;0 1 0;-1 0 0;0 -1 0;0 0 1;0 0 -1]; + +edges = [1 2;1 4;1 5; 1 6;2 3;2 5;2 6;3 4;3 5;3 6;4 5;4 6]; + +faces = [1 2 5;2 3 5;3 4 5;4 1 5;1 6 2;2 6 3;3 6 4;1 4 6]; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createRhombododecahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createRhombododecahedron.m new file mode 100644 index 0000000..9be4360 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createRhombododecahedron.m @@ -0,0 +1,61 @@ +function varargout = createRhombododecahedron() +%CREATERHOMBODODECAHEDRON Create a 3D mesh representing a rhombododecahedron +% +% [V E F] = createRhombododecahedron +% V is a 14-by-3 array with vertex coordinate, +% E is a 12-by-2 array containing indices of neighbour vertices, +% F is a 8-by-3 array containing vertices array of each face. +% +% [V F] = createRhombododecahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createRhombododecahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [v e f] = createRhombododecahedron; +% drawMesh(v, f); +% +% +% See also +% meshes3d, drawMesh +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +nodes = [0 0 2;... + 1 -1 1;1 1 1;-1 1 1;-1 -1 1;... + 2 0 0;0 2 0;-2 0 0;0 -2 0;... + 1 -1 -1;1 1 -1;-1 1 -1;-1 -1 -1;... + 0 0 -2]; + +edges = [... + 1 2;1 3;1 4;1 5;... + 2 6;2 9;3 6;3 7;4 7;4 8;5 8;5 9;... + 6 10;6 11;7 11;7 12;8 12;8 13;9 10;9 13; ... + 10 14;11 14;12 14;13 14]; + +faces = [... + 1 2 6 3;... + 1 3 7 4;... + 1 4 8 5;... + 1 5 9 2;... + 2 9 10 6;... + 3 6 11 7;... + 4 7 12 8;... + 5 8 13 9;... + 6 10 14 11;... + 7 11 14 12;... + 8 12 14 13;... + 9 13 14 10]; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createSoccerBall.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createSoccerBall.m new file mode 100644 index 0000000..1371140 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createSoccerBall.m @@ -0,0 +1,41 @@ +function varargout = createSoccerBall() +%CREATESOCCERBALL Create a 3D mesh representing a soccer ball +% +% It is basically a wrapper of the 'bucky' function in matlab. +% [V E F] = createSoccerBall +% return vertices, edges and faces that constitute a soccerball +% V is a 60-by-3 array containing vertex coordinates +% E is a 90-by-2 array containing indices of neighbor vertices +% F is a 32-by-1 cell array containing vertex indices of each face +% Example +% [v f] = createSoccerBall; +% drawMesh(v, f); +% +% See also +% meshes, drawMesh, bucky +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-08-09 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 2007-01-04 remove unused variables, enhance output processing +% 2010-12-07 clean up edges, uses formatMeshOutput + + +% get vertices and adjacency matrix of the buckyball +[b n] = bucky; + +% compute edges +[i j] = find(b); +e = [i j]; +e = unique(sort(e, 2), 'rows'); + +% compute polygons that correspond to each 3D face +f = minConvexHull(n)'; + +% format output +varargout = formatMeshOutput(nargout, n, e, f); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrahedron.m new file mode 100644 index 0000000..6e5c456 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrahedron.m @@ -0,0 +1,53 @@ +function varargout = createTetrahedron() +%CREATETETRAHEDRON Create a 3D mesh representing a tetrahedron +% +% [V E F] = createTetrahedron +% create a simple tetrahedron, using mesh representation. The tetrahedron +% is inscribed in the unit cube. +% V is a 4-by-3 array with vertex coordinates, +% E is a 6-by-2 array containing indices of neighbour vertices, +% F is a 4-by-3 array containing vertices array of each (triangular) face. +% +% [V F] = createTetrahedron; +% Returns only the vertices and the faces. +% +% MESH = createTetrahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% +% Example +% % Create and display a tetrahedron +% [V E F] = createTetrahedron; +% drawMesh(V, F); +% +% See also +% meshes3d, drawMesh +% createCube, createOctahedron, createDodecahedron, createIcosahedron +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 21/03/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +x0 = 0; dx= 1; +y0 = 0; dy= 1; +z0 = 0; dz= 1; + +nodes = [... + x0 y0 z0; ... + x0+dx y0+dy z0; ... + x0+dx y0 z0+dz; ... + x0 y0+dy z0+dz]; + +edges = [1 2;1 3;1 4;2 3;3 4;4 2]; + +faces = [1 2 3;1 3 4;1 4 2;4 3 2]; + + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrakaidecahedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrakaidecahedron.m new file mode 100644 index 0000000..e764461 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/createTetrakaidecahedron.m @@ -0,0 +1,60 @@ +function varargout = createTetrakaidecahedron() +%CREATETETRAKAIDECAHEDRON Create a 3D mesh representing a tetrakaidecahedron +% +% [V E F] = createTetrakaidecahedron; +% Create a mesh structure representing a tetrakaidecahedron, composed of +% both square and hexagonal faces. Tetrakaidecahedron can be used to tile +% the 3D Euclidean space. +% +% V is a 24-by-3 array with vertex coordinates, +% E is a 36-by-2 array containing indices of neighbour vertices, +% F is a 14-by-1 cell array containing vertex indices array of each face. +% +% [V F] = createTetrakaidecahedron; +% Returns only the vertices and the face vertex indices. +% +% MESH = createTetrakaidecahedron; +% Returns the data as a mesh structure, with fields 'vertices', 'edges' +% and 'faces'. +% +% Example +% [n e f] = createTetrakaidecahedron; +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 04/01/2007: remove unused variables + +nodes = [... + 1 0 2;0 1 2;-1 0 2;0 -1 2;... + 2 0 1;0 2 1;-2 0 1;0 -2 1;... + 2 1 0;1 2 0;-1 2 0;-2 1 0;-2 -1 0;-1 -2 0;1 -2 0;2 -1 0;... + 2 0 -1;0 2 -1;-2 0 -1;0 -2 -1;... + 1 0 -2;0 1 -2;-1 0 -2;0 -1 -2]; + +edges = [... + 1 2;1 4;1 5;2 3;2 6;3 4;3 7;4 8;... + 5 9;5 16;6 10;6 11;7 12;7 13;8 14;8 15;... + 9 10;9 17;10 18;11 12;11 18;12 19;13 14;13 19;14 20;15 16;15 20;16 17;.... + 17 21;18 22;19 23;20 24;21 22;21 24;22 23;23 24]; + + +faces = {... + [1 2 3 4], ... + [1 4 8 15 16 5], [1 5 9 10 6 2], [2 6 11 12 7 3], [3 7 13 14 8 4],... + [5 16 17 9], [6 10 18 11], [7 12 19 13], [8 14 20 15],... + [9 17 21 22 18 10], [11 18 22 23 19 12], [13 19 23 24 20 14], [15 20 24 21 17 16], ... + [21 24 23 22]}; +faces = faces'; + +% format output +varargout = formatMeshOutput(nargout, nodes, edges, faces); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawFaceNormals.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawFaceNormals.m new file mode 100644 index 0000000..d722287 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawFaceNormals.m @@ -0,0 +1,40 @@ +function varargout = drawFaceNormals(varargin) +%DRAWFACENORMALS Draw normal vector of each face in a mesh +% +% drawFaceNormals(V, E, F) +% Compute and draw the face normals of the mesh defined by vertices V, +% edges E and faces F. See meshes3d for format of each argument. +% +% H = drawFaceNormals(...) +% Return handle array to the created objects. +% +% Example +% % draw face normals of a cube +% drawMesh(v, f) +% axis([-1 2 -1 2 -1 2]); +% hold on +% drawFaceNormals(v, e, f) +% +% See also +% meshes3d, quiver3 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% extract vertices and faces +[vertices faces] = parseMeshData(varargin{:}); + +% compute vector data +c = faceCentroids(vertices, faces); +n = faceNormal(vertices, faces); + +% display an arrow for each normal +h = quiver3(c(:,1), c(:,2), c(:,3), n(:,1), n(:,2), n(:,3)); + +% format output +if nargout > 0 + varargout{1} = h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawMesh.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawMesh.m new file mode 100644 index 0000000..0aba3f4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawMesh.m @@ -0,0 +1,133 @@ +function varargout = drawMesh(vertices, faces, varargin) +%DRAWMESH Draw a 3D mesh defined by vertices and faces +% +% drawMesh(VERTICES, FACES) +% Draws the 3D mesh defined by vertices VERTICES and the faces FACES. +% vertices is a [NVx3] array containing coordinates of vertices, and FACES +% is either a [NFx3] or [NFx4] array containing indices of vertices of +% the triangular or rectangular faces. +% FACES can also be a cell array, in the content of each cell is an array +% of indices to the vertices of the current face. Faces can have different +% number of vertices. +% +% drawMesh(MESH) +% Where mesh is a structure with fields 'vertices' and 'faces', draws the +% given mesh. +% +% drawMesh(..., COLOR) +% Use the specified color to render the mesh faces. +% +% drawMesh(..., NAME, VALUE) +% Use one or several pairs of parameter name/value to specify drawing +% options. Options are the same as the 'patch' function. +% +% +% H = drawMesh(...); +% Also returns a handle to the created patch. +% +% Example: +% [v f] = createSoccerBall; +% drawMesh(v, f); +% +% See also: +% polyhedra, meshes3d, patch +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 07/11/2005 update doc. +% 04/01/2007 typo +% 18/01/2007 add support for 2D polyhedra ("vertices" is N-by-2 array), and +% make 'cnodes' a list of points instead of a list of indices +% 14/08/2007 add comment, add support for NaN in faces (complex polygons) +% 14/09/2007 rename as drawPolyhedron +% 16/10/2008 better support for colors +% 27/07/2010 renamed as drawMesh +% 09/11/2010 update doc +% 07/12/2010 update management of mesh structures + + +%% Initialisations + +% Check if the input is a mesh structure +if isstruct(vertices) + % refresh options + if nargin > 1 + varargin = [{faces} varargin]; + end + + % extract data to display + faces = vertices.faces; + vertices = vertices.vertices; +end + +% process input arguments +switch length(varargin) + case 0 + % default color is red + varargin = {'facecolor', [1 0 0]}; + case 1 + % use argument as color for faces + varargin = {'facecolor', varargin{1}}; + otherwise + % otherwise keep varargin unchanged +end + +% overwrites on current figure +hold on; + +% if vertices are 2D points, add a z=0 coordinate +if size(vertices, 2)==2 + vertices(1,3)=0; +end + + +%% Use different processing depending on the type of faces +if isnumeric(faces) + % array FACES is a NC*NV indices array, with NV : number of vertices of + % each face, and NC number of faces + h = patch('vertices', vertices, 'faces', faces, varargin{:}); + +elseif iscell(faces) + % array FACES is a cell array + h = zeros(length(faces(:)), 1); + + for f=1:length(faces(:)) + % get vertices of the cell + face = faces{f}; + + % Special processing in case of multiple polygonal face: + % each polygonal loop is separated by a NaN. + if sum(isnan(face))~=0 + + % find indices of loops breaks + inds = find(isnan(face)); + + % replace NaNs by index of first vertex of each polygon + face(inds(2:end)) = face(inds(1:end-1)+1); + face(inds(1)) = face(1); + face(length(face)+1)= face(inds(end)+1); + end + + % draw current face + cnodes = vertices(face, :); + h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); + end + + % set up drawing options + set(h, varargin{:}); +else + error('second argument must be a face array'); +end + + +%% Process output arguments + +% format output parameters +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedra.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedra.m new file mode 100644 index 0000000..825b09d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedra.m @@ -0,0 +1,109 @@ +function varargout = drawPolyhedra(varargin) +%DRAWPOLYHEDRA draw polyhedra defined by vertices and faces +% +% DEPRECATED: use drawPolyhedron instead. +% +% drawPolyhedra(NODES, FACES) +% Draw the polyhedra defined by vertices NODES and the faces FACES. +% NODES is a [NNx3] array containing coordinates of vertices, and FACES +% is either a [NFx3] or [NFx4] array containing indices of vertices of +% the tria,gular or rectangular faces. +% FACES can also be a cell array, in the content of each cell is an array +% of indices to the nodes of the current face. Faces can have different +% number of vertices. +% +% H = drawPolyhedra(...) also return handles to the created patches. +% +% Example: +% [n f] = createSoccerBall; +% drawPolyhedra(n, f); +% +% See also : drawPolygon, drawPolyhedron +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 07/11/2005 update doc. +% 04/01/2007 typo +% 18/01/2007 add support for 2D polyhedra ("nodes" is N-by-2 array), and +% make 'cnodes' a list of points instead of a list of indices +% 14/08/2007 add comment, add support for NaN in faces (complex polygons) +% 17/10/2008 deprecate and add warning + + +warning('IMAEL:deprecatedFunction', ... + 'This function is deprecated, use ''drawPolyhedron'' instead'); + + +%% Initialisations + +% process input parameters +if length(varargin)<=2 + nodes = varargin{1}; + faces = varargin{2}; +else + error ('wrong number of arguments in "drawPolyhedra"'); +end + +% default color is red +color = [1 0 0]; + +% overwrites on current figure +hold on; + +% if nodes are 2D points, add a z=0 coordinate +if size(nodes, 2)==2 + nodes(1,3)=0; +end + + +%% main loop : for each face + +if iscell(faces) + % array FACES is a cell array + h = zeros(length(faces(:)), 1); + + for f=1:length(faces(:)) + % get nodes of the cell + face = faces{f}; + + if sum(isnan(face))~=0 + % Special processing in case of multiple polygonal face. + % each polygonal loop is separated by a NaN. + + % find indices of loops breaks + inds = find(isnan(face)); + + % replace NaNs by index of first vertex of each polygon + face(inds(2:end)) = face(inds(1:end-1)+1); + face(inds(1)) = face(1); + face(length(face)+1)= face(inds(end)+1); + + end + + % draw current face + cnodes = nodes(face, :); + h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), color); + end + +else + % array FACES is a NC*NV indices array, with NV : number of vertices of + % each face, and NC number of faces + h = zeros(size(faces, 1), 1); + for f=1:size(faces, 1) + % get nodes of the cell + cnodes = nodes(faces(f,:)', :); + h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), color); + end +end + + +% format output parameters +if nargout>0 + varargout{1}=h; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedron.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedron.m new file mode 100644 index 0000000..7b11775 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/drawPolyhedron.m @@ -0,0 +1,112 @@ +function varargout = drawPolyhedron(nodes, faces, varargin) +%DRAWPOLYHEDRON draw polyhedron defined by vertices and faces +% +% drawPolyhedron(NODES, FACES) +% Draws the polyhedron defined by vertices NODES and the faces FACES. +% NODES is a [NNx3] array containing coordinates of vertices, and FACES +% is either a [NFx3] or [NFx4] array containing indices of vertices of +% the triangular or rectangular faces. +% FACES can also be a cell array, in the content of each cell is an array +% of indices to the nodes of the current face. Faces can have different +% number of vertices. +% +% H = drawPolyhedron(...); +% Also returns a handle to the created patche. +% +% Example: +% [n f] = createSoccerBall; +% drawPolyhedron(n, f); +% +% See also: +% polyhedra, drawPolygon +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 10/02/2005. +% + +% HISTORY +% 07/11/2005 update doc. +% 04/01/2007 typo +% 18/01/2007 add support for 2D polyhedra ("nodes" is N-by-2 array), and +% make 'cnodes' a list of points instead of a list of indices +% 14/08/2007 add comment, add support for NaN in faces (complex polygons) +% 14/09/2007 rename as drawPolyhedron +% 16/10/2008 better support for colors +% 27/07/2010 copy to 'drawMesh' + + +%% Initialisations + + +% process input arguments +switch length(varargin) + case 0 + % default color is red + varargin = {'facecolor', [1 0 0]}; + case 1 + % use argument as color for faces + varargin = {'facecolor', varargin{1}}; + otherwise + % otherwise do nothing +end + +% overwrites on current figure +hold on; + +% if nodes are 2D points, add a z=0 coordinate +if size(nodes, 2)==2 + nodes(1,3)=0; +end + + +%% main loop : for each face + +if iscell(faces) + % array FACES is a cell array + h = zeros(length(faces(:)), 1); + + for f=1:length(faces(:)) + % get nodes of the cell + face = faces{f}; + + if sum(isnan(face))~=0 + % Special processing in case of multiple polygonal face. + % each polygonal loop is separated by a NaN. + + % find indices of loops breaks + inds = find(isnan(face)); + + % replace NaNs by index of first vertex of each polygon + face(inds(2:end)) = face(inds(1:end-1)+1); + face(inds(1)) = face(1); + face(length(face)+1)= face(inds(end)+1); + end + + % draw current face + cnodes = nodes(face, :); + h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); + end + +else + % array FACES is a NC*NV indices array, with NV : number of vertices of + % each face, and NC number of faces + h = zeros(size(faces, 1), 1); + for f=1:size(faces, 1) + % get nodes of the cell + cnodes = nodes(faces(f,:)', :); + h(f) = patch(cnodes(:, 1), cnodes(:, 2), cnodes(:, 3), [1 0 0]); + end +end + +% set up drawing options +if ~isempty(varargin) + set(h, varargin{:}); +end + +% format output parameters +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceCentroids.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceCentroids.m new file mode 100644 index 0000000..34552ff --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceCentroids.m @@ -0,0 +1,50 @@ +function centroids = faceCentroids(nodes, faces) +%FACECENTROIDS Compute centroids of a mesh faces +% +% NORMALS = faceCentroids(VERTICES, FACES) +% VERTICES is a set of 3D points (as a Nx3 array), and FACES is either a +% [Nx3] indices array or a cell array of indices. The function computes +% the centroid of each face. +% +% +% +% See also: +% meshes3d, drawMesh, faceNormal, convhull, convhulln +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-07-05 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 2007/09/18 fix: worked only for 2D case, now works also for 3D + + +if isnumeric(faces) + nf = size(faces, 1); + centroids = zeros(nf, size(nodes, 2)); + if size(nodes, 2)==2 + for f=1:nf + centroids(f,:) = polygonCentroid(nodes(faces(f,:), :)); + end + else + for f=1:nf + centroids(f,:) = polygonCentroid3d(nodes(faces(f,:), :)); + end + end +else + nf = length(faces); + centroids = zeros(nf, size(nodes, 2)); + if size(nodes, 2)==2 + for f=1:nf + centroids(f,:) = polygonCentroid(nodes(faces{f}, :)); + end + else + for f=1:nf + centroids(f,:) = polygonCentroid3d(nodes(faces{f}, :)); + end + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceNormal.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceNormal.m new file mode 100644 index 0000000..f4a765c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/faceNormal.m @@ -0,0 +1,58 @@ +function normals = faceNormal(nodes, faces) +%FACENORMAL Compute normal vector of faces in a 3D mesh +% +% NORMALS = faceNormal(VERTICES, FACES) +% VERTICES is a set of 3D points (as a Nx3 array), and FACES is either a +% [Nx3] indices array or a cell array of indices. The function computes +% the normal of each face. +% The orientation of the normal is undefined. +% +% +% Example +% [n e f] = createCube; +% normals1 = faceNormal(n, f); +% +% pts = rand(50, 3); +% hull = minConvexHull(pts); +% normals2 = faceNormal(pts, hull); +% +% See also +% meshes3d, drawMesh, convhull, convhulln +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-07-05 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +if isnumeric(faces) + % compute vector of first edge + v1 = nodes(faces(:,2),1:3) - nodes(faces(:,1),1:3); + v2 = nodes(faces(:,3),1:3) - nodes(faces(:,1),1:3); + + % normalize vectors + v1 = normalizeVector3d(v1); + v2 = normalizeVector3d(v2); + + % compute normals using cross product + normals = cross(v1, v2, 2); + +else + normals = zeros(length(faces), 3); + + for i=1:length(faces) + face = faces{i}; + % compute vector of first edges + v1 = nodes(face(2),1:3) - nodes(face(1),1:3); + v2 = nodes(face(3),1:3) - nodes(face(1),1:3); + + % normalize vectors + v1 = normalizeVector3d(v1); + v2 = normalizeVector3d(v2); + + % compute normals using cross product + normals(i, :) = cross(v1, v2, 2); + end +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/gridmeshToQuadmesh.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/gridmeshToQuadmesh.m new file mode 100644 index 0000000..97bf593 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/gridmeshToQuadmesh.m @@ -0,0 +1,62 @@ +function varargout = gridmeshToQuadmesh(x, y, varargin) +%GRIDMESHTOQUADMESH Create a quad mesh from a grid mesh +% +% [V F] = gridmeshToQuadmesh(X, Y) +% [V F] = gridmeshToQuadmesh(X, Y, Z) +% +% Example +% [X,Y] = meshgrid(-2:.2:2, -2:.2:2); +% Z = X .* exp(-X.^2 - Y.^2); +% [V F] = gridmeshToQuadmesh(X, Y, Z); +% figure; +% drawMesh(V, F); +% +% See also +% meshgrid, drawMesh +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-18, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% number of vertices +dim = size(x); +nv = prod(dim); + +% vertex indices in grid +inds = reshape(1:nv, dim); + +% create vertices +if isempty(varargin) + vertices = [x(:) y(:)]; +else + z = varargin{1}; + vertices = [x(:) y(:) z(:)]; +end + +% create faces +v1 = inds(1:end-1, 1:end-1); +v2 = inds(1:end-1, 2:end); +v3 = inds(2:end, 2:end); +v4 = inds(2:end, 1:end-1); + +faces = [v1(:) v2(:) v3(:) v4(:)]; + +% format output +if nargout <= 1 + % concatenate into one structure + mesh.vertices = vertices; + mesh.edges = edges; + mesh.faces = faces; + varargout = {mesh}; + +elseif nargout == 2 + % returns as separate arguments + varargout = {vertices, faces}; + +elseif nargout == 3 + % also return vertex indices + varargout = {vertices, faces, inds}; + +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/intersectLineMesh3d.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/intersectLineMesh3d.m new file mode 100644 index 0000000..1678a88 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/intersectLineMesh3d.m @@ -0,0 +1,95 @@ +function [points pos faceInds] = intersectLineMesh3d(line, vertices, faces) +%INTERSECTLINEMESH3D Intersection points of a 3D line with a mesh +% +% output = intersectLineMesh3d(input) +% +% Example +% intersectLineMesh3d +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% nf = size(faces, 1); + +% pts = NaN * ones(nf, 3); + +% % code using a loop: +% for i = 1:nf +% face = faces(i,:); +% tri = [vertices(face(1), :) vertices(face(2), :) vertices(face(3), :)]; +% +% pts(i,:) = intersectLineTriangle3d(line, tri); +% end +% +% pts = unique(pts(isfinite(pts(:,1)), :), 'rows'); + +tol = 1e-12; + +% find triangle edge vectors +t0 = vertices(faces(:,1), :); +u = vertices(faces(:,2), :) - t0; +v = vertices(faces(:,3), :) - t0; + +% triangle normal +n = normalizeVector3d(vectorCross3d(u, v)); + +% direction vector of line +dir = line(4:6); + +% vector between triangle origin and line origin +w0 = bsxfun(@minus, line(1:3), t0); + +a = -dot(n, w0, 2); +b = dot(n, repmat(dir, size(n, 1), 1), 2); + +valid = abs(b) > tol & vectorNorm3d(n) > tol; + +% compute intersection point of line with supporting plane +% If pos < 0: point before ray +% IF pos > |dir|: point after edge +pos = a ./ b; + +% coordinates of intersection point +points = bsxfun(@plus, line(1:3), bsxfun(@times, pos, dir)); + + +%% test if intersection point is inside triangle + +% normalize direction vectors of triangle edges +uu = dot(u, u, 2); +uv = dot(u, v, 2); +vv = dot(v, v, 2); + +% coordinates of vector v in triangle basis +w = points - t0; +wu = dot(w, u, 2); +wv = dot(w, v, 2); + +% normalization constant +D = uv.^2 - uu .* vv; + +% test first coordinate +s = (uv .* wv - vv .* wu) ./ D; +ind1 = s < 0.0 | s > 1.0; +points(ind1, :) = NaN; +pos(ind1) = NaN; + +% test second coordinate, and third triangle edge +t = (uv .* wu - uu .* wv) ./ D; +ind2 = t < 0.0 | (s + t) > 1.0; +points(ind2, :) = NaN; +pos(ind2) = NaN; + +% keep only interesting points +inds = ~ind1 & ~ind2 & valid; +points = points(inds, :); + +pos = pos(inds); +faceInds = find(inds); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshDihedralAngles.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshDihedralAngles.m new file mode 100644 index 0000000..518af48 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshDihedralAngles.m @@ -0,0 +1,65 @@ +function alpha = meshDihedralAngles(vertices, edges, faces) +%MESHDIHEDRALANGLES Dihedral at edges of a polyhedal mesh +% +% ALPHA = meshDihedralAngles(V, E, F) +% where V, E and F represent vertices, edges and faces of a mesh, +% computes the dihedral angle between the two adjacent faces of each edge +% in the mesh. ALPHA is a column array with as many rows as the number of +% edges. The i-th element of ALPHA corresponds to the i-th edge. +% +% Note: the function assumes that the faces are correctly oriented. The +% face vertices should be indexed counter-clockwise when considering the +% supporting plane of the face, with the outer normal oriented outwards +% of the mesh. +% +% Example +% [v e f] = createCube; +% rad2deg(meshDihedralAngles(v, e, f)) +% ans = +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% 90 +% +% See also +% meshes3d, polyhedronMeanBreadth, dihedralAngle +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% compute normal of each face +normals = faceNormal(vertices, faces); + +% indices of faces adjacent to each edge +edgeFaces = meshEdgeFaces(vertices, edges, faces); + +% allocate memory for resulting angles +Ne = size(edges, 1); +alpha = zeros(Ne, 1); + +% iterate over edges +for i = 1:Ne + % indices of adjacent faces + indFace1 = edgeFaces(i, 1); + indFace2 = edgeFaces(i, 2); + + % normal vector of adjacent faces + normal1 = normals(indFace1, :); + normal2 = normals(indFace2, :); + + % compute dihedral angle of two vectors + alpha(i) = vectorAngle3d(normal1, normal2); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeFaces.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeFaces.m new file mode 100644 index 0000000..a02c0ea --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeFaces.m @@ -0,0 +1,87 @@ +function edgeFaces = meshEdgeFaces(vertices, edges, faces) %#ok +%MESHEDGEFACES Compute index of faces adjacent to each edge of a mesh +% +% EF = meshEdgeFaces(V, E, F) +% +% Example +% meshEdgeFaces +% +% See also +% meshes3d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +Ne = size(edges, 1); + +% indices of faces adjacent to each edge +edgeFaces = zeros(Ne, 2); + +% different method for extracting current face depending if faces are +% stored as index 2D array or as cell array of 1D arrays. +if isnumeric(faces) + Nf = size(faces, 1); + for i = 1:Nf + face = faces(i, :); + processFace(face, i) + end +elseif iscell(faces) + Nf = length(faces); + for i = 1:Nf + face = faces{i}; + processFace(face, i) + end +end + + function processFace(face, indFace) + % iterate on face edges + for j = 1:length(face) + % build edge: array of vertices + j2 = mod(j, length(face)) + 1; + + % do not process edges with same vertices + if face(j) == face(j2) + continue; + end + + % vertex indices of current edge + currentEdge = [face(j) face(j2)]; + + % find index of current edge, assuming face is left-located + b1 = ismember(edges, currentEdge, 'rows'); + indEdge = find(b1); + if ~isempty(indEdge) + if edgeFaces(indEdge, 1) ~= 0 + error('meshes3d:IllegalTopology', ... + 'Two faces were found on left side of edge %d ', indEdge); + end + + edgeFaces(indEdge, 1) = indFace; + continue; + end + + % otherwise, assume the face is right-located + b2 = ismember(edges, currentEdge([2 1]), 'rows'); + indEdge = find(b2); + if ~isempty(indEdge) + if edgeFaces(indEdge, 2) ~= 0 + error('meshes3d:IllegalTopology', ... + 'Two faces were found on left side of edge %d ', indEdge); + end + + edgeFaces(indEdge, 2) = indFace; + continue; + end + + % If face was neither left nor right, error + warning('meshes3d:IllegalTopology', ... + 'Edge %d of face %d was not found in edge array', ... + j, indFace); + continue; + end + end + +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeLength.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeLength.m new file mode 100644 index 0000000..af886ea --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshEdgeLength.m @@ -0,0 +1,23 @@ +function lengths = meshEdgeLength(vertices, edges, faces) %#ok +%MESHEDGELENGTH Lengths of edges of a polygonal or polyhedral mesh +% +% output = meshEdgeLength(V, E, F) +% +% Example +% meshEdgeLength +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% extract vertices +p1 = vertices(edges(:, 1), :); +p2 = vertices(edges(:, 2), :); + +% compute euclidean distance betwenn the two vertices +lengths = sqrt(sum((p2-p1).^2, 2)); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshFace.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshFace.m new file mode 100644 index 0000000..20df8eb --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshFace.m @@ -0,0 +1,38 @@ +function face = meshFace(faces, index) +%MESHFACE Return the vertex indices of a face in a mesh +% +% FACE = meshFace(FACES, INDEX) +% Return the vertex indices of the i-th face in the face array. This is +% mainly an utilitary function that manages faces stored either as int +% array (when all faces have same number of sides) or cell array (when +% faces may have different number of edges). +% +% Example +% meshFace +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + + +% process mesh given as structure +if isstruct(faces) + if isfield(faces, 'faces') + faces = faces.faces; + else + error('Mesh structure should contains a field ''faces'''); + end +end + +% switch between numeric or cell array +if isnumeric(faces) + face = faces(index, :); +else + face = faces{index}; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshReduce.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshReduce.m new file mode 100644 index 0000000..806ca58 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshReduce.m @@ -0,0 +1,366 @@ +function varargout = meshReduce(nodes, varargin) +%MESHREDUCE Merge coplanar faces of a polyhedral mesh +% +% [NODES FACES] = meshReduce(NODES, FACES) +% [NODES EDGES FACES] = meshReduce(NODES, EDGES, FACES) +% NODES is a set of 3D points (as a Nn-by-3 array), +% and FACES is one of: +% - a Nf-by-X array containing vertex indices of each face, with each +% face having the same number of vertices, +% - a Nf-by 1 cell array, each cell containing indices of a face. +% The function groups faces which are coplanar and contiguous, resulting +% in a "lighter" mesh. This can be useful to visualize binary 3D images +% for example. +% +% FACES = meshReduce(..., PRECISION) +% Adjust the threshold for deciding if two faces are coplanar or +% parallel. Default value is 1e-14. +% +% Example +% [n e f] = createCube; +% f2 = meshReduce(n); +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh, convhull, convhulln, minConvexHull +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-07-05 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% 20/07/2006 add tolerance for coplanarity test +% 21/08/2006 fix small bug due to difference of methods to test +% coplanaritity, sometimes resulting in 3 points of a face not coplanar ! +% Also add control on precision +% 14/08/2007 rename minConvexHull->meshReduce, and extend to non convex +% shapes +% 2011-01-14 code clean up + + +%% Process input arguments + +% set up precision +acc = 1e-14; +if ~isempty(varargin) + var = varargin{end}; + if length(var)==1 + acc = var; + varargin(end) = []; + end +end + +% extract faces and edges +if length(varargin)==1 + faces = varargin{1}; +else + faces = varargin{2}; +end + + +%% Initialisations + +% number of faces +Nn = size(nodes, 1); +Nf = size(faces, 1); + +% compute number of vertices of each face +Fn = ones(Nf, 1)*size(faces, 2); + +% compute normal of each faces +normals = faceNormal(nodes, faces); + +% initialize empty faces and edges +faces2 = cell(0, 1); +edges2 = zeros(0, 2); + +% Processing flag for each face +% 1: face to process, 0: already processed +% in the beginning, every triangle face need to be processed +flag = ones(Nf, 1); + + +%% Main iteration + +% iterate on each face +for f=1:Nf + + % check if face was already performed + if ~flag(f) + continue; + end + + % indices of faces with same normal + ind = find(abs(vectorNorm3d(cross(repmat(normals(f, :), [Nf 1]), normals))) + planeEdges2 = reshape(J, size(planeEdges)); + component = grLabel(nodes(planeNodes, :), planeEdges2); + + % compute degree (number of adjacent faces) of each edge. + Npe = size(planeEdges, 1); + edgesDegree = zeros(Npe, 1); + for i=1:length(ind2) + face = faces(ind2(i), :); + faceEdges = sort([face' face([2:end 1])'], 2); + for j=1:size(faceEdges, 1) + indEdge = find(sum(ismember(planeEdges, faceEdges(j,:)),2)==2); + edgesDegree(indEdge) = edgesDegree(indEdge)+1; + end + end + + % extract unique edges and nodes of the plane + planeEdges = planeEdges(edgesDegree==1, :); + planeEdges2 = planeEdges2(edgesDegree==1, :); + + % find connected component of each edge + planeEdgesComp = zeros(size(planeEdges, 1), 1); + for e=1:size(planeEdges, 1) + planeEdgesComp(e) = component(planeEdges2(e, 1)); + end + + % iterate on connected faces + for c=1:max(component) + + % convert to chains of nodes + loops = graph2Contours(nodes, planeEdges(planeEdgesComp==c, :)); + + % add a simple Polygon for each loop + facePolygon = loops{1}; + for l=2:length(loops) + facePolygon = [facePolygon, NaN, loops{l}]; + end + faces2{length(faces2)+1, 1} = facePolygon; + + % also add news edges + edges2 = unique([edges2; planeEdges], 'rows'); + end + + % mark processed faces + flag(ind2) = 0; +end + + +%% Additional processing on nodes + +% select only nodes which appear in at least one edge +indNodes = unique(edges2(:)); + +% for each node, compute index of corresponding new node (or 0 if dropped) +refNodes = zeros(Nn, 1); +for i=1:length(indNodes) + refNodes(indNodes(i)) = i; +end + +% changes indices of nodes in edges2 array +for i=1:length(edges2(:)) + edges2(i) = refNodes(edges2(i)); +end + +% changes indices of nodes in faces2 array +for f=1:length(faces2) + face = faces2{f}; + for i=1:length(face) + if ~isnan(face(i)) + face(i) = refNodes(face(i)); + end + end + faces2{f} = face; +end + +% keep only boundary nodes +nodes2 = nodes(indNodes, :); + + +%% Process output arguments + +if nargout == 1 + varargout{1} = faces2; +elseif nargout == 2 + varargout{1} = nodes2; + varargout{2} = faces2; +elseif nargout==3 + varargout{1} = nodes2; + varargout{2} = edges2; + varargout{3} = faces2; +end + + +function labels = grLabel(nodes, edges) +%GRLABEL associate a label to each connected component of the graph +% LABELS = grLabel(NODES, EDGES) +% Returns an array with as many rows as the array NODES, containing index +% number of each connected component of the graph. If the graph is +% totally connected, returns an array of 1. +% +% Example +% nodes = rand(6, 2); +% edges = [1 2;1 3;4 6]; +% labels = grLabel(nodes, edges); +% labels = +% 1 +% 1 +% 1 +% 2 +% 3 +% 2 +% +% See also +% getNeighbourNodes +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-08-14, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% init +Nn = size(nodes, 1); +labels = (1:Nn)'; + +% iteration +modif = true; +while modif + modif = false; + + for i=1:Nn + neigh = getNeighbourNodes(i, edges); + neighLabels = labels([i;neigh]); + + % check for a modification + if length(unique(neighLabels))>1 + modif = true; + end + + % put new labels + labels(ismember(labels, neighLabels)) = min(neighLabels); + end +end + +% change to have fewer labels +labels2 = unique(labels); +for i=1:length(labels2) + labels(labels==labels2(i)) = i; +end + +function nodes2 = getNeighbourNodes(node, edges) +%GETNEIGHBOURNODES find nodes adjacent to a given node +% +% NEIGHS = getNeighbourNodes(NODE, EDGES) +% NODE: index of the node +% EDGES: the complete edges list +% NEIGHS: the nodes adjacent to the given node. +% +% NODE can also be a vector of node indices, in this case the result is +% the set of neighbors of any input node. +% +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 16/08/2004. +% + +% HISTORY +% 10/02/2004 documentation +% 13/07/2004 faster algorithm +% 03/10/2007 can specify several input nodes + +[i, j] = find(ismember(edges, node)); +nodes2 = edges(i,1:2); +nodes2 = unique(nodes2(:)); +nodes2 = sort(nodes2(~ismember(nodes2, node))); + +function curves = graph2Contours(nodes, edges) +%GRAPH2CONTOURS convert a graph to a set of contour curves +% +% CONTOURS = GRAPH2CONTOURS(NODES, EDGES) +% NODES, EDGES is a graph representation (type "help graph" for details) +% The algorithm assume every node has degree 2, and the set of edges +% forms only closed loops. The result is a list of indices arrays, each +% array containing consecutive point indices of a contour. +% +% To transform contours into drawable curves, please use : +% CURVES{i} = NODES(CONTOURS{i}, :); +% +% +% NOTE : contours are not oriented. To manage contour orientation, edges +% also need to be oriented. So we must precise generation of edges. +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/08/2004. +% + + +curves = {}; +c = 0; + +while size(edges,1)>0 + % find first point of the curve + n0 = edges(1,1); + curve = n0; + + % second point of the curve + n = edges(1,2); + e = 1; + + while true + % add current point to the curve + curve = [curve n]; + + % remove current edge from the list + edges = edges((1:size(edges,1))~=e,:); + + % find index of edge containing reference to current node + e = find(edges(:,1)==n | edges(:,2)==n); + e = e(1); + + % get index of next current node + % (this is the other node of the current edge) + if edges(e,1)==n + n = edges(e,2); + else + n = edges(e,1); + end + + % if node is same as start node, loop is closed, and we stop + % node iteration. + if n==n0 + break; + end + end + + % remove the last edge of the curve from edge list. + edges = edges((1:size(edges,1))~=e,:); + + % add the current curve to the list, and start a new curve + c = c+1; + curves{c} = curve; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshSurfaceArea.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshSurfaceArea.m new file mode 100644 index 0000000..7cc37a8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/meshSurfaceArea.m @@ -0,0 +1,68 @@ +function area = meshSurfaceArea(vertices, edges, faces) +%MESHSURFACEAREA Surface area of a polyhedral mesh +% +% S = meshSurfaceArea(V, F) +% S = meshSurfaceArea(V, E, F) +% Computes the surface area of the mesh specified by vertex array V and +% face array F. Vertex array is a NV-by-3 array of coordinates. +% Face array can be a NF-by-3 or NF-by-4 numeric array, or a Nf-by-1 cell +% array, containing vertex indices of each face. +% +% This functions iterates on faces, extract vertices of the current face, +% and computes the sum of face areas. +% +% This function assumes faces are coplanar and convex. If faces are all +% triangular, the function "trimeshSurfaceArea" should be more efficient. +% +% +% Example +% % compute the surface of a unit cube (should be equal to 6) +% [v f] = createCube; +% meshSurfaceArea(v, f) +% ans = +% 6 +% +% See also +% meshes3d, trimeshSurfaceArea +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-13, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + + +% check input number +if nargin == 2 + faces = edges; +end + +% pre-compute normals +normals = normalizeVector3d(faceNormal(vertices, faces)); + +% init accumulator +area = 0; + + +if isnumeric(faces) + % iterate on faces in a numeric array + for i = 1:size(faces, 1) + poly = vertices(faces(i, :), :); + area = area + polyArea3d(poly, normals(i,:)); + end + +else + % iterate on faces in a cell array + for i = 1:size(faces, 1) + poly = vertices(faces{i}, :); + area = area + polyArea3d(poly, normals(i,:)); + end +end + + +function a = polyArea3d(v, normal) + +nv = size(v, 1); +v0 = repmat(v(1,:), nv, 1); +products = sum(cross(v-v0, v([2:end 1], :)-v0, 2), 1); +a = abs(dot(products, normal, 2))/2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/minConvexHull.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/minConvexHull.m new file mode 100644 index 0000000..de82ffc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/minConvexHull.m @@ -0,0 +1,94 @@ +function faces = minConvexHull(nodes, varargin) +%MINCONVEXHULL Return the unique minimal convex hull of a set of 3D points +% +% FACES = minConvexHull(NODES) +% NODES is a set of 3D points (as a Nx3 array). The function computes +% the convex hull, and merge contiguous coplanar faces. The result is a +% set of polygonal faces, such that there are no coplanar faces. +% FACES is a cell array, each cell containing the vector of indices of +% nodes given in NODES for the corresponding face. +% +% FACES = minConvexHull(NODES, PRECISION) +% Adjust the threshold for deciding if two faces are coplanar or +% parallel. Default value is 1e-14. +% +% Example +% [n e f] = createCube; +% f2 = minConvexHull(n); +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh, convhull, convhulln +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-07-05 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% HISTORY +% 20/07/2006 add tolerance for coplanarity test +% 21/08/2006 fix small bug due to difference of methods to test +% coplanarity, sometimes resulting in 3 points of a face being not +% coplanar ! Also add control on precision +% 18/09/2007 ensure faces are given as horizontal vectors + +% set up precision +acc = 1e-14; +if ~isempty(varargin) + acc = varargin{1}; +end + +% triangulated convex hull. It is not uniquely defined. +hull = convhulln(nodes); + +% number of base triangular faces +N = size(hull, 1); + +% compute normals of given faces +normals = planeNormal(createPlane(... + nodes(hull(:,1),:), nodes(hull(:,2),:), nodes(hull(:,3),:))); + +% initialize empty faces +faces = {}; + + +% Processing flag for each triangle +% 1 : triangle to process, 0 : already processed +% in the beginning, every triangle face need to be processed +flag = ones(N, 1); + +% iterate on each triangle face +for i=1:N + + % check if face was already performed + if ~flag(i) + continue; + end + + % indices of faces with same normal + ind = find(abs(vectorNorm3d(cross(repmat(normals(i, :), [N 1]), normals))) + end + end + + + % compute order of the vertices in current face + vertices = unique(hull(ind2, :)); + [tmp I] = angleSort3d(nodes(vertices, :)); %#ok + + % add a new face to the list + face = vertices(I); + faces = [faces {face(:)'}]; %#ok + + % mark processed faces + flag(ind2) = 0; +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedra.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedra.m new file mode 100644 index 0000000..dfc9983 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedra.m @@ -0,0 +1,30 @@ +function polyhedra(varargin) +%POLYHEDRA Index of classical polyhedral meshes +% +% Polyhedra are specific meshes, with additional assumptions: +% * the set of faces is assumed to enclose a single 3D domain +% * each face has a neighbor face for each edge +% * some functions also assume that normals of all faces point ouwards +% +% Example +% % create a soccer ball mesh and display it +% [n e f] = createSoccerBall; +% drawMesh(n, f, 'faceColor', 'g', 'linewidth', 2); +% axis equal; +% +% See also +% meshes3d +% createCube, createCubeOctahedron, createIcosahedron, createOctahedron +% createRhombododecahedron, createTetrahedron, createTetrakaidecahedron +% createDodecahedron, createSoccerBall, createMengerSponge +% steinerPolytope +% polyhedronNormalAngle, polyhedronMeanBreadth, minConvexHull +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2008-10-13, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronMeanBreadth.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronMeanBreadth.m new file mode 100644 index 0000000..2f6795c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronMeanBreadth.m @@ -0,0 +1,54 @@ +function breadth = polyhedronMeanBreadth(vertices, edges, faces) +%POLYHEDRONMEANBREADTH Mean breadth of a convex polyhedron +% +% BREADTH = polyhedronMeanBreadth(V, E, F) +% Return the mean breadth (average of polyhedron caliper diameter over +% all direction) of a convex polyhedron. +% +% The mean breadth is omputed using the sum, over the edges of the +% polyhedron, of the edge dihedral angles multiplied by the edge length, +% the final sum being divided by (4*PI). +% +% Note: the function assumes that the faces are correctly oriented. The +% face vertices should be indexed counter-clockwise when considering the +% supporting plane of the plane, with the outer normal oriented outwards +% of the polyhedron. +% +% Typical values for classical polyhedra are: +% cube side a breadth = (3/2)*a +% cuboid sides a, b, c breadth = (a+b+c)/2 +% tetrahedron side a breadth = 0.9123*a +% octaedron side a beradth = 1.175*a +% dodecahedron, side a breadth = 15*arctan(2)*a/(2*pi) +% icosaehdron, side a breadth = 15*arcsin(2/3)*a/(2*pi) +% +% Example +% [v e f] = createCube; +% polyhedronMeanBreadth(v, e, f) +% ans = +% 1.5 +% +% See also +% meshes3d, meshEdgeFaces, meshDihedralAngles +% +% References +% Stoyan D., Kendall W.S., Mecke J. (1995) "Stochastic Geometry and its +% Applications", John Wiley and Sons, p. 26 +% Ohser, J., Muescklich, F. (2000) "Statistical Analysis of +% Microstructures in Materials Sciences", John Wiley and Sons, p.352 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-10-04, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + + +% compute dihedral angle of each edge +alpha = meshDihedralAngles(vertices, edges, faces); + +% compute length of each edge +lengths = meshEdgeLength(vertices, edges); + +% compute product of length by angles +breadth = sum(alpha.*lengths)/(4*pi); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronNormalAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronNormalAngle.m new file mode 100644 index 0000000..0a50da9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronNormalAngle.m @@ -0,0 +1,95 @@ +function theta = polyhedronNormalAngle(varargin) +%POLYHEDRONNORMALANGLE Compute normal angle at a vertex of a 3D polyhedron +% +% THETA = polyhedraNormalAngle(NODES, EDGES, FACES, IND); +% THETA = polyhedraNormalAngle(NODES, FACES, IND); +% where NODES is a set of 3D points, and FACES a set of faces, whose +% elements are indices to NODES array, compute the normal angle at the +% vertex whose index is given by IND. +% +% THETA = polyhedraNormalAngle(GRAPH, IND); +% Uses a graph structure. GRAPH should contain at least fields : 'nodes' +% and 'faces'. +% +% Example : +% % create a simple (irregular) tetrahedra +% nodes = [0 0 0;1 0 0;0 1 0;0 0 1]; +% faces = [1 2 3;1 2 4;1 3 4;2 3 4]; +% % compute normal angle at each vertex +% theta = polyhedronNormalAngle(nodes, faces, 1:size(nodes, 1)); +% % sum of normal angles should be equal to 4*pi : +% sum(theta) +% +% +% TODO works only for polyhedra with convex faces ! ! ! +% +% See also +% polyhedra, polygon3dNormalAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-30 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +if length(varargin)==4 + nodes = varargin{1}; + faces = varargin{3}; + ind = varargin{4}; + +elseif length(varargin)==3 + nodes = varargin{1}; + faces = varargin{2}; + ind = varargin{3}; + +elseif length(varargin)==2 + graph = varargin{1}; + nodes = graph.nodes; + faces = graph.faces; + ind = varargin{2}; +else + error('wrong number of arguments'); +end + + +% number of angles to compute +na = length(ind); + +theta = zeros(na, 1); +for i=1:na + + thetaf = []; + + % find faces containing given vertex, + % and compute normal angle at each face containing vertex + if iscell(faces) + for j=1:length(faces) + if ismember(ind(i), faces{j}) + % create 3D polygon + face = nodes(faces{j}, :); + + % index of point in polygon + indp = find(faces{j}==i); + + % compute normal angle of vertex + thetaf = [thetaf polygon3dNormalAngle(face, indp)]; %#ok + end + end + else + indf = find(sum(ismember(faces, ind(i)), 2)); + + thetaf = zeros(length(indf), 1); + for j=1:length(indf) + ind2 = faces(indf(j), :); + face = nodes(ind2, :); + indp = find(ind2==ind(i)); + thetaf(j) = pi - polygon3dNormalAngle(face, indp); + end + end + + + % compute normal angle of polyhedron, by use of angle defect formula + theta(i) = 2*pi - sum(thetaf); + +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronSlice.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronSlice.m new file mode 100644 index 0000000..8f7f437 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/polyhedronSlice.m @@ -0,0 +1,55 @@ +function points = polyhedronSlice(nodes, faces, plane) +%POLYHEDRONSLICE Intersect a convex polyhedron with a plane. +% +% SLICE = polyhedronSlice(NODES, FACES, PLANE) +% NODES: a Nx3 array +% FACES: either a cell array or a Nf*3 or Nf*4 array +% PLANE: a plane representation [x0 y0 z0 dx1 dy1 dz1 dx2 dy2 dz2]. +% return the intersection polygon of the polyhedra with the plane, in the +% form of a set of ordered points. +% +% Works only for convex polyhedra. +% +% Example +% polyhedronSlice +% +% See also +% polyhedra, clipConvexPolyhedronHP +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-09-18, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% if faces is a numeric array, convert it to cell array +if isnumeric(faces) + faces2 = cell(size(faces, 1), 1); + for f=1:length(faces2) + faces2{f} = faces(f,:); + end + faces = faces2; +else + % ensure we have face with horizontal vectors... + for f=1:length(faces) + face = faces{f}; + faces{f} = face(:)'; + end +end + +% compute edges of the polyhedron +inds = zeros(0, 2); +for f=1:length(faces) + face = faces{f}'; + inds = [inds ; sort([face face([2:end 1])], 2)]; +end +inds = unique(inds, 'rows'); +edges = [nodes(inds(:,1), :) nodes(inds(:,2), :)]; + +% intersection of edges with plane +points = intersectEdgePlane(edges, plane); +points = points(sum(isfinite(points), 2)==3, :); + +if ~isempty(points) + points = angleSort3d(points); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/formatMeshOutput.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/formatMeshOutput.m new file mode 100644 index 0000000..a221055 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/formatMeshOutput.m @@ -0,0 +1,62 @@ +function res = formatMeshOutput(nbArgs, vertices, edges, faces) +%FORMATMESHOUTPUT Format mesh output depending on nargout +% +% OUTPUT = formatMeshOutput(NARGOUT, VERTICES, EDGES, FACES) +% Utilitary function to convert mesh data . +% If NARGOUT is 0 or 1, return a matlab structure with fields vertices, +% edges and faces. +% If NARGOUT is 2, return a cell array with data VERTICES and FACES. +% If NARGOUT is 3, return a cell array with data VERTICES, EDGES and +% FACES. +% +% OUTPUT = formatMeshOutput(NARGOUT, VERTICES, FACES) +% Same as before, but do not intialize EDGES in output. NARGOUT can not +% be equal to 3. +% +% Example +% % Typical calling sequence (for a very basic mesh of only one face) +% v = [0 0; 0 1;1 0;1 1]; +% e = [1 2;1 3;2 4;3 4]; +% f = [1 2 3 4]; +% +% varargout = formatMeshOutput(nargout, v, e, f); +% +% See also +% meshes3d, parseMeshData +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-12-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +if nargin < 4 + faces = edges; + edges = []; +end + +switch nbArgs + case {0, 1} + % output is a data structure with fields vertices, edges and faces + mesh.vertices = vertices; + mesh.edges = edges; + mesh.faces = faces; + res = {mesh}; + + case 2 + % keep only vertices and faces + res = cell(nbArgs, 1); + res{1} = vertices; + res{2} = faces; + + case 3 + % return vertices, edges and faces as 3 separate outputs + res = cell(nbArgs, 1); + res{1} = vertices; + res{2} = edges; + res{3} = faces; + + otherwise + error('Can not manage more than 3 outputs'); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/parseMeshData.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/parseMeshData.m new file mode 100644 index 0000000..f05993b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/private/parseMeshData.m @@ -0,0 +1,47 @@ +function varargout = parseMeshData(varargin) +%PARSEMESHDATA Conversion of data representation for meshes +% +% MESH = parseMeshData(VERTICES, EDGES, FACES) +% MESH = parseMeshData(VERTICES, FACES) +% [VERTICES EDGES FACES] = parseMeshData(MESH) +% [VERTICES FACES] = parseMeshData(MESH) +% +% +% See also +% meshes3d, formatMeshOutput +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-12-06, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +% initialize edges +edges = []; + +% Process input arguments +if nargin == 1 + % input is a data structure + mesh = varargin{1}; + vertices = mesh.vertices; + faces = mesh.faces; + if isfield(mesh, 'edges') + edges = mesh.edges; + end + +elseif nargin == 2 + % input are vertices and faces + vertices = varargin{1}; + faces = varargin{2}; + +elseif nargin == 3 + % input are vertices, edges and faces + vertices = varargin{1}; + edges = varargin{2}; + faces = varargin{3}; + +else + error('Wrong number of arguments'); +end + +varargout = formatMeshOutput(nargout, vertices, edges, faces); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/readMesh_off.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/readMesh_off.m new file mode 100644 index 0000000..22fa9b5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/readMesh_off.m @@ -0,0 +1,59 @@ +function [vertices faces] = readMesh_off(fileName) +%READMESH_OFF Read mesh data stord in OFF format +% +% [VERTICES FACES] = readMesh_off(FILNAME) +% +% Example +% readMesh_off +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-20, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% open file +f = fopen(fileName, 'r'); +if f == -1 + error('matGeom:readMesh_off:FileNotFound', ... + ['Could not find file: ' fileName]); +end + +% check format +line = fgets(f); % -1 if eof +if ~strcmp(line(1:3), 'OFF') + error('matGeom:readMesh_off:FileFormatError', ... + 'Not a valid OFF file'); +end + +% number of faces and vertices +line = fgets(f); +vals = sscanf(line, '%d %d'); +nv = vals(1); +nf = vals(2); + + +% read vertex data +[vertices count] = fscanf(f, '%f ', [3 nv]); +if count ~= nv*3 + error('matGeom:readMesh_off:FileFormatError', ... + ['Could not read all the ' num2str(nv) ' vertices']); +end +vertices = vertices'; + +% read face data (face start by index) +[faces count] = fscanf(f, '%d %d %d %d\n', [4 nf]); +if count ~= nf * 4 + error('matGeom:readMesh_off:FileFormatError', ... + ['Could not read all the ' num2str(nf) ' faces']); +end + +% clean up: remove index, and use 1-indexing +faces = faces(2:4, :)' + 1; + +% close the file +fclose(f); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/steinerPolytope.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/steinerPolytope.m new file mode 100644 index 0000000..20591c9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/steinerPolytope.m @@ -0,0 +1,38 @@ +function [nodes faces] = steinerPolytope(points) +%STEINERPOLYTOPE Create a steiner polytope from a set of vectors +% +% [NODES FACES] = steinerPolygon(POINTS) +% create the steiner polytope defined by points POINTS. +% +% Example +% [n f] = steinerPolytope([1 0 0;0 1 0;0 0 1;1 1 1]); +% drawMesh(n, f); +% +% See also +% meshes3d, drawMesh +% +% ------ +% Author: David Legland +% e-mail: david.legland@jouy.inra.fr +% Created: 2006-04-28 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +% create candidate points +nodes = zeros(1, size(points, 2)); +for i=1:length(points) + nodes = [nodes; nodes+repmat(points(i,:), [size(nodes, 1) 1])]; +end + +% compute convex hull +K = convhulln(nodes); + +% keep only relevant points, and update faces indices +ind = unique(K); +for i=1:length(ind) + K(K==ind(i))=i; +end + +% return results +nodes = nodes(ind, :); +faces = K; + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/triangulateFaces.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/triangulateFaces.m new file mode 100644 index 0000000..19b955e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/triangulateFaces.m @@ -0,0 +1,77 @@ +function tri = triangulateFaces(faces) +%TRIANGULATEFACES Convert face array to an array of triangular faces +% +% TRI = triangulateFaces(FACES) +% Returns a 3-columns array of indices, based on the data stored in the +% argument FACES: +% - if FACES is a N-by-3 array, returns the same array +% - if FACES is a N-by-4 array, returns an array with 2*N rows and 3 +% columns, splitting each square into 2 triangles (uses first and +% third vertex of each square as diagonal). +% - if FACES is a cell array, split each face into a set of triangles, +% and returns the union of all triangles. Faces are supposed to be +% convex. +% +% Example +% % create a basic shape +% [n e f] = createCubeOctahedron; +% % draw with plain faces +% figure; +% drawMesh(n, f); +% % draw as a triangulation +% tri = triangulateFaces(f); +% figure; +% patch('vertices', n, 'faces', tri, 'facecolor', 'r'); +% +% See also +% meshes3d, drawMesh +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2008-09-08, using Matlab 7.4.0.287 (R2007a) +% Copyright 2008 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% avoid to triagulate a triangulation +if isnumeric(faces) && size(faces, 2)==3 + tri = faces; + return; +end + +% for square faces, divide each square into 2 triangles +if isnumeric(faces) && size(faces, 2)==4 + nf = size(faces, 1); + tri = zeros(nf*2, 3); + tri(1:2:end, :) = faces(:, [1 2 3]); + tri(2:2:end, :) = faces(:, [1 3 4]); + return; +end + +% number of faces +nf = length(faces); + +% compute total number of triangles +ni = zeros(nf, 1); +for i=1:nf + % as many triangles as the number of vertices minus 1 + ni(i) = length(faces{i})-2; +end +nt = sum(ni); + +% allocate memory for triangle array +tri = zeros(nt, 3); + +% convert faces to triangles +t = 1; +for i=1:nf + face = faces{i}; + nv = length(face); + v0 = face(1); + for j=3:nv + tri(t, :) = [v0 face(j-1) face(j)]; + t = t+1; + end +end + + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/trimeshSurfaceArea.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/trimeshSurfaceArea.m new file mode 100644 index 0000000..a2a50ae --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/trimeshSurfaceArea.m @@ -0,0 +1,40 @@ +function area = trimeshSurfaceArea(v, e, f) +%TRIMESHSURFACEAREA Surface area of a triangular mesh +% +% S = trimeshSurfaceArea(V, F) +% S = trimeshSurfaceArea(V, E, F) +% Computes the surface area of the mesh specified by vertex array V and +% face array F. Vertex array is a NV-by-3 array of coordinates. +% Face array is a NF-by-3, containing vertex indices of each face. +% +% Example +% % Compute area of an octahedron (equal to 2*sqrt(3)*a*a, with +% % a = sqrt(2) in this case) +% [v f] = createOctahedron; +% trimeshSurfaceArea(v, f) +% ans = +% 6.9282 +% +% See also +% meshes3d, meshSurfaceArea +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-08-26, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% check input number +if nargin == 2 + f = e; +end + +% compute two direction vectors, using first face vertex as origin +v1 = v(f(:, 2), :) - v(f(:, 1), :); +v2 = v(f(:, 3), :) - v(f(:, 1), :); + +% area of each triangle is half the cross product norm +vn = vectorNorm(vectorCross3d(v1, v2)); + +% sum up and normalize +area = sum(vn) / 2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/vertexNormal.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/vertexNormal.m new file mode 100644 index 0000000..f5a38bc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/meshes3d/vertexNormal.m @@ -0,0 +1,48 @@ +function normals = vertexNormal(vertices, faces) +%VERTEXNORMAL Compute normals to a mesh vertices +% +% output = vertexNormal(input) +% +% Example +% vertexNormal +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-19, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + + +nv = size(vertices, 1); +nf = size(faces, 1); + +% unit normals to the faces +faceNormals = normalizeVector3d(faceNormal(vertices, faces)); + +% compute normal of each vertex: sum of normals to each face +normals = zeros(nv, 3); +if isnumeric(faces) + for i = 1:nf + face = faces(i, :); + for j = 1:length(face) + v = face(j); + normals(v, :) = normals(v,:) + faceNormals(i,:); + end + end +else + for i = 1:nf + face = faces{i}; + for j = 1:length(face) + v = face(j); + normals(v, :) = normals(v,:) + faceNormals(i,:); + end + end +end + +% normalize vertex normals to unit vectors +normals = normalizeVector3d(normals); + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/Contents.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/Contents.m new file mode 100644 index 0000000..4ac6773 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/Contents.m @@ -0,0 +1,153 @@ +% MATGEOM-POLYGONS +% +% The 'polygons' module contains functions operating on shapes composed +% of a vertex list, like polygons or polylines. +% +% We call 'polyline' the curve defined by a series of vertices. +% A polyline can be either closed or open, depending on whether the last +% vertex is connected to the first one or not. This can be given as an +% option is some functions in the module. +% A 'polygon' is the planar domain delimited by a closed polyline. We +% sometimes want to consider 'complex polygons', whose boundary is +% composed of several disjoint domains. The domain defined by a single +% closed polyline is called 'simple polygon'. +% We call 'curve' a polyline with many vertices, such that the polyline +% can be considered as a discrete approximation of a "real" curve. +% +% A simple polygon or polyline is represented by a N-by-2 array, each row +% of the array representing the coordinates of a vertex. +% Simple polygons are assumed to be closed, so there is no need to repeat +% the first vertex at the end. +% As both polygons and polylines can be represented by a list of vertex +% coordinates, some functions also consider the vertex list itself. Such +% functions are prefixed by 'pointSet'. Also, many functions prefixed by +% 'polygon' or 'polyline' works also on the other type of shape. +% +% For multiple-connected polygons, the different connected boundaries are +% separated by a row [NaN NaN]. +% +% For some functions, the orientation of the polygon can be relevant: CCW +% stands for 'Conter-Clockwise' (positive orientation), CW stands for +% 'Clockwise'. +% +% Polylines are parametrized in the following way: +% * the i-th vertex is located at position i-1 +% * points of the i-th edge have positions ranging linearly from i-1 to i +% The parametrization domain for an open polyline is from 0 to Nv-1, and +% from 0 to Nv for a closed polyline (positions 0 and Nv correspond to +% the same point). +% +% Example: +% % Simple polygon: +% P1 = [1 1;2 1;2 2;1 2]; +% drawPolygon(P1); +% axis([0 5 0 5]); +% % Multiple polygon: +% P2 = [10 10;40 10;40 40;10 40;NaN NaN;20 20;20 30;30 30;30 20]; +% figure;drawPolygon(P2); axis([0 50 0 50]); +% +% +% Point Sets +% pointSetsAverage - Compute the average of several point sets +% minimumCaliperDiameter - Minimum caliper diameter of a set of points +% findPoint - Find index of a point in an set from its coordinates +% convexHull - Convex hull of a set of points +% +% Polylines +% polylinePoint - Extract a point from a polyline +% polylineLength - Return length of a polyline given as a list of points +% polylineCentroid - Compute centroid of a curve defined by a series of points +% polylineSubcurve - Extract a portion of a polyline +% resamplePolyline - Distribute N points equally spaced on a polyline +% reversePolyline - Reverse a polyline, by iterating vertices from the end +% isPointOnPolyline - Test if a point belongs to a polyline +% projPointOnPolyline - Compute position of a point projected on a polyline +% distancePointPolyline - Compute shortest distance between a point and a polyline +% distancePolylines - Compute the shortest distance between 2 polylines +% intersectPolylines - Find the common points between 2 polylines +% polylineSelfIntersections - Find self-intersections points of a polyline +% +% Polygons +% polygonPoint - Extract a point from a polygon +% polygonSubcurve - Extract a portion of a polygon +% reversePolygon - Reverse a polygon, by iterating vertices from the end +% resamplePolygon - Distribute N points equally spaced on a polygon +% projPointOnPolygon - Compute position of a point projected on a polygon +% splitPolygons - Convert a NaN separated polygon list to a cell array of polygons +% clipPolygon - Clip a polygon with a rectangular box +% clipPolygonHP - Clip a polygon with a Half-plane defined by a directed line +% intersectLinePolygon - Intersection points between a line and a polygon +% intersectRayPolygon - Intersection points between a ray and a polygon +% polygonSelfIntersections - Find-self intersection points of a polygon +% polygonLoops - Divide a possibly self-intersecting polygon into a set of simple loops +% expandPolygon - Expand a polygon by a given (signed) distance +% densifyPolygon - Add several points on each edge of the polygon +% triangulatePolygon - Compute a triangulation of the polygon +% medialAxisConvex - Compute medial axis of a convex polygon +% +% Measures on Polygons +% isPointInPolygon - Test if a point is located inside a polygon +% polygonContains - Test if a point is contained in a multiply connected polygon +% polygonCentroid - Compute the centroid (center of mass) of a polygon +% polygonArea - Compute the signed area of a polygon +% polygonLength - Perimeter of a polygon +% polygonNormalAngle - Compute the normal angle at a vertex of the polygon +% polygonBounds - Compute the bounding box of a polygon +% distancePointPolygon - Compute shortest distance between a point and a polygon +% distancePolygons - Compute the shortest distance between 2 polygons +% +% Curves (polylines with lot of vertices) +% parametrize - Parametrization of a polyline, based on edges lengths +% curvature - Estimate curvature of a polyline defined by points +% cart2geod - Convert cartesian coordinates to geodesic coord. +% geod2cart - Convert geodesic coordinates to cartesian coord. +% curveMoment - Compute inertia moment of a 2D curve +% curveCMoment - Compute centered inertia moment of a 2D curve +% curveCSMoment - Compute centered scaled moment of a 2D curve +% +% Functions from stochastic geometry +% steinerPoint - Compute steiner point (weighted centroid) of a polygon +% steinerPolygon - Create a Steiner polygon from a set of vectors +% supportFunction - Compute support function of a polygon +% convexification - Compute the convexification of a polygon +% +% Input, Output and conversions +% readPolygon - Read a polygon stored in a file +% polygonToRow - Convert polygon coordinates to a row vector +% rowToPolygon - Create a polygon from a row vector +% rectAsPolygon - Convert a (centered) rectangle into a series of points +% +% Drawing functions +% drawPolyline - Draw a polyline specified by a list of points +% drawPolygon - Draw a polygon specified by a list of points +% fillPolygon - Fill a polygon specified by a list of points +% drawVertices - Draw the vertices of a polygon or polyline +% +% +% Credits: +% * function intersectPolylines uses the 'interX' contribution from "NS" +% (file exchange 22441, called 'curve-intersections') +% +% ----- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 07/11/2005. +% Homepage: http://matgeom.sourceforge.net/ +% http://www.pfl-cepia.inra.fr/index.php?page=geom2d +% Copyright INRA - Cepia Software Platform. + +help('Contents'); + +%% Requires further development + + +%% Deprecated functions + +% polygonExpand - 'expand' a polygon with a given distance +% subCurve - extract a portion of a curve +% curveLength - return length of a curve (a list of points) +% curveCentroid - compute centroid of a curve defined by a series of points +% drawCurve - draw a curve specified by a list of points + + +%% Others... diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/cart2geod.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/cart2geod.m new file mode 100644 index 0000000..705d112 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/cart2geod.m @@ -0,0 +1,44 @@ +function point = cart2geod(src, curve) +%CART2GEOD Convert cartesian coordinates to geodesic coord. +% +% PT2 = cart2geod(PT1, CURVE) +% PT1 is the point to transform, in Cartesian coordinates (same system +% used for the curve). +% CURVE is a [N*2] array which represents positions of the curve. +% +% The function first compute the projection of PT1 on the curve. Then, +% the first geodesic coordinate is the length of the curve to the +% projected point, and the second geodesic coordinate is the +% distance between PT1 and it projection. +% +% +% TODO : add processing of points not projected on the curve. +% -> use the closest end +% +% See also +% polylines2d, geod2cart, curveLength +% +% --------- +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% created the 08/04/2004. +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 15/02/2007 replace minDistance by minDistancePoints + + +% parametrization approximation +t = parametrize(curve); + +% compute distance between each src point and the curve +[dist ind] = minDistancePoints(src, curve); + +% convert to 'geodesic' coordinate +point = [t(ind) dist]; + +% Old version: +% for i=1:size(pt1, 1) +% [dist, ind] = minDistance(src(i,:), curve); +% point(i,:) = [t(ind) dist]; +% end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/changelog.txt b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/changelog.txt new file mode 100644 index 0000000..044a58e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/changelog.txt @@ -0,0 +1,27 @@ +change log for geom2d + +geom2d, release 2011.06.30 +========================== + +Changes +- re-organized the library in three sub-directories: geom2d, polygons2d, and + polynomialCurves2d +- cleanup of code and doc + +New functions +- added function drawOrientedBox +- added function pointSetBounds, that computes bounding box of a set of points +- added function pointSetsAverage +- added function minimumCaliperDiameter +- added function isPointInTriangle +- added function findPoint + +Changes +- function intersectLinePolygon now returns unique intersections +- enhanced intersectLinePolygon +- enhanced polygonSelfIntersections + +Bug fixes +- general code and doc cleanup +- fixed bugs in polygonLength and parametrize + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygon.m new file mode 100644 index 0000000..90e75b1 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygon.m @@ -0,0 +1,68 @@ +function poly2 = clipPolygon(polygon, w) +%CLIPPOLYGON Clip a polygon with a rectangular box +% +% POLY2 = clipPolygon(POLY, BOX); +% POLY is [Nx2] array of points +% BOX has the form: [XMIN XMAX YMIN YMAX]. +% Returns the polygon created by the itnersection of the polygon POLY and +% the bounding box BOX. +% +% Note: Works only for convex polygons at the moment. +% +% See also: +% polygons2d, boxes2d, clipPolygonHP +% +% --------- +% author : David Legland +% created the 14/05/2005. +% Copyright 2010 INRA - Cepia Software Platform. + +% HISTORY +% 2007/09/14 fix doc + +% check case of polygons stored in cell array +if iscell(polygon) + poly2 = cell(1, length(polygon)); + for i=1:length(polygon) + poly2{i} = clipPolygon(polygon{i}, w); + end + return; +end + +% check case of empty polygon +N = size(polygon, 1); +if N==0 + poly2 = zeros(0, 2); + return +end + +% create edges array of polygon +edges = [polygon polygon([2:N 1], :)]; + +% clip edges +edges = clipEdge(edges, w); + +% select non empty edges, and get their vertices +ind = sum(abs(edges), 2)>1e-14; +pts = unique([edges(ind, 1:2); edges(ind, 3:4)], 'rows'); + +% add vertices of window corner +corners = [w(1) w(3); w(1) w(4);w(2) w(3);w(2) w(4)]; +ind = inpolygon(corners(:,1), corners(:,2), polygon(:,1), polygon(:,2)); +pts = [pts; corners(ind, :)]; + +% polygon totally outside the window +if size(pts, 1)==0 + poly2 = pts; + return; +end + +% compute centroid of visible polygon +pc = centroid(pts); + +% sort vertices around polygon +angle = edgeAngle([repmat(pc, [size(pts, 1) 1]) pts]); +[dummy I] = sort(angle); %#ok + +% create resulting polygon +poly2 = pts(I, :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygonHP.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygonHP.m new file mode 100644 index 0000000..f5a156c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/clipPolygonHP.m @@ -0,0 +1,88 @@ +function poly2 = clipPolygonHP(poly, line) +%CLIPPOLYGONHP Clip a polygon with a Half-plane defined by a directed line +% +% POLY2 = clipPolygonHP(POLY, LINE) +% POLY is a [Nx2] array of points, and LINE is given as [x0 y0 dx dy]. +% The result POLY2 is also an array of points, sometimes smaller than +% poly, and that can be [0x2] (empty polygon). +% +% See also: +% polygons2d, clipPolygon +% +% --------- +% author : David Legland +% created the 31/07/2005. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 15/08/2005 add test to avoid empty polygons +% 13/06/2007 deprecate +% 10/10/2008 'reprecate' + + +% avoid to process empty polygons +if size(poly, 1)<3 + poly2 = zeros([0 2]); + return; +end + +% ensure the last point is the same as the first one +if sum(poly(end, :)==poly(1,:))~=2 + poly = [poly; poly(1,:)]; +end + +N = size(poly, 1); +edges = [poly([N 1:N-1], :) poly]; + +b = isLeftOriented(poly, line); + +% case of totally clipped polygon +if sum(b)==0 + poly2 = zeros(0, 2); + return; +end + + +poly2 = zeros(0, 2); + +i=1; +while i<=N + + if isLeftOriented(poly(i,:), line) + % keep all points located on the right side of line + poly2 = [poly2; poly(i,:)]; %#ok + else + % compute of preceeding edge with line + if i>1 + poly2 = [poly2; intersectLineEdge(line, edges(i, :))]; %#ok + end + + % go to the next point on the left side + i=i+1; + while i<=N + + % find the next point on the right side + if isLeftOriented(poly(i,:), line) + % add intersection of previous edge + poly2 = [poly2; intersectLineEdge(line, edges(i, :))]; %#ok + + % add current point + poly2 = [poly2; poly(i,:)]; %#ok + + % exit the second loop + break; + end + + i=i+1; + end + end + + i=i+1; +end + +% remove last point if it is the same as the first one +if sum(poly2(end, :)==poly(1,:))==2 + poly2 = poly2(1:end-1, :); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexHull.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexHull.m new file mode 100644 index 0000000..02dd6ad --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexHull.m @@ -0,0 +1,39 @@ +function [hull inds] = convexHull(points) +%CONVEXHULL Convex hull of a set of points +% +% POLY = convexHull(POINTS) +% Computes the convex hull of the set of points POINTS. This function is +% mainly a wrapper to the convhull function, that format the result to a +% polygon. +% +% [POLY INDS] = convexHull(POINTS) +% Also returns the indices of convex hull vertices within the original +% array of points. +% +% Example +% % Draw the convex hull of a set of random points +% pts = rand(30,2); +% drawPoint(pts, '.'); +% hull = convexHull(pts); +% hold on; +% drawPolygon(hull); +% +% See also +% polygons2d, convhull +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% checkup on array size +if size(points, 1) < 3 + hull = points; + inds = 1:size(points, 1); + return; +end + +% compute convex hull by calling the 'convhull' function +inds = convhull(points(:,1), points(:,2)); +hull = points(inds, :); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexification.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexification.m new file mode 100644 index 0000000..c675ed6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/convexification.m @@ -0,0 +1,79 @@ +function co = convexification(varargin) +%CONVEXIFICATION Compute the convexification of a polygon +% +% CO = convexification(H) +% Creates convexification from support function. Support function is +% supposed to be uniformly distributed over [0 2pi]. +% +% CO = convexification(POLYGON) +% Computes support function of the polygon, then the corresponding +% convexification. +% +% CO = convexification(POLYGON, N) +% Uses N points for convexification computation. Note that the number of +% points of CO can be lower than N. +% +% CAUTION: The result will be valid only for convex polygons. +% +% See also +% polygons2d, supportFunction +% +% --------- +% author: David Legland +% created the 12/01/2005. +% Copyright 2010 INRA - Cepia Software Platform. +% + +% HISTORY +% 13/06/2007: clean up code + +if ~isempty(varargin)>0 + var = varargin{1}; + if size(var, 2)==1 + h = var; + else + poly = var; + N = 128; + if length(varargin)>1 + N = varargin{2}; + end + h = supportFunction(poly, N); + end +else + error('not enough input arguments'); +end + +N = length(h); +u = (0:2*pi/N:2*pi*(1-1/N))'; +v = [cos(u) sin(u)].*[h h]; + +i1 = 1:N; +i2 = [2:N 1]; +i3 = [3:N 1 2]; + +circ = zeros(N, 4); +for i=1:N + circ(i, 1:4) = createDirectedCircle(v(i1(i),:), v(i2(i),:), v(i3(i), :)); +end + +% remove non direct-oriented circles +circ = circ(circ(:,4)==0, :); + +% keep only circles seen several times +dp = diff(circ(:,1:2)); +dp = sum(dp.*dp, 2); +ind1 = [1; find(dp<1e-10)+1]; +circ = circ(ind1, :); + +% keep only one instance of each circle +dp = diff(circ(:,1:2)); +dp = sum(dp.*dp, 2); +ind = [1; find(dp>1e-10)+1]; +co = 2*circ(ind, 1:2); + +% eventually remove the last point if it is the same as the first one +if distancePoints(co(1,:), co(end, :))<1e-10 && size(co, 1)>1 + co = co(1:end-1,:); +end + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curvature.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curvature.m new file mode 100644 index 0000000..a5adc27 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curvature.m @@ -0,0 +1,147 @@ +function kappa = curvature(varargin) +%CURVATURE Estimate curvature of a polyline defined by points +% +% KAPPA = curvature(T, PX, PY, METHOD, DEGREE) +% First compute an approximation of the curve given by PX and PY, with +% the parametrization T. METHOD used for approximation can be only: +% 'polynom', with specified degree +% Further methods will be provided in a future version. +% T, PX, and PY are N*1 array of the same length. +% Then compute the curvature of approximated curve for each point. +% +% For example: +% KAPPA = curvature(t, px, py, 'polynom', 6) +% +% KAPPA = curvature(T, POINTS, METHOD, DEGREE) +% specify curve as a suite of points. POINTS is size [N*2]. +% +% KAPPA = curvature(PX, PY, METHOD, DEGREE) +% KAPPA = curvature(POINTS, METHOD, DEGREE) +% compute implicite normalization of the curve, based on euclidian +% distance between 2 consecutive points, and normalized between 0 and 1. +% +% +% See Also: +% polygons2d, parametrize +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/04/2003. +% + + +% default values +degree = 5; +t=0; % parametrization of curve +tc=0; % indices of points wished for curvature + + +% ================================================================= + +% Extract method and degree ------------------------------ + +nargin = length(varargin); +varN = varargin{nargin}; +varN2 = varargin{nargin-1}; + +if ischar(varN2) + % method and degree are specified + method = varN2; + degree = varN; + varargin = varargin(1:nargin-2); +elseif ischar(varN) + % only method is specified, use degree 6 as default + method = varN; + varargin = varargin{1:nargin-1}; +else + % method and degree are implicit : use 'polynom' and 6 + method = 'polynom'; +end + +% extract input parametrization and curve. ----------------------- +nargin = length(varargin); +if nargin==1 + % parameters are just the points -> compute caracterization. + var = varargin{1}; + px = var(:,1); + py = var(:,2); +elseif nargin==2 + var = varargin{2}; + if size(var, 2)==2 + % parameters are t and POINTS + px = var(:,1); + py = var(:,2); + t = varargin{1}; + else + % parameters are px and py + px = varargin{1}; + py = var; + end +elseif nargin==3 + var = varargin{2}; + if size(var, 2)==2 + % parameters are t, POINTS, and tc + px = var(:,1); + py = var(:,2); + t = varargin{1}; + else + % parameters are t, px and py + t = varargin{1}; + px = var; + py = varargin{3}; + end +elseif nargin==4 + % parameters are t, px, py and tc + t = varargin{1}; + px = varargin{2}; + py = varargin{3}; + tc = varargin{4}; +end + +% compute implicit parameters -------------------------- + +% if t and/or tc are not computed, use implicit definition +if t==0 + t = parametrize(px, py); + t = t/t(length(t)); % normalize between 0 and 1 +end + +% if tc not defined, compute curvature for all points +if tc==0 + tc = t; +else + % else convert from indices to parametrization values + tc = t(tc); +end + + +% ================================================================= +% compute curvature for each point of the curve + +if strcmp(method, 'polynom') + % compute coefficients of interpolation functions + x0 = polyfit(t, px, degree); + y0 = polyfit(t, py, degree); + + % compute coefficients of first and second derivatives. In the case of a + % polynom, it is possible to compute coefficient of derivative by + % multiplying with a matrix. + derive = diag(degree:-1:0); + xp = circshift(x0*derive, [0 1]); + yp = circshift(y0*derive, [0 1]); + xs = circshift(xp*derive, [0 1]); + ys = circshift(yp*derive, [0 1]); + + % compute values of first and second derivatives for needed points + xprime = polyval(xp, tc); + yprime = polyval(yp, tc); + xsec = polyval(xs, tc); + ysec = polyval(ys, tc); + + % compute value of curvature + kappa = (xprime.*ysec - xsec.*yprime)./ ... + power(xprime.*xprime + yprime.*yprime, 3/2); +else + error('unknown method'); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCMoment.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCMoment.m new file mode 100644 index 0000000..1cf82d2 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCMoment.m @@ -0,0 +1,42 @@ +function m = curveCMoment(curve, p, q) +%CURVECMOMENT Compute centered inertia moment of a 2D curve +% M = curveCMoment(CURVE, P, Q) +% +% Example +% curveCMoment +% +% See also +% polygons2d, curveMoment, curveCSMoment +% +% Reference +% Based on ideas and references in: +% "Affine curve moment invariants for shape recognition" +% Dongmin Zhao and Jie Chen +% Pattern Recognition, 1997, vol. 30, pp. 865-901 +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% compute curve centroid +centroid = polylineCentroid(curve); + +% coordinate of vertices +px = curve(:,1)-centroid(1); +py = curve(:,2)-centroid(2); + +% compute centroids of line segments +cx = (px(1:end-1)+px(2:end))/2; +cy = (py(1:end-1)+py(2:end))/2; + +% compute length of each line segment +dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); + +% compute moment +m = zeros(size(p)); +for i=1:length(p(:)) + m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCSMoment.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCSMoment.m new file mode 100644 index 0000000..bf436ac --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCSMoment.m @@ -0,0 +1,45 @@ +function m = curveCSMoment(curve, p, q) +%CURVECSMOMENT Compute centered scaled moment of a 2D curve +% M = curveCSMoment(CURVE, P, Q) +% +% Example +% curveCSMoment +% +% See also +% polygons2d, curveMoment, curveCMoment +% +% Reference +% Based on ideas and references in: +% "Affine curve moment invariants for shape recognition" +% Dongmin Zhao and Jie Chen +% Pattern Recognition, 1997, vol. 30, pp. 865-901 +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% compute curve centroid +centroid = polylineCentroid(curve); + +% compute perimeter +L = polylineLength(curve); + +% coordinate of vertices +px = curve(:,1)-centroid(1); +py = curve(:,2)-centroid(2); + +% compute centroids of line segments +cx = (px(1:end-1)+px(2:end))/2; +cy = (py(1:end-1)+py(2:end))/2; + +% compute length of each line segment +dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); + +% compute moment +m = zeros(size(p)); +for i=1:length(p(:)) + d = (p(i)+q(i))/2+1; + m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)) / L^d; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCentroid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCentroid.m new file mode 100644 index 0000000..1c629dc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveCentroid.m @@ -0,0 +1,65 @@ +function center = curveCentroid(varargin) +%CURVECENTROID compute centroid of a curve defined by a series of points +% +% PT = curveCentroid(POINTS); +% Computes center of mass of a curve defined by POINTS. POINTS is a [NxD] +% array of double, N D-dimensional points. +% +% PT = curveCentroid(PTX, PTY); +% PT = curveCentroid(PTX, PTY, PTZ); +% Specifies points as separate column vectors +% +% PT = curveCentroid(..., TYPE); +% Specifies if the last point is connected to the first one. TYPE can be +% either 'closed' or 'open'. +% +% +% See also : +% polygons2d, centroid, polygonCentroid, curveLength +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 22/05/2006. +% + +% HISTORY +% 23/07/2009 deprecate and replace by 'reverseLine'. + +% deprecation warning +warning('geom2d:deprecated', ... + '''curveCentroid'' is deprecated, use ''polylineCentroid'' instead'); + + +%% process input arguments + +% check whether the curve is closed +closed = false; +var = varargin{end}; +if ischar(var) + if strcmpi(var, 'closed') + closed = true; + end + varargin = varargin(1:end-1); +end + +% extract point coordinates +if length(varargin)==1 + points = varargin{1}; +elseif length(varargin)==2 + points = [varargin{1} varargin{2}]; +end + +% compute centers and lengths composing the curve +if closed + centers = (points + points([2:end 1],:))/2; + lengths = sqrt(sum(diff(points([1:end 1],:)).^2, 2)); +else + centers = (points(1:end-1,:) + points(2:end,:))/2; + lengths = sqrt(sum(diff(points).^2, 2)); +end + +% centroid of edge centers weighted by edge length +%weigths = repmat(lengths/sum(lengths), [1 size(points, 2)]); +center = sum(centers.*repmat(lengths, [1 size(points, 2)]), 1)/sum(lengths); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveLength.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveLength.m new file mode 100644 index 0000000..cbb97a0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveLength.m @@ -0,0 +1,63 @@ +function len = curveLength(varargin) +%CURVELENGTH return length of a curve (a list of points) +% +% Compute the length of a curve given as a list of following points. +% +% L = curveLength(X, Y); +% L = curveLength(POINTS); +% POINTS should be a [NxD] array, with N being the numbe of points and D +% the dimension of the points. +% +% PT = curveLength(..., TYPE); +% Specifies if the last point is connected to the first one. TYPE can be +% either 'closed' or 'open'. +% +% TODO : specify norm (euclidian, taxi, ...). +% +% Example: +% Compute the perimeter of a circle with radius 1 +% curveLength(circleAsPolygon([0 0 1], 500), 'closed') +% -> return 6.2831 +% +% See also: +% polygons2d, curveCentroid +% +% --------- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 14/06/2004 +% + +% HISTORY +% 22/05/2006 manage any dimension for points, closed and open curves, +% and update doc accordingly. +% 30/06/2009 deprecate and replace by 'polylineLength'. + +% deprecation warning +warning('geom2d:deprecated', ... + '''curveLength'' is deprecated, use ''polylineLength'' instead'); + +% check whether the curve is closed +closed = false; +var = varargin{end}; +if ischar(var) + if strcmpi(var, 'closed') + closed = true; + end + varargin = varargin(1:end-1); +end + +% extract point coordinates +if length(varargin)==1 + points = varargin{1}; +elseif length(varargin)==2 + points = [varargin{1} varargin{2}]; +end + +% compute lengths of each line segment +if closed + len = sum(sqrt(sum(diff(points([1:end 1],:)).^2, 2))); +else + len = sum(sqrt(sum(diff(points).^2, 2))); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveMoment.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveMoment.m new file mode 100644 index 0000000..d256dba --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/curveMoment.m @@ -0,0 +1,39 @@ +function m = curveMoment(curve, p, q) +%CURVEMOMENT Compute inertia moment of a 2D curve +% M = curveMoment(CURVE, P, Q) +% +% Example +% curveMoment +% +% See also +% polygons2d, curveCMoment, curveCSMoment +% +% Reference +% Based on ideas and references in: +% "Affine curve moment invariants for shape recognition" +% Dongmin Zhao and Jie Chen +% Pattern Recognition, 1997, vol. 30, pp. 865-901 +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-03-25, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% coordinate of vertices +px = curve(:,1); +py = curve(:,2); + +% compute centroids of line segments +cx = (px(1:end-1)+px(2:end))/2; +cy = (py(1:end-1)+py(2:end))/2; + +% compute length of each line segment +dl = hypot(px(2:end)-px(1:end-1), py(2:end)-py(1:end-1)); + +% compute moment +m = zeros(size(p)); +for i=1:length(p(:)) + m(i) = sum(cx(:).^p(i) .* cy(:).^q(i) .* dl(:)); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/densifyPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/densifyPolygon.m new file mode 100644 index 0000000..67b7b12 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/densifyPolygon.m @@ -0,0 +1,50 @@ +function poly2 = densifyPolygon(poly, N) +%DENSIFYPOLYGON Add several points on each edge of the polygon +% +% POLY2 = densifyPolygon(POLY, N) +% POLY is a NV-by-2 array containing polygon coordinates. The function +% iterates on polygon edges, divides it into N subedges (by inserting N-1 +% new vertices on each edges), and return the resulting polygon. +% The new polygon POLY has therefore N*NV vertices. +% +% Example +% % Densifies a simple polygon +% poly = [0 0 ; 10 0;5 10;15 15;5 20;-5 10]; +% poly2 = densifyPolygon(poly, 10); +% figure; drawPolygon(poly); axis equal +% hold on; drawPoint(poly2); +% +% See also +% drawPolygon, edgeToPolyline +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-11-25, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% number of vertices, and of edges +Nv = size(poly, 1); + +% number of vertices in new polygon +N2 = N * Nv; +poly2 = zeros(N2, 2); + +% iterate on polygon edges +for i = 1:Nv + % extract current edge + v1 = poly(i, :); + v2 = poly(mod(i, Nv) + 1, :); + + % convert current edge to polyline + newVertices = edgeToPolyline([v1 v2], N); + + % indices of current polyline to resulting polygon + i1 = (i-1)*N + 1; + i2 = i * N; + + % fill up polygon + poly2(i1:i2, :) = newVertices(1:end-1, :); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolygon.m new file mode 100644 index 0000000..e31010d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolygon.m @@ -0,0 +1,29 @@ +function varargout = distancePointPolygon(point, poly) +%DISTANCEPOINTPOLYGON Compute shortest distance between a point and a polygon +% output = distancePointPolygon(POINT, POLYGON) +% +% Example +% distancePointPolygon +% +% See also +% polygons2d, points2d, distancePointPolyline +% distancePointEdge, projPointOnPolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% eventually copy first point at the end to ensure closed polygon +if sum(poly(end, :)==poly(1,:))~=2 + poly = [poly; poly(1,:)]; +end + +% call to distancePointPolyline +minDist = distancePointPolyline(point, poly); + +% process output arguments +if nargout<=1 + varargout{1} = minDist; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolyline.m new file mode 100644 index 0000000..a8c9a7d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePointPolyline.m @@ -0,0 +1,48 @@ +function varargout = distancePointPolyline(point, poly, varargin) +%DISTANCEPOINTPOLYLINE Compute shortest distance between a point and a polyline +% output = distancePointPolyline(POINT, POLYLINE) +% +% Example: +% pt1 = [30 20]; +% pt2 = [30 5]; +% poly = [10 10;50 10;50 50;10 50]; +% distancePointPolyline([pt1;pt2], poly) +% ans = +% 10 +% 5 +% +% See also +% polygons2d, points2d +% distancePointEdge, projPointOnPolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% HISTORY +% 2009-06-23 compute all distances in one call + +% number of points +Np = size(point, 1); + +% allocate memory for result +minDist = inf * ones(Np, 1); + +% process each point +for p = 1:Np + % construct the set of edges + edges = [poly(1:end-1, :) poly(2:end, :)]; + + % compute distance between current each point and all edges + dist = distancePointEdge(point(p, :), edges); + + % update distance if necessary + minDist(p) = min(dist); +end + +% process output arguments +if nargout<=1 + varargout{1} = minDist; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolygons.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolygons.m new file mode 100644 index 0000000..880e18c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolygons.m @@ -0,0 +1,22 @@ +function dist = distancePolygons(poly1, poly2) +%DISTANCEPOLYGONS Compute the shortest distance between 2 polygons +% DIST = distancePolygons(POLY1, POLY2) +% +% Example +% distancePolygons +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-17, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% compute distance of each vertex of a polygon to the other polygon +dist1 = min(distancePointPolygon(poly1, poly2)); +dist2 = min(distancePointPolygon(poly2, poly1)); + +% keep the minimum of the two distances +dist = min(dist1, dist2); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolylines.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolylines.m new file mode 100644 index 0000000..6c08b54 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/distancePolylines.m @@ -0,0 +1,23 @@ +function dist = distancePolylines(poly1, poly2) +%DISTANCEPOLYLINES Compute the shortest distance between 2 polylines +% +% DIST = distancePolylines(POLY1, POLY2) +% POLY1 and POLY2 should be two polylines represented by their list of +% vertices. +% +% +% See also +% polygons2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-17, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% compute distance of each vertex of a polyline to the other polyline +dist1 = min(distancePointPolyline(poly1, poly2)); +dist2 = min(distancePointPolyline(poly2, poly1)); + +% keep the minimum of the two distances +dist = min(dist1, dist2); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawCurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawCurve.m new file mode 100644 index 0000000..43185bc --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawCurve.m @@ -0,0 +1,107 @@ +function varargout = drawCurve(varargin) +%DRAWCURVE draw a curve specified by a list of points +% +% drawCurve(COORD); +% packs coordinates in a single [N*2] array. +% +% drawCurve(PX, PY); +% specifies coordinates in separate arrays. PX and PY must be column +% vectors with the same length. +% +% drawCurve(..., TYPE); +% where TYPE is either 'closed' or 'open', specifies if last point must +% be connected to the first one ('closed') or not ('open'). +% Default is 'open'. +% +% drawCurve(..., PARAM, VALUE); +% specify plot options as described for plot command. +% +% H = drawCurve(...) also return a handle to the list of line objects. +% +% Example: +% % Draw a curve representing an ellipse +% t = linspace(0, 2*pi, 100)'; +% px = 10*cos(t); py = 5*sin(t); +% drawCurve([px py], 'closed'); +% axis equal; +% +% % The same, with different drawing options +% drawCurve([px py], 'closed', 'lineWidth', 2, 'lineStyle', '--'); +% +% See Also: +% polygons2d, drawPolyline +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 03/01/2007 better processing of input, and update doc (drawing +% options and CLOSE option) +% 03/03/2010 add deprecation warning + +% deprecation warning +warning('geom2d:deprecated', ... + '''drawCurve'' is deprecated, use ''drawPolyline'' instead'); + +% default values +closed = false; + + +% If first argument is a cell array, draw each curve individually, +% and eventually returns handle of each plot. +var = varargin{1}; +if iscell(var) + h = []; + for i=1:length(var(:)) + h = [h ; drawCurve(var{i}, varargin{2:end})]; %#ok + end + if nargout>0 + varargout{1}=h; + end + return; +end + +% extract curve coordinate +if size(var, 2)==1 + % first argument contains x coord, second argument contains y coord + px = var; + if length(varargin)==1 + error('Wrong number of arguments in drawCurve'); + end + py = varargin{2}; + varargin = varargin(3:end); +else + % first argument contains both coordinate + px = var(:, 1); + py = var(:, 2); + varargin = varargin(2:end); +end + +% check if curve is closed or open +if ~isempty(varargin) + var = varargin{1}; + if strncmpi(var, 'close', 5) + closed = true; + varargin = varargin(2:end); + elseif strncmpi(var, 'open', 4) + closed = false; + varargin = varargin(2:end); + end +end + +% add first point at the end to close the curve +if closed + px = [px; px(1)]; + py = [py; py(1)]; +end + +% plot the curve, with eventually optional parameters +h = plot(px, py, varargin{:}); + +% format output arguments +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolygon.m new file mode 100644 index 0000000..7a0a1eb --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolygon.m @@ -0,0 +1,128 @@ +function varargout = drawPolygon(varargin) +%DRAWPOLYGON Draw a polygon specified by a list of points +% +% drawPolygon(POLY); +% Packs coordinates in a single N-by-2 array. +% +% drawPolygon(PX, PY); +% Specifies coordinates in separate arrays. +% +% drawPolygon(POLYS) +% Packs coordinate of several polygons in a cell array. Each element of +% the array is a Ni-by-2 double array. +% +% drawPolygon(..., NAME, VALUE); +% Specifies drawing options by using one or several parameter name-value +% pairs, see the doc of plot function for details. +% +% drawPolygon(AX, ...) +% Specifies the axis to draw the polygon on. +% +% H = drawPolygon(...); +% Also return a handle to the list of line objects. +% +% +% See also: +% polygons2d, drawCurve +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/05/2004. +% + +% HISTORY +% 2008/10/15 manage polygons with holes +% 2011-10-11 add management of axes handle + +% check input +if isempty(varargin) + error('need to specify a polygon'); +end + +% extract handle of axis to draw on +if ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +var = varargin{1}; + +%% Manage cell arrays of polygons + +% case of a set of polygons stored in a cell array +if iscell(var) + N = length(var); + h = zeros(N, 1); + for i = 1:N + state = ishold(gca); + hold on; + % check for empty polygons + if ~isempty(var{i}) + h(i) = drawPolygon(ax, var{i}, varargin{2:end}); + end + if ~state + hold off + end + end + + if nargout > 0 + varargout = {h}; + end + + return; +end + + +%% Parse coordinates and options + +% Extract coordinates of polygon vertices +if size(var, 2) > 1 + % first argument is a polygon array + px = var(:, 1); + py = var(:, 2); + varargin(1) = []; +else + % arguments 1 and 2 correspond to x and y coordinate respectively + if length(varargin) < 2 + error('Should specify either a N-by-2 array, or 2 N-by-1 vectors'); + end + + px = varargin{1}; + py = varargin{2}; + varargin(1:2) = []; +end + +% set default line format +if isempty(varargin) + varargin = {'b-'}; +end + +% check case of polygons with holes +if any(isnan(px(:))) + polygons = splitPolygons([px py]); + h = drawPolygon(ax, polygons); + + if nargout > 0 + varargout = {h}; + end + + return; +end + + +%% Draw the polygon + +% ensure last point is the same as the first one +px(size(px, 1)+1, :) = px(1,:); +py(size(py, 1)+1, :) = py(1,:); + +% draw the polygon outline +h = plot(ax, px, py, varargin{:}); + +% format output arg +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolyline.m new file mode 100644 index 0000000..be7d0f9 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawPolyline.m @@ -0,0 +1,110 @@ +function varargout = drawPolyline(varargin) +%DRAWPOLYLINE Draw a polyline specified by a list of points +% +% drawPolyline(COORD); +% packs coordinates in a single [N*2] array. +% +% drawPolyline(PX, PY); +% specifies coordinates in separate arrays. PX and PY must be column +% vectors with the same length. +% +% drawPolyline(..., TYPE); +% where TYPE is either 'closed' or 'open', specifies if last point must +% be connected to the first one ('closed') or not ('open'). +% Default is 'open'. +% +% drawPolyline(..., PARAM, VALUE); +% specify plot options as described for plot command. +% +% H = drawPolyline(...) also return a handle to the list of line objects. +% +% Example: +% % Draw a curve representing an ellipse +% t = linspace(0, 2*pi, 100)'; +% px = 10*cos(t); py = 5*sin(t); +% drawPolyline([px py], 'closed'); +% axis equal; +% +% % The same, with different drawing options +% drawPolyline([px py], 'closed', 'lineWidth', 2, 'lineStyle', '--'); +% +% See Also: +% polygons2d, drawPolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2004. +% + +% HISTORY +% 03/01/2007: better processing of input, and update doc (drawing +% options and CLOSE option) +% 30/04/2009 rename as drawPolyline. +% 2011-10-11 add management of axes handle + + +% extract handle of axis to draw on +if ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +% If first argument is a cell array, draw each curve individually, +% and eventually returns handle of each plot. +var = varargin{1}; +if iscell(var) + h = []; + for i = 1:length(var(:)) + h = [h ; drawPolyline(ax, var{i}, varargin{2:end})]; + end + if nargout > 0 + varargout = {h}; + end + return; +end + +% extract curve coordinate +if size(var, 2) == 1 + % first argument contains x coord, second argument contains y coord + px = var; + if length(varargin) == 1 + error('Wrong number of arguments in drawPolyline'); + end + py = varargin{2}; + varargin = varargin(3:end); +else + % first argument contains both coordinate + px = var(:, 1); + py = var(:, 2); + varargin = varargin(2:end); +end + +% check if curve is closed or open +closed = false; +if ~isempty(varargin) + var = varargin{1}; + if strncmpi(var, 'close', 5) + closed = true; + varargin = varargin(2:end); + elseif strncmpi(var, 'open', 4) + closed = false; + varargin = varargin(2:end); + end +end + +% if curve is closed, add first point at the end of the list +if closed + px = [px; px(1)]; + py = [py; py(1)]; +end + +% plot the curve, with eventually optional parameters +h = plot(ax, px, py, varargin{:}); + +% format output arguments +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawVertices.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawVertices.m new file mode 100644 index 0000000..f37f906 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/drawVertices.m @@ -0,0 +1,95 @@ +function varargout = drawVertices(varargin) +%DRAWVERTICES Draw the vertices of a polygon or polyline +% +% drawVertices(POLY) +% Draws the vertices of the given polygon, using pre-defined style. +% Default is to draw vertices as squares, with the first vertex filled. +% +% Example +% poly = circleToPolygon([20 30 40], 16); +% drawPolygon(poly); +% hold on; axis equal; +% drawVertices(poly); +% +% See also +% drawPoint, drawPolygon, drawPolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-11, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% extract handle of axis to draw on +if ishandle(varargin{1}) + ax = varargin{1}; + varargin(1) = []; +else + ax = gca; +end + +var = varargin{1}; + + +%% Manage cell arrays of polygons / polylines + +% case of a set of polygons stored in a cell array +if iscell(var) + N = length(var); + h = zeros(N, 1); + for i = 1:N + state = ishold(gca); + hold on; + % check for empty polygons + if ~isempty(var{i}) + h(i) = drawPolygon(ax, var{i}, varargin{2:end}); + end + if ~state + hold off + end + end + + if nargout > 0 + varargout = {h}; + end + + return; +end + + +%% Parse coordinates and options + +% Extract coordinates of vertices +if size(var, 2) > 1 + % first argument is a vertex array + px = var(:, 1); + py = var(:, 2); + varargin(1) = []; +else + % arguments 1 and 2 correspond to x and y coordinate respectively + if length(varargin) < 2 + error('Should specify either a N-by-2 array, or 2 N-by-1 vectors'); + end + + px = varargin{1}; + py = varargin{2}; + varargin(1:2) = []; +end + +if isempty(varargin) + varargin = {'ks', 'MarkerSize', 4}; +end + + +%% Draw the vertices + +% draw the vertices +h = plot(ax, px, py, varargin{:}); + +% draw the first vertex with a different style +plot(ax, px(1), py(1), 'ks', 'MarkerFaceColor', 'k', 'MarkerSize', 4); + +% format output arg +if nargout > 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/expandPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/expandPolygon.m new file mode 100644 index 0000000..4e43217 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/expandPolygon.m @@ -0,0 +1,65 @@ +function loops = expandPolygon(poly, dist) +%EXPANDPOLYGON Expand a polygon by a given (signed) distance +% +% POLY2 = expandPolygon(POLY, DIST); +% Associates to each edge of the polygon POLY the parallel line located +% at distance DIST from the current edge, and compute intersections with +% neighbor parallel lines. The resulting polygon is simplified to remove +% inner "loops", and can be disconnected. +% The result is a cell array, each cell containing a simple linear ring. +% +% This is a kind of dilation, but behaviour on corners is different. +% This function keeps angles of polygons, but there is no direct relation +% between length of 2 polygons. +% +% It is also possible to specify negative distance, and get all points +% inside the polygon. If the polygon is convex, the result equals +% morphological erosion of polygon by a ball with radius equal to the +% given distance. +% +% See also: +% polygons2d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 14/05/2005. +% + +% HISTORY : +% 31/07/2005 : change algo for negative distance : use clipping of +% polygon by half-planes + + + +% eventually copy first point at the end to ensure closed polygon +if sum(poly(end, :)==poly(1,:))~=2 + poly = [poly; poly(1,:)]; +end + +% number of vertices of the polygon +N = size(poly, 1)-1; + +% find lines parallel to polygon edges located at distance DIST +lines = zeros(N, 4); +for i=1:N + side = createLine(poly(i,:), poly(i+1,:)); + lines(i, 1:4) = parallelLine(side, dist); +end + +% compute intersection points of consecutive lines +lines = [lines;lines(1,:)]; +poly2 = zeros(N, 2); +for i=1:N + poly2(i,1:2) = intersectLines(lines(i,:), lines(i+1,:)); +end + +% split result polygon into set of loops (simple polygons) +loops = polygonLoops(poly2); + +% keep only loops whose distance to original polygon is correct +distLoop = zeros(length(loops), 1); +for i=1:length(loops) + distLoop(i) = distancePolygons(loops{i}, poly); +end +loops = loops(abs(distLoop-abs(dist))0 + varargout{1}=h; + end + return; +end + +% Extract coordinates of polygon vertices +if size(var, 2)>1 + % first argument is a polygon array + px = var(:, 1); + py = var(:, 2); + varargin(1) = []; +else + % arguments 1 and 2 correspond to x and y coordinate respectively + if length(varargin)<2 + error('should specify either a N*2 array, or 2 N*1 vectors'); + end + + px = varargin{1}; + py = varargin{2}; + varargin(1:2) = []; +end + + +% Find position of breaks, and copies first point of each loop at the +% end +inds = find(isnan(px(:))); +i1 = [inds ; length(px)+1]; +i0 = [1 ; inds+1]; +px(i1, :) = px(i0, :); +py(i1, :) = py(i0, :); + + +% set default line format +if isempty(varargin) + varargin = {'b'}; +end + + +% fill the polygon with desired style +h = fill(px, py, varargin{:}, 'lineStyle', 'none'); + +% output +if nargout>0 + varargout{1}=h; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/findPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/findPoint.m new file mode 100644 index 0000000..76fa0c5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/findPoint.m @@ -0,0 +1,40 @@ +function index = findPoint(coord, points) +%FINDPOINT Find index of a point in an set from its coordinates +% +% IND = findPoint(POINT, ARRAY) +% Returns the index of point whose coordinates match the 1-by-2 row array +% POINT in the N-by-2 array ARRAY. If the point is not found, returns 0. +% If several points are found, keep only the first one. +% +% If POINT is a M-by-2 array, the result is a M-by-1 array, containing +% the index in the array of each point given by COORD, or 0. +% +% +% ----- +% +% author: David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 17/07/2003. +% + +% HISTORY +% 10/02/2004 documentation +% 09/08/2004 rewrite faster, and add support for multiple points + +% number of points +np = size(coord, 1); + +% allocate memory for result +index = zeros(np, 1); + +for i = 1:np + % indices of matches + ind = find(points(:,1) == coord(i,1) & points(:,2) == coord(i,2)); + + % format current result + if isempty(ind) + index(i) = 0; + else + index(i) = ind(1); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/geod2cart.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/geod2cart.m new file mode 100644 index 0000000..c0c7f5f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/geod2cart.m @@ -0,0 +1,36 @@ +function point = geod2cart(src, curve, normal) +%GEOD2CART Convert geodesic coordinates to cartesian coord. +% +% PT2 = geod2cart(PT1, CURVE, NORMAL) +% CURVE and NORMAL are both [N*2] array with the same length, and +% represent positions of the curve, and normal to each point. +% PT1 is the point to transform, in geodesic coordinate (first coord is +% distance from the curve start, and second coord is distance between +% point and curve). +% +% The function return the coordinate of PT1 in the same coordinate system +% than for the curve. +% +% TODO : add processing of points not projected on the curve. +% -> use the closest end +% +% See also +% polylines2d, cart2geod, curveLength +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 08/04/2004. +% + +t = parametrize(curve); +N = size(src, 1); +ind = zeros(N, 1); +for i=1:N + indices = find(t>=src(i,1)); + ind(i) = indices(1); +end + +theta = lineAngle([zeros(N,1) zeros(N,1) normal(ind,:)]); +d = src(:,2); +point = [curve(ind,1)+d.*cos(theta), curve(ind,2)+d.*sin(theta)]; \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectLinePolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectLinePolygon.m new file mode 100644 index 0000000..bfb9293 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectLinePolygon.m @@ -0,0 +1,102 @@ +function [intersects edgeIndices] = intersectLinePolygon(line, poly, varargin) +%INTERSECTLINEPOLYGON Intersection points between a line and a polygon +% +% P = intersectLinePolygon(LINE, POLY) +% Returns the intersection points of the lines LINE with polygon POLY. +% LINE is a 1-by-4 row vector containing parametric representation of the +% line (in the format [x0 y0 dx dy], see the function 'createLine' for +% details). +% POLY is a NV-by-2 array containing coordinates of the polygon vertices +% P is a K-by-2 array containing the coordinates of the K intersection +% points. +% +% P = intersectLinePolygon(LINE, POLY, TOL) +% Specifies the tolerance for geometric tests. Default is 1e-14. +% +% [P INDS] = intersectLinePolygon(...) +% Also returns the indices of edges involved in intersections. INDS is a +% K-by-1 column vector, such that P(i,:) corresponds to intersection of +% the line with the i-th edge of the polygon. If the intersection occurs +% at a polygon vertex, the index of only one of the two neighbor edges is +% returned. +% Note that due to numerical approximations, the use of function +% 'isPointOnEdge' may give results not consistent with this function. +% +% +% Examples +% % compute intersections between a square and an horizontal line +% poly = [0 0;10 0;10 10;0 10]; +% line = [5 5 1 0]; +% intersectLinePolygon(line, poly) +% ans = +% 10 5 +% 0 5 +% % also return indices of edges +% [inters inds] = intersectLinePolygon(line, poly) +% inters = +% 10 5 +% 0 5 +% inds = +% 4 +% 2 +% +% % compute intersections between a square and a diagonal line +% poly = [0 0;10 0;10 10;0 10]; +% line = [5 5 1 1]; +% intersectLinePolygon(line, poly) +% ans = +% 0 0 +% 10 10 +% +% See Also +% lines2d, polygons2d, intersectLines, intersectRayPolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 31/10/2003. +% + +% HISTORY +% 2008-11-24 rename 'pi' as 'intersects', update doc +% 2009-07-23 removed forgotten occurence of 'pi' variable (thanks to Bala +% Krishnamoorthy) +% 2010-01-26 rewrite using vectorisation +% 2011-05-20 returns unique results +% 2011-07-20 returns intersected edge indices + +% get computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% create the array of edges +N = size(poly, 1); +edges = [poly(1:N, :) poly([2:N 1], :)]; + +% compute intersections with supporting lines of polygon edges +supportLines = edgeToLine(edges); +intersects = intersectLines(line, supportLines, tol); + +% find edges that are not parallel to the input line +inds = find(isfinite(intersects(:, 1))); + +% compute position of intersection points on corresponding lines +pos = linePosition(intersects(inds, :), supportLines(inds, :)); + +% and keep only intersection points located on edges +b = pos > -tol & pos < 1+tol; +inds = inds(b); +intersects = intersects(inds, :); + +% remove multiple vertices (can occur for intersections located at polygon +% vertices) +[intersects I J] = unique(intersects, 'rows'); %#ok + +if nargout > 1 + % return indices of edges involved in intersection + % (in case of intersection located at a vertex, only one of the + % neighbor edges is returned) + edgeIndices = inds(I); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectPolylines.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectPolylines.m new file mode 100644 index 0000000..c736163 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectPolylines.m @@ -0,0 +1,44 @@ +function pts = intersectPolylines(poly1, varargin) +%INTERSECTPOLYLINES Find the common points between 2 polylines +% +% INTERS = intersectPolylines(POLY1, POLY2) +% Returns the intersection points between two polylines. Each polyline is +% defined by a N-by-2 array representing coordinates of its vertices: +% [X1 Y1 ; X2 Y2 ; ... ; XN YN] +% INTERS is a NP-by-2 array containing coordinates of intersection +% points. +% +% INTERS = intersectPolylines(POLY1) +% Compute self-intersections of the polyline. +% +% Example +% % Compute intersection points between 2 simple polylines +% poly1 = [20 10 ; 20 50 ; 60 50 ; 60 10]; +% poly2 = [10 40 ; 30 40 ; 30 60 ; 50 60 ; 50 40 ; 70 40]; +% pts = intersectPolylines(poly1, poly2); +% figure; hold on; +% drawPolyline(poly1, 'b'); +% drawPolyline(poly2, 'm'); +% drawPoint(pts); +% axis([0 80 0 80]); +% +% See also +% polygons2d, polylineSelfIntersections, intersectLinePolygon +% +% This function uses the 'interX' function, found on the FileExchange, +% and stored in 'private' directory of this function. +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +if isempty(varargin) + % Compute self-intersections + pts = InterX(poly1')'; + +else + % compute intersection between two lines + pts = InterX(poly1', varargin{1}')'; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectRayPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectRayPolygon.m new file mode 100644 index 0000000..b6dd533 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/intersectRayPolygon.m @@ -0,0 +1,33 @@ +function intersects = intersectRayPolygon(ray, poly, varargin) +%INTERSECTRAYPOLYGON Intersection points between a ray and a polygon +% +% P = intersectRayPolygon(RAY, POLY) +% Returns the intersection points of the ray RAY with polygon POLY. +% RAY is a 1x4 array containing parametric representation of the ray +% (in the form [x0 y0 dx dy], see createRay for details). +% POLY is a Nx2 array containing coordinate of polygon vertices +% +% P = intersectRayPolygon(RAY, POLY, TOL) +% Specifies the tolerance for geometric tests. Default is 1e-14. +% +% See also +% rays2d, polygons2d, intersectLinePolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 26/01/2010 + + +% HISTORY +% 2010/01/26 creation from intersectLinePolygon + + +% compute intersections with supporting line +intersects = intersectLinePolygon(ray, poly, varargin{:}); + +% compute position of intersects on the supporting line +pos = linePosition(intersects, ray); + +% keep only intersects with position>0 +intersects(pos<0, :) = []; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointInPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointInPolygon.m new file mode 100644 index 0000000..cb2d78d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointInPolygon.m @@ -0,0 +1,29 @@ +function b = isPointInPolygon(point, poly) +%ISPOINTINPOLYGON Test if a point is located inside a polygon +% +% B = isPointInPolygon(POINT, POLYGON) +% Returns true if the point is located within the given polygon. +% +% This function is simply a wrapper for the function inpolygon, to avoid +% decomposition of point and polygon coordinates. +% +% Example +% pt1 = [30 20]; +% pt2 = [30 5]; +% poly = [10 10;50 10;50 50;10 50]; +% isPointInPolygon([pt1;pt2], poly) +% ans = +% 1 +% 0 +% +% See also +% points2d, polygons2d, inpolygon, isPointInTriangle + +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +b = inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointOnPolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointOnPolyline.m new file mode 100644 index 0000000..e7c3290 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/isPointOnPolyline.m @@ -0,0 +1,38 @@ +function res = isPointOnPolyline(point, poly, varargin) +%ISPOINTONPOLYLINE Test if a point belongs to a polyline +% +% B = isPointOnPolyline(POINT, POLY) +% Returns TRUE of the point POINT belong to the polyline defined by the +% set of points in POLY. +% +% B = isPointOnPolyline(POINT, POLY, TOL) +% Specify the absolute tolerance for testing the distance between the +% point and the polyline. +% +% Example +% pt1 = [30 20]; +% pt2 = [30 10]; +% poly = [10 10;50 10;50 50;10 50]; +% isPointOnPolyline([pt1;pt2], poly) +% ans = +% 0 +% 1 +% +% See also +% points2d, polygons2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-19, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + + +% extract computation tolerance +tol = 1e-14; +if ~isempty(varargin) + tol = varargin{1}; +end + +% return true if distance is below a given threshold +res = distancePointPolyline(point, poly) < tol; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/medialAxisConvex.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/medialAxisConvex.m new file mode 100644 index 0000000..5083cca --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/medialAxisConvex.m @@ -0,0 +1,132 @@ +function [nodes, edges] = medialAxisConvex(points) +%MEDIALAXISCONVEX Compute medial axis of a convex polygon +% +% [N, E] = medialAxisConvex(POLYGON); +% where POLYGON is given as a set of points [x1 y1;x2 y2 ...], returns +% the medial axis of the polygon as a graph. +% N is a set of nodes. The first elements of N are the vertices of the +% original polygon. +% E is a set of edges, containing indices of source and target nodes. +% Edges are sorted according to order of creation. Index of first vertex +% is lower than index of last vertex, i.e. edges always point to newly +% created nodes. +% +% Notes: +% - Is not fully implemented, need more development (usually crashes for +% polygons with more than 6-7 points...) +% - Works only for convex polygons. +% - Complexity is not optimal: this algorithm is O(n*log n), but linear +% algorithms exist. +% +% See also: +% polygons2d, bisector +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 07/07/2005. +% + +% HISTORY +% 18/04/2007: fix some typos, note the function to be unimplemented + +% TODO: is not fully implemented, need to finish it + +% eventually remove the last point if it is the same as the first one +if points(1,:) == points(end, :) + nodes = points(1:end-1, :); +else + nodes = points; +end + +% special case of triangles: +% compute directly the gravity center, and simplify computation. +if size(nodes, 1)==3 + nodes = [nodes; mean(nodes, 1)]; + edges = [1 4;2 4;3 4]; + return +end + +% number of nodes, and also of initial rays +N = size(nodes, 1); + +% create ray of each vertex +rays = zeros(N, 4); +rays(1, 1:4) = bisector(nodes([2 1 N], :)); +rays(N, 1:4) = bisector(nodes([1 N N-1], :)); +for i=2:N-1 + rays(i, 1:4) = bisector(nodes([i+1, i, i-1], :)); +end + +% add indices of edges producing rays (indices of first vertex, second +% vertex is obtained by adding one modulo N). +rayEdges = [[N (1:N-1)]' (1:N)']; + +pint = intersectLines(rays, rays([2:N 1], :)); +%ti = linePosition(pint, rays); +%ti = min(linePosition(pint, rays), linePosition(pint, rays([2:N 1], :))); +ti = distancePointLine(pint, ... + createLine(points([N (1:N-1)]', :), points((1:N)', :))); + +% create list of events. +% terms are : R1 R2 X Y t0 +% R1 and R2 are indices of involved rays +% X and Y is coordinate of intersection point +% t0 is position of point on rays +events = sortrows([ (1:N)' [2:N 1]' pint ti], 5); + +% initialize edges +edges = zeros(0, 2); + + +% ------------------- +% process each event until there is no more + +% start after index of last vertex, and process N-3 intermediate rays +for i=N+1:2*N-3 + % add new node at the rays intersection + nodes(i,:) = events(1, 3:4); + + % add new couple of edges + edges = [edges; events(1,1) i; events(1,2) i]; + + % find the two edges creating the new emanating ray + n1 = rayEdges(events(1, 1), 1); + n2 = rayEdges(events(1, 2), 2); + + % create the new ray + line1 = createLine(nodes(n1, :), nodes(mod(n1,N)+1, :)); + line2 = createLine(nodes(mod(n2,N)+1, :), nodes(n2, :)); + ray0 = bisector(line1, line2); + + % set its origin to emanating point + ray0(1:2) = nodes(i, :); + + % add the new ray to the list + rays = [rays; ray0]; + rayEdges(size(rayEdges, 1)+1, 1:2) = [n1 n2]; + + % find the two neighbour rays + ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2)==0; + ir = unique(events(ind, 1:2)); + ir = ir(~ismember(ir, events(1,1:2))); + + % create new intersections + pint = intersectLines(ray0, rays(ir, :)); + %ti = min(linePosition(pint, ray0), linePosition(pint, rays(ir, :))) + events(1,5); + ti = distancePointLine(pint, line1); + + % remove all events involving old intersected rays + ind = sum(ismember(events(:,1:2), events(1, 1:2)), 2)==0; + events = events(ind, :); + + % add the newly formed events + events = [events; ir(1) i pint(1,:) ti(1); ir(2) i pint(2,:) ti(2)]; + + % and sort them according to 'position' parameter + events = sortrows(events, 5); +end + +% centroid computation for last 3 rays +nodes = [nodes; mean(events(:, 3:4))]; +edges = [edges; [unique(events(:,1:2)) ones(3, 1)*(2*N-2)]]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/minimumCaliperDiameter.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/minimumCaliperDiameter.m new file mode 100644 index 0000000..5515c58 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/minimumCaliperDiameter.m @@ -0,0 +1,110 @@ +function [min_width min_angle] = minimumCaliperDiameter(points) +%MINIMUMCALIPERDIAMETER Minimum caliper diameter of a set of points +% +% WIDTH = minimumCaliperDiameter(POINTS) +% Computes the minimum width of a set of points. As polygons and +% polylines are represented as point lists, this function works also for +% polygons and polylines. +% +% [WIDTH THETA] = minimumCaliperDiameter(POINTS) +% Also returns the direction of minimum width. The direction corresponds +% to the horizontal angle of the edge that minimizes the width. THETA is +% given in radians, between 0 and PI. +% +% +% Example +% % Compute minimal caliper diameter, and check coords of rotated points +% % have expected extent +% points = randn(30, 2); +% [width theta] = minimumCaliperDiameter(points); +% points2 = transformPoint(points, createRotation(-theta)); +% diff = max(points2) - min(points2); +% abs(width - diff(2)) < 1e-10 +% ans = +% 1 +% +% References +% Algorithms use rotating caliper. Implementation was based on that of +% Wikipedia: +% http://en.wikipedia.org/wiki/Rotating_calipers +% +% See also +% polygons2d, convexHull +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-08, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% first, compute convex hull of the polygon +inds = convhull(points(:,1), points(:,2)); +hull = points(inds, :); + +% if first and last points are the same, remove the last one +if inds(1) == inds(end) + hull = hull(1:end-1, :); +end + +% number of hull vertices +nV = size(hull, 1); + +% default values +rotated_angle = 0; +min_width = inf; +min_angle = 0; + +% avoid degenerated cases +if nV < 3 + return; +end + +[tmp p_a] = min(hull(:, 2)); %#ok +[tmp p_b] = max(hull(:, 2)); %#ok + +caliper_a = [ 1 0]; % Caliper A points along the positive x-axis +caliper_b = [-1 0]; % Caliper B points along the negative x-axis + +while rotated_angle < pi + % compute the direction vectors corresponding to each edge + ind_a2 = mod(p_a, nV) + 1; + vector_a = hull(ind_a2, :) - hull(p_a, :); + + ind_b2 = mod(p_b, nV) + 1; + vector_b = hull(ind_b2, :) - hull(p_b, :); + + % Determine the angle between each caliper and the next adjacent edge + % in the polygon + angle_a = vectorAngle(caliper_a, vector_a); + angle_b = vectorAngle(caliper_b, vector_b); + + % Determine the smallest of these angles + minAngle = min(angle_a, angle_b); + + % Rotate the calipers by the smallest angle + caliper_a = rotateVector(caliper_a, minAngle); + caliper_b = rotateVector(caliper_b, minAngle); + + rotated_angle = rotated_angle + minAngle; + + % compute current width, and update opposite vertex + if angle_a < angle_b + line = createLine(hull(p_a, :), hull(ind_a2, :)); + width = distancePointLine(hull(p_b, :), line); + p_a = mod(p_a, nV) + 1; + + else + line = createLine(hull(p_b, :), hull(ind_b2, :)); + width = distancePointLine(hull(p_a, :), line); + p_b = mod(p_b, nV) + 1; + + end + + % update minimum width and corresponding angle if needed + if width < min_width + min_width = width; + min_angle = rotated_angle; + end + +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/parametrize.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/parametrize.m new file mode 100644 index 0000000..14eed24 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/parametrize.m @@ -0,0 +1,83 @@ +function par = parametrize(varargin) +%PARAMETRIZE Parametrization of a polyline, based on edges lengths +% +% PAR = parametrize(POLY); +% Returns a parametrization of the curve defined by the serie of points, +% based on euclidean distance between two consecutive points. +% POLY is a N-by-2 array, representing coordinates of vertices. The +% result PAR is N-by-1, and contains the cumulative length of edges until +% corresponding vertex. +% +% PAR = parametrize(PX, PY); +% is the same, but specify points coordinates in separate column vectors. +% +% PAR = parametrize(..., 'normalize', 1); +% PAR = parametrize(..., 'normalize', true); +% Rescales the result such that the last element of PAR is 1. +% +% Example +% % Parametrize a circle approximation +% poly = circleToPolygon([0 0 1], 200); +% p = parametrize(poly); +% p(end) +% ans = +% 6.2829 +% +% See also: +% polygons2d, polylineLength +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2003. +% + + +%% Process inputs + +% extract vertex coordinates +if size(varargin{1}, 2) > 1 + % vertices in a single array + pts = varargin{1}; + varargin(1) = []; + +elseif length(varargin) == 2 + % points as separate arrays + pts = [varargin{1} varargin{2}]; + varargin(1:2) = []; + +end + +% by default, do not normalize +normalize = false; + +% extract options +while length(varargin) > 1 + param = varargin{1}; + switch lower(param) + case 'normalize' + normalize = varargin{2}; + otherwise + error('Unknown parameter name: %s', param); + end + varargin(1:2) = []; +end + + +%% Parametrize polyline + +% compute cumulative sum of euclidean distances between consecutive +% vertices, setting distance of first vertex to 0. +if size(pts, 2) == 2 + % process points in 2D + par = [0 ; cumsum(hypot(diff(pts(:,1)), diff(pts(:,2))))]; +else + % process points in arbitrary dimension + par = [0 ; cumsum(sqrt(sum(diff(pts).^2, 2)))]; +end + +% eventually rescale between 0 and 1 +if normalize + par = par / par(end); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/pointSetsAverage.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/pointSetsAverage.m new file mode 100644 index 0000000..91d8fd6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/pointSetsAverage.m @@ -0,0 +1,49 @@ +function average = pointSetsAverage(pointSets, varargin) +%POINTSETSAVERAGE Compute the average of several point sets +% +% AVERAGESET = pointSetsAverage(POINTSETS) +% POINTSETS is a cell array containing several liste of points with the +% same number of points. The function compute the average coordinate of +% each vertex, and return the resulting average point set. +% +% Example +% pointSetsAverage +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-04-01, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% check input +if ~iscell(pointSets) + error('First argument must be a cell array'); +end + +% number of sets +nSets = length(pointSets); + +% get reference size of coordinates array +set1 = pointSets{1}; +refSize = size(set1); + +% allocate memory for result +average = zeros(refSize); + +% iterate on point sets +for i = 1:nSets + % get current point set, and check its size + set = pointSets{i}; + if sum(size(set) ~= refSize) > 0 + error('All point sets must have the same size'); + end + + % cumulative sum of coordinates + average = average + set; +end + +% normalize by the number of sets +average = average / nSets; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonArea.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonArea.m new file mode 100644 index 0000000..4f8a0c5 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonArea.m @@ -0,0 +1,70 @@ +function area = polygonArea(varargin) +%POLYGONAREA Compute the signed area of a polygon +% +% A = polygonArea(POINTS); +% Compute area of a polygon defined by POINTS. POINTS is a N-by-2 array +% of double containing coordinates of vertices. +% +% Vertices of the polygon are supposed to be oriented Counter-Clockwise +% (CCW). In this case, the signed area is positive. +% If vertices are oriented Clockwise (CW), the signed area is negative. +% +% If polygon is self-crossing, the result is undefined. +% +% Examples +% % compute area of a simple shape +% poly = [10 10;30 10;30 20;10 20]; +% area = polygonArea(poly) +% area = +% 200 +% +% % compute area of CW polygon +% area2 = polygonArea(poly(end:-1:1, :)) +% area2 = +% -200 +% +% References +% algo adapted from P. Bourke web page +% http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/ +% +% See also : +% polygons2d, polygonCentroid, drawPolygon, triangleArea +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/05/2004. +% + +% HISTORY +% 25/04/2005: add support for multiple polygons +% 12/10/2007: update doc + +% in case of polygon sets, computes several areas +if nargin > 0 + var = varargin{1}; + if iscell(var) + area = zeros(length(var), 1); + for i = 1:length(var) + area(i) = polygonArea(var{i}, varargin{2:end}); + end + return; + end +end + +% extract coordinates +if nargin == 1 + var = varargin{1}; + px = var(:, 1); + py = var(:, 2); +elseif nargin == 2 + px = varargin{1}; + py = varargin{2}; +end + +% indices of next vertices +N = length(px); +iNext = [2:N 1]; + +% compute area (vectorized version) +area = sum(px .* py(iNext) - px(iNext) .* py) / 2; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonBounds.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonBounds.m new file mode 100644 index 0000000..f2c7943 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonBounds.m @@ -0,0 +1,38 @@ +function box = polygonBounds(polygon) +%POLYGONBOUNDS Compute the bounding box of a polygon +% +% BOX = polygonBounds(POLYGON); +% Returns the bounding box of the polygon. +% BOX has the format: [XMIN XMAX YMIN YMAX]. +% +% +% See also +% polygons2d, boxes2d, polygonBounds +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-12, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +% transform as a cell array of simple polygons +polygons = splitPolygons(polygon); + +% init extreme values +xmin = inf; +xmax = -inf; +ymin = inf; +ymax = -inf; + +for i=1:length(polygons) + polygon = polygons{i}; + + xmin = min(xmin, min(polygon(:,1))); + xmax = max(xmax, max(polygon(:,1))); + ymin = min(ymin, min(polygon(:,2))); + ymax = max(ymax, max(polygon(:,2))); +end + +box = [xmin xmax ymin ymax]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonCentroid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonCentroid.m new file mode 100644 index 0000000..2e037d6 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonCentroid.m @@ -0,0 +1,40 @@ +function pt = polygonCentroid(varargin) +%POLYGONCENTROID Compute the centroid (center of mass) of a polygon +% +% PT = polygonCentroid(POINTS) +% PT = polygonCentroid(PTX, PTY) +% Computes center of mass of a polygon defined by POINTS. POINTS is a +% [N*2] array of double. +% +% +% See also: +% polygons2d, polygonArea, drawPolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 05/05/2004. +% + + +if nargin==1 + var = varargin{1}; + px = var(:,1); + py = var(:,2); +elseif nargin==2 + px = varargin{1}; + py = varargin{2}; +end + +% Algorithme P. Bourke +sx = 0; +sy = 0; +N = length(px); +for i=1:N-1 + sx = sx + (px(i)+px(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); + sy = sy + (py(i)+py(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); +end +sx = sx + (px(N)+px(1))*(px(N)*py(1) - px(1)*py(N)); +sy = sy + (py(N)+py(1))*(px(N)*py(1) - px(1)*py(N)); + +pt = [sx sy]/6/polygonArea(px, py); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonContains.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonContains.m new file mode 100644 index 0000000..d10cd8d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonContains.m @@ -0,0 +1,48 @@ +function varargout = polygonContains(poly, point) +%POLYGONCONTAINS Test if a point is contained in a multiply connected polygon +% +% B = polygonContains(POLYGON, POINT); +% Returns TRUE if the (possibly multi-connected) polygon POLYGON contains +% the point(s) given by POINT. +% This is an extension of the Matlab function inpolygon for the case of +% polygons with holes. +% +% Example +% POLY = [0 0; 10 0;10 10;0 10;NaN NaN;3 3;3 7;7 7;7 3]; +% PT = [5 1;5 4]; +% polygonContains(POLY, PT); +% ans = +% 1 +% 0 +% +% See also +% polygons2d, +% inpolygon +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-11, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +% transform as a cell array of simple polygons +polygons = splitPolygons(poly); +N = length(polygons); +Np = size(point, 1); + +% compute orientation of polygon, and format to have Np*N matrix +ccw = polygonArea(polygons)>0; +ccw = repmat(ccw', Np, 1); + +% test if point inside each polygon +in = false(size(point, 1), N); +for i=1:N + poly = polygons{i}; + in(:, i) = inpolygon(point(:,1), point(:,2), poly(:,1), poly(:,2)); +end + +% count polygons containing point, weighted by polygon orientation +res = sum(in.*(ccw==1) - in.*(ccw==0), 2); + +varargout{1} = res; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonExpand.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonExpand.m new file mode 100644 index 0000000..0ca0b39 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonExpand.m @@ -0,0 +1,68 @@ +function poly2 = polygonExpand(polygon, dist) +%POLYGONEXPAND 'expand' a polygon with a given distance +% +% EXPOLY = polygonExpand(POLYGON, D); +% Associates each edge of POLYGON to an edge located at distance D, and +% computes polygon given by growing edges. +% This is a kind of dilatation, but behaviour on corners is different. +% This function keeps angles of polygons, but there is no direct relation +% between length of 2 polygons. +% +% It works fine for convex polygons, or for polygons whose complexity is +% not too high (self intersection of result polygon is not tested). +% +% It is also possible to specify negative distance, and get all points +% inside the polygon. If the polygon is convex, the result equals +% morphological erosion of polygon by a ball with radius equal to the +% given distance. +% +% See also: +% polygons2d +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 14/05/2005. +% + +% HISTORY : +% 31/07/2005 : change algo for negative distance : use clipping of +% polygon by half-planes +% 17/06/2009 deprecate + +% deprecation warning +warning('geom2d:deprecated', ... + '''polygonExpand'' is deprecated, use ''expandPolygon'' instead'); + +% eventually copy first point at the end +if sum(polygon(end, :)==polygon(1,:))~=2 + polygon = [polygon; polygon(1,:)]; +end + +% number of vertics of polygon +N = size(polygon, 1)-1; + +% find lines parallel to polygon edges with distance DIST +line = zeros(N, 4); +for i=1:N + side = createLine(polygon(i,:), polygon(i+1,:)); + %perp = orthogonalLine(side, polygon(i,:)); + %pts2 = pointOnLine(perp, -dist); + line(i, 1:4) = parallelLine(side, -dist); +end + + +if dist>0 + % compute intersection points of consecutive lines + line = [line;line(1,:)]; + poly2 = zeros(N, 2); + for i=1:N + poly2(i,1:2) = intersectLines(line(i,:), line(i+1,:)); + end +else + poly2 = polygon; + % clip polygon with all lines parallel to edges + for i=1:N + poly2 = clipPolygonHP(poly2, line(i,:)); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLength.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLength.m new file mode 100644 index 0000000..51fb61a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLength.m @@ -0,0 +1,54 @@ +function len = polygonLength(poly, varargin) +%POLYGONLENGTH Perimeter of a polygon +% +% L = polygonLength(POLYGON); +% Computes the boundary length of a polygon. POLYGON is given by a N-by-2 +% array of vertices. +% +% Example +% % Perimeter of a circle approximation +% poly = circleAsPolygon([0 0 1], 200); +% polygonLength(poly) +% ans = +% 6.2829 +% +% See also: +% polygons2d, polygonCentroid, polygonArea, drawPolygon, polylineLength +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 11/05/2005. +% + +% HISTORY +% 2011-03-31 add control for empty polygons, code cleanup +% 2011-05-27 fix bugs +% If first argument is a cell array, this is a multi-polygon, and we simply +% add the lengths of individual polygons +if iscell(poly) + len = 0; + for i = 1:length(poly) + len = len + polygonLength(poly{i}); + end + return; +end + +% case of a polygon given as two coordinate arrays +if nargin == 2 + poly = [poly varargin{1}]; +end + +% check there are enough points +if size(poly, 1) < 2 + len = 0; + return; +end + +% compute length +if size(poly, 2) == 2 + dp = diff(poly([1:end 1], :), 1, 1); + len = sum(hypot(dp(:, 1), dp(:, 2))); +else + len = sum(sqrt(sum(diff(poly([1:end 1], :), 1, 1).^2, 2))); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLoops.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLoops.m new file mode 100644 index 0000000..79f420f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonLoops.m @@ -0,0 +1,117 @@ +function loops = polygonLoops(poly) +%POLYGONLOOPS Divide a possibly self-intersecting polygon into a set of simple loops +% +% LOOPS = polygonLoops(POLYGON); +% POLYGON is a polygone defined by a series of vertices, +% LOOPS is a cell array of polygons, containing the same vertices of the +% original polygon, but no loop self-intersect, and no couple of loops +% intersect each other. +% +% Example: +% poly = [0 0;0 10;20 10;20 20;10 20;10 0]; +% loops = polygonLoops(poly); +% figure(1); hold on; +% drawPolygon(loops); +% polygonArea(loops) +% +% See also +% polygons2d, polygonSelfIntersections +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + + +%% Initialisations + +% compute intersections +[inters pos1 pos2] = polygonSelfIntersections(poly); + +% case of a polygon without self-intersection +if isempty(inters) + loops = {poly}; + return; +end + +% array for storing loops +loops = cell(0, 1); + +positions = sortrows([pos1 pos2;pos2 pos1]); + + +%% First loop + +pos0 = 0; +loop = polygonSubcurve(poly, pos0, positions(1, 1)); +pos = positions(1, 2); +positions(1, :) = []; + +while true + % index of next intersection point + ind = find(positions(:,1)>pos, 1, 'first'); + + % if not found, break + if isempty(ind) + break; + end + + % add portion of curve + loop = [loop;polygonSubcurve(poly, pos, positions(ind, 1))]; %#ok + + % look for next intersection point + pos = positions(ind, 2); + positions(ind, :) = []; +end + +% add the last portion of curve +loop = [loop;polygonSubcurve(poly, pos, pos0)]; + +% remove redundant vertices +loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; +if sum(diff(loop([1 end], :))==0)==2 + loop(end, :) = []; +end + +% add current loop to the list of loops +loops{1} = loop; + + +%% Other loops + +Nl = 1; +while ~isempty(positions) + + loop = []; + pos0 = positions(1, 2); + pos = positions(1, 2); + + while true + % index of next intersection point + ind = find(positions(:,1)>pos, 1, 'first'); + + % add portion of curve + loop = [loop;polygonSubcurve(poly, pos, positions(ind, 1))]; %#ok + + % look for next intersection point + pos = positions(ind, 2); + positions(ind, :) = []; + + % if not found, break + if pos==pos0 + break; + end + end + + % remove redundant vertices + loop(sum(loop(1:end-1,:) == loop(2:end,:) ,2)==2, :) = []; %#ok + if sum(diff(loop([1 end], :))==0)==2 + loop(end, :) = []; %#ok + end + + % add current loop to the list of loops + Nl = Nl + 1; + loops{Nl} = loop; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonNormalAngle.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonNormalAngle.m new file mode 100644 index 0000000..2f17144 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonNormalAngle.m @@ -0,0 +1,54 @@ +function theta = polygonNormalAngle(points, ind) +%POLYGONNORMALANGLE Compute the normal angle at a vertex of the polygon +% +% THETA = polygonNormalAngle(POLYGON, IND); +% where POLYGON is a set of points, and IND is index of a point in +% polygon. The function compute the angle of the normal cone localized at +% this vertex. +% If IND is a vector of indices, normal angle is computed for each vertex +% specified by IND. +% +% Example +% % creates a simple polygon +% poly = [0 0;0 1;-1 1;0 -1;1 0]; +% % compute normal angle at each vertex +% theta = polygonNormalAngle(poly, 1:size(poly, 1)); +% % sum of all normal angle of a non-intersecting polygon equals 2xpi +% % (can be -2xpi if polygon is oriented clockwise) +% sum(theta) +% +% See also: +% polygons2d, formatAngle +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2005-11-30 +% Copyright 2005 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + + +% number of points +np = size(points, 1); + +% number of angles to compute +nv = length(ind); + +theta = zeros(nv, 1); + +for i=1:nv + p0 = points(ind(i), :); + + if ind(i)==1 + p1 = points(np, :); + else + p1 = points(ind(i)-1, :); + end + + if ind(i)==np + p2 = points(1, :); + else + p2 = points(ind(i)+1, :); + end + + theta(i) = angle3Points(p1, p0, p2) - pi; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonPoint.m new file mode 100644 index 0000000..3e4459e --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonPoint.m @@ -0,0 +1,58 @@ +function point = polygonPoint(poly, pos) +%POLYGONPOINT Extract a point from a polygon +% +% POINT = polygonPoint(POLYGON, POS) +% +% +% Example +% polygonPoint +% +% See also +% polygons2d, polylinePoint +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% eventually copy first point at the end to ensure closed polygon +if sum(poly(end, :)==poly(1,:))~=2 + poly = [poly; poly(1,:)]; +end + +% number of points to compute +Np = length(pos(:)); + +% number of vertices in polygon +Nv = size(poly, 1)-1; + +% allocate memory results +point = zeros(Np, 2); + +% iterate on points +for i=1:Np + % compute index of edge (between 0 and Nv) + ind = floor(pos(i)); + + % special case of last point of polyline + if ind==Nv + point(i,:) = poly(end,:); + continue; + end + + % format index to ensure being on polygon + ind = min(max(ind, 0), Nv-1); + + % position on current edge + t = min(max(pos(i)-ind, 0), 1); + + % parameters of current edge + x0 = poly(ind+1, 1); + y0 = poly(ind+1, 2); + dx = poly(ind+2,1)-x0; + dy = poly(ind+2,2)-y0; + + % compute position of current point + point(i, :) = [x0+t*dx, y0+t*dy]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSelfIntersections.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSelfIntersections.m new file mode 100644 index 0000000..2d30f4c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSelfIntersections.m @@ -0,0 +1,63 @@ +function varargout = polygonSelfIntersections(poly, varargin) +%POLYGONSELFINTERSECTIONS Find-self intersection points of a polygon +% +% PTS = polygonSelfIntersections(POLY) +% Return the position of self intersection points +% +% [PTS POS1 POS2] = polygonSelfIntersections(POLY) +% Also return the 2 positions of each intersection point (the position +% when meeting point for first time, then position when meeting point +% for the second time). +% +% Example +% % use a '8'-shaped polygon +% poly = [10 0;0 0;0 10;20 10;20 20;10 20]; +% polygonSelfIntersections(poly) +% ans = +% 10 10 +% +% See also +% polygons2d, polylineSelfIntersections +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% HISTORY +% 2011-06-22 fix bug when removing origin vertex (thanks to Federico +% Bonelli) + +tol = 1e-14; + +% ensure the last point equals the first one +if sum(abs(poly(end, :)-poly(1,:)) < tol) ~= 2 + poly = [poly; poly(1,:)]; +end + +% compute intersections by calling algo for polylines +[points pos1 pos2] = polylineSelfIntersections(poly); + +% It may append that first vertex of polygon is detected as intersection, +% the following tries to detect this +n = size(poly, 1) - 1; +inds = (pos1 == 0 & pos2 == n) | (pos1 == n & pos2 == 0); +points(inds, :) = []; +pos1(inds) = []; +pos2(inds) = []; + +% remove multiple intersections +[points I J] = unique(points, 'rows', 'first'); %#ok +pos1 = pos1(I); +pos2 = pos2(I); + + +%% Post-processing + +% process output arguments +if nargout <= 1 + varargout = {points}; +elseif nargout == 3 + varargout = {points, pos1, pos2}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSubcurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSubcurve.m new file mode 100644 index 0000000..7ee65e4 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polygonSubcurve.m @@ -0,0 +1,57 @@ +function res = polygonSubcurve(poly, t0, t1) +%POLYGONSUBCURVE Extract a portion of a polygon +% +% POLY2 = polygonSubcurve(POLYGON, POS0, POS1) +% Create a new polyline, by keeping vertices located between positions +% POS0 and POS1, and adding points corresponding to positions POS0 and +% POS1 if they are not already vertices. +% +% Example +% Nv = 100; +% poly = circleAsPolygon([10 20 30], Nv); +% poly2 = polygonSubcurve(poly, 15, 65); +% drawCurve(poly2); +% +% See also +% polygons2d, polylineSubcurve +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% number of vertices +Nv = size(poly, 1); + +if t01 + t0 = varargin{1}; + t1 = varargin{2}; + end + + % extract a portion of the polyline + poly = polylineSubcurve(poly, t0, t1); +end + +% compute lengths of each line segment, and sum up +if closed + len = sum(sqrt(sum(diff(poly([1:end 1],:)).^2, 2))); +else + len = sum(sqrt(sum(diff(poly).^2, 2))); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylinePoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylinePoint.m new file mode 100644 index 0000000..9af429a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylinePoint.m @@ -0,0 +1,64 @@ +function point = polylinePoint(poly, pos) +%POLYLINEPOINT Extract a point from a polyline +% +% POINT = polylinePoint(POLYLINE, POS) +% POLYLINE is a N*2 array containing coordinate of polyline vertices +% POS is comprised between 0 (first point of polyline) and Nv-1 (last +% point of the polyline). +% +% +% Example +% poly = [10 10;20 10;20 20;30 30]; +% polylinePoint(poly, 0) +% [10 10] +% polylinePoint(poly, 3) +% [30 30] +% polylinePoint(poly, 1.4) +% [20 14] +% +% +% See also +% polygons2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + + +% number of points to compute +Np = length(pos(:)); + +% number of vertices in polyline +Nv = size(poly, 1); + +% allocate memory results +point = zeros(Np, 2); + +% iterate on points +for i=1:Np + % compute index of edge (between 0 and Nv) + ind = floor(pos(i)); + + % special case of last point of polyline + if ind==Nv-1 + point(i,:) = poly(end,:); + continue; + end + + % format index to ensure being on polyline + ind = min(max(ind, 0), Nv-2); + + % position on current edge + t = min(max(pos(i)-ind, 0), 1); + + % parameters of current edge + x0 = poly(ind+1, 1); + y0 = poly(ind+1, 2); + dx = poly(ind+2,1)-x0; + dy = poly(ind+2,2)-y0; + + % compute position of current point + point(i, :) = [x0+t*dx, y0+t*dy]; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSelfIntersections.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSelfIntersections.m new file mode 100644 index 0000000..2caf1db --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSelfIntersections.m @@ -0,0 +1,130 @@ +function varargout = polylineSelfIntersections(poly, varargin) +%POLYLINESELFINTERSECTIONS Find self-intersections points of a polyline +% +% PTS = polylineSelfIntersections(POLY); +% Return the position of self intersection points +% +% [PTS POS1 POS2] = polylineSelfIntersections(POLY); +% Also return the 2 positions of each intersection point (the position +% when meeting point for first time, then position when meeting point +% for the second time). +% +% Example +% % use a gamma-shaped polyline +% poly = [0 0;0 10;20 10;20 20;10 20;10 0]; +% polylineSelfIntersections(poly) +% ans = +% 10 10 +% +% % use a 'S'-shaped polyline +% poly = [10 0;0 0;0 10;20 10;20 20;10 20]; +% polylineSelfIntersections(poly) +% ans = +% 10 10 +% +% See also +% polygons2d, intersectPolylines, polygonSelfIntersections +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-15, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% HISTORY +% 2009/06/18 check bounding boxes before computing intersections + + +%% Initialisations + +% determine whether the polyline is closed +closed = false; +if ~isempty(varargin) + closed = varargin{1}; + if ischar(closed) + if strcmp(closed, 'closed') + closed = true; + elseif strcmp(closed, 'open') + closed = false; + end + end +end + +% if polyline is closed, ensure the last point equals the first one +if closed + if sum(abs(poly(end, :)-poly(1,:))<1e-14)~=2 + poly = [poly; poly(1,:)]; + end +end + +% arrays for storing results +points = zeros(0, 2); +pos1 = zeros(0, 1); +pos2 = zeros(0, 1); + +% number of vertices +Nv = size(poly, 1); + + +%% Main processing + +% index of current intersection +ip = 0; + +% iterate over each couple of edge ( (N-1)*(N-2)/2 iterations) +for i=1:Nv-2 + % create first edge + edge1 = [poly(i, :) poly(i+1, :)]; + for j=i+2:Nv-1 + % create second edge + edge2 = [poly(j, :) poly(j+1, :)]; + + % check conditions on bounding boxes + if min(edge1([1 3]))>max(edge2([1 3])) + continue; + end + if max(edge1([1 3]))max(edge2([2 4])) + continue; + end + if max(edge1([2 4])) + points(ind,:) = []; + pos1(ind) = []; + pos2(ind) = []; +end + +%% Post-processing + +% process output arguments +if nargout<=1 + varargout{1} = points; +elseif nargout==3 + varargout{1} = points; + varargout{2} = pos1; + varargout{3} = pos2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSubcurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSubcurve.m new file mode 100644 index 0000000..0d1e7a3 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/polylineSubcurve.m @@ -0,0 +1,53 @@ +function res = polylineSubcurve(poly, t0, t1) +%POLYLINESUBCURVE Extract a portion of a polyline +% +% POLY2 = polylineSubcurve(POLYLINE, POS0, POS1) +% Create a new polyline, by keeping vertices located between positions +% POS0 and POS1, and adding points corresponding to positions POS0 and +% POS1 if they are not already vertices. +% +% Example +% Nv = 100; +% poly = circleAsPolygon([10 20 30], Nv); +% poly2 = polylineSubcurve(poly, 15, 65); +% drawCurve(poly2); +% +% See also +% polygons2d, polygonSubCurve +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% number of vertices +Nv = size(poly, 1); + +if t0 the polyline is closed +% 'open' -> the polyline is open +% a column vector of logical with the same number of elements as the +% number of points -> specify individually if each polyline is +% closed (true=closed). +% +% [POS DIST] = projPointOnPolyline(...) +% Also returns the distance between POINT and POLYLINE. +% +% Example +% projPointOnPolyline +% +% See also +% points2d, polygons2d, polylinePoint +% distancePointPolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-04-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +% check if input polyline is closed or not +closed = false; +if ~isempty(varargin) + var = varargin{1}; + if strcmp('closed', var) + closed = true; + elseif strcmp('open', var) + closed = false; + elseif islogical(var) + closed = var; + end +end + +% closes the polyline if necessary +if closed + poly = [poly;poly(1,:)]; +end + +% number of points +Np = size(point, 1); + +% number of vertices in polyline +Nv = size(poly, 1); + +% allocate memory results +pos = zeros(Np, 1); +minDist = inf*ones(Np, 1); + +% iterate on points +for p=1:Np + % compute smallest distance to each edge + for i=1:Nv-1 + % build current edge + edge = [poly(i,:) poly(i+1,:)]; + + % compute distance between current point and edge + [dist edgePos] = distancePointEdge(point(p, :), edge); + + % update distance and position if necessary + if dist +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rectAsPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rectAsPolygon.m new file mode 100644 index 0000000..d66b049 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rectAsPolygon.m @@ -0,0 +1,47 @@ +function varargout = rectAsPolygon(rect) +%RECTASPOLYGON Convert a (centered) rectangle into a series of points +% +% P = rectAsPolygon(RECT); +% Converts rectangle given as [x0 y0 w h] or [x0 y0 w h theta] into a +% 4*2 array double, containing coordinate of rectangle vertices. +% +% See also: +% polygons2d, drawRect, drawOrientedBox, drawPolygon +% +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 06/04/2005. +% + +% HISTORY + +theta = 0; +x = rect(1); +y = rect(2); +w = rect(3)/2; % easier to compute with w and h divided by 2 +h = rect(4)/2; +if length(rect)>4 + theta = rect(5); +end + +cot = cos(theta); +sit = sin(theta); + +tx(1) = x - w*cot + h*sit; +ty(1) = y - w*sit - h*cot; +tx(2) = x + w*cot + h*sit; +ty(2) = y + w*sit - h*cot; +tx(3) = x + w*cot - h*sit; +ty(3) = y + w*sit + h*cot; +tx(4) = x - w*cot - h*sit; +ty(4) = y - w*sit + h*cot; + + +if nargout==1 + varargout{1}=[tx' ty']; +elseif nargout==2 + varargout{1}=tx'; + varargout{2}=ty'; +end \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolygon.m new file mode 100644 index 0000000..3c2a29f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolygon.m @@ -0,0 +1,27 @@ +function poly2 = resamplePolygon(poly, n) +%RESAMPLEPOLYGON Distribute N points equally spaced on a polygon +% +% output = resamplePolygon(input) +% +% Example +% poly = [0 0;20 0;20 10;0 10]; +% figure; drawPolygon(poly, 'b'); +% % draw vertices of original polygon +% hold on; drawPoint(poly, 'ks'); +% % sub-sample the polygon +% poly2 = resamplePolygon(poly, 24); +% drawPolygon(poly2, 'bx'); +% axis equal; axis([-10 30 -10 20]); +% +% +% See also +% polygons2d, drawPolygon, resamplePolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +poly2 = resamplePolyline(poly([1:end 1],:), n+1); +poly2(end, :) = []; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolyline.m new file mode 100644 index 0000000..228b143 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/resamplePolyline.m @@ -0,0 +1,55 @@ +function poly2 = resamplePolyline(poly, n) +%RESAMPLEPOLYLINE Distribute N points equally spaced on a polyline +% +% RES = resamplePolyline(POLY, N) +% Resample the input polyline POLY such that the resulting polyline RES +% has N points. All points of RES belong to the initial polyline, but are +% not necessarily vertices. +% +% Example +% poly = [0 10;0 0;20 0]; +% figure; drawPolyline(poly, 'b'); +% poly2 = resamplePolyline(poly, 10); +% hold on; +% drawPolyline(poly2, 'bo'); +% axis equal; axis([-10 30 -10 20]); +% +% See also +% polygons2d, drawPolyline, resamplePolygon +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-12-09, using Matlab 7.9.0.529 (R2009b) +% Copyrightf 2011 INRA - Cepia Software Platform. + +% parametrisation of the curve +s = parametrize(poly); + +% distribute N points equally spaced +Lmax = s(end); +pos = linspace(0, Lmax, n); + +poly2 = zeros(n, size(poly, 2)); +for i = 1:n + % index of surrounding vertices before and after + ind0 = find(s <= pos(i), 1, 'last'); + ind1 = find(s >= pos(i), 1, 'first'); + + if ind0 == ind1 + % get position of a vertex in input polyline + poly2(i, :) = poly(ind0, :); + continue; + end + + % position of surrounding vertices + pt0 = poly(ind0, :); + pt1 = poly(ind1, :); + + % weights associated to each neighbor + l0 = pos(i) - s(ind0); + l1 = s(ind1) - pos(i); + + % linear interpolation of neighbor positions + poly2(i, :) = (pt0 * l1 + pt1 * l0) / (l0 + l1); +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolygon.m new file mode 100644 index 0000000..8aeca3a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolygon.m @@ -0,0 +1,20 @@ +function rev = reversePolygon(poly) +%REVERSEPOLYGON Reverse a polygon, by iterating vertices from the end +% +% POLY2 = reversePolygon(POLY) +% POLY2 has same vertices as POLY, but in different order. The first +% vertex of the polygon is still the same. +% +% Example +% reversePolygon +% +% See also +% polygons2d, reversePolyline +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +rev = poly([1 end:-1:2], :); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolyline.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolyline.m new file mode 100644 index 0000000..1f40116 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/reversePolyline.m @@ -0,0 +1,20 @@ +function rev = reversePolyline(poly) +%REVERSEPOLYLINE Reverse a polyline, by iterating vertices from the end +% +% POLY2 = reversePolyline(POLY) +% POLY2 has same vertices as POLY, but POLY2(i,:) is the same as +% POLY(END-i+1,:). +% +% Example +% reversePolyline +% +% See also +% polygons2d, reversePolygon +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2009-06-30, using Matlab 7.7.0.471 (R2008b) +% Copyright 2009 INRA - Cepia Software Platform. + +rev = poly(end:-1:1, :); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rowToPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rowToPolygon.m new file mode 100644 index 0000000..663623a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/rowToPolygon.m @@ -0,0 +1,47 @@ +function poly = rowToPolygon(row, varargin) +%ROWTOPOLYGON Create a polygon from a row vector +% +% POLY = rowToPolygon(ROW) +% Convert a 1-by-2*N row vector that concatenates all polygon vertex +% coordinates into a N-by-2 array of coordinates. +% Default ordering of coordinates in ROW is: +% [X1 Y1 X2 Y2 X3 Y3 .... XN YN]. +% +% POLY = rowToPolygon(ROW, METHOD) +% Specifies the method for concatenating coordinates. METHOS is one of: +% 'interlaced': default method, described above. +% 'packed': the vector ROW has format: +% [X1 X2 X3 ... XN Y1 Y2 Y3 ... YN]. +% +% Example +% % Concatenate coordinates of a circle and draw it as a polygon +% t = linspace (0, 2*pi, 200); +% row = [cos(t) sin(t)]; +% poly = rowToPolygon(row, 'packed'); +% figure;drawPolygon(poly) +% +% See also +% polygons2d, polygonToRow +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2010-07-23, using Matlab 7.9.0.529 (R2009b) +% Copyright 2010 INRA - Cepia Software Platform. + +type = 'interlaced'; +if ~isempty(varargin) + type = varargin{1}; +end + +% polygon vertex number +Np = length(row)/2; + +if strcmp(type, 'interlaced') + % ordering is [X1 Y1 X2 X2... XN YN] + poly = reshape(row, [2 Np])'; + +elseif strcmp(type, 'packed') + % ordering is [X1 X2 X3... XN Y1 Y2 Y3... YN] + poly = [row(1:Np)' row(Np+1:end)']; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/splitPolygons.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/splitPolygons.m new file mode 100644 index 0000000..9b6fcf0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/splitPolygons.m @@ -0,0 +1,39 @@ +function polygons = splitPolygons(polygon) +%SPLITPOLYGONS Convert a NaN separated polygon list to a cell array of polygons +% +% POLYGONS = splitPolygons(POLYGON); +% POLYGON is a N*2 array of points, with possibly couples of NaN values. +% The functions separates each component separated by NaN values, and +% returns a cell array of polygons. +% +% See also: +% polygons2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-10-12, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +if iscell(polygon) + % case of a cell array + polygons = polygon; + +elseif sum(isnan(polygon(:)))==0 + % single polygon -> no break + polygons = {polygon}; + +else + % find indices of NaN couples + inds = find(sum(isnan(polygon), 2)>0); + + % number of polygons + N = length(inds)+1; + polygons = cell(N, 1); + + % iterate over NaN-separated regions to create new polygon + inds = [0;inds;size(polygon, 1)+1]; + for i=1:N + polygons{i} = polygon((inds(i)+1):(inds(i+1)-1), :); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPoint.m new file mode 100644 index 0000000..c84e75b --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPoint.m @@ -0,0 +1,42 @@ +function pt = steinerPoint(varargin) +%STEINERPOINT Compute steiner point (weighted centroid) of a polygon +% +% PT = steinerPoint(POINTS); +% PT = steinerPoint(PTX, PTY); +% Computes steiner point of a polygon defined by POINTS. POINTS is a +% [N*2] array of double. +% +% The steiner point is computed the same way as the polygon centroid, +% except that a weight depending on the angle is given to each vertex. +% +% See also: +% polygons2d, polygonArea, polygonCentroid, drawPolygon +% +% --------- +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 11/11/2004. +% + + +if nargin==1 + var = varargin{1}; + px = var(:,1); + py = var(:,2); +elseif nargin==2 + px = varargin{1}; + py = varargin{2}; +end + +% Algorithme P. Bourke +sx = 0; +sy = 0; +N = length(px); +for i=1:N-1 + sx = sx + (px(i)+px(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); + sy = sy + (py(i)+py(i+1))*(px(i)*py(i+1) - px(i+1)*py(i)); +end +sx = sx + (px(N)+px(1))*(px(N)*py(1) - px(1)*py(N)); +sy = sy + (py(N)+py(1))*(px(N)*py(1) - px(1)*py(N)); + +pt = [sx sy]/6/polygonArea(px, py); \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPolygon.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPolygon.m new file mode 100644 index 0000000..24255a0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/steinerPolygon.m @@ -0,0 +1,28 @@ +function nodes = steinerPolygon(points) +%STEINERPOLYGON Create a Steiner polygon from a set of vectors +% +% NODES = steinerPolygon(VECTORS); +% Builds the (convex) polygon which contains an edge for each one of the +% vectors given by VECTORS. +% +% Example +% n = steinerPolygon([1 0;0 1;1 1]); +% drawPolygon(n); +% +% See also +% polygons2d, drawPolygon +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2006-04-28 +% Copyright 2006 INRA - CEPIA Nantes - MIAJ (Jouy-en-Josas). + +nodes = [0 0]; +for i=1:length(points) + nodes = [nodes; nodes+repmat(points(i,:), [size(nodes, 1) 1])]; %#ok +end + +K = convhull(nodes(:,1), nodes(:,2)); +nodes = nodes(K, :); + \ No newline at end of file diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/subCurve.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/subCurve.m new file mode 100644 index 0000000..321e57f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polygons2d/subCurve.m @@ -0,0 +1,52 @@ +function res = subCurve(curve, P1, P2, varargin) +%SUBCURVE extract a portion of a curve +% +% CURVE2 = subCurve(CURVE, POS1, POS2) +% extract a subcurve by keeping only points located between indices POS1 +% and POS2. If POS1>POS2, function considers all points after POS1 and +% all points before POS2. +% +% CURVE2 = subCurve(CURVE, POS1, POS2, DIRECT) +% If DIRECT is false, curve points are taken in reverse order, from POS1 +% to POS2 with -1 increment, or from POS1 to 1, then from last point to +% POS2 index. If direct is true, behaviour corresponds to the first +% described case. +% +% Example +% C = circleAsPolygon([0 0 10], 120); +% C2 = subCurve(C, 30, 60); +% +% See also +% polygons2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-08-23, using Matlab 7.4.0.287 (R2007a) +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% deprecation warning +warning('geom2d:deprecated', ... + '''subCurve'' will be deprecated in a future release, please consider using ''polylineSubcurve'''); + +% check if curve is inverted +direct = true; +if ~isempty(varargin) + direct = varargin{1}; +end + +% process different cases +if direct + if P1 0 + varargout = {h}; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polyfit2.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polyfit2.m new file mode 100644 index 0000000..6608d49 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polyfit2.m @@ -0,0 +1,180 @@ +function coef = polyfit2(varargin) +%POLYFIT2 Polynomial approximation of a curve +% +% +% usage : +% P = POLYFIT2(X, Y, N) finds the coefficients of a polynomial P(X) of +% degree N that fits the data, P(X(I))~=Y(I), in a least-squares sense. +% +% P = POLYFIT2(Y, N) use default equal spacing between all values of Y +% array. +% +% P = POLYFIT2(..., COND) specify end conditions for interpolated +% polynom. COND is [M*1] array of values, M(0) is value of interpolated +% polynom for X(1), M(2) is value of first derivative at first point, and +% so on for each derivative degree of X. +% If COND is [M*2] array, first column gives conditions for first point, +% and second column gives conditions for second point. +% +% P = POLYFIT2(..., COND1, COND2) +% where COND1 and COND2 are column arrays, specify different end +% condition for each limit of the polynom domain. +% +% Example +% % defines a basis and a function to interpolate +% N = 50; % 50 points +% x = linspace(0, pi, N); % basis range from 0 to PI +% y = cos(x)+randn(1,N)*.2; % cosine plus gaussian noise +% figure; plot(x, y, '+'); % display result +% % Fit a degree 3 polynom, imposing to pass through end points [0 1] and +% % [PI -1]: +% p1 = polyfit2(x, y, 3, [1], [-1]); +% % Fit a degree 3 polynom, imposing to pass through end points [0 1] and +% % [PI -1], and imposing first derivative equals to zero at end points: +% p2 = polyfit2(x, y, 3, [1;0], [-1;0]); +% % display the different approximations +% hold on; +% plot(x, polyval(p1, x), 'g'); +% plot(x, polyval(p2, x), 'r'); +% +% +% See also : +% polyfit (matlab) +% +% ----- +% +% author : David Legland +% INRA - TPV URPOI - BIA IMASTE +% created the 30/04/2004. +% + +% HISTORY +% 05/01/2007 adapt to polynom bases others than [0...1] +% 08/01/2007 update doc accordingly +% 27/02/2007 code clean up + +%% Default values + +% boundary conditions +cond1 = []; +cond2 = []; + + +%% extract input arguments + +if length(varargin)>2 + t = varargin{1}; + x = varargin{2}; + N = varargin{3}; + + % extract end conditions + if length(varargin)==4 + % one input for both end conditions + var = varargin{4}; + if size(var, 2)==1 + % only first condition is specified + cond1 = var; + cond2 = []; + else + % two end conditions in a single array + cond1 = var(:,1); + cond2 = var(:,2); + end + elseif length(varargin)==5 + % both end conditions are given is separates inputs + cond1 = varargin{4}; + cond2 = varargin{5}; + end +elseif length(varargin)==2 + % extract curve values and interpolation order, and compute default + % parametrization. + x = varargin{1}; + t = 0:1/(length(x)-1):1; + N = varargin{2}; +else + error ('POLYFIT2 : needs at least 2 input arguments'); +end + + +%% Initializations + +% transform to column vectors +x= x(:); +t = t(:); + +% number of points +L = length(x); + +% start and end values of parametrisation +t0 = t(1); +t1 = t(end); + + +%% Initialize matrices for end conditions + +% For a solution vector 'x', the following relation must hold: +% Aeq * x == beq, +% with: +% Aeq Matrix M*N +% beq column vector with length M +% The coefficients of the Aeq matrix are initialized as follow: +% First point and last point are considered successively. For each point, +% k-th condition is the value of the (k-1)th derivative. This value is +% computed using relation of the form: +% value = sum_i ( fact(i) * t_j^pow(i) ) +% with: +% i indice of the (i-1) derivative. +% fact row vector containing coefficient of each power of t, initialized +% with a row vector equals to [1 1 ... 1], and updated for each +% derivative by multiplying by corresponding power minus 1. +% pow row vector of the powers of each monome. It is represented by a +% row vector containing an increasing series of power, eventually +% completed with zeros for lower degrees (for the k-th derivative, +% the coefficients with power lower than k are not relevant). + +% Example for degree 5 polynom: +% iter deriv pow fact +% 1 0 [0 1 2 3 4 5] [1 1 1 1 1 1] +% 2 1 [0 0 1 2 3 4] [0 1 2 3 4 5] +% 3 2 [0 0 0 1 2 3] [0 0 1 2 3 4] +% 4 3 [0 0 0 0 1 2] [0 0 0 1 2 3] +% ... + +% Initialize empty matrices +Aeq = zeros(0, N+1); +beq = zeros(0, 1); + +% start condition initialisations +fact = ones(1, N+1); +for i=1:length(cond1) + pow = [zeros(1, i) 1:N+1-i]; + Aeq = [Aeq ; fact.*power(t0, pow)]; + beq = [beq; cond1(i)]; + fact = fact.*pow; +end + +% end condition initialisations +fact = ones(1, N+1); +for i=1:length(cond2) + pow = [zeros(1, i) 1:N+1-i]; + Aeq = [Aeq ; fact.*power(t1, pow)]; + beq = [beq; cond2(i)]; + fact = fact.*pow; +end + +%% Main algorithm + +% main matrix of the problem, size L*(deg+1) +X = ones(L, N+1); +for i=1:N + X(:, i+1) = power(t, i); +end + +% compute interpolation +coef = lsqlin(X, x, zeros(1, N+1), 1, Aeq, beq); + + +%% format output + +% format output to a format similar to polyfit +coef = coef(end:-1:1)'; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCentroid.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCentroid.m new file mode 100644 index 0000000..bb92aea --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCentroid.m @@ -0,0 +1,83 @@ +function centroid = polynomialCurveCentroid(tBounds, varargin) +%POLYNOMIALCURVECENTROID Compute the centroid of a polynomial curve +% +% C = polynomialCurveCentroid(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a 1x2 row vector, containing the bounds of the parametrization +% variable: T = [T0 T1], with T taking all values between T0 and T1. +% C contains coordinate of the polynomila curve centroid. +% +% C = polynomialCurveCentroid(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% C = polynomialCurveCentroid(..., TOL) +% TOL is the tolerance fo computation (absolute). +% +% Example +% polynomialCurveCentroid +% +% See also +% polynomialCurves2d, polynomialCurveLength +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@gignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% Extract input parameters + +% parametrization bounds +t0 = tBounds(1); +t1 = tBounds(end); + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; + varargin(1) = []; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; + varargin(1:2)=[]; +else + xCoef = var(1,:); + yCoef = var(2,:); + varargin(1)=[]; +end + +% tolerance +tol = 1e-6; +if ~isempty(varargin) + tol = varargin{1}; +end + +%% compute length by numerical integration + +% compute derivative of the polynomial +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% convert to polyval format +dx = dx(end:-1:1); +dy = dy(end:-1:1); + +cx = xCoef(end:-1:1); +cy = yCoef(end:-1:1); + +% compute curve length by integrating the Jacobian +L = quad(@(t)sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); + +% compute first coordinate of centroid +xc = quad(@(t)polyval(cx, t).*sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); + +% compute first coordinate of centroid +yc = quad(@(t)polyval(cy, t).*sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); + +% divide result of integration by total length of the curve +centroid = [xc yc]/L; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvature.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvature.m new file mode 100644 index 0000000..4f6b6fd --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvature.m @@ -0,0 +1,67 @@ +function kappa = polynomialCurveCurvature(t, varargin) +%POLYNOMIALCURVECURVATURE Compute the local curvature of a polynomial curve +% +% KAPPA = polynomialCurveCurvature(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% KAPPA is the local curvature of the polynomial curve, computed for +% position T. If T is a vector, KAPPA has the same length as T. +% +% KAPPA = polynomialCurveCurvature(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% Example +% polynomialCurveCurvature +% +% See also +% polynomialCurves2d, polynomialCurveLength, polynomialCurveDerivative +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@nantes.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +%% Extract input parameters + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; +else + xCoef = var(1,:); + yCoef = var(2,:); +end + + +%% compute derivative + +% compute first derivatives of the polynomials +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% compute second derivatives +sx = polynomialDerivate(dx); +sy = polynomialDerivate(dy); + +% convert to polyval convention +dx = dx(end:-1:1); +dy = dy(end:-1:1); +sx = sx(end:-1:1); +sy = sy(end:-1:1); + +% compute local first and second derivatives +xp = polyval(dx, t); +yp = polyval(dy, t); +xs = polyval(sx, t); +ys = polyval(sy, t); + +% compute local curvature of polynomial curve +kappa = (xp.*ys - xs.*yp) ./ power(xp.*xp + yp.*yp, 3/2); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvatures.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvatures.m new file mode 100644 index 0000000..f40a5f0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveCurvatures.m @@ -0,0 +1,133 @@ +function varargout = polynomialCurveCurvatures(t, varargin) +%POLYNOMIALCURVECURVATURES Compute curvatures of a polynomial revolution surface +% +% KAPPAS = polynomialCurveCurvatures(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a column vector, containing the parametrization values for which +% curvatures have to be computed. +% KAPPAS is a matrix with 2 columns and as many rows as T, containing the +% 2 main curvatures for each specified T. +% Curvatures are computed by assuming the curve to be rotated around the +% vertical axis (from point (0,0), in direction (1,0)). +% +% KAPPAS = polynomialCurveCurvatures(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% [KAPPA1 KAPPA2] = polynomialCurveCurvatures(...) +% return the 2 main curvatures in separate arrays. +% +% ... = polynomialCurveCurvatures(..., AXIS) +% Specify the revolution axis. By default, revolution axis is the +% vertical axis, going through point (0,0) and having direction vector +% given by (0,1). Another axis of revolution can be specified in format: +% AXIS = [x0 y0 dx dy]. +% +% +% See also +% polynomialCurves2d, polynomialCurveCurvature +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% HISTORY +% 28/02/2007 fix bug for the sign of the second curvature... +% 12/03/2007 base on vertical revolution axis, and adapt to manage any +% revolution axis + + +%% Extract input parameters + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + % coefficients are given in a cell array + xCoef = var{1}; + yCoef = var{2}; + varargin(1)=[]; + +elseif size(var, 1) == 1 + % coefficients are given as two numeric vectors + xCoef = varargin{1}; + yCoef = varargin{2}; + varargin(1:2)=[]; + +else + % coefficients are given as a 2-by-N numeric array + xCoef = var(1,:); + yCoef = var(2,:); + varargin(1)=[]; +end + +% revolution axis is the 2D vertical axis by default +axis = [0 0 0 1]; +if ~isempty(varargin) + axis = varargin{1}; +end + + +%% Coordinate of curve points + +% compute coordinates in original base +pts = polynomialCurvePoint(t, xCoef, yCoef); + +% compute the matrix which transform points such that axis becomes the +% vertical axis +angle = lineAngle(axis); +trans = createRotation(axis(1:2), pi/2 - angle); + +% transform points +pts = transformPoint(pts, trans); + + +%% compute first derivatives + +% compute first derivatives of the polynomials +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% compute local first derivatives +xp = polyval(dx(end:-1:1), t); +yp = polyval(dy(end:-1:1), t); + +% transform vectors of first derivatives +vect = transformVector([xp yp], trans); +xp = vect(:,1); +yp = vect(:,2); + + +%% compute second derivatives + +% compute second derivatives +sx = polynomialDerivate(dx); +sy = polynomialDerivate(dy); + +% compute local second derivatives +xs = polyval(sx(end:-1:1), t); +ys = polyval(sy(end:-1:1), t); + +% transform vectors of first derivatives +vect = transformVector([xs ys], trans); +xs = vect(:,1); +ys = vect(:,2); + + +%% computation of curvatures + +% compute local curvatures of polynomial curve +kappa1 = sign(pts(:,1)) .* (xs.*yp - xp.*ys) ./ power(xp.*xp + yp.*yp, 3/2); +kappa2 = -yp ./ abs(pts(:,1)) ./ sqrt(xp.*xp + yp.*yp); + + +%% Format output arguments + +if nargout < 2 + varargout{1} = [kappa1 kappa2]; +else + varargout{1} = kappa1; + varargout{2} = kappa2; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveDerivative.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveDerivative.m new file mode 100644 index 0000000..6f27492 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveDerivative.m @@ -0,0 +1,57 @@ +function v = polynomialCurveDerivative(t, varargin) +%POLYNOMIALCURVEDERIVATIVE Compute derivative vector of a polynomial curve +% +% VECT = polynomialCurveLength(T, XCOEF, YCOEF); +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% VECT is a 1x2 array containing direction of derivative of polynomial +% curve, computed for position T. If T is a vector, VECT has as many rows +% as the length of T. +% +% VECT = polynomialCurveLength(T, COEFS); +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% Example +% polynomialCurveDerivative +% +% See also +% polynomialCurves2d, polynomialCurveNormal, polynomialCurvePoint, +% polynomialCurveCurvature +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +%% Extract input parameters + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; +else + xCoef = var(1,:); + yCoef = var(2,:); +end + + +%% compute derivative + +% compute derivative of the polynomial +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% convert to polyval convention +dx = dx(end:-1:1); +dy = dy(end:-1:1); + +% numerical integration of the Jacobian of parametrized curve +v = [polyval(dx, t) polyval(dy, t)]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveFit.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveFit.m new file mode 100644 index 0000000..131985d --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveFit.m @@ -0,0 +1,240 @@ +function varargout = polynomialCurveFit(t, varargin) +%POLYNOMIALCURVEFIT Fit a polynomial curve to a series of points +% +% [XC YC] = polynomialCurveFit(T, XT, YT, ORDER) +% T is a Nx1 vector +% XT and YT are coordinate for each parameter value (column vectors) +% ORDER is the degree of the polynomial used for interpolation +% XC and YC are polynomial coefficients, given in ORDER+1 row vectors, +% starting from degree 0 and up to degree ORDER. +% +% [XC YC] = polynomialCurveFit(T, POINTS, ORDER); +% specifies coordinate of points in a Nx2 array. +% +% Example: +% N = 50; +% t = linspace(0, 3*pi/4, N)'; +% xp = cos(t); yp = sin(t); +% [xc yc] = polynomialCurveFit(t, xp, yp, 3); +% curve = polynomialCurvePoint(t, xc, yc); +% drawCurve(curve); +% +% +% [XC YC] = polynomialCurveFit(..., T_I, COND_I); +% Impose some specific conditions. T_I is a value of the parametrization +% variable. COND_I is a cell array, with 2 columns, and as many rows as +% the derivatives specified for the given T_I. Format for COND_I is: +% COND_I = {X_I, Y_I; X_I', Y_I'; X_I", Y_I"; ...}; +% with X_I and Y_I being the imposed coordinate at position T_I, X_I' and +% Y_I' being the imposed first derivatives, X_I" and Y_I" the imposed +% second derivatives, and so on... +% To specify a derivative without specifying derivative with lower +% degree, value of lower derivative can be let empty, using '[]' +% +% Example: +% % defines a curve (circle arc) with small perturbations +% N = 100; +% t = linspace(0, 3*pi/4, N)'; +% xp = cos(t)+.1*randn(size(t)); yp = sin(t)+.1*randn(size(t)); +% +% % plot the points +% figure(1); clf; hold on; +% axis([-1.2 1.2 -.2 1.2]); axis equal; +% drawPoint(xp, yp); +% +% % fit without knowledge on bounds +% [xc0 yc0] = polynomialCurveFit(t, xp, yp, 5); +% curve0 = polynomialCurvePoint(t, xc0, yc0); +% drawCurve(curve0); +% +% % fit by imposing coordinate on first point +% [xc1 yc1] = polynomialCurveFit(t, xp, yp, 5, 0, {1, 0}); +% curve1 = polynomialCurvePoint(t, xc1, yc1); +% drawCurve(curve1, 'r'); +% +% % fit by imposing coordinate (1,0) and derivative (0,1) on first point +% [xc2 yc2] = polynomialCurveFit(t, xp, yp, 5, 0, {1, 0;0 1}); +% curve2 = polynomialCurvePoint(t, xc2, yc2); +% drawCurve(curve2, 'g'); +% +% % fit by imposing several conditions on various points +% [xc3 yc3] = polynomialCurveFit(t, xp, yp, 5, ... +% 0, {1, 0;0 1}, ... % coord and first derivative of first point +% 3*pi/4, {-sqrt(2)/2, sqrt(2)/2}, ... % coord of last point +% pi/2, {[], [];-1, 0}); % derivative of point on the top of arc +% curve3 = polynomialCurvePoint(t, xc3, yc3); +% drawCurve(curve3, 'k'); +% +% Requires the optimization Toolbox. +% +% +% Examples: +% polynomialCurveFit +% +% See also +% polynomialCurves2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-27 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +%% extract input arguments + +% extract curve coordinate +var = varargin{1}; +if min(size(var))==1 + % curve given as separate arguments + xt = varargin{1}; + yt = varargin{2}; + varargin(1:2)=[]; +else + % curve coordinate bundled in a matrix + if size(var, 1)1 + Dx = var(1); + Dy = var(2); +else + Dx = var; + Dy = var; +end +varargin(1)=[]; + + +%% Initialize local conditions + +% For a solution vector 'x', the following relation must hold: +% Aeq * x == beq, +% with: +% Aeq Matrix M*N +% beq column vector with length M +% The coefficients of the Aeq matrix are initialized as follow: +% First point and last point are considered successively. For each point, +% k-th condition is the value of the (k-1)th derivative. This value is +% computed using relation of the form: +% value = sum_i ( fact(i) * t_j^pow(i) ) +% with: +% i indice of the (i-1) derivative. +% fact row vector containing coefficient of each power of t, initialized +% with a row vector equals to [1 1 ... 1], and updated for each +% derivative by multiplying by corresponding power minus 1. +% pow row vector of the powers of each monome. It is represented by a +% row vector containing an increasing series of power, eventually +% completed with zeros for lower degrees (for the k-th derivative, +% the coefficients with power lower than k are not relevant). + +% Example for degree 5 polynom: +% iter deriv pow fact +% 1 0 [0 1 2 3 4 5] [1 1 1 1 1 1] +% 2 1 [0 0 1 2 3 4] [0 1 2 3 4 5] +% 3 2 [0 0 0 1 2 3] [0 0 1 2 3 4] +% 4 3 [0 0 0 0 1 2] [0 0 0 1 2 3] +% ... +% The process is repeated for coordinate x and for coordinate y. + +% Initialize empty matrices +Aeqx = zeros(0, Dx+1); +beqx = zeros(0, 1); +Aeqy = zeros(0, Dy+1); +beqy = zeros(0, 1); + +% Process local conditions +while ~isempty(varargin) + if length(varargin)==1 + warning('MatGeom:PolynomialCurveFit:ArgumentNumber', ... + 'Wrong number of arguments in polynomialCurvefit'); + end + + % extract parameter t, and cell array of local conditions + ti = varargin{1}; + cond = varargin{2}; + + % factors for coefficients of each polynomial. At the beginning, they + % all equal 1. With successive derivatives, their value increase by the + % corresponding powers. + factX = ones(1, Dx+1); + factY = ones(1, Dy+1); + + % start condition initialisations + for i = 1:size(cond, 1) + % degrees of each polynomial + powX = [zeros(1, i) 1:Dx+1-i]; + powY = [zeros(1, i) 1:Dy+1-i]; + + % update conditions for x coordinate + if ~isempty(cond{i,1}) + Aeqx = [Aeqx ; factY.*power(ti, powX)]; %#ok + beqx = [beqx; cond{i,1}]; %#ok + end + + % update conditions for y coordinate + if ~isempty(cond{i,2}) + Aeqy = [Aeqy ; factY.*power(ti, powY)]; %#ok + beqy = [beqy; cond{i,2}]; %#ok + end + + % update polynomial degrees for next derivative + factX = factX.*powX; + factY = factY.*powY; + end + + varargin(1:2)=[]; +end + + +%% Initialisations + +% ensure column vectors +t = t(:); +xt = xt(:); +yt = yt(:); + +% number of points to fit +L = length(t); + + +%% Compute coefficients of each polynomial + +% avoid optimization warnings +warning('off', 'optim:lsqlin:LinConstraints'); + +% options to turn display off +options = optimset('display', 'off'); + +% main matrix for x coordinate, size L*(degX+1) +T = ones(L, Dx+1); +for i = 1:Dx + T(:, i+1) = power(t, i); +end + +% compute interpolation +xc = lsqlin(T, xt, zeros(1, Dx+1), 1, Aeqx, beqx, [], [], [], options)'; + +% main matrix for y coordinate, size L*(degY+1) +T = ones(L, Dy+1); +for i = 1:Dy + T(:, i+1) = power(t, i); +end + +% compute interpolation +yc = lsqlin(T, yt, zeros(1, Dy+1), 1, Aeqy, beqy, [], [], [], options)'; + + +%% Format output arguments +if nargout <= 1 + varargout{1} = {xc, yc}; +else + varargout{1} = xc; + varargout{2} = yc; +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveLength.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveLength.m new file mode 100644 index 0000000..ef6cf6f --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveLength.m @@ -0,0 +1,69 @@ +function L = polynomialCurveLength(tBounds, varargin) +%POLYNOMIALCURVELENGTH Compute the length of a polynomial curve +% +% LENGTH = polynomialCurveLength(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a 1x2 row vector, containing the bounds of the parametrization +% variable: T = [T0 T1], with T taking all values between T0 and T1. +% +% LENGTH = polynomialCurveLength(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% LENGTH = polynomialCurveLength(..., TOL) +% TOL is the tolerance fo computation (absolute). +% +% Example +% polynomialCurveLength +% +% See also +% polynomialCurves2d, polynomialCurveCentroid +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +%% Extract input parameters + +% parametrization bounds +t0 = tBounds(1); +t1 = tBounds(end); + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; + varargin(1) = []; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; + varargin(1:2)=[]; +else + xCoef = var(1,:); + yCoef = var(2,:); + varargin(1)=[]; +end + +% tolerance +tol = 1e-6; +if ~isempty(varargin) + tol = varargin{1}; +end + +%% compute length by numerical integration + +% compute derivative of the polynomial +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% convert to polyval format +dx = dx(end:-1:1); +dy = dy(end:-1:1); + +% numerical integration of the Jacobian of parametrized curve +L = quad(@(t)sqrt(polyval(dx, t).^2+polyval(dy, t).^2), t0, t1, tol); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveNormal.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveNormal.m new file mode 100644 index 0000000..f4d9c0a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveNormal.m @@ -0,0 +1,41 @@ +function v = polynomialCurveNormal(t, varargin) +%POLYNOMIALCURVENORMAL Compute the normal of a polynomial curve +% +% N = polynomialCurveNormal(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a 1x2 row vector, containing the bounds of the parametrization +% variable: T = [T0 T1], with T taking all values between T0 and T1. +% T can also be a larger vector, in this case only bounds are kept. +% N is a 1x2 row vector, containing direction of curve normal in T. +% If T is column vector, the result is a matrix with 2 columns containing +% normal vector for each position. +% +% The normal is oriented such that oriented angle from derivative +% vector to normal vector equals PI/2. The normal points to the 'left' +% when travelling along the curve. + +% N = polynomialCurveNormal(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% N = polynomialCurveNormal(..., TOL) +% TOL is the tolerance fo computation (absolute). +% +% Example +% polynomialCurveNormal +% +% See also +% polynomialCurves2d, polynomialCurveDerivative +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% extract the derivative +v = polynomialCurveDerivative(t, varargin{:}); + +% rotate by PI/2 Counter clockwise +v = [-v(:,2) v(:,1)]; diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePoint.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePoint.m new file mode 100644 index 0000000..2be8633 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePoint.m @@ -0,0 +1,53 @@ +function point = polynomialCurvePoint(t, varargin) +%POLYNOMIALCURVEPOINT Compute point corresponding to a position +% +% POINT = polynomialCurvePoint(T, XCOEF, YCOEF) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a either a scalar, or a column vector, containing values of the +% parametrization variable. +% POINT is a 1x2 array containing coordinate of point corresponding to +% position given by T. If T is a vector, POINT has as many rows as T. +% +% POINT = polynomialCurvePoint(T, COEFS) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% Example +% polynomialCurvePoint +% +% See also +% polynomialCurves2d, polynomialCurveLength +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +%% Extract input parameters + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; +else + xCoef = var(1,:); + yCoef = var(2,:); +end + + +%% compute length by numerical integration + +% convert polynomial coefficients to polyval convention +cx = xCoef(end:-1:1); +cy = yCoef(end:-1:1); + +% numerical integration of the Jacobian of parametrized curve +point = [polyval(cx, t) polyval(cy, t)]; + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePosition.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePosition.m new file mode 100644 index 0000000..083623a --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurvePosition.m @@ -0,0 +1,105 @@ +function pos = polynomialCurvePosition(tBounds, varargin) +%POLYNOMIALCURVEPOSITION Compute position on a curve for a given length +% +% POS = polynomialCurvePosition(T, XCOEF, YCOEF, L) +% XCOEF and YCOEF are row vectors of coefficients, in the form: +% [a0 a1 a2 ... an] +% T is a 1x2 row vector, containing the bounds of the parametrization +% variable: T = [T0 T1], with T taking all values between T0 and T1. +% L is the geodesic length corresponding to the searched position. +% POS is a scalar, verifying relation: +% L = polynomialCurveLength([T(1) POS], XCOEF, YCOEF); +% +% POS = polynomialCurvePosition(T, COEFS, L) +% COEFS is either a 2xN matrix (one row for the coefficients of each +% coordinate), or a cell array. +% +% POS = polynomialCurvePosition(..., TOL) +% TOL is the tolerance fo computation (absolute). +% +% See also +% polynomialCurves2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-26 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% parametrization bounds +t0 = tBounds(1); +t1 = tBounds(end); + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; + varargin(1) = []; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; + varargin(1:2)=[]; +else + xCoef = var(1,:); + yCoef = var(2,:); + varargin(1)=[]; +end + +% geodesic length corresponding to searched position +L = varargin{1}; +varargin(1)=[]; + +% tolerance +tol = 1e-6; +if ~isempty(varargin) + tol = varargin{1}; +end + +% compute derivative of the polynomial +dx = polynomialDerivate(xCoef); +dy = polynomialDerivate(yCoef); + +% convert to format of polyval +dx = dx(end:-1:1); +dy = dy(end:-1:1); + +% avoid warning for t=0 +warning off 'MATLAB:quad:MinStepSize' + +% set up precision for t +options = optimset('TolX', tol); + +% starting point, located in the middle of the paramtrization domain +ts = (t0+t1)/2; + +% compute parameter corresponding to geodesic position by solving g(t)-tg=0 +pos = fzero(@(t)funCurveLength(t0, t, dx, dy, tol)- L, ts, options); + + + +function res = funCurveLength(t0, t1, c1, c2, varargin) +%FUNCURVELENGTH return the length of polynomial curve arc +% output = funCurveLength(t0, t1, c1, c2) +% t0 and t1 are the limits of the integral +% c1 and c2 are derivative polynoms of each coordinate parametrization, +% given from greater order to lower order (polyval convention). +% c1 = [an a_n-1 ... a2 a1 a0]. +% +% Example +% funCurveLength(0, 1, C2, C2); +% funCurveLength(0, 1, C2, C2, RES); +% RES is the resolution (ex: 1e-6). +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-14 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +res = quad(@(t)sqrt(polyval(c1, t).^2+polyval(c2, t).^2), t0, t1, varargin{:}); + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveProjection.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveProjection.m new file mode 100644 index 0000000..25ae9e8 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveProjection.m @@ -0,0 +1,63 @@ +function pos = polynomialCurveProjection(tBounds, varargin) +%POLYNOMIALCURVEPROJECTION Projection of a point on a polynomial curve +% +% T = polynomialCurveProjection([T0 T1], XCOEFS, YCOEFS, POINT); +% Computes the position of POINT on the polynomial curve, such that +% polynomialCurvePoint([T0 T1], XCOEFS, YCOEFS) is the same as POINT. +% +% See also +% polynomialCurves2d, polynomialCurvePoint +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-12-21 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% parametrization bounds +t0 = tBounds(1); +t1 = tBounds(end); + +% polynomial coefficients for each coordinate +var = varargin{1}; +if iscell(var) + xCoef = var{1}; + yCoef = var{2}; + varargin(1) = []; +elseif size(var, 1)==1 + xCoef = varargin{1}; + yCoef = varargin{2}; + varargin(1:2)=[]; +else + xCoef = var(1,:); + yCoef = var(2,:); + varargin(1)=[]; +end + + +% the point to project +point = varargin{1}; +varargin(1)=[]; + +% tolerance +tol = 1e-6; +if ~isempty(varargin) + tol = varargin{1}; +end + +% update coefficient according to point position +xCoef(1) = xCoef(1) - point(1); +yCoef(1) = yCoef(1) - point(2); + +% convert to format of polyval +c1 = xCoef(end:-1:1); +c2 = yCoef(end:-1:1); + +% avoid warning for t=0 +warning off 'MATLAB:quad:MinStepSize' + +% set up precision for t +options = optimset('TolX', tol^2); + +% compute minimisation of the distance function +pos = fminbnd(@(t) polyval(c1, t).^2+polyval(c2, t).^2, t0, t1, options); diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveSetFit.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveSetFit.m new file mode 100644 index 0000000..8470525 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialCurveSetFit.m @@ -0,0 +1,217 @@ +function [coefs lblBranches] = polynomialCurveSetFit(seg, varargin) +%POLYNOMIALCURVESETFIT Fit a set of polynomial curves to a segmented image +% +% COEFS = polynomialCurveSetFit(IMG); +% COEFS = polynomialCurveSetFit(IMG, DEG); +% Result is a cell array of matrices. Each matrix is DEG+1-by-2, and +% contains coefficients of polynomial curve for each coordinate. +% IMG is first binarised, then skeletonized. Each cure +% +% [COEFS LBL] = polynomialCurveSetFit(...); +% also returns an image of labels for the segmented curves. The max label +% is the number of curves, and the length of COEFS. +% +% Requires the toolboxes: +% - Optimization +% - Image Processing +% +% Example +% polynomialCurveSetFit +% +% See also +% polynomialCurves2d, polynomialCurveFit +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-03-21 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + +% default degree for curves +deg = 2; +if ~isempty(varargin) + deg = varargin{1}; +end + + +% ajoute un contour +seg([1 end], :) = 1; +seg(:, [1 end]) = 1; + +% skeletise le segmentat +seg = bwmorph(seg, 'shrink', Inf); + +% compute image of multiple points (intersections between curves) +imgNodes = imfilter(double(seg), ones([3 3])) .* seg > 3; + +% compute coordinate of nodes, as c entroids of the multiple points +lblNodes = bwlabel(imgNodes, 4); +struct = regionprops(lblNodes, 'Centroid'); +nodes = zeros(length(struct), 2); +for i=1:length(struct) + nodes(i, 1:2) = struct(i).Centroid; +end + +% enleve les bords de l'image +seg([1 end], :) = 0; +seg(:, [1 end]) = 0; + +% Isoles les branches +imgBranches = seg & ~imgNodes; +lblBranches = bwlabel(imgBranches, 8); + +% % donne une couleur a chaque branche, et affiche +% map = colorcube(max(lblBranches(:))+1); +% rgbBranches = label2rgb(lblBranches, map, 'w', 'shuffle'); +% imshow(rgbBranches); + +% number of curves +nBranches = max(lblBranches(:)); + +% allocate memory +coefs = cell(nBranches, 1); + + +% For each curve, find interpolated polynomial curve +for i = 1:nBranches + disp(i); + + % extract points corresponding to current curve + imgBranch = lblBranches == i; + points = chainPixels(imgBranch); + + % check number of points is sufficient + if size(points, 1) < max(deg+1-2, 2) + % find labels of nodes + inds = unique(lblNodes(imdilate(imgBranch, ones(3,3)))); + inds = inds(inds ~= 0); + + if length(inds) < 2 + disp(['Could not find extremities of branch number ' num2str(i)]); + continue; + end + + % consider extremity nodes + node0 = nodes(inds(1), :); + node1 = nodes(inds(2), :); + + % use only a linear approximation + xc = zeros(1, deg+1); + yc = zeros(1, deg+1); + xc(1) = node0(1); + yc(1) = node0(2); + xc(2) = node1(1)-node0(1); + yc(2) = node1(2)-node0(2); + + % assigne au tableau de courbes + coefs{i} = [xc;yc]; + + % next branch + continue; + end + + % find nodes closest to first and last points of the current curve + [dist, ind0] = minDistancePoints(points(1, :), nodes); %#ok<*ASGLU> + [dist, ind1] = minDistancePoints(points(end, :), nodes); + + % add nodes to the curve. + points = [nodes(ind0,:); points; nodes(ind1,:)]; %#ok + + % parametrization of the polyline + t = parametrize(points); + t = t / max(t); + + % fit a polynomial curve to the set of points + [xc yc] = polynomialCurveFit(... + t, points, deg, ... + 0, {points(1,1), points(1,2)},... + 1, {points(end,1), points(end,2)}); + + % stores result + coefs{i} = [xc;yc]; +end + + + + +function points = chainPixels(img, varargin) +%CHAINPIXELS return the list of points which constitute a curve on image +% output = chainPixels(input) +% +% Example +% chainPixels +% +% See also +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-03-21 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +conn = 8; +if ~isempty(varargin) + conn = varargin{1}; +end + +% matrice de voisinage +if conn == 4 + f = [0 1 0;1 1 1;0 1 0]; +elseif conn == 8 + f = ones([3 3]); +end + +% find extremity points +nb = imfilter(double(img), f) .* img; +imgEnding = nb == 2 | nb == 1; +[yi xi] = find(imgEnding); + +% extract coordinates of points +[y x] = find(img); + +% index of first point +if isempty(xi) + % take arbitrary point + ind = 1; +else + ind = find(x==xi(1) & y==yi(1)); +end + +% allocate memory +points = zeros(length(x), 2); + +if conn == 8 + for i = 1:size(points, 1) + % avoid multiple neighbors (can happen in loops) + ind = ind(1); + + % add current point to chained curve + points(i,:) = [x(ind) y(ind)]; + + % remove processed coordinate + x(ind) = []; + y(ind) = []; + + % find next candidate + ind = find(abs(x-points(i,1))<=1 & abs(y-points(i,2))<=1); + end + +else + for i = 1:size(points, 1) + % avoid multiple neighbors (can happen in loops) + ind = ind(1); + + % add current point to chained curve + points(i,:) = [x(ind) y(ind)]; + + % remove processed coordinate + x(ind) = []; + y(ind) = []; + + % find next candidate + ind = find(abs(x-points(i,1)) + abs(y-points(i,2)) <=1 ); + end +end diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialDerivate.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialDerivate.m new file mode 100644 index 0000000..506ae17 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/polynomialCurves2d/polynomialDerivate.m @@ -0,0 +1,32 @@ +function deriv = polynomialDerivate(poly) +%POLYNOMIALDERIVATE Derivate a polynomial +% +% DERIV = polynomialDERIVATE(POLY) +% POLY is a row vector of [n+1] coefficients, in the form: +% [a0 a1 a2 ... an] +% DERIV has the same format, with length n: +% [a1 a2*2 ... an*n] +% +% +% Example +% T = polynomialDerivate([2 3 4]) +% returns: +% T = [3 8] +% +% See also +% polynomialCurves2d +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2007-02-23 +% Copyright 2007 INRA - BIA PV Nantes - MIAJ Jouy-en-Josas. + + +% create the derivation matrices +matrix = diag(0:length(poly)-1); + +% compute coefficients of first derivative polynomials +deriv = circshift(poly*matrix, [0 -1]); + + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/matGeom/setupMatGeom.m b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/setupMatGeom.m new file mode 100644 index 0000000..1465169 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/matGeom/setupMatGeom.m @@ -0,0 +1,36 @@ +function setupMatGeom(varargin) +%SETUPMATGEOM Add the different directories of MatGeom to the path +% +% Usage: +% setupMatGeom; +% +% Example +% setupMatGeom; +% +% +% +% ------ +% Author: David Legland +% e-mail: david.legland@grignon.inra.fr +% Created: 2011-01-11, using Matlab 7.9.0.529 (R2009b) +% Copyright 2011 INRA - Cepia Software Platform. + +% extract library path +fileName = mfilename('fullpath'); +libDir = fileparts(fileName); + +moduleNames = {... + 'geom2d', 'polygons2d', 'graphs', ... + 'polynomialCurves2d', ... + 'geom3d', 'meshes3d'}; + +disp('Installing MatGeom Library'); + +% add all library modules +for i = 1:length(moduleNames) + name = moduleNames{i}; + fprintf('Adding module: %-20s', name); + addpath(fullfile(libDir, name)); + disp(' (ok)'); +end + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/minBoundingBox.m b/algorithms/Karagiorgou_tracebundle/libraries/minBoundingBox.m new file mode 100644 index 0000000..f8ca299 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/minBoundingBox.m @@ -0,0 +1,63 @@ +function bb = minBoundingBox(X) +% compute the minimum bounding box of a set of 2D points +% Use: boundingBox = minBoundingBox(point_matrix) +% +% Input: 2xn matrix containing the [x,y] coordinates of n points +% *** there must be at least 3 points which are not collinear +% output: 2x4 matrix containing the coordinates of the bounding box corners +% +% Example : generate a random set of point in a randomly rotated rectangle +% n = 50000; +% t = pi*rand(1); +% X = [cos(t) -sin(t) ; sin(t) cos(t)]*[7 0; 0 2]*rand(2,n); +% X = [X 20*(rand(2,1)-0.5)]; % add an outlier +% +% tic +% c = minBoundingBox(X); +% toc +% +% figure(42); +% hold off, plot(X(1,:),X(2,:),'.') +% hold on, plot(c(1,[1:end 1]),c(2,[1:end 1]),'r') +% axis equal + +% compute the convex hull (CH is a 2*k matrix subset of X) +k = convhull(X(1,:),X(2,:)); +CH = X(:,k); + +% compute the angle to test, which are the angle of the CH edges as: +% "one side of the bounding box contains an edge of the convex hull" +E = diff(CH,1,2); % CH edges +T = atan2(E(2,:),E(1,:)); % angle of CH edges (used for rotation) +T = unique(mod(T,pi/2)); % reduced to the unique set of first quadrant angles + +% create rotation matrix which contains +% the 2x2 rotation matrices for *all* angles in T +% R is a 2n*2 matrix +R = cos( reshape(repmat(T,2,2),2*length(T),2) ... % duplicate angles in T + + repmat([0 -pi ; pi 0]/2,length(T),1)); % shift angle to convert sine in cosine + +% rotate CH by all angles +RCH = R*CH; + +% compute border size [w1;h1;w2;h2;....;wn;hn] +% and area of bounding box for all possible edges +bsize = max(RCH,[],2) - min(RCH,[],2); +area = prod(reshape(bsize,2,length(bsize)/2)); + +% find minimal area, thus the index of the angle in T +[a,i] = min(area); + +% compute the bound (min and max) on the rotated frame +Rf = R(2*i+[-1 0],:); % rotated frame +bound = Rf * CH; % project CH on the rotated frame +bmin = min(bound,[],2); +bmax = max(bound,[],2); + +% compute the corner of the bounding box +Rf = Rf'; +bb(:,4) = bmax(1)*Rf(:,1) + bmin(2)*Rf(:,2); +bb(:,1) = bmin(1)*Rf(:,1) + bmin(2)*Rf(:,2); +bb(:,2) = bmin(1)*Rf(:,1) + bmax(2)*Rf(:,2); +bb(:,3) = bmax(1)*Rf(:,1) + bmax(2)*Rf(:,2); + diff --git a/algorithms/Karagiorgou_tracebundle/libraries/timestamp.m b/algorithms/Karagiorgou_tracebundle/libraries/timestamp.m new file mode 100644 index 0000000..536852c --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/libraries/timestamp.m @@ -0,0 +1,8 @@ +function ts = timestamp() +% +% TIMESTAMP returns the current system time. +% The output is type string and without EOL. +% (LB 9'02) + +TempTime=clock; +ts = ['(' num2str(TempTime(4),'%02.0f') ':' num2str(TempTime(5),'%02.0f') ':' num2str(TempTime(6),'%02.0f') ')']; diff --git a/algorithms/Karagiorgou_tracebundle/source/intersection_nodes_extraction.m b/algorithms/Karagiorgou_tracebundle/source/intersection_nodes_extraction.m new file mode 100644 index 0000000..81f97c0 --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/source/intersection_nodes_extraction.m @@ -0,0 +1,611 @@ +% TraceBundle map construction 1.0 +% Copyright 2013 Sophia Karagiorgou and Dieter Pfoser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +% +% ------------------------------------------------------------------------ +% +% This software is based on the following article(s). Please cite this +% article when using this code as part of a research publication: +% +% S. Karagiorgou and D. Pfoser. On Vehicle Tracking Data-Based Road Network Generation. +% In Proc. 20th ACM SIGSPATIAL GIS Conference, pp. 89-98, 2012. +% +% S. Karagiorgou and D. Pfoser. Segmentation-Based Road Network Construction. +% In Proc. 21th ACM SIGSPATIAL GIS Conference, pp. 470-473, 2013. +% +% ------------------------------------------------------------------------ +% +% Author: Sophia Karagiorgou (karagior@gmail.com) +% Filename: intersection_nodes_extraction.m + +clear; +currentFolder = pwd; +cd(currentFolder); +fprintf('Starting at %s\n', timestamp); + +filetype=1; +total=0; + +rz=[]; +angles=[]; +pts_ln=[]; +turn_pts=[]; +turn_seeds=[]; +centre_pts=[]; +clusterseeds=[]; +pts_to_inter=[]; +inter_to_cluster=[]; + +dist=40; %clustering distance range +angle_tol = 12.5; % angle tolerance after which a point is considered an interstion or turn + +if filetype==0 + [fnames,path]=uigetfile('*.dat','...select trajectory files!','MultiSelect','on'); + lgth=length(fnames); + n=ceil(sqrt(lgth)); + m=floor(lgth/n); +else + [fnames,path]=uigetfile('*.txt','...select trajectory files!','MultiSelect','on'); + lgth=1; + n=ceil(sqrt(lgth)); + m=floor(lgth/n); +end + +% --------------------------- +% loop over trajectory files +% --------------------------- +ss=0; +dd=0; + +rectr=[]; +my_corner_pts=[]; +mcnt=1; + + +fprintf('Looping over trajectories\n'); + + +for g=1:length(fnames(1,:)) + mat=load([path,fnames{1,g}]); + sm=size(mat); + len=sm(1); + + x=mat(:,1); + y=mat(:,2); + t=mat(:,3); + + subtr=1; + isubtr=1; + + %produce delta times for pt2-pt1, etc. + dt=t(2:len) - t(1:len-1); % times for pt2 and on + + %distance between points pt2-pt1, etc. + ds=sqrt((x(2:len)-x(1:len-1)).^2+(y(2:len)-y(1:len-1)).^2); + dv=(ds./dt)/1000*3600; + + dx=(x(2:len)-x(1:len-1)); % diff p2-p1, p3-p2, etc. + dy=(y(2:len)-y(1:len-1)); + + ta=dy./dx; %tan a + + rx=dx./dt; + ry=dy./dt; + + xy=[]; + imem=0; + jmem=0; + + for j=2:len-1 % starts for second point, but index for ta is len-1, hence the -1 + + if ds(j-1)>=1000 || (dt(j-1)>=45 && ds(j-1)>=1000) || (imem == g && abs(j-jmem)>1) + subtr=subtr+1; + isubtr=1; + end + + if j==len-1 + p1=[x(j-1),y(j-1)]; + p2=[x(j),y(j)]; + a1=rad2deg(angle2Points(p1,p2)); + + p1=[x(j),y(j)]; + p2=[x(j+1),y(j+1)]; + a2=rad2deg(angle2Points(p1,p2)); + + pts_ln=vertcat(pts_ln,[x(j) y(j) g j t(j) a1 a2 subtr isubtr]); + imem=g; + jmem=j; + + if ds(j)>=1000 || (dt(j)>=45 && ds(j)>=1000) + subtr=subtr+1; + isubtr=1; + pts_ln=vertcat(pts_ln,[x(j+1) y(j+1) g j+1 t(j+1) a2 -1 subtr isubtr]); + imem=g; + jmem=j+1; + else + isubtr=isubtr+1; + pts_ln=vertcat(pts_ln,[x(j+1) y(j+1) g j+1 t(j+1) a2 -1 subtr isubtr]); + imem=g; + jmem=j+1; + end + + rectr=vertcat(rectr,[x(j) y(j) g j t(j) x(j+1) y(j+1) g j+1 t(j+1) subtr isubtr]); + + elseif j==2 + + p1=[x(j-1),y(j-1)]; + p2=[x(j),y(j)]; + a1=rad2deg(angle2Points(p1,p2)); + + p1=[x(j),y(j)]; + p2=[x(j+1),y(j+1)]; + a2=rad2deg(angle2Points(p1,p2)); + + if ds(j-1)>=1000 || (dt(j-1)>=45 && ds(j-1)>=1000) + pts_ln=vertcat(pts_ln,[x(j-1) y(j-1) g j-1 t(j-1) -1 a1 subtr isubtr]); + subtr=subtr+1; + isubtr=1; + imem=g; + jmem=j-1; + else + pts_ln=vertcat(pts_ln,[x(j-1) y(j-1) g j-1 t(j-1) -1 a1 subtr isubtr]); + isubtr=isubtr+1; + imem=g; + jmem=j-1; + end + pts_ln=vertcat(pts_ln,[x(j) y(j) g j t(j) a1 a2 subtr isubtr]); + imem=g; + jmem=j; + + rectr=vertcat(rectr,[x(j-1) y(j-1) g j-1 t(j-1) x(j) y(j) g j t(j) subtr isubtr]); + else + p1=[x(j-1),y(j-1)]; + p2=[x(j),y(j)]; + a1=rad2deg(angle2Points(p1,p2)); + + p1=[x(j),y(j)]; + p2=[x(j+1),y(j+1)]; + a2=rad2deg(angle2Points(p1,p2)); + + pts_ln=vertcat(pts_ln,[x(j) y(j) g j t(j) a1 a2 subtr isubtr]); + imem=g; + jmem=j; + + rectr=vertcat(rectr,[x(j) y(j) g j t(j) x(j+1) y(j+1) g j+1 t(j+1) subtr isubtr]); + end + + xy=vertcat(xy,[x(j), y(j)]); + p1=[x(j-1),y(j-1)]; + p2=[x(j),y(j)]; + p3=p2; + p4=[x(j+1),y(j+1)]; + + angle = lines_angle(p1,p2,p3,p4); % angle difference between incoming and outgoing edge of pt + aangle = abs(angle); %absolute angle + + a1=rad2deg(angle2Points(p1,p2)); %incoming angle + a2=rad2deg(angle2Points(p3,p4)); %outgoing angle + + angles=vertcat(angles,[rad2deg(angle2Points(p1,p2)) angle]); + + if ((aangle >= angle_tol && aangle <= 180 - angle_tol) || ... + (aangle >= 180 + angle_tol && aangle <= 360 - angle_tol)) && ((dv(j)/dv(j-1)<=1) || dv(j) <= 40 && dv(j)>=1) + my_corner_pts=vertcat(my_corner_pts,[x(j) y(j) g j x(j-1) y(j-1) x(j+1) y(j+1) a1 a2 dt(j-1) dt(j) mcnt dv(j-1) dv(j) subtr isubtr]); + mcnt=mcnt+1; + end + isubtr=isubtr+1; + dd=dd+polylineLength(xy,'open'); + total=total+length(x); + end +end + +slk=[]; +vehicles=pts_ln(:,3); +vehicles=unique(vehicles,'rows'); +for g=1:length(vehicles) + tr=find(pts_ln(:,3)==vehicles(g)); + itr=unique(pts_ln(tr,8),'rows'); + + for k=1:length(itr) + tx=find(pts_ln(tr,8)==itr(k)); + if length(tx)<=1 + rh=find(my_corner_pts(:,3)==pts_ln(tr(tx),3) & my_corner_pts(:,16)==pts_ln(tr(tx),8) & my_corner_pts(:,17)==pts_ln(tr(tx),9)); + if ~isempty(rh) + my_corner_pts(rh,:)=[]; + end + else + xy=[pts_ln(tr(tx),1) pts_ln(tr(tx),2)]; + + for n=1:length(tx)-1 + xy=[pts_ln(tr(tx(n)),1) pts_ln(tr(tx(n)),2)]; + xy=vertcat(xy,[pts_ln(tr(tx(n+1)),1) pts_ln(tr(tx(n+1)),2)]); + mllk=[xy(1,1) xy(1,2) xy(2,1) xy(2,2) polylineLength(xy,'open')]; + + tllk=mllk; + rj=1000; + + if ~isempty(tllk) + while length(rj)~=0 + + rj=find(tllk(:,5)<=10); + ttllk=tllk(rj,:); + rj=find(tllk(:,5)>10); + for b=1:length(rj) + md=midPoint([[tllk(rj(b),1) tllk(rj(b),2)] [tllk(rj(b),3) tllk(rj(b),4)]]); + ttllk=vertcat(ttllk,[tllk(rj(b),1), tllk(rj(b),2),md(1,1),md(1,2), distancePoints([tllk(rj(b),1) tllk(rj(b),2)],[md(1,1) md(1,2)], 2)]); + ttllk=vertcat(ttllk,[md(1,1),md(1,2),tllk(rj(b),3), tllk(rj(b),4), distancePoints([md(1,1) md(1,2)],[tllk(rj(b),3) tllk(rj(b),4)], 2)]); + end + tllk=ttllk; + end + mllk=tllk; + slk=vertcat(slk,mllk); + end + end + end + end +end + +% ---------------------------------------------------------- +% finding cluster type of turn, range, cluster weight +% ---------------------------------------------------------- + +fprintf('Finding type of turns, cluster range and weight\n'); + +isim=[]; +idis=[]; +sim_angle=40; +for g=1:length(my_corner_pts(:,1)) + x1=my_corner_pts(g,1)+dist; + y1=my_corner_pts(g,2)+dist; + x2=my_corner_pts(g,1)+dist; + y2=my_corner_pts(g,2)-dist; + x3=my_corner_pts(g,1)-dist; + y3=my_corner_pts(g,2)+dist; + x4=my_corner_pts(g,1)-dist; + y4=my_corner_pts(g,2)-dist; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + p1=0; + p2=0; + p3=0; + p4=0; + pts=[]; + rz=[]; + rpts=[]; + + if my_corner_pts(g,14)=1 || my_corner_pts(g,14)>my_corner_pts(g,15) && my_corner_pts(g,15)<=1 + in = createLine([my_corner_pts(g,5) my_corner_pts(g,6)],[my_corner_pts(g,1) my_corner_pts(g,2)]); + e1 =orthogonalLine(in, [my_corner_pts(g,1) my_corner_pts(g,2)]); + ndegrees=my_corner_pts(g,9); + + for h=1:length(rss) + if slk(rss(h),1)~=my_corner_pts(g,1)&slk(rss(h),2)~=my_corner_pts(g,2)&slk(rss(h),3)~=my_corner_pts(g,1)&slk(rss(h),4)~=my_corner_pts(g,2) + e2 = createLine([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectLines(e1, e2); + + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && ((abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))<=20||abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))>=340)||(abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))>=160&&abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))<=200)) + rz=vertcat(rz,rss(h)); + pts=vertcat(pts,point); + end + end + end + + if ~isempty(pts) + p1=max(distancePoints([my_corner_pts(g,1) my_corner_pts(g,2)], pts,2)); + end + else + in = createLine([my_corner_pts(g,1) my_corner_pts(g,2)],[my_corner_pts(g,7) my_corner_pts(g,8)]); + e1 =orthogonalLine(in, [my_corner_pts(g,1) my_corner_pts(g,2)]); + ndegrees=my_corner_pts(g,10); + + for h=1:length(rss) + if slk(rss(h),1)~=my_corner_pts(g,1)&slk(rss(h),2)~=my_corner_pts(g,2)&slk(rss(h),3)~=my_corner_pts(g,1)&slk(rss(h),4)~=my_corner_pts(g,2) + e2 = createLine([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectLines(e1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && ((abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))<=20||abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))>=340)||(abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))>=160&&abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))<=200)) + pts=vertcat(pts,point); + rpts=vertcat(rpts,point); + end + end + end + + if ~isempty(rpts) + p2=max(distancePoints([my_corner_pts(g,1) my_corner_pts(g,2)], rpts,2)); + end + end + + if ~isempty(pts) + vpts=[]; + for h=1:length(pts(:,1)) + if distancePoints([my_corner_pts(g,1) my_corner_pts(g,2)], [pts(h,1) pts(h,2)], 2)<=dist + vpts=vertcat(vpts,[pts(h,1) pts(h,2)]); + end + end + + pts=vpts; + + if ~isempty(pts) + rv=find(pts(:,1)==my_corner_pts(g,1)&pts(:,2)==my_corner_pts(g,2)); + if isempty(rv) + pts=vertcat(pts,[my_corner_pts(g,1) my_corner_pts(g,2)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([my_corner_pts(g,1) my_corner_pts(g,2)], aa, 2)<=40 + my_corner_pts(g,1) = aa(1,1); + my_corner_pts(g,2) = aa(1,2); + p1=max(p1,p2); + end + end + end + end + + my_corner_pts(g,9)=rad2deg(angle2Points([my_corner_pts(g,5) my_corner_pts(g,6)],[my_corner_pts(g,1) my_corner_pts(g,2)])); + my_corner_pts(g,10)=rad2deg(angle2Points([my_corner_pts(g,1) my_corner_pts(g,2)],[my_corner_pts(g,7) my_corner_pts(g,8)])); + + if p1>1 + x1=my_corner_pts(g,1)+p1; + y1=my_corner_pts(g,2)+p1; + x2=my_corner_pts(g,1)+p1; + y2=my_corner_pts(g,2)-p1; + x3=my_corner_pts(g,1)-p1; + y3=my_corner_pts(g,2)+p1; + x4=my_corner_pts(g,1)-p1; + y4=my_corner_pts(g,2)-p1; + else + x1=my_corner_pts(g,1)+15; + y1=my_corner_pts(g,2)+15; + x2=my_corner_pts(g,1)+15; + y2=my_corner_pts(g,2)-15; + x3=my_corner_pts(g,1)-15; + y3=my_corner_pts(g,2)+15; + x4=my_corner_pts(g,1)-15; + y4=my_corner_pts(g,2)-15; + end + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rs=union(rs1,rs2,'rows'); + + itype=1; + dir=1; + aaa=[]; + ii=[]; + if length(rs)>1 + + for h=1:length(rs) + cangle=rad2deg(angle2Points([slk(rs(h),1) slk(rs(h),2)],[slk(rs(h),3) slk(rs(h),4)])); + aaa=vertcat(aaa,cangle); + end + [aaa ii]=unique(aaa,'rows'); + ii=sortrows(ii); + + idds=[]; + idds=vertcat(idds,[my_corner_pts(g,13) my_corner_pts(g,5) my_corner_pts(g,6) my_corner_pts(g,1) my_corner_pts(g,2) my_corner_pts(g,9) 1000 -1000 0 0]); + for h=1:length(ii) + cangle=rad2deg(angle2Points([slk(rs(ii(h)),1) slk(rs(ii(h)),2)],[slk(rs(ii(h)),3) slk(rs(ii(h)),4)])); + + cnt=0; + for d=1:length(idds(:,1)) + if cangle>idds(d,6) && abs(idds(d,8)-cangle)<=10 && idds(d,8)~=-1000 + cnt=cnt+1; + idds(d,9)=idds(d,9)+1; + + if cangle > idds(d,8) + idds(d,8)=cangle; + end + elseif cangle idds(d,8) && cangle > idds(d,6) + idds(d,8)=cangle; + elseif cangle < idds(d,7) && cangle < idds(d,6) + idds(d,7)=cangle; + end + end + end + if cnt==0 + idds=vertcat(idds,[my_corner_pts(g,13) slk(rs(ii(h)),1) slk(rs(ii(h)),2) slk(rs(ii(h)),3) slk(rs(ii(h)),4) cangle 1000 -1000 0 0]); + end + end + + for h=1:length(idds(:,1)) + idis=vertcat(idis,[idds(h,1) idds(h,2) idds(h,3) idds(h,4) idds(h,5) idds(h,6) idds(h,7) idds(h,8) idds(h,9)]); + end + + if ~isempty(idis) + if length(idds)>0 + itype=length(idds(:,1)); + end + end + end + + my_corner_pts(g,18)=itype; + my_corner_pts(g,19)=p1; + my_corner_pts(g,20)=length(ii); +end + + +temp_my_corner_pts=sortrows(my_corner_pts,-19); + +my_corner_pts=temp_my_corner_pts; +g=1; +idx=1; +while g<=length(my_corner_pts(:,1)) + p1=0; + if my_corner_pts(g,19)~=0 + if my_corner_pts(g,19)>1 + p1=my_corner_pts(g,19); + else + p1=dist/2; + end + else + p1=dist/2; + end + + x1=my_corner_pts(g,1)+p1; + y1=my_corner_pts(g,2)+p1; + x2=my_corner_pts(g,1)+p1; + y2=my_corner_pts(g,2)-p1; + x3=my_corner_pts(g,1)-p1; + y3=my_corner_pts(g,2)+p1; + x4=my_corner_pts(g,1)-p1; + y4=my_corner_pts(g,2)-p1; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in = inpolygon(my_corner_pts(:,1), my_corner_pts(:,2),mb(1,:), mb(2,:)); + rs=find(in==1); + rc=find(my_corner_pts(rs,13)~=my_corner_pts(g,13)); + rs=rs(rc); + + sim=[]; + for h=1:length(rs) + if abs(my_corner_pts(g,9)-my_corner_pts(rs(h),9))<=15 ||abs(my_corner_pts(g,9)+my_corner_pts(rs(h),9)-360)<=15 || abs(my_corner_pts(g,9)-my_corner_pts(rs(h),10))>=165&&abs(my_corner_pts(g,9)-my_corner_pts(rs(h),10))<=195 + sim=vertcat(sim,h); + elseif abs(my_corner_pts(g,10)-my_corner_pts(rs(h),10))<=15 ||abs(my_corner_pts(g,10)+my_corner_pts(rs(h),10)-360)<=15 || abs(my_corner_pts(g,10)-my_corner_pts(rs(h),9))>=165&&abs(my_corner_pts(g,10)-my_corner_pts(rs(h),9))<=195 + sim=vertcat(sim,h); + end + end + + rest=setdiff(rs,rs(sim)); + ra=find(idis(:,1)==my_corner_pts(g,13)); + for h=1:length(rest) + for l=1:length(ra) + if abs(idis(ra(l),6)-my_corner_pts(rest(h),9))<=idis(ra(l),6)-idis(ra(l),7) + ih=find(rs(:,1)==rest(h)); + sim=vertcat(sim,ih); + end + end + end + + sim=unique(sim,'rows'); + + if length(sim)~=0 + + pts_to_inter=vertcat(pts_to_inter,[1 1 my_corner_pts(g,3) my_corner_pts(g,4) my_corner_pts(g,13) my_corner_pts(g,1) my_corner_pts(g,2) my_corner_pts(g,5) my_corner_pts(g,6) my_corner_pts(g,7) my_corner_pts(g,8) idx]); + inter_to_cluster=vertcat(inter_to_cluster, [my_corner_pts(g,3), my_corner_pts(g,4), idx]); + mpts=[my_corner_pts(g,5) my_corner_pts(g,6) my_corner_pts(g,1) my_corner_pts(g,2)]; + mpts=vertcat(mpts,[my_corner_pts(g,1) my_corner_pts(g,2) my_corner_pts(g,7) my_corner_pts(g,8)]); + + xy=[my_corner_pts(g,1) my_corner_pts(g,2)]; + for h=1:length(sim) + xy=vertcat(xy,[my_corner_pts(rs(sim(h)),1) my_corner_pts(rs(sim(h)),2)]); + + mpts=vertcat(mpts,[my_corner_pts(rs(sim(h)),5) my_corner_pts(rs(sim(h)),6) my_corner_pts(rs(sim(h)),1) my_corner_pts(rs(sim(h)),2)]); + mpts=vertcat(mpts,[my_corner_pts(rs(sim(h)),1) my_corner_pts(rs(sim(h)),2) my_corner_pts(rs(sim(h)),7) my_corner_pts(rs(sim(h)),8)]); + + pts_to_inter=vertcat(pts_to_inter,[1 g my_corner_pts(rs(sim(h)),3) my_corner_pts(rs(sim(h)),4) my_corner_pts(rs(sim(h)),13) my_corner_pts(rs(sim(h)),1) my_corner_pts(rs(sim(h)),2) my_corner_pts(rs(sim(h)),5) my_corner_pts(rs(sim(h)),6) my_corner_pts(rs(sim(h)),7) my_corner_pts(rs(sim(h)),8) idx]); + inter_to_cluster=vertcat(inter_to_cluster, [my_corner_pts(rs(sim(h)),3), my_corner_pts(rs(sim(h)),4), idx]); + end + aa=centroid(xy); + + ipts=[aa(1,1) aa(1,2)]; + + for b=1:2:length(mpts(:,1))-1 + in1 = createLine([mpts(b,1) mpts(b,2)],[mpts(b,3) mpts(b,4)]); + d1=rad2deg(angle2Points([mpts(b,1) mpts(b,2)],[mpts(b,3) mpts(b,4)])); + in2 = createLine([mpts(b+1,1) mpts(b+1,2)],[mpts(b+1,3) mpts(b+1,4)]); + d2=rad2deg(angle2Points([mpts(b+1,1) mpts(b+1,2)],[mpts(b+1,3) mpts(b+1,4)])); + ipts=vertcat(ipts,[mpts(b,3) mpts(b,4)]); + for c=b+2:2:length(mpts(:,1))-2 + in3 = createLine([mpts(c,1) mpts(c,2)],[mpts(c,3) mpts(c,4)]); + d3=rad2deg(angle2Points([mpts(c,1) mpts(c,2)],[mpts(c,3) mpts(c,4)])); + in4 = createLine([mpts(c+1,1) mpts(c+1,2)],[mpts(c+1,3) mpts(c+1,4)]); + d4=rad2deg(angle2Points([mpts(c+1,1) mpts(c+1,2)],[mpts(c+1,3) mpts(c+1,4)])); + + if (abs(d1-d3)>=25&&abs(d1-d3)<=320) + point = intersectLines(in1, in3); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && distancePoints([aa(1,1) aa(1,2)], [point(1,1),point(1,2)], 2)<=p1 + ipts=vertcat(ipts,[point(1,1),point(1,2)]); + end + end + if (abs(d1-d4)>=25&&abs(d1-d4)<=320) + point = intersectLines(in1, in4); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && distancePoints([aa(1,1) aa(1,2)], [point(1,1),point(1,2)], 2)<=p1 + ipts=vertcat(ipts,[point(1,1),point(1,2)]); + end + end + if (abs(d2-d3)>=25&&abs(d2-d3)<=320) + point = intersectLines(in2, in3); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && distancePoints([aa(1,1) aa(1,2)], [point(1,1),point(1,2)], 2)<=p1 + ipts=vertcat(ipts,[point(1,1),point(1,2)]); + end + end + if (abs(d2-d4)>=45&&abs(d2-d4)<=320) + point = intersectLines(in2, in4); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && distancePoints([aa(1,1) aa(1,2)], [point(1,1),point(1,2)], 2)<=p1 + ipts=vertcat(ipts,[point(1,1),point(1,2)]); + end + end + end + end + + aaa=centroid(ipts); + aa=aaa; + turn_pts=vertcat(turn_pts,[aa(1,1), aa(1,2), idx, my_corner_pts(g,9), my_corner_pts(g,10), length(sim(:,1))+1, 1]); + turn_seeds=vertcat(turn_seeds,[idx g aa(1,1) aa(1,2) length(sim(:,1))+1 my_corner_pts(g,9) my_corner_pts(g,10) 1]); + + centre_pts=vertcat(centre_pts,[aa(1,1), aa(1,2), idx, my_corner_pts(g,9), my_corner_pts(g,10), (length(sim(:,1))+1), my_corner_pts(g,18), my_corner_pts(g,19),my_corner_pts(g,20)]); + clusterseeds=vertcat(clusterseeds,[idx i aa(1,1) aa(1,2) length(sim(:,1))+1 my_corner_pts(g,9), my_corner_pts(g,10)]); + + my_corner_pts(rs(sim),:)=[]; + my_corner_pts(g,:)=[]; + idx=idx+1; + else + rz=vertcat(rz,my_corner_pts(g,13)); + g=g+1; + end +end + +save('slk.mat','slk'); +save('pts_ln.mat','pts_ln'); +save('vehicles.mat','vehicles'); +save('centre_pts.mat','centre_pts'); +save('pts_to_inter.mat','pts_to_inter'); +save('clusterseeds.mat','clusterseeds'); +save('inter_to_cluster.mat','inter_to_cluster'); + +fprintf('Finishing at %s\n', timestamp); + diff --git a/algorithms/Karagiorgou_tracebundle/source/tracebundle.m b/algorithms/Karagiorgou_tracebundle/source/tracebundle.m new file mode 100644 index 0000000..54112cf --- /dev/null +++ b/algorithms/Karagiorgou_tracebundle/source/tracebundle.m @@ -0,0 +1,15406 @@ +% TraceBundle map construction 1.0 +% Copyright 2013 Sophia Karagiorgou and Dieter Pfoser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +% +% ------------------------------------------------------------------------ +% +% This software is based on the following article(s). Please cite this +% article when using this code as part of a research publication: +% +% S. Karagiorgou and D. Pfoser. On Vehicle Tracking Data-Based Road Network Generation. +% In Proc. 20th ACM SIGSPATIAL GIS Conference, pp. 89-98, 2012. +% +% S. Karagiorgou and D. Pfoser. Segmentation-Based Road Network Construction. +% In Proc. 21th ACM SIGSPATIAL GIS Conference, pp. 470-473, 2013. +% +% ------------------------------------------------------------------------ +% +% Author: Sophia Karagiorgou (karagior@gmail.com) +% Filename: tracebundle.m + + +currentFolder = pwd; +cd(currentFolder); + +pts_to_tr=[]; +inter_to_tr=[]; +cluster_to_tr=[]; + +idx=1; % index for angle matrix +id=1; + +fprintf('Starting at %s\n', timestamp); + +fprintf('Loading files\n'); + +lfile= 'centre_pts.mat'; +centre_pts_t=load(lfile) ; % load the file +centre_pts=centre_pts_t.centre_pts; + +ifile= 'clusterseeds.mat'; +clusterseeds = load(ifile) ; % load the file + +lfile= 'inter_to_cluster.mat'; +inter_to_cluster_t=load(lfile) ; % load the file +inter_to_cluster=inter_to_cluster_t.inter_to_cluster; + +ifile= 'pts_to_inter.mat'; +pts_to_inter = load(ifile) ; % load the file + +lfile= 'pts_ln.mat'; +pts_ln=load(lfile) ; % load the file + +lfile= 'slk.mat'; +slk_t=load(lfile) ; % load the file +slk=slk_t.slk; + +lfile= 'vehicles.mat'; +vehicles_t=load(lfile) ; % load the file +vehicles=vehicles_t.vehicles; + +fprintf('Finding correspondancies among position samples and intersections\n'); + +idx=1; +cluster_to_tr=[]; +netsections=[]; +for g=1:length(vehicles) + tr=find(pts_ln.pts_ln(:,3)==vehicles(g)); + itr=unique(pts_ln.pts_ln(tr,8),'rows'); + + res = find(pts_to_inter.pts_to_inter(:,3)==vehicles(g)); + if ~isempty(res) + pts_to_i=pts_to_inter.pts_to_inter(res,:); + pts_to_i=sortrows(pts_to_i,4); + for h=1:length(pts_to_i(:,1))-1 + rx1=find(inter_to_cluster(:,1)==pts_to_i(h,3) & inter_to_cluster(:,2)==pts_to_i(h,4)); + rx2=find(inter_to_cluster(:,1)==pts_to_i(h+1,3) & inter_to_cluster(:,2)==pts_to_i(h+1,4)); + cc1=find(centre_pts(:,3)==inter_to_cluster(rx1,3)); + cc2=find(centre_pts(:,3)==inter_to_cluster(rx2,3)); + + rp1=find(pts_ln.pts_ln(:,3)==vehicles(g) & pts_ln.pts_ln(:,4)==pts_to_i(h,4)); + rp2=find(pts_ln.pts_ln(:,3)==vehicles(g) & pts_ln.pts_ln(:,4)==pts_to_i(h+1,4)); + + if pts_ln.pts_ln(rp1,8)==pts_ln.pts_ln(rp2,8) + rp=find(pts_ln.pts_ln(:,3)==vehicles(g) & pts_ln.pts_ln(:,4)>pts_to_i(h,4)&pts_ln.pts_ln(:,4)1 + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(cc1,3) centre_pts(cc2,3) idx 2]); + for v=1:length(rp) + netsections=vertcat(netsections,[idx pts_ln.pts_ln(rp(v),1) pts_ln.pts_ln(rp(v),2)]); + end + idx=idx+1; + else + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(cc1,3) centre_pts(cc2,3) idx 2]); + netsections=vertcat(netsections,[idx pts_ln.pts_ln(rp(1),1) pts_ln.pts_ln(rp(1),2)]); + idx=idx+1; + end + + for b=1:length(rp) + pts_ln.pts_ln(rp(b),10)=pts_to_i(h,3); + pts_ln.pts_ln(rp(b),11)=pts_to_i(h,4); + pts_ln.pts_ln(rp(b),12)=pts_to_i(h+1,3); + pts_ln.pts_ln(rp(b),13)=pts_to_i(h+1,4); + pts_ln.pts_ln(rp(b),14)=centre_pts(cc1,3); + pts_ln.pts_ln(rp(b),15)=centre_pts(cc2,3); + pts_ln.pts_ln(rp(b),16)=1; + pts_ln.pts_ln(rp(b),17)=2; + end + else + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(cc1,3) centre_pts(cc2,3) idx 2]); + idx=idx+1; + end + end + end + end +end + + +for g=1:length(cluster_to_tr(:,1)) + res=[]; + sres=[]; + if ~isempty(netsections) + res=find(netsections(:,1)==cluster_to_tr(g,3)); + end + if ~isempty(cluster_to_tr) + sres=find(cluster_to_tr(:,3)==cluster_to_tr(g,3)); + end + if ~isempty(res) && ~isempty(sres) + + resc1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + resc2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + + st(1,1)=centre_pts(resc1,1); + st(1,2)=centre_pts(resc1,2); + en(1,1)=centre_pts(resc2,1); + en(1,2)=centre_pts(resc2,2); + + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(1),2), netsections(res(1),3)])); + netsections(res(1),4)=mdegrees1; + if length(res)>1 + for m=1:(length(res)-1) + if m==1 % outgoing direction + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + if length(res)>1 + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + else + mdegrees2=rad2deg(angle2Points([netsections(res(m),2),netsections(res(m),3)],[en(1,1), en(1,2)])); + netsections(res(m),5)=mdegrees2; + end + end + if m==(length(res)-1) + if m>1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + else + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + end + + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + + mdegrees1=mdegrees2; + netsections(res(m+1),4)=mdegrees1; + end + if m1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + end + end + end + mdegrees2=rad2deg(angle2Points([netsections(res(length(res)),2),netsections(res(length(res)),3)],[en(1,1), en(1,2)])); + netsections(res(length(res)),5)=mdegrees2; + end +end + + +minx=min(pts_ln.pts_ln(:,1)); +maxx=max(pts_ln.pts_ln(:,1)); +miny=min(pts_ln.pts_ln(:,2)); +maxy=max(pts_ln.pts_ln(:,2)); + +rc=find(centre_pts(:,1)>=minx¢re_pts(:,1)<=maxx¢re_pts(:,2)>=miny¢re_pts(:,2)<=maxy); +temp_centre_pts=centre_pts(rc,:); +nedges=[]; +for g=1:length(temp_centre_pts(:,1)) + rs=find(cluster_to_tr(:,1)==temp_centre_pts(g,3)|cluster_to_tr(:,2)==temp_centre_pts(g,3)); + if ~isempty(rs) + nedges=vertcat(nedges,cluster_to_tr(rs,3)); + end +end +nedges=unique(nedges,'rows'); +ic=[]; +for g=1:length(nedges) + rx=find(cluster_to_tr(:,3)==nedges(g)); + if ~isempty(rx) + ic=vertcat(ic, rx); + end +end + +cluster_to_tr=cluster_to_tr(ic,:); +centre_pts=temp_centre_pts; + +tempnetsections=netsections; +tempcluster=cluster_to_tr; +tempcluster2=tempcluster; +[cluster_to_tr, cluid]=unique([cluster_to_tr(:,1) cluster_to_tr(:,2)],'rows', 'first'); + + +netnodes=[]; +nnets=[]; +lk=[]; + +cluster_to_tr(:,4)=0; +cluster_to_tr(:,5)=0; +cluster_to_tr(:,6)=0; + + +fprintf('Compacting the same link samples\n'); + +for g=1:length(cluster_to_tr(:,1)) + rx=[]; + nx=[]; + rxo=[]; + nxo=[]; + pts=[]; + rx=find(tempcluster(:,1)==cluster_to_tr(g,1)&tempcluster(:,2)==cluster_to_tr(g,2)); + c1=find(centre_pts(:,3)==cluster_to_tr(g,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(g,2)); + + dist=(centre_pts(c1,8)+centre_pts(c2,8))/2; + cluster_to_tr(g,4)=round((centre_pts(c1,9)+centre_pts(c2,9))/2); + cluster_to_tr(g,5)=dist; + + if ~isempty(c1)&&~isempty(c2) + + if ~isempty(rx) + for h=1:length(rx) + xx=find(netsections(:,1)==tempcluster(rx(h),3)); + if ~isempty(xx) + nx=vertcat(nx,xx); + end + end + end + + if isempty(nx) + cluster_to_tr(g,3)=g; + netnodes=vertcat(netnodes, [g length(rx) 1]); + + lk=vertcat(lk,[centre_pts(c1,1), centre_pts(c1,2), centre_pts(c2,1), centre_pts(c2,2)]); + else + cluster_to_tr(g,3)=g; + netnodes=vertcat(netnodes, [g length(rx) 1]); + pts=unique([netsections(nx,2) netsections(nx,3)],'rows'); + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 10]; + idx=[]; + for l=1:length(pts(:,1)) + if isPointInCircle([pts(l,1), pts(l,2)], circle) + idx=vertcat(idx,l); + end + end + pts(idx,:)=[]; + + circle = [[centre_pts(c2,1) centre_pts(c2,2)] 10]; + idx=[]; + for l=1:length(pts(:,1)) + if isPointInCircle([pts(l,1), pts(l,2)], circle) + idx=vertcat(idx,l); + end + end + pts(idx,:)=[]; + + pseq=[]; + + if ~isempty(pts) + for b=1:length(pts(:,1)) + rb=find(netsections(nx,2)==pts(b,1)&netsections(nx,3)==pts(b,2)); + ndegrees=max(netsections(nx(rb),4)); + x1=pts(b,1)+dist; + y1=pts(b,2)+dist; + x2=pts(b,1)+dist; + y2=pts(b,2)-dist; + x3=pts(b,1)-dist; + y3=pts(b,2)+dist; + x4=pts(b,1)-dist; + y4=pts(b,2)-dist; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + if b==1 + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + elseif b==length(pts(:,1)) + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c2,1) centre_pts(c2,2)]); + elseif b=315||abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))>=135&&abs(ndegrees-rad2deg(angle2Points([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)])))<=225) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + rv=find(vpts(:,1)==pts(b,1)&vpts(:,2)==pts(b,2)); + if isempty(rv) + vpts=vertcat(vpts,[pts(b,1) pts(b,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + end + + pseq=pts; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c2,1) centre_pts(c2,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for k=1:length(SQ(:,:)) + SQ(k,k)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for h=1:length(idxk) + mindist=min(SQ(idxk(h),:)); + if mindist<=minip + minip=mindist; + index=h; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + ppseq=temp; + if ~isempty(ppseq) + for h=1:length(ppseq(:,1)) + nnets=vertcat(nnets,[g ppseq(h,1) ppseq(h,2) length(rx)]); + end + end + end + end + end +end + +rc=find(lk(:,1)>=minx&lk(:,1)<=maxx&lk(:,2)>=miny&lk(:,2)<=maxy&lk(:,3)>=minx&lk(:,3)<=maxx&lk(:,4)>=miny&lk(:,4)<=maxy); +lk=lk(rc,:); + +netsections=nnets; +rx=find(cluster_to_tr(:,3)==0); +cluster_to_tr(rx,:)=[]; + +fprintf('Calculating link samples network distance\n'); + +% calculate polyline dist +for g=1:length(cluster_to_tr(:,1)) + rx=find(netsections(:,1)==cluster_to_tr(g,3)); + rc=find(netnodes(:,1)==cluster_to_tr(g,3)); + c1=find(centre_pts(:,3)==cluster_to_tr(g,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(g,2)); + d=0; + if isempty(rx) + xy=[centre_pts(c1,1) centre_pts(c1,2)]; + xy=vertcat(xy,[centre_pts(c2,1) centre_pts(c2,2)]); + d = polylineLength(xy,'open'); + cluster_to_tr(g,6)=d; + netnodes(rc,4)=d; + else + xy=[centre_pts(c1,1) centre_pts(c1,2)]; + xy=vertcat(xy,[netsections(rx,2) netsections(rx,3)]); + xy=vertcat(xy,[centre_pts(c2,1) centre_pts(c2,2)]); + d = polylineLength(xy,'open'); + cluster_to_tr(g,6)=d; + netnodes(rc,4)=d; + end +end + +temp_netsections=netsections; +temp_netnodes=netnodes; +temp_cluster_to_tr=cluster_to_tr; +temp_centre=centre_pts; + +cnt=0; + +% clean cluster_to_tr +% after that len(netnodes)=len(cluster_to_tr) +toremove=[]; +for k=1:length(cluster_to_tr) + sres=find(netnodes(:,1)==cluster_to_tr(k,3)); + if isempty(sres) + toremove=vertcat(toremove,cluster_to_tr(k,3)); + end +end + +for k=1:length(toremove) + r=find(cluster_to_tr(:,3)==toremove(k)); + if ~isempty(r) + cluster_to_tr(r,:)=[]; + end +end + +toremove=[]; +for k=1:length(netnodes(:,1)) + sres=find(cluster_to_tr(:,3)==netnodes(k,1)); + if isempty(sres) + toremove=vertcat(toremove,netnodes(k,1)); + end +end + +for k=1:length(toremove) + r=find(netnodes(:,1)==toremove(k)); + if ~isempty(r) + netnodes(r,:)=[]; + end +end + +% calculating incoming-outgoing degrees +for g=1:length(netnodes(:,1)) + res=find(netsections(:,1)==netnodes(g,1)); + sres=find(cluster_to_tr(:,3)==netnodes(g,1)); + if ~isempty(res) && ~isempty(sres) + + resc1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + resc2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + + st(1,1)=centre_pts(resc1,1); + st(1,2)=centre_pts(resc1,2); + en(1,1)=centre_pts(resc2,1); + en(1,2)=centre_pts(resc2,2); + + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(1),2), netsections(res(1),3)])); + netsections(res(1),4)=mdegrees1; + if length(res)>1 + for m=1:(length(res)-1) + if m==1 % outgoing direction + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + if length(res)>1 + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + else + mdegrees2=rad2deg(angle2Points([netsections(res(m),2),netsections(res(m),3)],[en(1,1), en(1,2)])); + netsections(res(m),5)=mdegrees2; + end + end + if m==(length(res)-1) + if m>1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + else + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + end + + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + + mdegrees1=mdegrees2; + netsections(res(m+1),4)=mdegrees1; + end + if m1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + end + end + end + mdegrees2=rad2deg(angle2Points([netsections(res(length(res)),2),netsections(res(length(res)),3)],[en(1,1), en(1,2)])); + netsections(res(length(res)),5)=mdegrees2; + end +end + +% clean the same starting and ending nodes +ntoremove=[]; +for i=1:length(netnodes(:,1)) + r=find(cluster_to_tr(:,3)==netnodes(i,1)); + if cluster_to_tr(r,1)==cluster_to_tr(r,2) + ntoremove=vertcat(ntoremove,netnodes(i,1)); + end +end + +for i=1:length(ntoremove) + r=find(netnodes(:,1)==ntoremove(i)); + if ~isempty(r) + netnodes(r,:)=[]; + end + r=find(cluster_to_tr(:,3)==ntoremove(i)); + if ~isempty(r) + cluster_to_tr(r,:)=[]; + end + r=find(netsections(:,1)==ntoremove(i)); + if ~isempty(r) + r=unique(r); + h=length(r); + while h>=1 + netsections(r(h),:)=[]; + h=h-1; + end + end +end + +nodes=[]; +for k=1:length(netnodes(:,1)) + r=find(cluster_to_tr(:,3)==netnodes(k,1)); + nodes=vertcat(nodes, cluster_to_tr(r,1)); + nodes=vertcat(nodes, cluster_to_tr(r,2)); +end + +nodes=unique(nodes, 'rows'); +cnt=0; +for k=1:length(nodes(:,1)) + r=[]; + r=find(cluster_to_tr(:,1)==nodes(k)); + nodes(k,2)=length(r); + r=[]; + r=find(cluster_to_tr(:,2)==nodes(k)); + nodes(k,3)=length(r); + r=find(centre_pts(:,3)==nodes(k)); + cnt=cnt+centre_pts(r,6); +end + +idx=[]; +for k=1:length(cluster_to_tr(:,1)) + c1=find(centre_pts(:,3)==cluster_to_tr(k,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(k,2)); + rs=find(netsections(:,1)==cluster_to_tr(k,3)); + dd=(centre_pts(c1,8)+centre_pts(c2,8))/2; + if isempty(rs) + midp=midPoint([centre_pts(c1,1) centre_pts(c1,2) centre_pts(c2,1) centre_pts(c2,2)]); + + x1=midp(1,1)+10; + y1=midp(1,2)+10; + x2=midp(1,1)+10; + y2=midp(1,2)-10; + x3=midp(1,1)-10; + y3=midp(1,2)+10; + x4=midp(1,1)-10; + y4=midp(1,2)-10; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in=createLine([centre_pts(c1,1) centre_pts(c1,2)],[midp(1,1) midp(1,2)]); + e1 =orthogonalLine(in, [midp(1,1) midp(1,2)]); + ce1=createEdge(e1,15); + tr1 = createRotation([midp(1,1) midp(1,2)], 0); + tr2 = createRotation([midp(1,1) midp(1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if slk(rss(h),1)~=midp(1,1)&slk(rss(h),2)~=midp(1,2)&slk(rss(h),3)~=midp(1,1)&slk(rss(h),4)~=midp(1,2) + e2 = createEdge([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if isempty(vpts) + idx=vertcat(idx,k); + end + end +end + +for k=1:length(idx) + r=find(netnodes(:,1)==cluster_to_tr(idx(k),3)); + if ~isempty(r) + netnodes(r,:)=[]; + end +end +cluster_to_tr(idx,:)=[]; + +toremove=[]; +for k=1:length(netnodes(:,1)) + sres=find(cluster_to_tr(:,3)==netnodes(k,1)); + if isempty(sres) + toremove=vertcat(toremove,netnodes(k,1)); + end +end + +for k=1:length(toremove) + r=find(netnodes(:,1)==toremove(k)); + if ~isempty(r) + netnodes(r,:)=[]; + end +end + + +elk=slk; + +res=[]; +temp_netsections=netsections; +temp_netnodes=netnodes; +temp_cluster_to_tr=cluster_to_tr; +temp_centre=centre_pts; +iter=1; +times=1; +hold on; + +tempnet=sortrows(netnodes,-4); +netnodes=tempnet; + +classdx(1)=100; +classdx(2)=200; +classdx(3)=300; +classdx(4)=400; +classdx(5)=500; +classdx(6)=600; +classdx(7)=700; +classdx(8)=800; +classdx(9)=900; +classdx(10)=1000; + +classdy(1)=15; +classdy(2)=25; +classdy(3)=30; +classdy(4)=35; +classdy(5)=50; +classdy(6)=60; +classdy(7)=70; +classdy(8)=80; +classdy(9)=90; +classdy(10)=100; + +aclass(1)=30; +aclass(2)=60; +aclass(3)=90; +aclass(4)=120; +aclass(5)=150; +aclass(6)=180; +aclass(7)=210; +aclass(8)=240; +aclass(9)=270; +aclass(10)=300; +aclass(11)=330; +aclass(12)=360; + +clear inter_to_tr; +clear tempcluster; +clear tempcluster2; +clear inter_to_cluster; + +netnodes(:,5)=1; +netnodes(:,6)=0; +netnodes(:,7)=0; +netnodes(:,8)=0; +gscounter=2; + +k=1; +rlen=length(netnodes(:,1)); +distances=[]; +distances1=[]; +temp=[]; +currlen=length(cluster_to_tr(:,1)); +prevlen=0; +scounter=1; + +temp_netsections=netsections; +temp_netnodes=netnodes; +temp_cluster_to_tr=cluster_to_tr; +temp_centre=centre_pts; + +sss=0; +hold on; +tcase=[]; +ccase=[]; +d=[]; + +fprintf('Merging link samples into links\n'); + +while prevlen~=rlen && scounter<=gscounter + + prevlen=rlen; + maxclen=length(centre_pts(:,1)); + maxk=netnodes(rlen,1); + while (k<=rlen && netnodes(k,1)<=maxk)||k<=rlen + netnodes(k,8)=netnodes(k,8)+1; + res=find(netsections(:,1)==netnodes(k,1)); + sres=find(cluster_to_tr(:,3)==netnodes(k,1)); + + if ~isempty(res) && ~isempty(sres) + c1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + st(1,1)=centre_pts(c1,1); + st(1,2)=centre_pts(c1,2); + en(1,1)=centre_pts(c2,1); + en(1,2)=centre_pts(c2,2); + dy=abs(centre_pts(c1,2)-centre_pts(c2,2)); + nxtfl=[]; + prvfl=[]; + + memf=c2; + sid=1; + minids=[]; + mid=1; + + bbox=[]; + rbbox=[]; + bbox2=[]; + rbbox2=[]; + c4=[]; + intermediate2=[]; + + for t=1:length(res) + gdy=0; + if t==1 + ndegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(t),2),netsections(res(t),3)]); + dx1=sqrt((centre_pts(c1,1)-netsections(res(t),2))^2+(centre_pts(c1,2)-netsections(res(t),3))^2); + distances=vertcat(distances,[dx1 k]); + + if dx1<=classdx(1) + dy=classdy(1); + elseif dx1>classdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if length(res)>1 + pdegrees=line_angle([netsections(res(t),2),netsections(res(t),3)],[netsections(res(t+1),2),netsections(res(t+1),3)]); + else + pdegrees=line_angle([netsections(res(t),2),netsections(res(t),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + x1=centre_pts(c1,1)+(dy1)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy1)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy2)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy2)*sind(ndegrees+90); + x3=netsections(res(1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(dy2)*sind(ndegrees+90); + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + + in = inpolygon(centre_pts(:,1),centre_pts(:,2),mb(1,:),mb(2,:)); + c4=vertcat(c4,centre_pts(in,3)); + + in = inpolygon(pts_ln.pts_ln(:,1),pts_ln.pts_ln(:,2),mb(1,:),mb(2,:)); + intermediate2=vertcat(intermediate2,[pts_ln.pts_ln(in,1),pts_ln.pts_ln(in,2)]); + + + node=[x1 y1;x3 y3]; + rbbox=vertcat(rbbox,[x2 y2]); + rbbox=vertcat(rbbox,[x4 y4]); + bbox=vertcat(bbox,[node(:,1) node(:,2)]); + + x1=centre_pts(c1,1)+(gdy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(gdy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(gdy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(gdy)*sind(ndegrees+90); + x3=netsections(res(1),2)+(gdy)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(gdy)*sind(ndegrees-90); + x4=netsections(res(1),2)+(gdy)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3]; + rbbox2=vertcat(rbbox2,[x2 y2]); + rbbox2=vertcat(rbbox2,[x4 y4]); + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + end + if t==length(res) + ndegrees=line_angle([netsections(res(length(res)),2),netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + dy=abs(centre_pts(c2,2)-netsections(res(length(res)),3)); + dx1=sqrt((centre_pts(c2,1)-netsections(res(length(res)),2))^2+(centre_pts(c2,2)-netsections(res(length(res)),3))^2); + distances=vertcat(distances,[dx1 k]); + + if dx1<=classdx(1) + dy=classdy(1); + elseif dx1>classdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if length(res)>1 + pdegrees=line_angle([netsections(res(length(res)-1),2),netsections(res(length(res)-1),3)],[netsections(res(length(res)),2),netsections(res(length(res)),3)]); + else + pdegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(length(res)),2),netsections(res(length(res)),3)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + x1=netsections(res(length(res)),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(dy2)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy1)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy1)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy2)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy2)*sind(ndegrees+90); + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + + in = inpolygon(centre_pts(:,1),centre_pts(:,2),mb(1,:),mb(2,:)); + c4=vertcat(c4,centre_pts(in,3)); + + in = inpolygon(pts_ln.pts_ln(:,1),pts_ln.pts_ln(:,2),mb(1,:),mb(2,:)); + intermediate2=vertcat(intermediate2,[pts_ln.pts_ln(in,1),pts_ln.pts_ln(in,2)]); + + node=[x3 y3]; + rbbox=vertcat(rbbox,[x4 y4]); + bbox=vertcat(bbox,[node(:,1) node(:,2)]); + + x1=netsections(res(length(res)),2)+(gdy)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(gdy)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(gdy)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(gdy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(gdy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(gdy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(gdy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(gdy)*sind(ndegrees+90); + + node=[x3 y3]; + rbbox2=vertcat(rbbox2,[x4 y4]); + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + end + if tclassdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if (t+2)<=length(res) + pdegrees=line_angle([netsections(res(t+1),2),netsections(res(t+1),3)],[netsections(res(t+2),2),netsections(res(t+2),3)]); + else + pdegrees=line_angle([netsections(res(t+1),2),netsections(res(t+1),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + x1=netsections(res(t),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(t),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(dy2)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(dy2)*sind(ndegrees+90); + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + + in = inpolygon(centre_pts(:,1),centre_pts(:,2),mb(1,:),mb(2,:)); + c4=vertcat(c4,centre_pts(in,3)); + + in = inpolygon(pts_ln.pts_ln(:,1),pts_ln.pts_ln(:,2),mb(1,:),mb(2,:)); + intermediate2=vertcat(intermediate2,[pts_ln.pts_ln(in,1),pts_ln.pts_ln(in,2)]); + + node=[x3 y3]; + rbbox=vertcat(rbbox,[x4 y4]); + bbox=vertcat(bbox,[node(:,1) node(:,2)]); + + x1=netsections(res(t),2)+(gdy)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(gdy)*sind(ndegrees-90); + x2=netsections(res(t),2)+(gdy)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(gdy)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(gdy)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(gdy)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(gdy)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(gdy)*sind(ndegrees+90); + + node=[x3 y3]; + rbbox2=vertcat(rbbox2,[x4 y4]); + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + end + end + intermediate2(:,3)=1; + ni=length(rbbox(:,1)); + + while ni>=1 + bbox=vertcat(bbox,[rbbox(ni,1) rbbox(ni,2)]); + ni=ni-1; + end + bbox=vertcat(bbox,[bbox(1,1) bbox(1,2)]); + + ni=length(rbbox2(:,1)); + + while ni>=1 + bbox2=vertcat(bbox2,[rbbox2(ni,1) rbbox2(ni,2)]); + ni=ni-1; + end + bbox2=vertcat(bbox2,[bbox2(1,1) bbox2(1,2)]); + + if scounter>5 + x1=centre_pts(c1,1)+(gdy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(gdy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(gdy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(gdy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(gdy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(gdy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(gdy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + bbox2=node; + end + + c4=unique(c4,'rows'); + + hold on; + nsegs=[]; + validids=[]; + segscl=[]; + poly1=[centre_pts(c1,1) centre_pts(c1,2)]; + poly1=vertcat(poly1,[netsections(res,2) netsections(res,3)]); + poly1=vertcat(poly1,[centre_pts(c2,1) centre_pts(c2,2)]); + cx=[]; + cnt=0; + + + + if ~isempty(c4) + intermediate=[]; + split=[]; + for h=1:length(c4) + rc=find(cluster_to_tr(:,1)==c4(h)|cluster_to_tr(:,2)==c4(h)); + + if isempty(rc) + for t=1:length(res) + + if t==1 + rcen=find(centre_pts(:,3)==c4(h)); + Ddist=vertcat([centre_pts(rcen,1) centre_pts(rcen,2)]); + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + if d<=10 + rcv=find(centre_pts(:,3)==c4(h)); + validids=vertcat(validids, [rcv centre_pts(rcv,6)]); + end + end + if t==length(res) + rcen=find(centre_pts(:,3)==c4(h)); + Ddist=vertcat([centre_pts(rcen,1) centre_pts(rcen,2)]); + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + if d<=10 + rcv=find(centre_pts(:,3)==c4(h)); + validids=vertcat(validids, [rcv centre_pts(rcv,6)]); + end + end + if tclassdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if dy>maxd + maxd=dy; + end + + if length(res)>1 + pdegrees=line_angle([netsections(res(t),2),netsections(res(t),3)],[netsections(res(t+1),2),netsections(res(t+1),3)]); + else + pdegrees=line_angle([netsections(res(t),2),netsections(res(t),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + if ndegrees>=0 && ndegrees<90 + x1=centre_pts(c1,1)+(dy1)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy1)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy2)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy2)*sind(ndegrees+90); + x3=netsections(res(1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>=295 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>=295 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + + end + elseif ndegrees>=90 && ndegrees<180 + x1=centre_pts(c1,1)+(dy2)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy2)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy1)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy1)*sind(ndegrees+90); + x3=netsections(res(1),2)+(dy2)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(dy2)*sind(ndegrees-90); + x4=netsections(res(1),2)+(dy1)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=180 && ndegrees<270 + x1=centre_pts(c1,1)+(dy1)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy1)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy2)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy2)*sind(ndegrees+90); + x3=netsections(res(1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=270 && ndegrees<=361 + x1=centre_pts(c1,1)+(dy2)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy2)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy1)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy1)*sind(ndegrees+90); + x3=netsections(res(1),2)+(dy2)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(dy2)*sind(ndegrees-90); + x4=netsections(res(1),2)+(dy1)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + + + end + else + + disp(['mpikes4' num2str(ndegrees)]) + end + end + if t==length(res) + ndegrees=line_angle([netsections(res(length(res)),2),netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + dy=abs(centre_pts(c2,2)-netsections(res(length(res)),3)); + dx1=sqrt((centre_pts(c2,1)-netsections(res(length(res)),2))^2+(centre_pts(c2,2)-netsections(res(length(res)),3))^2); + if dx1<=classdx(1) + dy=classdy(1); + elseif dx1>classdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if dy>maxd + maxd=dy; + end + + if length(res)>1 + pdegrees=line_angle([netsections(res(length(res)-1),2),netsections(res(length(res)-1),3)],[netsections(res(length(res)),2),netsections(res(length(res)),3)]); + else + pdegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(length(res)),2),netsections(res(length(res)),3)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + if ndegrees>=0 && ndegrees<90 + x1=netsections(res(length(res)),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(dy2)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy1)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy1)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy2)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + + + elseif ndegrees>=90 && ndegrees<180 + x1=netsections(res(length(res)),2)+(dy2)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(dy2)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(dy1)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(dy1)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy2)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy2)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy1)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=180 && ndegrees<270 + x1=netsections(res(length(res)),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(dy2)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy1)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy1)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy2)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=270 && ndegrees<=361 + x1=netsections(res(length(res)),2)+(dy2)*cosd(ndegrees-90); + y1=netsections(res(length(res)),3)+(dy2)*sind(ndegrees-90); + x2=netsections(res(length(res)),2)+(dy1)*cosd(ndegrees+90); + y2=netsections(res(length(res)),3)+(dy1)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy2)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy2)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy1)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + else disp(['mpikes5' num2str(ndegrees)]) + end + end + if tclassdx(1)&&dx1<=classdx(2) + dy=classdy(2); + elseif dx1>classdx(2)&&dx1<=classdx(3) + dy=classdy(3); + elseif dx1>classdx(3)&&dx1<=classdx(4) + dy=classdy(4); + elseif dx1>classdx(4) + dy=classdy(5); + end + + if dy>maxd + maxd=dy; + end + + if (t+2)<=length(res) + pdegrees=line_angle([netsections(res(t+1),2),netsections(res(t+1),3)],[netsections(res(t+2),2),netsections(res(t+2),3)]); + else + pdegrees=line_angle([netsections(res(t+1),2),netsections(res(t+1),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + end + + if scounter>10 + dy1=20; + dy2=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy1=cluster_to_tr(sres,5)+5; + dy2=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy1=cluster_to_tr(sres,5); + dy2=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy1=45; + dy2=45; + gdy=20; + end + end + + if ndegrees>=0 && ndegrees<90 + x1=netsections(res(t),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(t),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(dy2)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t+1),3)-netsections(res(t),3))/(netsections(res(t+1),2)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=90 && ndegrees<180 + x1=netsections(res(t),2)+(dy2)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(dy2)*sind(ndegrees-90); + x2=netsections(res(t),2)+(dy1)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(dy1)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(dy2)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(dy2)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(dy1)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t+1),3)-netsections(res(t),3))/(netsections(res(t+1),2)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=180 && ndegrees<270 + x1=netsections(res(t),2)+(dy1)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(dy1)*sind(ndegrees-90); + x2=netsections(res(t),2)+(dy2)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(dy2)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(dy1)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(dy1)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(dy2)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(dy2)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t+1),3)-netsections(res(t),3))/(netsections(res(t+1),2)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + elseif ndegrees>=270 && ndegrees<=361 + x1=netsections(res(t),2)+(dy2)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(dy2)*sind(ndegrees-90); + x2=netsections(res(t),2)+(dy1)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(dy1)*sind(ndegrees+90); + x3=netsections(res(t+1),2)+(dy2)*cosd(ndegrees-90); + y3=netsections(res(t+1),3)+(dy2)*sind(ndegrees-90); + x4=netsections(res(t+1),2)+(dy1)*cosd(ndegrees+90); + y4=netsections(res(t+1),3)+(dy1)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<45||abs(ndegrees-pdegrees)>315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o315 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) + segment(o+1,3)=in; + end + end + else + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(netsections(res(t+1),3)-netsections(res(t),3))/(netsections(res(t+1),2)-netsections(res(t),2)); + b=netsections(res(t),3) - slope*netsections(res(t),2); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20 && (in1~=0||in2~=0) + segment(1,3)=1; + segment(2,3)=1; + else + if d(1)<=20 && (in1~=0||in2~=0) + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 && (in1~=0||in2~=0) + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + if in==1 + memcntr=rc1; + end + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<225) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + if in==1 + memcntr=rc2; + end + end + end + end + else disp(['mpikes6' num2str(ndegrees)]) + end + end + + end + nrs=find(segment(:,3)==1); + + + if ~isempty(rn) && ~isempty(nrs) + if (length(nrs)/length(segment(:,1)))~=1 + if length(nrs)==1 && (centre_pts(rc1,3)==centre_pts(c1,3)||centre_pts(rc1,3)==centre_pts(c2,3)||centre_pts(rc2,3)==centre_pts(c1,3)||centre_pts(rc2,3)==centre_pts(c2,3)) + else + if segment(1,3)==0&&segment(length(segment(:,1)),3)==0 + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + + elseif segment(1,3)==0||segment(length(segment(:,1)),3)==0 + if segment(1,3)==1 + validids=vertcat(validids, [rc1 cluster_to_tr(rc(n),4)]); + elseif segment(length(segment(:,1)),3)==1 + validids=vertcat(validids, [rc2 cluster_to_tr(rc(n),4)]); + end + + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + + + if length(nrs)>1 + % fix new segment + if segment(1,3)==0 + new=[]; + g=2; + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g+1; + while segment(g,3)~=1 && g<=length(segment(:,1)) + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g+1; + end + + memcen=[segment(g,1) segment(g,2)]; + pdegrees=line_angle([new(length(new(:,1)),1), new(length(new(:,1)),2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + if centre_pts(rc1,1)~=new(length(new(:,1)),1)&¢re_pts(rc1,2)~=new(length(new(:,1)),2) + rcen=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + rcenm=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if ~isempty(rcen)%centre1_exists + rl=find(cluster_to_tr(:,1)==centre_pts(rc1,3) & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl) + if centre_pts(rc1,3)~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),centre_pts(rcen,3), maxcl, round((centre_pts(rc1,9)+centre_pts(rcen,9))/2), round((centre_pts(rc1,8)+centre_pts(rcen,8))/2), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rcen,1) centre_pts(rcen,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=1; + while g1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + + rl2=find(cluster_to_tr(:,1)==centre_pts(rcen,3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rcen,3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcen,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rcen,1) centre_pts(rcen,2)], [centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + + end + + else%centre_1_not_exists + x1=new(length(new(:,1)),1)+10; + y1=new(length(new(:,1)),2)+10; + x2=new(length(new(:,1)),1)+10; + y2=new(length(new(:,1)),2)-10; + x3=new(length(new(:,1)),1)-10; + y3=new(length(new(:,1)),2)+10; + x4=new(length(new(:,1)),1)-10; + y4=new(length(new(:,1)),2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + mflag=0; + if ~isempty(inidx) + if length(inidx)>1 + Pd=[new(length(new(:,1)),1), new(length(new(:,1)),2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + mflag=1; + else + rxc=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[new(length(new(:,1)),1) new(length(new(:,1)),2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + + rl2=find(cluster_to_tr(:,1)==centre_pts(rc1,3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rc1,3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=1; + while g1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc2=centre_pts(inidx(rm(1)-1),3); + else + maxc2=centre_pts(inidx(rm-1),3); + end + else + maxc2=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc2=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc2 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==maxc2); + if isempty(rl2) + if maxc~=maxc2 + maxcl=(max(netnodes(:,1))+1); + rmc1=find(centre_pts(:,3)==maxc); + rmc2=find(centre_pts(:,3)==maxc2); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,maxc2, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rmc1,1) centre_pts(rmc1,2)], [centre_pts(rmc2,1) centre_pts(rmc2,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + + nrsp=find(segment(:,3)==0); + if length(nrsp)==2 && maxc2~=rc2 && length(segment(:,3))<5 + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + split=vertcat(split,[maxc2, centre_pts(rc2,3), netnodes(wht,2), cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5)]); + end + end + end + end + end + + elseif segment(length(segment(:,1)),3)==0 + new=[]; + g=length(segment(:,1))-1; + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g-1; + while segment(g,3)~=1 && g>0 + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g-1; + end + + + memcen=[segment(g,1) segment(g,2)]; + + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[new(length(new(:,1)),1), new(length(new(:,1)),2)]); + + if centre_pts(rc2,1)~=new(length(new(:,1)),1)&¢re_pts(rc2,2)~=new(length(new(:,1)),2) + rcen=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + rcenm=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if ~isempty(rcen)%centre_exists + rl=find(cluster_to_tr(:,2)==centre_pts(rc2,3) & cluster_to_tr(:,1)==centre_pts(rcen,3)); + if isempty(rl) + if centre_pts(rcen,3)~=centre_pts(rc2,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcen,3),centre_pts(rc2,3), maxcl, round((centre_pts(rcen,9)+centre_pts(rc2,9))/2), round((centre_pts(rcen,8)+centre_pts(rc2,8))/2), distancePoints([centre_pts(rcen,1) centre_pts(rcen,2)], [centre_pts(rc2,1) centre_pts(rc2,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=length(new(:,1))-1; + while g>0 + netsections=vertcat(netsections,[maxcl new(g,1) new(g,2) 0 0]); + g=g-1; + end + end + end + end + + if ~isempty(rcenm)%centre2_exists + rl2=find(cluster_to_tr(:,1)==centre_pts(rcenm,3) & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl2) + if centre_pts(rcenm,3)~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcenm,3),centre_pts(rcen,3), maxcl, round((centre_pts(rcenm,9)+centre_pts(rcen,9))/2), round((centre_pts(rcenm,8)+centre_pts(rcen,8))/2), distancePoints([centre_pts(rcenm,1) centre_pts(rcenm,2)], [centre_pts(rcen,1) centre_pts(rcen,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + else + x1=memcen(1,1)+10; + y1=memcen(1,2)+10; + x2=memcen(1,1)+10; + y2=memcen(1,2)-10; + x3=memcen(1,1)-10; + y3=memcen(1,2)+10; + x4=memcen(1,1)-10; + y4=memcen(1,2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + if ~isempty(inidx) + if length(inidx)>1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl2) + if maxc~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,centre_pts(rcen,3), maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], [centre_pts(rcen,1) centre_pts(rcen,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + + end + else + x1=new(length(new(:,1)),1)+10; + y1=new(length(new(:,1)),2)+10; + x2=new(length(new(:,1)),1)+10; + y2=new(length(new(:,1)),2)-10; + x3=new(length(new(:,1)),1)-10; + y3=new(length(new(:,1)),2)+10; + x4=new(length(new(:,1)),1)-10; + y4=new(length(new(:,1)),2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + if ~isempty(inidx) + if length(inidx)>1 + Pd=[new(length(new(:,1)),1), new(length(new(:,1)),2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[new(length(new(:,1)),1) new(length(new(:,1)),2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==centre_pts(rc2,3)); + if isempty(rl2) + if maxc~=centre_pts(rc2,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,centre_pts(rc2,3), maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], [centre_pts(rc2,1) centre_pts(rc2,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=length(new(:,1))-1; + while g>0 + netsections=vertcat(netsections,[maxcl new(g,1) new(g,2) 0 0]); + g=g-1; + end + end + end + end + if ~isempty(rcenm)%centre2_exists + rl2=find(cluster_to_tr(:,1)==centre_pts(rcenm(1),3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rcenm(1),3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcenm,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rcenm,1) centre_pts(rcenm,2)], [centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + else + x1=memcen(1,1)+10; + y1=memcen(1,2)+10; + x2=memcen(1,1)+10; + y2=memcen(1,2)-10; + x3=memcen(1,1)-10; + y3=memcen(1,2)+10; + x4=memcen(1,1)-10; + y4=memcen(1,2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + if ~isempty(inidx) + if length(inidx)>1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc2=centre_pts(inidx(rm(1)-1),3); + else + maxc2=centre_pts(inidx(rm-1),3); + end + else + maxc2=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc2=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc2 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc2 & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if maxc2~=maxc + maxcl=(max(netnodes(:,1))+1); + rmc1=find(centre_pts(:,3)==maxc2); + rmc2=find(centre_pts(:,3)==maxc); + cluster_to_tr=vertcat(cluster_to_tr,[maxc2,maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rmc1,1) centre_pts(rmc1,2)], [centre_pts(rmc2,1) centre_pts(rmc2,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + + nrsp=find(segment(:,3)==0); + if length(nrsp)==2 && maxc2~=rc1 && length(segment(:,3))<5 + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + split=vertcat(split,[centre_pts(rc1,3), maxc2, netnodes(wht,2), cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5)]); + end + end + end + end + end + end + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),2]); + else + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),1]); + end + end + else + validids=vertcat(validids, [rc1 cluster_to_tr(rc(n),4)]); + validids=vertcat(validids, [rc2 cluster_to_tr(rc(n),4)]); + + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),2]); + else + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),1]); + end + end + end + else + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + elseif isempty(rn)&&(length(nrs)/length(segment(:,1)))>=0.5 + if length(nrs)/length(segment(:,1))>0.5 + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + + elseif memcntr~=0 && memcntr~=centre_pts(c1,3) && memcntr~=centre_pts(c2,3) + validids=vertcat(validids, [memcntr cluster_to_tr(rc(n),4)]); + elseif centre_pts(c1,3)==centre_pts(rc1,3)||centre_pts(c2,3)==centre_pts(rc1,3)||centre_pts(c1,3)==centre_pts(rc2,3)||centre_pts(c2,3)==centre_pts(rc2,3) + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + rt=find(cluster_to_tr(:,1)==cnode(rcn)&cluster_to_tr(:,2)==centre_pts(c1,3)|cluster_to_tr(:,1)==centre_pts(c1,3)&cluster_to_tr(:,2)==cnode(rcn)); + if ~isempty(rl1)&&~isempty(rl2) + maxr=max([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + medr=median([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + minr=min([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + if cluster_to_tr(sres,4)==minr%||cluster_to_tr(sres,4)==medr + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + tcase=vertcat(tcase,[cluster_to_tr(sres,3),cluster_to_tr(sres,4), cluster_to_tr(sres,6), cluster_to_tr(rc(n),3),cluster_to_tr(rc(n),4),cluster_to_tr(rc(n),6),cluster_to_tr(rt(1),3),cluster_to_tr(rt(1),4),cluster_to_tr(rt(1),6),6]); + ccase=vertcat(ccase,[cluster_to_tr(sres,1) cluster_to_tr(sres,2) cluster_to_tr(rc(n),1) cluster_to_tr(rc(n),2) cluster_to_tr(rt(1),1) cluster_to_tr(rt(1),2)]); + end + + + end + elseif length(rcn)==2 + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + end + end + end + end + end + end + end + + + + if ~isempty(intermediate) + sss=sss+length(intermediate(:,1)); + end + if ~isempty(split) + for g=1:length(split(:,1)) + rc1=find(centre_pts(:,3)==split(g,1)); + rc2=find(centre_pts(:,3)==split(g,2)); + in1 = inpolygon(centre_pts(rc1,1),centre_pts(rc1,2),bbox2(:,1),bbox2(:,2)); + in2 = inpolygon(centre_pts(rc2,1),centre_pts(rc2,2),bbox2(:,1),bbox2(:,2)); + ds=sqrt((centre_pts(rc1,1)-centre_pts(rc2,1))^2+(centre_pts(rc1,2)-centre_pts(rc2,2))^2); + if (in1==0||in2==0)&&(centre_pts(rc1,3)~=centre_pts(rc2,3)) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),centre_pts(rc2,3), maxcl, round((centre_pts(rc1,9)+centre_pts(rc2,9))/2), round((centre_pts(rc1,8)+centre_pts(rc2,8))/2), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)], 2)]); + netnodes=vertcat(netnodes,[maxcl,split(g,3),0,1,1,0,0,0]); + end + end + end + + validids=unique(validids,'rows'); + + cm=find(c4(:)~=centre_pts(c1,3)&c4(:)~=centre_pts(c2,3)); + if ~isempty(cm) && scounter>=1 + for g=1:length(cm) + if ~isempty(validids) + rv=find(centre_pts(validids(:,1),3)==c4(cm(g))); + if isempty(rv)%compute vert dist + for t=1:length(res) + gdy=0; + if t==1 + bbox2=[]; + slope=(netsections(res(t),3)-centre_pts(c1,2))/(netsections(res(t),2)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + rcen=find(centre_pts(:,3)==c4(cm(g))); + d=abs(slope*centre_pts(rcen,1) + (-1)*centre_pts(rcen,2) + b)/sqrt(slope^2+(-1)^2); + dx1=sqrt((centre_pts(c1,1)-netsections(res(t),2))^2+(centre_pts(c1,2)-netsections(res(t),3))^2); + + ndegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(t),2),netsections(res(t),3)]); + + + if scounter<=10 + gdy=20; + else + gdy=15; + end + + + x1=centre_pts(c1,1)+(gdy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(gdy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(gdy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(gdy)*sind(ndegrees+90); + x3=netsections(res(1),2)+(gdy)*cosd(ndegrees-90); + y3=netsections(res(1),3)+(gdy)*sind(ndegrees-90); + x4=netsections(res(1),2)+(gdy)*cosd(ndegrees+90); + y4=netsections(res(1),3)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + + inp = inpolygon(centre_pts(rcen,1),centre_pts(rcen,2),bbox2(:,1),bbox2(:,2)); + if d<=gdy && inp==1 + validids=vertcat(validids,[rcen centre_pts(rcen,6)]); + end + end + if t==length(res) + bbox2=[]; + slope=(centre_pts(c2,2)-netsections(res(t),3))/(centre_pts(c2,1)-netsections(res(t),2)); + b=centre_pts(c2,2) - slope*centre_pts(c2,1); + rcen=find(centre_pts(:,3)==c4(cm(g))); + d=abs(slope*centre_pts(rcen,1) + (-1)*centre_pts(rcen,2) + b)/sqrt(slope^2+(-1)^2); + dx1=sqrt((centre_pts(c2,1)-netsections(res(t),2))^2+(centre_pts(c2,2)-netsections(res(t),3))^2); + + ndegrees=line_angle([netsections(res(t),2),netsections(res(t),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + + if scounter<=10 + gdy=20; + else + gdy=15; + end + + x1=netsections(res(t),2)+(gdy)*cosd(ndegrees-90); + y1=netsections(res(t),3)+(gdy)*sind(ndegrees-90); + x2=netsections(res(t),2)+(gdy)*cosd(ndegrees+90); + y2=netsections(res(t),3)+(gdy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(gdy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(gdy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(gdy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + + inp = inpolygon(centre_pts(rcen,1),centre_pts(rcen,2),bbox2(:,1),bbox2(:,2)); + + if d<=gdy && inp==1 + validids=vertcat(validids,[rcen centre_pts(rcen,6)]); + end + end + if t1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + cclust(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + cclust(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + tclusters=[]; + tid=1; + len=length(cclust); + cl=find(cclust(:)~=0); + cclust=cclust(cl); + for n=1:length(cclust) + if cclust(n)~=1 && cclust(n)~=len + tclusters(tid)=cclust(n); + tid=tid+1; + end + end + + cclust=tclusters-1; + Cldist=[]; + Cldist=[centre_pts(c1,1), centre_pts(c1,2)]; + Cldist=vertcat(Cldist, [centre_pts(nodes(cclust),1) centre_pts(nodes(cclust),2)]); + Cldist=vertcat(Cldist, [centre_pts(c2,1), centre_pts(c2,2)]); + + + pointset=[]; + for l=1:length(res) + pointset=vertcat(pointset,[netsections(res(l),2) netsections(res(l),3) netnodes(k,2)]); + end + + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + r=find(netsections(:,1)==nsegs(l,1)); + if ~isempty(r) + for m=1:length(r) + pointset=vertcat(pointset,[netsections(r(m),2) netsections(r(m),3) nsegs(l,2)]); + end + end + end + end + + if ~isempty(intermediate) + intermediate=unique(intermediate,'rows'); + for l=1:length(intermediate(:,1)) + pointset=vertcat(pointset,[intermediate(l,1) intermediate(l,2) intermediate(l,3)]); + end + end + + if ~isempty(pointset) + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pointset(:,1)) + if isPointInCircle([pointset(l,1), pointset(l,2)], circle) + idx=vertcat(idx,l); + end + end + pointset(idx,:)=[]; + + circle = [[centre_pts(c2,1) centre_pts(c2,2)] 15]; + idx=[]; + for l=1:length(pointset(:,1)) + if isPointInCircle([pointset(l,1), pointset(l,2)], circle) + idx=vertcat(idx,l); + end + end + pointset(idx,:)=[]; + for g=1:length(cclust) + circle = [[centre_pts(nodes(cclust(g)),1) centre_pts(nodes(cclust(g)),2)] 15]; + idx=[]; + for l=1:length(pointset(:,1)) + if isPointInCircle([pointset(l,1), pointset(l,2)], circle) + idx=vertcat(idx,l); + end + end + pointset(idx,:)=[]; + end + end + + if ~isempty(pointset) + [ps idps]=unique([pointset(:,1) pointset(:,2)],'rows'); + pointset=pointset(idps,:); + end + + pseq=pointset; + + ppseq=[]; + ptemp=[]; + if ~isempty(pseq) + Cldist=[]; + Cldist=[centre_pts(c1,1), centre_pts(c1,2)]; + Cldist=vertcat(Cldist, [pseq(:,1), pseq(:,2)]); + Cldist=vertcat(Cldist, [centre_pts(c2,1), centre_pts(c2,2)]); + Y = pdist(Cldist,'euclid'); + SQ=squareform(Y); + mclust=zeros(length(Cldist), 1); + + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of centres point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Cldist(:,1)) + + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclust(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclust(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + mc=mclust~=0; + mclust=mclust(mc); + pseq=pseq(mclust(2:length(mclust)-1)-1,:); + ptemp=temp; + Cldist(:,3)=1; + temp=Cldist(mclust(2:length(mclust)-1),:); + ppseq=pseq; + end + + pseq=ppseq; + + if ~isempty(pseq) + rp= pseq(:,1)==centre_pts(c1,1)&pseq(:,2)==centre_pts(c1,2); + pseq(rp,:)=[]; + rp=pseq(:,1)==centre_pts(c2,1)&pseq(:,2)==centre_pts(c2,2); + pseq(rp,:)=[]; + for v=1:length(cclust) + rp= pseq(:,1)==centre_pts(nodes(cclust(v)),1)&pseq(:,2)==centre_pts(nodes(cclust(v)),2); + if ~isempty(rp) + pseq(rp,:)=[]; + end + end + end + + + Cldist=[]; + Cldist=[centre_pts(c1,1), centre_pts(c1,2)]; + if ~isempty(pseq) + PP=vertcat([centre_pts(nodes(cclust),1), centre_pts(nodes(cclust),2)],[pseq(:,1), pseq(:,2)]); + else + PP=[centre_pts(nodes(cclust),1), centre_pts(nodes(cclust),2)]; + end + PP=unique(PP,'rows'); + Cldist=vertcat(Cldist, PP); + Cldist=vertcat(Cldist, [centre_pts(c2,1), centre_pts(c2,2)]); + Y = pdist(Cldist,'euclid'); + SQ=squareform(Y); + pointseq=[]; + pointseq=zeros(length(Cldist), 1); + + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of centres point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Cldist(:,1)) + + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + pointseq(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + pointseq(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + seq=find(pointseq~=0); + pointseq=pointseq(seq); + sequence=[]; + + for l=1:length(pointseq) + sequence=vertcat(sequence,[Cldist(pointseq(l),1), Cldist(pointseq(l),2)]); + end + + idx=[]; + for g=1:length(cclust) + rc=find(sequence(:,1)==centre_pts(nodes(cclust(g)),1)&sequence(:,2)==centre_pts(nodes(cclust(g)),2)); + if ~isempty(rc) + idx=vertcat(idx,g); + end + end + + if ~isempty(segscl) + ids=[]; + for g=1:length(segscl(:,1)) + rg=find(cluster_to_tr(:,3)==segscl(g,1)); + if ~isempty(rg) + ri1=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,1)); + ri2=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,2)); + if isempty(ri1)&&isempty(ri2) + ids=vertcat(ids,g); + end + end + end + if ~isempty(ids) + ids=unique(ids); + segscl(ids,:)=[]; + end + end + + if ~isempty(nsegs) + ids=[]; + for g=1:length(nsegs(:,1)) + rg=find(cluster_to_tr(:,3)==nsegs(g,1)); + if ~isempty(rg) + ri1=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,1)); + ri2=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,2)); + if isempty(ri1)||isempty(ri2) + ids=vertcat(ids,g); + end + end + end + if ~isempty(ids) + ids=unique(ids); + nsegs(ids,:)=[]; + end + end + + if ~isempty(idx) + cclust=cclust(idx); + end + + if ~isempty(pseq) + idx=[]; + for g=1:length(pseq(:,1)) + rc=find(sequence(:,1)==pseq(g,1)&sequence(:,2)==pseq(g,2)); + if isempty(rc) + idx=vertcat(idx,g); + end + end + if ~isempty(idx) + pseq(idx,:)=[]; + end + end + + if ~isempty(cclust) + + drc=[]; + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(c1,3),2]); + end + end + end + end + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c2,3)||cluster_to_tr(r,2)==centre_pts(c2,3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(c2,3),2]); + end + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(c1,3),2]); + end + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c2,3)||cluster_to_tr(r,2)==centre_pts(c2,3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(c2,3),2]); + end + end + end + end + for l=1:length(cclust) + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(nodes(cclust(l)),3),2]); + end + end + end + end + end + for l=1:length(cclust) + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(nodes(cclust(l)),3),2]); + end + end + end + end + end + + if ~isempty(drc) + [dr drid]=unique(drc(:,1),'rows'); + drc=drc(drid,:); + end + + w1=netnodes(k,2); + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w1=w1+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + rr=find(netnodes(:,1)==segscl(g,1)); + w1=w1+netnodes(rr,2); + end + end + end + + w2=netnodes(k,2); + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(memf,3)||cluster_to_tr(r,2)==centre_pts(memf,3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w2=w2+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(memf,3)||cluster_to_tr(r,2)==centre_pts(memf,3) + rr=find(netnodes(:,1)==segscl(g,1)); + w2=w2+netnodes(rr,2); + end + end + end + + + wgt=[]; + for l=1:length(cclust) + w=0; + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w=w+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + rr=find(netnodes(:,1)==segscl(g,1)); + w=w+netnodes(rr,2); + end + end + end + wgt=vertcat(wgt,[centre_pts(nodes(cclust(l)),3),w]); + end + + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + rr=find(cluster_to_tr(:,3)==nsegs(l,1)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + rr=find(netsections(:,1)==nsegs(l,1)); + rr=unique(rr); + h=length(rr); + while h>=1 + netsections(rr(h),:)=[]; + h=h-1; + end + end + end + + if ~isempty(segscl) + for l=1:length(segscl(:,1)) + rr=find(cluster_to_tr(:,3)==segscl(l,1)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + rr=find(netsections(:,1)==segscl(l,1)); + rr=unique(rr); + h=length(rr); + while h>=1 + netsections(rr(h),:)=[]; + h=h-1; + end + end + end + + if ~isempty(prvfl) + for v=1:length(prvfl) + dx=sqrt((centre_pts(c1,1)-centre_pts(prvfl(v),1))^2+(centre_pts(c1,2)-centre_pts(prvfl(v),2))^2); + if dx<=100 + rch=find(cluster_to_tr(:,1)==centre_pts(prvfl(v),3) & cluster_to_tr(:,2)==centre_pts(c1,3)); + if isempty(rch) + if centre_pts(prvfl(v),3)~=centre_pts(c1,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(prvfl(v),3),centre_pts(c1,3), clid, round((centre_pts(c1,9)+centre_pts(prvfl(v),9))/2), round((centre_pts(c1,8)+centre_pts(prvfl(v),8))/2), distancePoints([centre_pts(prvfl(v),1) centre_pts(prvfl(v),2)], [centre_pts(c1,1) centre_pts(c1,2)], 2)]); + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(prvfl(v),3)|drc(:,1)==centre_pts(c1,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + end + end + end + end + + for t=1:length(cclust) + c7=find(centre_pts(:,3)==centre_pts(nodes(cclust(t)),3)); + if t==1 + rch=find(cluster_to_tr(:,1)==centre_pts(c1,3) & cluster_to_tr(:,2)==centre_pts(c7,3)); + if isempty(rch) + if centre_pts(c1,3)~=centre_pts(c7,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c1,3), centre_pts(c7,3), clid, round((centre_pts(c1,9)+centre_pts(c7,9))/2), round((centre_pts(c1,8)+centre_pts(c7,8))/2), distancePoints([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(c7,3)|drc(:,1)==centre_pts(c1,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c1,1) & sequence(:,2)==centre_pts(c1,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c1,8)+centre_pts(c7,8))/2); + + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c1,1) & sequence(:,2)==centre_pts(c1,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + dd=round((centre_pts(c1,8)+centre_pts(c7,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + else + c8=find(centre_pts(:,3)==centre_pts(nodes(cclust(t-1)),3)); + rch=find(cluster_to_tr(:,1)==centre_pts(c8,3) & cluster_to_tr(:,2)== centre_pts(c7,3)); + if isempty(rch) + if centre_pts(c8,3)~=centre_pts(c7,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c8,3), centre_pts(c7,3), clid, round((centre_pts(c8,9)+centre_pts(c7,9))/2), round((centre_pts(c8,8)+centre_pts(c7,8))/2), distancePoints([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(c7,3)|drc(:,1)==centre_pts(c8,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c8,1) & sequence(:,2)==centre_pts(c8,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c8,8)+centre_pts(c7,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c8,1) centre_pts(c8,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c8,1) centre_pts(c8,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c8,1) & sequence(:,2)==centre_pts(c8,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + dd=round((centre_pts(c8,8)+centre_pts(c7,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c8,1) centre_pts(c8,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c8,1) centre_pts(c8,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + end + end + + if cclust(length(cclust))~=0 + c7=find(centre_pts(:,3)==centre_pts(nodes(cclust(length(cclust))),3)); + rch=find(cluster_to_tr(:,1)==centre_pts(c7,3) & cluster_to_tr(:,2)== centre_pts(memf,3)); + if isempty(rch) + if centre_pts(c7,3)~=centre_pts(memf,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c7,3), centre_pts(memf,3), clid, round((centre_pts(c7,9)+centre_pts(memf,9))/2), round((centre_pts(c7,8)+centre_pts(memf,8))/2), distancePoints([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(memf,3)|drc(:,1)==centre_pts(c7,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r2=find(sequence(:,1)==centre_pts(memf,1) & sequence(:,2)==centre_pts(memf,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c7,8)+centre_pts(memf,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(memf,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(memf,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(memf,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(memf,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(memf,1) centre_pts(memf,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c7,1) centre_pts(c7,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(memf,1) centre_pts(memf,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r2=find(sequence(:,1)==centre_pts(memf,1) & sequence(:,2)==centre_pts(memf,2)); + dd=round((centre_pts(c7,8)+centre_pts(memf,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(memf,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(memf,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(memf,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(memf,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(memf,1) centre_pts(memf,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c7,1) centre_pts(c7,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(memf,1) centre_pts(memf,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + end + + if ~isempty(nxtfl) + for v=1:length(nxtfl) + dx=sqrt((centre_pts(memf,1)-centre_pts(nxtfl(v),1))^2+(centre_pts(memf,2)-centre_pts(nxtfl(v),2))^2); + if dx<=100 + rch=find(cluster_to_tr(:,1)==centre_pts(memf,3) & cluster_to_tr(:,2)==centre_pts(nxtfl(v),3)); + if isempty(rch) + if centre_pts(memf,3)~=centre_pts(nxtfl(v),3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(memf,3),centre_pts(nxtfl(v),3), clid, round((centre_pts(memf,9)+centre_pts(nxtfl(v),9))/2), round((centre_pts(memf,8)+centre_pts(nxtfl(v),8))/2), distancePoints([centre_pts(memf,1) centre_pts(memf,2)], [centre_pts(nxtfl(v),1) centre_pts(nxtfl(v),2)], 2)]); + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(memf,3)|drc(:,1)==centre_pts(nxtfl(v),3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + end + end + end + end + + rr=find(cluster_to_tr(:,1)==centre_pts(c1,3)&cluster_to_tr(:,2)==centre_pts(c2,3)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + if ~isempty(res) + r=find(netsections(:,1)==netnodes(k,1)); + r=unique(r); + h=length(r); + while h>=1 + netsections(r(h),:)=[]; + h=h-1; + end + end + + else + p1=0; + p2=0; + p3=0; + p4=0; + + + dd=round((centre_pts(c1,8)+centre_pts(c2,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(res) + for v=1:length(res) + if v==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + + rv=find(pts(:,1)==centre_pts(c1,1)&pts(:,2)==centre_pts(c1,2)); + if isempty(rv) + pts=vertcat(pts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + p1=length(pts(:,1)); + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=pts; + mb=unique(pts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + + x1=netsections(res(1),2)+dd; + y1=netsections(res(1),3)+dd; + x2=netsections(res(1),2)+dd; + y2=netsections(res(1),3)-dd; + x3=netsections(res(1),2)-dd; + y3=netsections(res(1),3)+dd; + x4=netsections(res(1),2)-dd; + y4=netsections(res(1),3)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + ndegrees=rad2deg(angle2Points([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)])); + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)]); + + e1 =orthogonalLine(in, [netsections(res(1),2) netsections(res(1),3)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([netsections(res(1),2) netsections(res(1),3)], 0); + tr2 = createRotation([netsections(res(1),2) netsections(res(1),3)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=netsections(res(1),2)&elk(rss(h),2)~=netsections(res(1),3)&elk(rss(h),3)~=netsections(res(1),2)&elk(rss(h),4)~=netsections(res(1),3) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + if ~isempty(pts) + + rv=find(pts(:,1)==netsections(res(1),2)&pts(:,2)==netsections(res(1),3)); + if isempty(rv) + pts=vertcat(pts,[netsections(res(1),2) netsections(res(1),3)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([netsections(res(1),2) netsections(res(1),3)], aa, 2)<=dd + netsections(res(1),2)=aa(1,1); + netsections(res(1),3)=aa(1,2); + end + + end + end + end + if v==length(res) + ndegrees=rad2deg(angle2Points([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)])); + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + + in = createLine([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c2,1),centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1),centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1),centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c2,1)&elk(rss(h),2)~=centre_pts(c2,2)&elk(rss(h),3)~=centre_pts(c2,1)&elk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + + rv=find(pts(:,1)==centre_pts(c2,1)&pts(:,2)==centre_pts(c2,2)); + if isempty(rv) + pts=vertcat(pts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + p2=length(pts(:,1)); + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=pts; + mb=unique(pts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + + + x1=netsections(res(length(res)),2)+dd; + y1=netsections(res(length(res)),3)+dd; + x2=netsections(res(length(res)),2)+dd; + y2=netsections(res(length(res)),3)-dd; + x3=netsections(res(length(res)),2)-dd; + y3=netsections(res(length(res)),3)+dd; + x4=netsections(res(length(res)),2)-dd; + y4=netsections(res(length(res)),3)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + e1 =orthogonalLine(in, [netsections(res(length(res)),2) netsections(res(length(res)),3)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([netsections(res(length(res)),2) netsections(res(length(res)),3)], 0); + tr2 = createRotation([netsections(res(length(res)),2) netsections(res(length(res)),3)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=netsections(res(length(res)),2)&elk(rss(h),2)~=netsections(res(length(res)),3)&elk(rss(h),3)~=netsections(res(length(res)),2)&elk(rss(h),4)~=netsections(res(length(res)),3) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + rv=find(pts(:,1)==netsections(res(length(res)),2)&pts(:,2)==netsections(res(length(res)),3)); + if isempty(rv) + pts=vertcat(pts,[netsections(res(length(res)),2) netsections(res(length(res)),3)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([netsections(res(length(res)),2) netsections(res(length(res)),3)], aa, 2)<=dd + netsections(res(length(res)),2)=aa(1,1); + netsections(res(length(res)),3)=aa(1,2); + end + end + end + end + if v1 + aa=centroid(pts); + if distancePoints([netsections(res(v),2) netsections(res(v),3)], aa, 2)<=dd + netsections(res(v),2)=aa(1,1); + netsections(res(v),3)=aa(1,2); + end + end + end + end + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c2,1) centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c2,1)&elk(rss(h),2)~=centre_pts(c2,2)&elk(rss(h),3)~=centre_pts(c2,1)&elk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c2,1)&vpts(:,2)==centre_pts(c2,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + + cluster_to_tr(sres,4)=max(p1,p2); + cluster_to_tr(sres,5)=max(p3,p4); + end + end + + + elseif isempty(res) && ~isempty(sres) + + c1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + st(1,1)=centre_pts(c1,1); + st(1,2)=centre_pts(c1,2); + en(1,1)=centre_pts(c2,1); + en(1,2)=centre_pts(c2,2); + dx1=sqrt((centre_pts(c1,1)-centre_pts(c2,1))^2+(centre_pts(c1,2)-centre_pts(c2,2))^2); + gdy=0; + + distances1=vertcat(distances1,dx1); + + if scounter>10 + dy=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy=45; + gdy=20; + end + end + + memf=c2; + + validids=[]; + vid=1; + segment=[]; + sid=1; + minids=[]; + mid=1; + + bbox=[]; + rbbox=[]; + + ndegrees=rad2deg(angle2Points([centre_pts(c1,1),centre_pts(c1,2)],[centre_pts(c2,1),centre_pts(c2,2)])); + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + bbox=mb'; + poly1=[centre_pts(c1,1) centre_pts(c1,2)]; + poly1=vertcat(poly1,[centre_pts(c2,1) centre_pts(c2,2)]); + in = inpolygon(centre_pts(:,1),centre_pts(:,2),bbox(:,1),bbox(:,2)); + c4=centre_pts(in,3); + + hold on; + nsegs=[]; + segscl=[]; + validids=[]; + if ~isempty(c4) + intermediate=[]; + split=[]; + for h=1:length(c4) + rc=find(cluster_to_tr(:,1)==c4(h)|cluster_to_tr(:,2)==c4(h)); + for n=1:length(rc) + segment=[]; + maxd=2000; + if cluster_to_tr(rc(n),1)==cluster_to_tr(sres,1)&&cluster_to_tr(rc(n),2)==cluster_to_tr(sres,2) + continue; + elseif cluster_to_tr(rc(n),1)==cluster_to_tr(sres,2)&&cluster_to_tr(rc(n),2)==cluster_to_tr(sres,1) + rw=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes(k,2)=netnodes(k,2)+netnodes(rw,2); + netnodes(k,4)=2; + nsegs=vertcat(nsegs,[cluster_to_tr(rc(n),3),2]); + continue; + else + memcntr=0; + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + rn=find(netsections(:,1)==cluster_to_tr(rc(n),3)); + segment=[centre_pts(rc1,1) centre_pts(rc1,2)]; + segment=vertcat(segment, [netsections(rn,2) netsections(rn,3)]); + segment=vertcat(segment, [centre_pts(rc2,1) centre_pts(rc2,2)]); + segment(:,3)=0; + dx1=sqrt((centre_pts(c1,1)-centre_pts(c2,1))^2+(centre_pts(c1,2)-centre_pts(c2,2))^2); + maxd=dy; + ri=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + if ~isempty(ri) + riw=netnodes(ri,2); + end + + if scounter>10 + dy=20; + gdy=15; + elseif scounter<=10 + if cluster_to_tr(sres,5)~=0 + if cluster_to_tr(sres,5)<=50 + dy=cluster_to_tr(sres,5)+5; + gdy=20; + else + dy=cluster_to_tr(sres,5); + gdy=20; + end + + else + dy=45; + gdy=20; + end + end + + ndegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[centre_pts(c2,1),centre_pts(c2,2)]); + + if ndegrees>=0 && ndegrees<90 + + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=100||d(2)<=100) && (cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))&&... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3)) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + if d(rd)>dy && d(rd)<100 + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + else + if (d(1)<=200||d(2)<=200) && ((cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))||... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3))) + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + if ~isempty(rl1) && ~isempty(rl2) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)<=25&&d(2)<=dd + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)==0&&d(2)<=50||d(1)<=50&&d(2)==0 + rd=find(d==max(d)); + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + end + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + end + else + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20&&in1==1&&in2==1 + segment(1,3)=1; + segment(2,3)=1; + elseif d(1)<=20&&d(2)<=20&&(in1==1||in1==0)&&(in2==1||in1==0) + segment(1,3)=in1; + segment(2,3)=in2; + else + if d(1)<=20 + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + in1=0; + in2=0; + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + + else + in1=in; + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + + else + in2=in; + end + + if in1==1&& in2==1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(1,3)=1; + segment(2,3)=1; + end + end + end + elseif ndegrees>=90 && ndegrees<180 + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + + if (d(1)<=100||d(2)<=100) && (cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))&&... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3)) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + if d(rd)>dy && d(rd)<100 + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + else + if (d(1)<=200||d(2)<=200) && ((cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))||... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3))) + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + if ~isempty(rl1) && ~isempty(rl2) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)<=25&&d(2)<=dd + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)==0&&d(2)<=50||d(1)<=50&&d(2)==0 + rd=find(d==max(d)); + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + end + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + end + else + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20&&in1==1&&in2==1 + segment(1,3)=1; + segment(2,3)=1; + elseif d(1)<=20&&d(2)<=20&&(in1==1||in1==0)&&(in2==1||in1==0) + segment(1,3)=in1; + segment(2,3)=in2; + else + if d(1)<=20 + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + in1=0; + in2=0; + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + + else + in1=in; + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + + else + in2=in; + end + + if in1==1&& in2==1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(1,3)=1; + segment(2,3)=1; + end + end + end + elseif ndegrees>=180 && ndegrees<270 + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + + if (d(1)<=100||d(2)<=100) && (cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))&&... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3)) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + if d(rd)>dy && d(rd)<100 + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + else + if (d(1)<=200||d(2)<=200) && ((cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))||... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3))) + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + if ~isempty(rl1) && ~isempty(rl2) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + + else + if d(1)<=25&&d(2)<=dd + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)==0&&d(2)<=50||d(1)<=50&&d(2)==0 + rd=find(d==max(d)); + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + end + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<60 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + end + else + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20&&in1==1&&in2==1 + segment(1,3)=1; + segment(2,3)=1; + elseif d(1)<=20&&d(2)<=20&&(in1==1||in1==0)&&(in2==1||in1==0) + segment(1,3)=in1; + segment(2,3)=in2; + else + if d(1)<=20 + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + in1=0; + in2=0; + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + + else + in1=in; + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + + else + in2=in; + end + + if in1==1&& in2==1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(1,3)=1; + segment(2,3)=1; + end + end + end + elseif ndegrees>=270 && ndegrees<=361 + Ddist=vertcat([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rc2,1) centre_pts(rc2,2)]); + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + d=abs(slope*Ddist(:,1) + (-1)*Ddist(:,2) + b)/sqrt(slope^2+(-1)^2); + + if (d(1)<=100||d(2)<=100) && (cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))&&... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3)) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + if d(rd)>dy && d(rd)<100 + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + else + if (d(1)<=200||d(2)<=200) && ((cluster_to_tr(rc(n),1)==centre_pts(c1,3)||cluster_to_tr(rc(n),1)==centre_pts(c2,3))||... + (cluster_to_tr(rc(n),2)==centre_pts(c1,3)||cluster_to_tr(rc(n),2)==centre_pts(c2,3))) + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + if ~isempty(rl1) && ~isempty(rl2) + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)<=25&&d(2)<=dd + rd=find(d==max(d)); + if d(rd)==0 + x1=centre_pts(c1,1)+5*cosd(ndegrees-90); + y1=centre_pts(c1,2)+5*sind(ndegrees-90); + x2=centre_pts(c1,1)+5*cosd(ndegrees+90); + y2=centre_pts(c1,2)+5*sind(ndegrees+90); + x3=centre_pts(c2,1)+5*cosd(ndegrees-90); + y3=centre_pts(c2,2)+5*sind(ndegrees-90); + x4=centre_pts(c2,1)+5*cosd(ndegrees+90); + y4=centre_pts(c2,2)+5*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + end + else + if d(1)==0&&d(2)<=50||d(1)<=50&&d(2)==0 + rd=find(d==max(d)); + x1=centre_pts(c1,1)+d(rd)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+d(rd)*sind(ndegrees-90); + x2=centre_pts(c1,1)+d(rd)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+d(rd)*sind(ndegrees+90); + x3=centre_pts(c2,1)+d(rd)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+d(rd)*sind(ndegrees-90); + x4=centre_pts(c2,1)+d(rd)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+d(rd)*sind(ndegrees+90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + end + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + end + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + if ~isempty(rn) + for o=1:length(rn) + if o==1 + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[netsections(rn(1),2),netsections(rn(1),3)]); + if segment(o,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(1),2),netsections(rn(1),3),bbox(:,1),bbox(:,2)); + if segment(o+1,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + + end + if o==length(rn) + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([netsections(rn(length(rn)),2),netsections(rn(length(rn)),3)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if segment(length(rn)+2,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+2,3)=in; + end + [in,bnd] = inpolygon(netsections(rn(length(rn)),2),netsections(rn(length(rn)),3),bbox(:,1),bbox(:,2)); + if segment(length(rn)+1,3)~=1 && (abs(ndegrees-pdegrees)<60||abs(ndegrees-pdegrees)>300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(length(rn)+1,3)=in; + end + end + [in,bnd] = inpolygon(netsections(rn(o),2), netsections(rn(o),3),bbox(:,1),bbox(:,2)); + if o300 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(o+1,3)=in; + end + end + else + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + [in,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + if (d(1)<=20||d(2)<=20)&&(abs(ndegrees-pdegrees)<=25||abs(ndegrees-pdegrees)>=345||abs(ndegrees-pdegrees)>=165&&abs(ndegrees-pdegrees)<=195) + if d(1)~=0&&d(2)~=0 + if d(1)<=20&&d(2)<=20&&in1==1&&in2==1 + segment(1,3)=1; + segment(2,3)=1; + elseif d(1)<=20&&d(2)<=20&&(in1==1||in1==0)&&(in2==1||in1==0) + segment(1,3)=in1; + segment(2,3)=in2; + else + if d(1)<=20 + memcntr=rc1; + segment(1,3)=1; + end + if d(2)<=20 + memcntr=rc2; + segment(2,3)=1; + end + end + else + if centre_pts(rc1,3)~=centre_pts(c1,3)&¢re_pts(rc1,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + if centre_pts(rc2,3)~=centre_pts(c1,3)&¢re_pts(rc2,3)~=centre_pts(c2,3) + + if in1==1 + validids=vertcat(validids,[rc1 cluster_to_tr(rc(n),4)]); + elseif in2==1 + validids=vertcat(validids,[rc2 cluster_to_tr(rc(n),4)]); + end + segment(1,3)=in1; + segment(2,3)=in2; + end + end + else + in1=0; + in2=0; + if segment(1,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(1,3)=in; + + else + in1=in; + end + [in,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + + if segment(2,3)~=1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) && (d(1)<=100&&d(2)<=100) + segment(2,3)=in; + + else + in2=in; + end + + if in1==1&& in2==1 && (abs(ndegrees-pdegrees)<=80||abs(ndegrees-pdegrees)>=280 || abs(ndegrees-pdegrees)>135 && abs(ndegrees-pdegrees)<240) + segment(1,3)=1; + segment(2,3)=1; + end + end + end + else + disp('mpikes') + end + + nrs=find(segment(:,3)==1); + if ~isempty(rn) && ~isempty(nrs) + if (length(nrs)/length(segment(:,1)))~=1 + if length(nrs)==1 && (centre_pts(rc1,3)==centre_pts(c1,3)||centre_pts(rc1,3)==centre_pts(c2,3)||centre_pts(rc2,3)==centre_pts(c1,3)||centre_pts(rc2,3)==centre_pts(c2,3)) + else + if segment(1,3)==0&&segment(length(segment(:,1)),3)==0 + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + elseif segment(1,3)==0||segment(length(segment(:,1)),3)==0 + if segment(1,3)==1 + validids=vertcat(validids, [rc1 cluster_to_tr(rc(n),4)]); + elseif segment(length(segment(:,1)),3)==1 + validids=vertcat(validids, [rc2 cluster_to_tr(rc(n),4)]); + end + + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + + + if length(nrs)>1 + % fix new segment + if segment(1,3)==0 + new=[]; + g=2; + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g+1; + while segment(g,3)~=1 && g<=length(segment(:,1)) + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g+1; + end + + memcen=[segment(g,1) segment(g,2)]; + pdegrees=line_angle([new(length(new(:,1)),1), new(length(new(:,1)),2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + + + if centre_pts(rc1,1)~=new(length(new(:,1)),1)&¢re_pts(rc1,2)~=new(length(new(:,1)),2) + rcen=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + rcenm=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if ~isempty(rcen)%centre1_exists + rl=find(cluster_to_tr(:,1)==centre_pts(rc1,3) & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl) + if centre_pts(rc1,3)~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),centre_pts(rcen,3), maxcl, round((centre_pts(rc1,9)+centre_pts(rcen,9))/2), round((centre_pts(rc1,8)+centre_pts(rcen,8))/2), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(rcen,1) centre_pts(rcen,2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=1; + while g1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + mflag=1; + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + + rl2=find(cluster_to_tr(:,1)==centre_pts(rcen,3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rcen,3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcen,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rcen,1) centre_pts(rcen,2)], [centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + + end + + end + + else%centre_1_not_exists + x1=new(length(new(:,1)),1)+10; + y1=new(length(new(:,1)),2)+10; + x2=new(length(new(:,1)),1)+10; + y2=new(length(new(:,1)),2)-10; + x3=new(length(new(:,1)),1)-10; + y3=new(length(new(:,1)),2)+10; + x4=new(length(new(:,1)),1)-10; + y4=new(length(new(:,1)),2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + mflag=0; + if ~isempty(inidx) + if length(inidx)>1 + Pd=[new(length(new(:,1)),1), new(length(new(:,1)),2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + mflag=1; + else + rxc=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[new(length(new(:,1)),1) new(length(new(:,1)),2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + + rl2=find(cluster_to_tr(:,1)==centre_pts(rc1,3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rc1,3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)], [centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)], 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=1; + while g1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc2=centre_pts(inidx(rm(1)-1),3); + else + maxc2=centre_pts(inidx(rm-1),3); + end + else + maxc2=centre_pts(inidx,3); + end + mflag=1; + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc2=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc2 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==maxc2); + if isempty(rl2) + if maxc~=maxc2 + maxcl=(max(netnodes(:,1))+1); + rmc1=find(centre_pts(:,3)==maxc); + rmc2=find(centre_pts(:,3)==maxc2); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,maxc2, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rmc1,1) centre_pts(rmc1,2)],[centre_pts(rmc2,1) centre_pts(rmc2,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + + nrsp=find(segment(:,3)==0); + if length(nrsp)==2 && maxc2~=rc2 + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + split=vertcat(split,[maxc2, centre_pts(rc2,3), netnodes(wht,2),cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5)]); + end + end + end + end + end + + elseif segment(length(segment(:,1)),3)==0 + new=[]; + g=length(segment(:,1))-1; + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g-1; + while segment(g,3)~=1 && g>0 + new=vertcat(new,[segment(g,1) segment(g,2)]); + g=g-1; + end + + memcen=[segment(g,1) segment(g,2)]; + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[new(length(new(:,1)),1), new(length(new(:,1)),2)]); + + if centre_pts(rc2,1)~=new(length(new(:,1)),1)&¢re_pts(rc2,2)~=new(length(new(:,1)),2) + rcen=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + rcenm=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if ~isempty(rcen)%centre_exists + rl=find(cluster_to_tr(:,2)==centre_pts(rc2,3) & cluster_to_tr(:,1)==centre_pts(rcen,3)); + if isempty(rl) + if centre_pts(rcen,3)~=centre_pts(rc2,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcen,3),centre_pts(rc2,3), maxcl, round((centre_pts(rcen,9)+centre_pts(rc2,9))/2), round((centre_pts(rcen,8)+centre_pts(rc2,8))/2), distancePoints([centre_pts(rcen,1) centre_pts(rcen,2)],[centre_pts(rc2,1) centre_pts(rc2,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=length(new(:,1))-1; + while g>0 + netsections=vertcat(netsections,[maxcl new(g,1) new(g,2) 0 0]); + g=g-1; + end + end + end + end + + if ~isempty(rcenm)%centre2_exists + rl2=find(cluster_to_tr(:,1)==centre_pts(rcenm,3) & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl2) + if centre_pts(rcenm,3)~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcenm,3),centre_pts(rcen,3), maxcl, round((centre_pts(rcenm,9)+centre_pts(rcen,9))/2), round((centre_pts(rcenm,8)+centre_pts(rcen,8))/2), distancePoints([centre_pts(rcenm,1) centre_pts(rcenm,2)],[centre_pts(rcen,1) centre_pts(rcen,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + else + x1=memcen(1,1)+10; + y1=memcen(1,2)+10; + x2=memcen(1,1)+10; + y2=memcen(1,2)-10; + x3=memcen(1,1)-10; + y3=memcen(1,2)+10; + x4=memcen(1,1)-10; + y4=memcen(1,2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + if ~isempty(inidx) + if length(inidx)>1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + else + maxc=centre_pts(inidx,3); + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==centre_pts(rcen,3)); + if isempty(rl2) + if maxc~=centre_pts(rcen,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,centre_pts(rcen,3), maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)],[centre_pts(rcen,1) centre_pts(rcen,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + + end + else + x1=new(length(new(:,1)),1)+10; + y1=new(length(new(:,1)),2)+10; + x2=new(length(new(:,1)),1)+10; + y2=new(length(new(:,1)),2)-10; + x3=new(length(new(:,1)),1)-10; + y3=new(length(new(:,1)),2)+10; + x4=new(length(new(:,1)),1)-10; + y4=new(length(new(:,1)),2)-10; + cflag=0; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + if ~isempty(inidx) + if length(inidx)>1 + Pd=[new(length(new(:,1)),1), new(length(new(:,1)),2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc=centre_pts(inidx(rm(1)-1),3); + else + maxc=centre_pts(inidx(rm-1),3); + end + cflag=1; + else + maxc=centre_pts(inidx,3); + cflag=1; + end + else + rxc=find(centre_pts(:,1)==new(length(new(:,1)),1)¢re_pts(:,2)==new(length(new(:,1)),2)); + if isempty(rxc) + maxc=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[new(length(new(:,1)),1) new(length(new(:,1)),2) maxc 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc & cluster_to_tr(:,2)==centre_pts(rc2,3)); + if isempty(rl2) + if maxc~=centre_pts(rc2,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,centre_pts(rc2,3), maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)],[centre_pts(rc2,1) centre_pts(rc2,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=length(new(:,1))-1; + while g>0 + netsections=vertcat(netsections,[maxcl new(g,1) new(g,2) 0 0]); + g=g-1; + end + end + end + elseif ~isempty(rl2)&&cflag==1 %near to the first node + if maxc~=centre_pts(rc2,3) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[maxc,centre_pts(rc2,3), maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)],[centre_pts(rc2,1) centre_pts(rc2,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + if length(new(:,1))>1 + g=length(new(:,1))-1; + while g>0 + netsections=vertcat(netsections,[maxcl new(g,1) new(g,2) 0 0]); + g=g-1; + end + end + end + end + if ~isempty(rcenm)%centre2_exists + rl2=find(cluster_to_tr(:,1)==centre_pts(rcenm(1),3) & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if centre_pts(rcenm(1),3)~=maxc + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rcenm,3),maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rcenm,1) centre_pts(rcenm,2)],[centre_pts(length(centre_pts(:,1)),1) centre_pts(length(centre_pts(:,1)),2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + end + end + else + x1=memcen(1,1)+10; + y1=memcen(1,2)+10; + x2=memcen(1,1)+10; + y2=memcen(1,2)-10; + x3=memcen(1,1)-10; + y3=memcen(1,2)+10; + x4=memcen(1,1)-10; + y4=memcen(1,2)-10; + + node=[x1 y1;x2 y2;x4 y4;x3 y3;x1 y1]; + in = inpolygon(centre_pts(:,1), centre_pts(:,2),node(:,1),node(:,2)); + inidx=find(in~=0); + cflag=0; + if ~isempty(inidx) + if length(inidx)>1 + Pd=[memcen(1,1) memcen(1,2)]; + Pd=vertcat(Pd,[centre_pts(inidx,1) centre_pts(inidx,2)]); + Y = pdist(Pd,'euclid'); + SQ=squareform(Y); + minid=find(SQ(1,:)>0); + mindist=min(SQ(minid)); + rm=find(SQ(1,:)==mindist); + if length(rm)>1% two with the same distance + maxc2=centre_pts(inidx(rm(1)-1),3); + else + maxc2=centre_pts(inidx(rm-1),3); + end + cflag=1; + else + maxc2=centre_pts(inidx,3); + cflag=1; + end + else + rxc=find(centre_pts(:,1)==memcen(1,1)¢re_pts(:,2)==memcen(1,2)); + if isempty(rxc) + maxc2=(max(centre_pts(:,3))+1); + centre_pts=vertcat(centre_pts,[memcen(1,1) memcen(1,2) maxc2 0 0 round((centre_pts(c1,6)+centre_pts(c2,6))/2) round((centre_pts(c1,7)+centre_pts(c2,7))/2) (centre_pts(c1,8)+centre_pts(c2,8))/2 round((centre_pts(c1,9)+centre_pts(c2,9))/2)]); + end + end + rl2=find(cluster_to_tr(:,1)==maxc2 & cluster_to_tr(:,2)==maxc); + if isempty(rl2) + if maxc2~=maxc + maxcl=(max(netnodes(:,1))+1); + rmc1=find(centre_pts(:,3)==maxc2); + rmc2=find(centre_pts(:,3)==maxc); + cluster_to_tr=vertcat(cluster_to_tr,[maxc2,maxc, maxcl, cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5), distancePoints([centre_pts(rmc1,1) centre_pts(rmc1,2)],[centre_pts(rmc2,1) centre_pts(rmc2,2)] , 2)]); + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + netnodes=vertcat(netnodes,[maxcl,netnodes(wht,2),0,1,1,0,0,0]); + + nrsp=find(segment(:,3)==0); + if length(nrsp)==2 && maxc2~=rc1 + wht=find(netnodes(:,1)==cluster_to_tr(rc(n),3)); + split=vertcat(split,[centre_pts(rc1,3), maxc2, netnodes(wht,2),cluster_to_tr(rc(n),4), cluster_to_tr(rc(n),5)]); + end + end + end + end + end + end + end + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),2]); + else + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),1]); + end + + end + else + validids=vertcat(validids, [rc1 cluster_to_tr(rc(n),4)]); + validids=vertcat(validids, [rc2 cluster_to_tr(rc(n),4)]); + + g=2; + while g<=(length(segment(:,1))-1) + if segment(g,3)==1 + intermediate=vertcat(intermediate,[segment(g,1) segment(g,2) riw]); + end + g=g+1; + end + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),2]); + else + segscl=vertcat(segscl, [cluster_to_tr(rc(n),3),1]); + end + end + end + else + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + elseif isempty(rn)&&(length(nrs)/length(segment(:,1)))>=0.5 + if length(nrs)/length(segment(:,1))>0.5 + + cnode=[]; + cnode=vertcat(cnode,cluster_to_tr(rc(n),1)); + cnode=vertcat(cnode,cluster_to_tr(rc(n),2)); + rcn=find(cnode(:)~=centre_pts(c1,3)&cnode(:)~=centre_pts(c2,3)); + if length(rcn)==1 + rl=find(cluster_to_tr(:,1)==cnode(rcn)|cluster_to_tr(:,2)==cnode(rcn)); + anodes=[]; + for g=1:length(rl) + anodes=vertcat(anodes,cluster_to_tr(rl(g),1)); + anodes=vertcat(anodes,cluster_to_tr(rl(g),2)); + end + anodes=unique(anodes,'rows'); + rl1=find(anodes(:)==centre_pts(c1,3)); + rl2=find(anodes(:)==centre_pts(c2,3)); + if ~isempty(rl1)&&~isempty(rl2) + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + rt=find(cluster_to_tr(:,1)==cnode(rcn)&cluster_to_tr(:,2)==centre_pts(c1,3)|cluster_to_tr(:,1)==centre_pts(c1,3)&cluster_to_tr(:,2)==cnode(rcn)); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + + maxr=max([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + medr=median([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + minr=min([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + if cluster_to_tr(sres,4)==minr + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + tcase=vertcat(tcase,[cluster_to_tr(sres,3),cluster_to_tr(sres,4), cluster_to_tr(sres,6), cluster_to_tr(rc(n),3),cluster_to_tr(rc(n),4),cluster_to_tr(rc(n),6),cluster_to_tr(rt(1),3),cluster_to_tr(rt(1),4),cluster_to_tr(rt(1),6),1]); + ccase=vertcat(ccase,[cluster_to_tr(sres,1) cluster_to_tr(sres,2) cluster_to_tr(rc(n),1) cluster_to_tr(rc(n),2) cluster_to_tr(rt(1),1) cluster_to_tr(rt(1),2)]); + end + else + + maxr=max([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + medr=median([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + minr=min([cluster_to_tr(sres,4) cluster_to_tr(rc(n),4) cluster_to_tr(rt(1),4)]); + if cluster_to_tr(sres,4)==minr + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + tcase=vertcat(tcase,[cluster_to_tr(sres,3),cluster_to_tr(sres,4), cluster_to_tr(sres,6), cluster_to_tr(rc(n),3),cluster_to_tr(rc(n),4),cluster_to_tr(rc(n),6),cluster_to_tr(rt(1),3),cluster_to_tr(rt(1),4),cluster_to_tr(rt(1),6),1]); + ccase=vertcat(ccase,[cluster_to_tr(sres,1) cluster_to_tr(sres,2) cluster_to_tr(rc(n),1) cluster_to_tr(rc(n),2) cluster_to_tr(rt(1),1) cluster_to_tr(rt(1),2)]); + end + end + elseif isempty(rl1)&&~isempty(rl2)||~isempty(rl1)&&isempty(rl2) + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + segment(:,3)=0; + rd=find(d==max(d)); + + if ~isempty(rd)&d(rd)<=80 + x1=centre_pts(c1,1)+(d(rd))*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(d(rd))*sind(ndegrees-90); + x3=centre_pts(c2,1)+(d(rd))*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(d(rd))*sind(ndegrees-90); + else + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + end + + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + if in1==1 && in2==1 && ((abs(ndegrees-pdegrees)<=50||abs(ndegrees-pdegrees)>=315)||abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225) + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + + segment(:,3)=0; + if ~isempty(rd)&d(rd)<=80 + x2=centre_pts(c1,1)+(d(rd))*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(d(rd))*sind(ndegrees+90); + x4=centre_pts(c2,1)+(d(rd))*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(d(rd))*sind(ndegrees+90); + else + x2=centre_pts(c1,1)+(dy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(dy)*sind(ndegrees+90); + x4=centre_pts(c2,1)+(dy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(dy)*sind(ndegrees+90); + end + + x1=centre_pts(c1,1)+(dy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(dy)*sind(ndegrees-90); + x3=centre_pts(c2,1)+(dy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(dy)*sind(ndegrees-90); + + node=[x1 y1;x3 y3;x4 y4;x2 y2;x1 y1]; + bbox=[node(:,1) node(:,2)]; + + [in1,bnd] = inpolygon(centre_pts(rc1,1), centre_pts(rc1,2),bbox(:,1),bbox(:,2)); + [in2,bnd] = inpolygon(centre_pts(rc2,1), centre_pts(rc2,2),bbox(:,1),bbox(:,2)); + if in1==1 && in2==1 && ((abs(ndegrees-pdegrees)<=50||abs(ndegrees-pdegrees)>=315)||abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225) + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + end + elseif length(rcn)==2 + rc1=find(centre_pts(:,3)==cluster_to_tr(rc(n),1)); + rc2=find(centre_pts(:,3)==cluster_to_tr(rc(n),2)); + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(rc1,1), centre_pts(rc1,2)],[centre_pts(rc2,1), centre_pts(rc2,2)]); + if abs(ndegrees-pdegrees)>=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + elseif memcntr~=0 + validids=vertcat(validids, [memcntr cluster_to_tr(rc(n),4)]); + end + elseif isempty(rn)&&(length(nrs)/length(segment(:,1)))>0.5 + if segment(1,3)==0 + dx1=sqrt((centre_pts(c1,1)-centre_pts(rc1,1))^2+(centre_pts(c1,2)-centre_pts(rc1,2))^2); + dx2=sqrt((centre_pts(c2,1)-centre_pts(rc1,1))^2+(centre_pts(c2,2)-centre_pts(rc1,2))^2); + if dx1=135&&abs(ndegrees-pdegrees)<=225 + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),2]); + else + nsegs=vertcat(nsegs, [cluster_to_tr(rc(n),3),1]); + end + end + end + end + end + end + if ~isempty(intermediate) + sss=sss+length(intermediate(:,1)); + end + cm=find(c4(:)~=centre_pts(c1,3)&c4(:)~=centre_pts(c2,3)); + if ~isempty(cm) && scounter>=1 + for g=1:length(cm) + if ~isempty(validids) + rv=find(centre_pts(validids(:,1),3)==c4(cm(g))); + if isempty(rv)%compute vert dist + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + rcen=find(centre_pts(:,3)==c4(cm(g))); + d=abs(slope*centre_pts(rcen,1) + (-1)*centre_pts(rcen,2) + b)/sqrt(slope^2+(-1)^2); + + if d<=gdy + validids=vertcat(validids,[rcen centre_pts(rcen,6)]); + end + end + else + slope=(centre_pts(c2,2)-centre_pts(c1,2))/(centre_pts(c2,1)-centre_pts(c1,1)); + b=centre_pts(c1,2) - slope*centre_pts(c1,1); + rcen=find(centre_pts(:,3)==c4(cm(g))); + d=abs(slope*centre_pts(rcen,1) + (-1)*centre_pts(rcen,2) + b)/sqrt(slope^2+(-1)^2); + + if d<=gdy + validids=vertcat(validids,[rcen centre_pts(rcen,6)]); + end + + end + + end + end + + if ~isempty(nsegs) + [nnsegs nids]=unique(nsegs(:,1),'rows'); + nsegs=nsegs(nids,:); + end + + if ~isempty(segscl) + [ssegscl sids]=unique(segscl(:,1),'rows'); + segscl=segscl(sids,:); + end + + validids=unique(validids,'rows'); + + nodes=[]; + if ~isempty(validids) + for l=1:length(validids(:,1)) + nodes=vertcat(nodes,validids(l,1)); + end + end + + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + m=find(cluster_to_tr(:,3)==nsegs(l,1)); + if ~isempty(m) + r=find(centre_pts(:,3)==cluster_to_tr(m,1)); + nodes=vertcat(nodes,r); + r=find(centre_pts(:,3)==cluster_to_tr(m,2)); + nodes=vertcat(nodes,r); + end + end + end + + nodes=unique(nodes,'rows'); + tokeep=[]; + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + m=find(cluster_to_tr(:,3)==nsegs(l,1)); + if ~isempty(m) + if ~isempty(nodes) + r1=find(centre_pts(nodes,3)==cluster_to_tr(m,1)); + r2=find(centre_pts(nodes,3)==cluster_to_tr(m,2)); + if ~isempty(r1)&&~isempty(r2) + tokeep=vertcat(tokeep,l); + end + end + end + end + end + + if ~isempty(tokeep) + nsegs=nsegs(tokeep,:); + end + + idnx=[]; + for l=1:length(nodes) + if centre_pts(c1,3)~=centre_pts(nodes(l),3) && centre_pts(c2,3)~=centre_pts(nodes(l),3) + idnx=vertcat(idnx,l); + end + end + nodes=nodes(idnx); + + [dsr d] = dsearchn([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(nodes,1) centre_pts(nodes,2)]); + pts=(d<=200); + nearest=nodes(pts,:); + idxp=[]; + prvfl=[]; + for j=1:length(nearest) + ndegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(c2,1), centre_pts(c2,2)]); + pdegrees=line_angle([centre_pts(c1,1), centre_pts(c1,2)],[centre_pts(nearest(j),1), centre_pts(nearest(j),2)]); + end + + if ~isempty(prvfl) + prid=find(prvfl~=0); + prvfl=prvfl(prid); + end + if ~isempty(idxp) + for m=1:length(idxp) + rs=find(nodes(:)==nearest(idxp(m))); + if ~isempty(rs) + nodes(rs,:)=[]; + end + end + end + + + [dsr d] = dsearchn([centre_pts(c2,1) centre_pts(c2,2)],[centre_pts(nodes,1) centre_pts(nodes,2)]); + pts=(d<=200); + nearest=nodes(pts,:); + idxp=[]; + nxtfl=[]; + for j=1:length(nearest) + ndegrees=line_angle([centre_pts(c2,1), centre_pts(c2,2)],[centre_pts(c1,1), centre_pts(c1,2)]); + pdegrees=line_angle([centre_pts(c2,1), centre_pts(c2,2)],[centre_pts(nearest(j),1), centre_pts(nearest(j),2)]); + end + if ~isempty(nxtfl) + nxid=find(nxtfl~=0); + nxtfl=nxtfl(nxid); + end + if ~isempty(idxp) + for m=1:length(idxp) + rs=find(nodes(:)==nearest(idxp(m))); + if ~isempty(rs) + nodes(rs,:)=[]; + end + end + end + + vn=[]; + if ~isempty(nodes) + lline=createLine([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)]); + for h=1:length(nodes(:,1)) + if ~isempty(validids) + rn=find(validids(:,1)==nodes(h)); + rnx=find(validids(rn,2)==max(validids(rn,2))); + if ~isempty(rnx) && validids(rn(rnx),2)1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + cclust(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + cclust(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + + tclusters=[]; + tid=1; + len=length(cclust); + cl=find(cclust(:)~=0); + cclust=cclust(cl); + for n=1:length(cclust) + if cclust(n)~=1 && cclust(n)~=len + tclusters(tid)=cclust(n); + tid=tid+1; + end + end + + cclust=tclusters-1; + Cldist=[]; + Cldist=[centre_pts(c1,1), centre_pts(c1,2)]; + Cldist=vertcat(Cldist, [centre_pts(nodes(cclust),1) centre_pts(nodes(cclust),2)]); + Cldist=vertcat(Cldist, [centre_pts(c2,1), centre_pts(c2,2)]); + + + idx=[]; + for v=2:length(Cldist(:,1))-2 + mdegrees1=line_angle([Cldist(v,1), Cldist(v,2)],[Cldist(v+1,1), Cldist(v+1,2)]); + mdegrees2=line_angle([Cldist(v,1), Cldist(v,2)],[Cldist(v+2,1), Cldist(v+2,2)]); + + if abs(mdegrees1-mdegrees2)>45 + + r=find(cluster_to_tr(:,1)==centre_pts(nodes(cclust(v)),3)|cluster_to_tr(:,2)==centre_pts(nodes(cclust(v)),3)); + + end + end + + if ~isempty(idx) + cclust(idx-1)=[]; + end + + + bbox2=[]; + rbbox2=[]; + if ~isempty(cclust) + for t=1:length(cclust) + if t==1 + ndegrees=line_angle([centre_pts(c1,1),centre_pts(c1,2)],[centre_pts(nodes(cclust(t)),1),centre_pts(nodes(cclust(t)),2)]); + x1=centre_pts(c1,1)+(gdy)*cosd(ndegrees-90); + y1=centre_pts(c1,2)+(gdy)*sind(ndegrees-90); + x2=centre_pts(c1,1)+(gdy)*cosd(ndegrees+90); + y2=centre_pts(c1,2)+(gdy)*sind(ndegrees+90); + x3=centre_pts(nodes(cclust(t)),1)+(gdy)*cosd(ndegrees-90); + y3=centre_pts(nodes(cclust(t)),2)+(gdy)*sind(ndegrees-90); + x4=centre_pts(nodes(cclust(t)),1)+(gdy)*cosd(ndegrees+90); + y4=centre_pts(nodes(cclust(t)),2)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3]; + rbbox2=vertcat(rbbox2,[x2 y2]); + rbbox2=vertcat(rbbox2,[x4 y4]); + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + + elseif t==length(cclust) + ndegrees=line_angle([centre_pts(nodes(cclust(t)),1),centre_pts(nodes(cclust(t)),2)],[centre_pts(c2,1),centre_pts(c2,2)]); + x1=centre_pts(nodes(cclust(t)),1)+(gdy)*cosd(ndegrees-90); + y1=centre_pts(nodes(cclust(t)),2)+(gdy)*sind(ndegrees-90); + x2=centre_pts(nodes(cclust(t)),1)+(gdy)*cosd(ndegrees+90); + y2=centre_pts(nodes(cclust(t)),2)+(gdy)*sind(ndegrees+90); + x3=centre_pts(c2,1)+(gdy)*cosd(ndegrees-90); + y3=centre_pts(c2,2)+(gdy)*sind(ndegrees-90); + x4=centre_pts(c2,1)+(gdy)*cosd(ndegrees+90); + y4=centre_pts(c2,2)+(gdy)*sind(ndegrees+90); + + node=[x1 y1;x3 y3]; + rbbox2=vertcat(rbbox2,[x2 y2]); + rbbox2=vertcat(rbbox2,[x4 y4]); + bbox2=vertcat(bbox2,[node(:,1) node(:,2)]); + + elseif t=1 + bbox2=vertcat(bbox2,[rbbox2(ni,1) rbbox2(ni,2)]); + ni=ni-1; + end + bbox2=vertcat(bbox2,[bbox2(1,1) bbox2(1,2)]); + in = inpolygon(pts_ln.pts_ln(:,1),pts_ln.pts_ln(:,2),bbox2(:,1),bbox2(:,2)); + + intermediate2=[pts_ln.pts_ln(in,1),pts_ln.pts_ln(in,2)]; + intermediate2(:,3)=1; + end + + if ~isempty(split) + for g=1:length(split(:,1)) + rc1=find(centre_pts(:,3)==split(g,1)); + rc2=find(centre_pts(:,3)==split(g,2)); + in1 = inpolygon(centre_pts(rc1,1),centre_pts(rc1,2),bbox2(:,1),bbox2(:,2)); + in2 = inpolygon(centre_pts(rc2,1),centre_pts(rc2,2),bbox2(:,1),bbox2(:,2)); + ds=sqrt((centre_pts(rc1,1)-centre_pts(rc2,1))^2+(centre_pts(rc1,2)-centre_pts(rc2,2))^2); + if (in1==0||in2==0)&&(centre_pts(rc1,3)~=centre_pts(rc2,3)) + maxcl=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(rc1,3),centre_pts(rc2,3), maxcl, round((centre_pts(rc1,9)+centre_pts(rc2,9))/2), round((centre_pts(rc1,8)+centre_pts(rc2,8))/2), distancePoints([centre_pts(rc1,1) centre_pts(rc1,2)],[centre_pts(rc2,1) centre_pts(rc2,2)] , 2)]); + netnodes=vertcat(netnodes,[maxcl,split(g,3),0,1,1,0,0,0]); + end + end + end + + + pointset=[]; + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + r=find(netsections(:,1)==nsegs(l,1)); + if ~isempty(r) + for m=1:length(r) + pointset=vertcat(pointset,[netsections(r(m),2) netsections(r(m),3) nsegs(l,2)]); + end + end + end + end + + if ~isempty(intermediate) + intermediate=unique(intermediate,'rows'); + for l=1:length(intermediate(:,1)) + pointset=vertcat(pointset,[intermediate(l,1) intermediate(l,2) intermediate(l,3)]); + end + end + + if ~isempty(pointset) + lline=createLine([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)]); + for h=1:length(pointset(:,1)) + if pointset(h,3)1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclust(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclust(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + mc=mclust~=0; + mclust=mclust(mc); + pseq=pseq(mclust(2:length(mclust)-1)-1,:); + ptemp=temp; + + Cldist(:,3)=1; + temp=Cldist(mclust(2:length(mclust)-1),:); + + ppseq=pseq; + end + + pseq=ppseq; + if ~isempty(pseq) + rp= pseq(:,1)==centre_pts(c1,1)&pseq(:,2)==centre_pts(c1,2); + pseq(rp,:)=[]; + rp=pseq(:,1)==centre_pts(c2,1)&pseq(:,2)==centre_pts(c2,2); + pseq(rp,:)=[]; + for v=1:length(cclust) + rp= pseq(:,1)==centre_pts(nodes(cclust(v)),1)&pseq(:,2)==centre_pts(nodes(cclust(v)),2); + if ~isempty(rp) + pseq(rp,:)=[]; + end + end + end + + Cldist=[]; + Cldist=[centre_pts(c1,1), centre_pts(c1,2)]; + if ~isempty(pseq) + PP=vertcat([centre_pts(nodes(cclust),1), centre_pts(nodes(cclust),2)],[pseq(:,1), pseq(:,2)]); + else + PP=[centre_pts(nodes(cclust),1), centre_pts(nodes(cclust),2)]; + end + PP=unique(PP,'rows'); + Cldist=vertcat(Cldist, PP); + Cldist=vertcat(Cldist, [centre_pts(c2,1), centre_pts(c2,2)]); + Y = pdist(Cldist,'euclid'); + SQ=squareform(Y); + pointseq=[]; + pointseq=zeros(length(Cldist), 1); + + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of centres point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Cldist(:,1)) + + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + pointseq(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + pointseq(j)=idxk; + j=j+1; + end + + if length(Cldist(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + curr=resi; + idxk=curr; + end + + seq=find(pointseq~=0); + pointseq=pointseq(seq); + sequence=[]; + + for l=1:length(pointseq) + sequence=vertcat(sequence,[Cldist(pointseq(l),1), Cldist(pointseq(l),2)]); + end + + idx=[]; + for g=1:length(cclust) + rc=find(sequence(:,1)==centre_pts(nodes(cclust(g)),1)&sequence(:,2)==centre_pts(nodes(cclust(g)),2)); + if ~isempty(rc) + idx=vertcat(idx,g); + end + end + + if ~isempty(segscl) + ids=[]; + for g=1:length(segscl(:,1)) + rg=find(cluster_to_tr(:,3)==segscl(g,1)); + if ~isempty(rg) + ri1=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,1)); + ri2=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,2)); + if isempty(ri1)&&isempty(ri2) + ids=vertcat(ids,g); + end + end + end + if ~isempty(ids) + ids=unique(ids); + segscl(ids,:)=[]; + end + end + + if ~isempty(nsegs) + ids=[]; + for g=1:length(nsegs(:,1)) + rg=find(cluster_to_tr(:,3)==nsegs(g,1)); + if ~isempty(rg) + ri1=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,1)); + ri2=find(centre_pts(nodes(cclust(idx)),3)==cluster_to_tr(rg,2)); + if isempty(ri1)||isempty(ri2) + ids=vertcat(ids,g); + end + end + end + if ~isempty(ids) + ids=unique(ids); + nsegs(ids,:)=[]; + end + end + + if ~isempty(idx) + cclust=cclust(idx); + end + + if ~isempty(pseq) + idx=[]; + for g=1:length(pseq(:,1)) + rc=find(sequence(:,1)==pseq(g,1)&sequence(:,2)==pseq(g,2)); + if isempty(rc) + idx=vertcat(idx,g); + end + end + if ~isempty(idx) + pseq(idx,:)=[]; + + end + end + + if ~isempty(cclust) + + drc=[]; + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(c1,3),2]); + end + end + end + end + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c2,3)||cluster_to_tr(r,2)==centre_pts(c2,3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(c2,3),2]); + end + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(c1,3),2]); + end + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c2,3)||cluster_to_tr(r,2)==centre_pts(c2,3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(c2,3),2]); + end + end + end + end + for l=1:length(cclust) + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + if nsegs(g,2)==2 + drc=vertcat(drc,[centre_pts(nodes(cclust(l)),3),2]); + end + end + end + end + end + for l=1:length(cclust) + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + if segscl(g,2)==2 + drc=vertcat(drc,[centre_pts(nodes(cclust(l)),3),2]); + end + end + end + end + end + + if ~isempty(drc) + [dr drid]=unique(drc(:,1),'rows'); + drc=drc(drid,:); + end + + w1=netnodes(k,2); + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w1=w1+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(c1,3)||cluster_to_tr(r,2)==centre_pts(c1,3) + rr=find(netnodes(:,1)==segscl(g,1)); + w1=w1+netnodes(rr,2); + end + end + end + + w2=netnodes(k,2); + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(memf,3)||cluster_to_tr(r,2)==centre_pts(memf,3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w2=w2+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(memf,3)||cluster_to_tr(r,2)==centre_pts(memf,3) + rr=find(netnodes(:,1)==segscl(g,1)); + w2=w2+netnodes(rr,2); + end + end + end + + + wgt=[]; + for l=1:length(cclust) + w=0; + if ~isempty(nsegs) + for g=1:length(nsegs(:,1)) + r=find(cluster_to_tr(:,3)==nsegs(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + rr=find(netnodes(:,1)==nsegs(g,1)); + w=w+netnodes(rr,2); + end + end + end + if ~isempty(segscl) + for g=1:length(segscl(:,1)) + r=find(cluster_to_tr(:,3)==segscl(g,1)); + if cluster_to_tr(r,1)==centre_pts(nodes(cclust(l)),3)||cluster_to_tr(r,2)==centre_pts(nodes(cclust(l)),3) + rr=find(netnodes(:,1)==segscl(g,1)); + w=w+netnodes(rr,2); + end + end + end + wgt=vertcat(wgt,[centre_pts(nodes(cclust(l)),3),w]); + end + + if ~isempty(nsegs) + for l=1:length(nsegs(:,1)) + rr=find(cluster_to_tr(:,3)==nsegs(l,1)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + rr=find(netsections(:,1)==nsegs(l,1)); + rr=unique(rr); + h=length(rr); + while h>=1 + netsections(rr(h),:)=[]; + h=h-1; + end + end + end + + if ~isempty(segscl) + for l=1:length(segscl(:,1)) + rr=find(cluster_to_tr(:,3)==segscl(l,1)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + rr=find(netsections(:,1)==segscl(l,1)); + rr=unique(rr); + h=length(rr); + while h>=1 + netsections(rr(h),:)=[]; + h=h-1; + end + end + end + + if ~isempty(prvfl) + for v=1:length(prvfl) + dx=sqrt((centre_pts(c1,1)-centre_pts(prvfl(v),1))^2+(centre_pts(c1,2)-centre_pts(prvfl(v),2))^2); + if dx<=100 + rch=find(cluster_to_tr(:,1)==centre_pts(prvfl(v),3) & cluster_to_tr(:,2)==centre_pts(c1,3)); + if isempty(rch) + if centre_pts(prvfl(v),3)~=centre_pts(c1,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(prvfl(v),3),centre_pts(c1,3), clid, round((centre_pts(c1,9)+centre_pts(prvfl(v),9))/2), round((centre_pts(c1,8)+centre_pts(prvfl(v),8))/2), distancePoints([centre_pts(prvfl(v),1) centre_pts(prvfl(v),2)], [centre_pts(c1,1) centre_pts(c1,2)], 2)]); + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(prvfl(v),3)|drc(:,1)==centre_pts(c1,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + end + end + end + end + + for t=1:length(cclust) + c7=find(centre_pts(:,3)==centre_pts(nodes(cclust(t)),3)); + if t==1 + rch=find(cluster_to_tr(:,1)==centre_pts(c1,3) & cluster_to_tr(:,2)==centre_pts(c7,3)); + if isempty(rch) + if centre_pts(c1,3)~=centre_pts(c7,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c1,3), centre_pts(c7,3), clid, round((centre_pts(c1,9)+centre_pts(c7,9))/2), round((centre_pts(c1,8)+centre_pts(c7,8))/2), distancePoints([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(c7,3)|drc(:,1)==centre_pts(c1,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c1,1) & sequence(:,2)==centre_pts(c1,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c1,8)+centre_pts(c7,8))/2); + + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c1,1) & sequence(:,2)==centre_pts(c1,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + dd=round((centre_pts(c1,8)+centre_pts(c7,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + else + c8=find(centre_pts(:,3)==centre_pts(nodes(cclust(t-1)),3)); + rch=find(cluster_to_tr(:,1)==centre_pts(c8,3) & cluster_to_tr(:,2)== centre_pts(c7,3)); + if isempty(rch) + if centre_pts(c8,3)~=centre_pts(c7,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c8,3), centre_pts(c7,3), clid, round((centre_pts(c8,9)+centre_pts(c7,9))/2), round((centre_pts(c8,8)+centre_pts(c7,8))/2), distancePoints([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(c7,3)|drc(:,1)==centre_pts(c8,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c8,1) & sequence(:,2)==centre_pts(c8,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c8,8)+centre_pts(c7,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c8,1) centre_pts(c8,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c8,1) centre_pts(c8,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c8,1) & sequence(:,2)==centre_pts(c8,2)); + r2=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + dd=round((centre_pts(c8,8)+centre_pts(c7,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c7,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c7,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c7,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c7,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c8,1) centre_pts(c8,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c8,1) centre_pts(c8,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c7,1) centre_pts(c7,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c8,1) centre_pts(c8,2)], [centre_pts(c7,1) centre_pts(c7,2)])); + + x1=centre_pts(c8,1)+dd; + y1=centre_pts(c8,2)+dd; + x2=centre_pts(c8,1)+dd; + y2=centre_pts(c8,2)-dd; + x3=centre_pts(c8,1)-dd; + y3=centre_pts(c8,2)+dd; + x4=centre_pts(c8,1)-dd; + y4=centre_pts(c8,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c8,1) centre_pts(c8,2)],[centre_pts(c7,1) centre_pts(c7,2)]); + e1 =orthogonalLine(in, [centre_pts(c8,1) centre_pts(c8,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], 0); + tr2 = createRotation([centre_pts(c8,1) centre_pts(c8,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c8,1)&elk(rss(h),2)~=centre_pts(c8,2)&elk(rss(h),3)~=centre_pts(c8,1)&elk(rss(h),4)~=centre_pts(c8,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c8,1)&vpts(:,2)==centre_pts(c8,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c8,1) centre_pts(c8,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c8,1) centre_pts(c8,2)], aa, 2)<=dd + centre_pts(c8,1)=aa(1,1); + centre_pts(c8,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c8,1) centre_pts(c8,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c8,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c7,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + end + end + + if cclust(length(cclust))~=0 + c7=find(centre_pts(:,3)==centre_pts(nodes(cclust(length(cclust))),3)); + rch=find(cluster_to_tr(:,1)==centre_pts(c7,3) & cluster_to_tr(:,2)== centre_pts(memf,3)); + if isempty(rch) + if centre_pts(c7,3)~=centre_pts(memf,3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(c7,3), centre_pts(memf,3), clid, round((centre_pts(c7,9)+centre_pts(memf,9))/2), round((centre_pts(c7,8)+centre_pts(memf,8))/2), distancePoints([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)], 2)]); + if round((w1+wgt(t,2))/2)==0 + w=1; + else + w=round((w1+wgt(t,2))/2); + end + + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(memf,3)|drc(:,1)==centre_pts(c7,3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + r1=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r2=find(sequence(:,1)==centre_pts(memf,1) & sequence(:,2)==centre_pts(memf,2)); + r3=find(cluster_to_tr(:,3)==clid); + dd=round((centre_pts(c7,8)+centre_pts(memf,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(memf,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(memf,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(memf,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(memf,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(memf,1) centre_pts(memf,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c7,1) centre_pts(c7,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(memf,1) centre_pts(memf,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid,temp(m,1),temp(m,2),0,0]); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + else + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + end + end + end + + cluster_to_tr(r3,4)=max(p1,p2); + cluster_to_tr(r3,5)=max(p3,p4); + end + end + else + for n=1:length(rch) + rm=find(netsections(:,1)==cluster_to_tr(rch(n),3)); + if ~isempty(rm) + netsections(rm,:)=[]; + end + end + r1=find(sequence(:,1)==centre_pts(c7,1) & sequence(:,2)==centre_pts(c7,2)); + r2=find(sequence(:,1)==centre_pts(memf,1) & sequence(:,2)==centre_pts(memf,2)); + dd=round((centre_pts(c7,8)+centre_pts(memf,8))/2); + clid=cluster_to_tr(rch,3); + + if dd<1 + dd=15; + end + + if ~isempty(r1)&&~isempty(r2) + interpts=sequence((r1+1):(r2-1),:); + p1=0; + p2=0; + p3=0; + p4=0; + if ~isempty(interpts) + pts=[round(interpts(:,1)*100000)/100000 round(interpts(:,2)*100000)/100000]; + [rpts ipts]=unique(pts,'rows'); + ipts=sortrows(ipts,1); + pts=pts(ipts,:); + + if ~isempty(pts) + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(memf,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(memf,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(memf,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(memf,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c7,1) centre_pts(c7,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(memf,1) centre_pts(memf,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c7,1) centre_pts(c7,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(memf,1) centre_pts(memf,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + for x=1:length(clid) + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[clid(x),temp(m,1),temp(m,2),0,0]); + end + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c7,1) centre_pts(c7,2)], [centre_pts(memf,1) centre_pts(memf,2)])); + + x1=centre_pts(c7,1)+dd; + y1=centre_pts(c7,2)+dd; + x2=centre_pts(c7,1)+dd; + y2=centre_pts(c7,2)-dd; + x3=centre_pts(c7,1)-dd; + y3=centre_pts(c7,2)+dd; + x4=centre_pts(c7,1)-dd; + y4=centre_pts(c7,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c7,1) centre_pts(c7,2)],[centre_pts(memf,1) centre_pts(memf,2)]); + e1 =orthogonalLine(in, [centre_pts(c7,1) centre_pts(c7,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], 0); + tr2 = createRotation([centre_pts(c7,1) centre_pts(c7,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c7,1)&elk(rss(h),2)~=centre_pts(c7,2)&elk(rss(h),3)~=centre_pts(c7,1)&elk(rss(h),4)~=centre_pts(c7,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c7,1)&vpts(:,2)==centre_pts(c7,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c7,1) centre_pts(c7,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c7,1) centre_pts(c7,2)], aa, 2)<=dd + centre_pts(c7,1)=aa(1,1); + centre_pts(c7,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c7,1) centre_pts(c7,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c7,8)=p3; + + sequence(r1,1)=aa(1,1); + sequence(r1,2)=aa(1,2); + + end + end + end + + x1=centre_pts(memf,1)+dd; + y1=centre_pts(memf,2)+dd; + x2=centre_pts(memf,1)+dd; + y2=centre_pts(memf,2)-dd; + x3=centre_pts(memf,1)-dd; + y3=centre_pts(memf,2)+dd; + x4=centre_pts(memf,1)-dd; + y4=centre_pts(memf,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(memf,1) centre_pts(memf,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], 0); + tr2 = createRotation([centre_pts(memf,1) centre_pts(memf,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(memf,1)&elk(rss(h),2)~=centre_pts(memf,2)&elk(rss(h),3)~=centre_pts(memf,1)&elk(rss(h),4)~=centre_pts(memf,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(memf,1)&vpts(:,2)==centre_pts(memf,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(memf,1) centre_pts(memf,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(memf,1) centre_pts(memf,2)], aa, 2)<=dd + centre_pts(memf,1)=aa(1,1); + centre_pts(memf,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(memf,1) centre_pts(memf,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(memf,8)=p4; + + sequence(r2,1)=aa(1,1); + sequence(r2,2)=aa(1,2); + + end + end + end + for n=1:length(rch) + cluster_to_tr(rch(n),4)=max(p1,p2); + cluster_to_tr(rch(n),5)=max(p3,p4); + end + end + end + end + end + + if ~isempty(nxtfl) + for v=1:length(nxtfl) + dx=sqrt((centre_pts(memf,1)-centre_pts(nxtfl(v),1))^2+(centre_pts(memf,2)-centre_pts(nxtfl(v),2))^2); + if dx<=100 + rch=find(cluster_to_tr(:,1)==centre_pts(memf,3) & cluster_to_tr(:,2)==centre_pts(nxtfl(v),3)); + if isempty(rch) + if centre_pts(memf,3)~=centre_pts(nxtfl(v),3) + clid=(max(netnodes(:,1))+1); + cluster_to_tr=vertcat(cluster_to_tr,[centre_pts(memf,3),centre_pts(nxtfl(v),3), clid, round((centre_pts(memf,9)+centre_pts(nxtfl(v),9))/2), round((centre_pts(memf,8)+centre_pts(nxtfl(v),8))/2), distancePoints([centre_pts(memf,1) centre_pts(memf,2)], [centre_pts(nxtfl(v),1) centre_pts(nxtfl(v),2)], 2)]); + if ~isempty(drc) + dir=find(drc(:,1)==centre_pts(memf,3)|drc(:,1)==centre_pts(nxtfl(v),3)); + end + if ~isempty(dir) + netnodes=vertcat(netnodes,[clid,w,0,2,1,0,0,0]); + else + netnodes=vertcat(netnodes,[clid,w,0,1,1,0,0,0]); + end + end + end + end + end + end + + rr=find(cluster_to_tr(:,1)==centre_pts(c1,3)&cluster_to_tr(:,2)==centre_pts(c2,3)); + if ~isempty(rr) + cluster_to_tr(rr,:)=[]; + end + + if ~isempty(res) + r=find(netsections(:,1)==netnodes(k,1)); + r=unique(r); + h=length(r); + while h>=1 + netsections(r(h),:)=[]; + h=h-1; + end + end + + else + p1=0; + p2=0; + p3=0; + p4=0; + + + dd=round((centre_pts(c1,8)+centre_pts(c2,8))/2); + + if dd<1 + dd=15; + end + + if ~isempty(res) + for v=1:length(res) + if v==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + + rv=find(pts(:,1)==centre_pts(c1,1)&pts(:,2)==centre_pts(c1,2)); + if isempty(rv) + pts=vertcat(pts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + p1=length(pts(:,1)); + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=pts; + mb=unique(pts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + + x1=netsections(res(1),2)+dd; + y1=netsections(res(1),3)+dd; + x2=netsections(res(1),2)+dd; + y2=netsections(res(1),3)-dd; + x3=netsections(res(1),2)-dd; + y3=netsections(res(1),3)+dd; + x4=netsections(res(1),2)-dd; + y4=netsections(res(1),3)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + ndegrees=rad2deg(angle2Points([centre_pts(c1,1),centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)])); + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[netsections(res(1),2) netsections(res(1),3)]); + + e1 =orthogonalLine(in, [netsections(res(1),2) netsections(res(1),3)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([netsections(res(1),2) netsections(res(1),3)], 0); + tr2 = createRotation([netsections(res(1),2) netsections(res(1),3)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=netsections(res(1),2)&elk(rss(h),2)~=netsections(res(1),3)&elk(rss(h),3)~=netsections(res(1),2)&elk(rss(h),4)~=netsections(res(1),3) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + if ~isempty(pts) + + rv=find(pts(:,1)==netsections(res(1),2)&pts(:,2)==netsections(res(1),3)); + if isempty(rv) + pts=vertcat(pts,[netsections(res(1),2) netsections(res(1),3)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([netsections(res(1),2) netsections(res(1),3)], aa, 2)<=dd + netsections(res(1),2)=aa(1,1); + netsections(res(1),3)=aa(1,2); + end + + end + end + end + if v==length(res) + ndegrees=rad2deg(angle2Points([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)])); + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + + in = createLine([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c2,1),centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1),centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1),centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c2,1)&elk(rss(h),2)~=centre_pts(c2,2)&elk(rss(h),3)~=centre_pts(c2,1)&elk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + + rv=find(pts(:,1)==centre_pts(c2,1)&pts(:,2)==centre_pts(c2,2)); + if isempty(rv) + pts=vertcat(pts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + p2=length(pts(:,1)); + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=pts; + mb=unique(pts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + + + x1=netsections(res(length(res)),2)+dd; + y1=netsections(res(length(res)),3)+dd; + x2=netsections(res(length(res)),2)+dd; + y2=netsections(res(length(res)),3)-dd; + x3=netsections(res(length(res)),2)-dd; + y3=netsections(res(length(res)),3)+dd; + x4=netsections(res(length(res)),2)-dd; + y4=netsections(res(length(res)),3)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([netsections(res(length(res)),2) netsections(res(length(res)),3)],[centre_pts(c2,1),centre_pts(c2,2)]); + e1 =orthogonalLine(in, [netsections(res(length(res)),2) netsections(res(length(res)),3)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([netsections(res(length(res)),2) netsections(res(length(res)),3)], 0); + tr2 = createRotation([netsections(res(length(res)),2) netsections(res(length(res)),3)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + pts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=netsections(res(length(res)),2)&elk(rss(h),2)~=netsections(res(length(res)),3)&elk(rss(h),3)~=netsections(res(length(res)),2)&elk(rss(h),4)~=netsections(res(length(res)),3) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + pts=vertcat(vpts,point); + end + end + end + + if ~isempty(pts) + rv=find(pts(:,1)==netsections(res(length(res)),2)&pts(:,2)==netsections(res(length(res)),3)); + if isempty(rv) + pts=vertcat(pts,[netsections(res(length(res)),2) netsections(res(length(res)),3)]); + end + pts=unique([pts(:,1) pts(:,2)],'rows'); + + if length(pts(:,1))>1 + aa=centroid(pts); + if distancePoints([netsections(res(length(res)),2) netsections(res(length(res)),3)], aa, 2)<=dd + netsections(res(length(res)),2)=aa(1,1); + netsections(res(length(res)),3)=aa(1,2); + end + end + end + end + if v1 + aa=centroid(pts); + if distancePoints([netsections(res(v),2) netsections(res(v),3)], aa, 2)<=dd + netsections(res(v),2)=aa(1,1); + netsections(res(v),3)=aa(1,2); + end + end + end + end + end + else + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c1,1)&elk(rss(h),2)~=centre_pts(c1,2)&elk(rss(h),3)~=centre_pts(c1,1)&elk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(elk(:,1), elk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(elk(:,3), elk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + e1 =orthogonalLine(in, [centre_pts(c2,1) centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if elk(rss(h),1)~=centre_pts(c2,1)&elk(rss(h),2)~=centre_pts(c2,2)&elk(rss(h),3)~=centre_pts(c2,1)&elk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([elk(rss(h),1) elk(rss(h),2)], [elk(rss(h),3) elk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==centre_pts(c2,1)&vpts(:,2)==centre_pts(c2,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + + cluster_to_tr(sres,4)=max(p1,p2); + cluster_to_tr(sres,5)=max(p3,p4); + end + end + end + k=k+1; + end + + + if scounter>=1&&scounter<=20 + temp_centre_pts=sortrows(centre_pts,-8); + centre_pts=temp_centre_pts; + + g=1; + while g<=length(centre_pts(:,1)) + + p1=0; + if centre_pts(g,8)~=0 + if centre_pts(g,8)>1 + p1=centre_pts(g,8); + else + p1=15; + end + else + p1=15; + end + + x1=centre_pts(g,1)+p1; + y1=centre_pts(g,2)+p1; + x2=centre_pts(g,1)+p1; + y2=centre_pts(g,2)-p1; + x3=centre_pts(g,1)-p1; + y3=centre_pts(g,2)+p1; + x4=centre_pts(g,1)-p1; + y4=centre_pts(g,2)-p1; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in = inpolygon(centre_pts(:,1), centre_pts(:,2),mb(1,:), mb(2,:)); + rs=find(in==1); + rc=find(centre_pts(rs,3)~=centre_pts(g,3)); + rs=rs(rc); + + xy=[centre_pts(g,1) centre_pts(g,2)]; + for l=1:length(rs) + xy=vertcat(xy,[centre_pts(rs(l),1), centre_pts(rs(l),2)]); + end + + if length(xy(:,1))>1 + + aa=centroid(xy); + + centre_pts(g,1) = aa(1,1); + centre_pts(g,2) = aa(1,2); + + merged=[]; + if length(rs)>=1 + for m=1:length(rs) + merged=vertcat(merged,centre_pts(rs(m),3)); + end + end + + if ~isempty(merged) + keptid=centre_pts(g,3); + for m=1:length(merged(:,1)) + rc=find(centre_pts(:,3)==merged(m,1)); + centre_pts(rc,:)=0; + end + + for m=1:length(merged(:,1)) + res=find(cluster_to_tr(:,1)==merged(m,1)); + if ~isempty(res) + cluster_to_tr(res,1)=keptid; + end + + res=find(cluster_to_tr(:,2)==merged(m,1)); + if ~isempty(res) + cluster_to_tr(res,2)=keptid; + end + + resp1=find(pts_ln.pts_ln(:,14)==merged(m,1)); + resp2=find(pts_ln.pts_ln(:,15)==merged(m,1)); + if ~isempty(resp1) + pts_ln.pts_ln(resp1,14)=keptid; + end + if ~isempty(resp2) + pts_ln.pts_ln(resp2,15)=keptid; + end + end + + mres= (centre_pts(:,1)~=0); + newcentre_pts=centre_pts(mres,:); + clear centre_pts; + centre_pts=newcentre_pts; + clear newcentre_pts; + end + end + g=g+1; + end + end + + % merge opposite sites + % ndegrees + for g=1:length(netnodes(:,1)) + res=find(netsections(:,1)==netnodes(g,1)); + sres=find(cluster_to_tr(:,3)==netnodes(g,1)); + if ~isempty(res) && ~isempty(sres) + + resc1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + resc2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + + st(1,1)=centre_pts(resc1,1); + st(1,2)=centre_pts(resc1,2); + en(1,1)=centre_pts(resc2,1); + en(1,2)=centre_pts(resc2,2); + + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(1),2), netsections(res(1),3)])); + netsections(res(1),4)=mdegrees1; + if length(res)>1 + for m=1:(length(res)-1) + if m==1 % outgoing direction + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + if length(res)>1 + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + else + mdegrees2=rad2deg(angle2Points([netsections(res(m),2),netsections(res(m),3)],[en(1,1), en(1,2)])); + netsections(res(m),5)=mdegrees2; + end + end + if m==(length(res)-1) + if m>1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + else + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + end + + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + + mdegrees1=mdegrees2; + netsections(res(m+1),4)=mdegrees1; + end + if m1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + end + end + end + mdegrees2=rad2deg(angle2Points([netsections(res(length(res)),2),netsections(res(length(res)),3)],[en(1,1), en(1,2)])); + netsections(res(length(res)),5)=mdegrees2; + end + end + + ntoremove=[]; + nchecked=[]; + tnetnodes=netnodes; + tcluster_to_tr=cluster_to_tr; + for i=1:length(netnodes(:,1)) + r=find(cluster_to_tr(:,3)==netnodes(i,1)); + if ~isempty(r) + r1=find(cluster_to_tr(:,1)==cluster_to_tr(r,2) & cluster_to_tr(:,2)==cluster_to_tr(r,1)); + if ~isempty(r1) + netnodes(r,3)=2; + rc=find(nchecked==cluster_to_tr(r,3)); + if isempty(rc) + for h=1:length(r1) + nchecked=vertcat(nchecked,[cluster_to_tr(r,3), cluster_to_tr(r1(h),3)]); + rn=find(netnodes(:,1)==cluster_to_tr(r1(h),3)); + if ~isempty(rn) + ntoremove=vertcat(ntoremove,cluster_to_tr(r1(h),3)); + end + end + end + end + end + end + + if ~isempty(nchecked) + for i=1:length(nchecked(:,1)) + nn1=find(netsections(:,1)==nchecked(i,1)); + nn2=find(netsections(:,1)==nchecked(i,2)); + r=find(cluster_to_tr(:,3)==nchecked(i,1)); + c1=find(centre_pts(:,3)==cluster_to_tr(r,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(r,2)); + respts=[]; + memid=nchecked(i,1); + dids=[]; + if ~isempty(nn1) + respts=vertcat(respts, [netsections(nn1,2) netsections(nn1,3) netsections(nn1,4)]); + dids=vertcat(dids,nn1); + end + + if ~isempty(nn2) + respts=vertcat(respts, [netsections(nn2,2) netsections(nn2,3) netsections(nn2,4)]); + dids=vertcat(dids,nn2); + end + + rrespts=respts; + + if ~isempty(dids) + dids=unique(dids); + h=length(dids); + while h>=1 + netsections(dids(h),:)=[]; + h=h-1; + end + end + + if ~isempty(respts) + respts=unique([respts(:,1) respts(:,2)], 'rows'); + + pts=respts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 10]; + idx=[]; + for l=1:length(pts(:,1)) + if isPointInCircle([pts(l,1), pts(l,2)], circle) + idx=vertcat(idx,l); + end + end + pts(idx,:)=[]; + + circle = [[centre_pts(c2,1) centre_pts(c2,2)] 10]; + idx=[]; + for l=1:length(pts(:,1)) + if isPointInCircle([pts(l,1), pts(l,2)], circle) + idx=vertcat(idx,l); + end + end + pts(idx,:)=[]; + + pseq=[]; + + if ~isempty(pts) + cl=[]; + for b=1:length(pts(:,1)) + inr = find(elk(:,1)==pts(b,1)&elk(:,2)==pts(b,2)|elk(:,3)==pts(b,1)&elk(:,4)==pts(b,2)); + if ~isempty(inr) + cl=vertcat(cl,inr); + end + if b==1 + inr = find(elk(:,1)==centre_pts(c1,1)&elk(:,2)==centre_pts(c1,2)|elk(:,3)==centre_pts(c1,1)&elk(:,4)==centre_pts(c1,2)); + if ~isempty(inr) + cl=vertcat(cl,inr); + end + inr = find(elk(:,1)==centre_pts(c2,1)&elk(:,2)==centre_pts(c2,2)|elk(:,3)==centre_pts(c2,1)&elk(:,4)==centre_pts(c2,2)); + if ~isempty(inr) + cl=vertcat(cl,inr); + end + end + end + + cl=unique(cl,'rows'); + + for b=1:length(pts(:,1)) + rb=find(rrespts(:,1)==pts(b,1)&rrespts(:,2)==pts(b,2)); + ndegrees=max(rrespts(rb,3)); + + x1=pts(b,1)+(45)*cosd(ndegrees-90); + y1=pts(b,2)+(45)*sind(ndegrees-90); + x2=pts(b,1)+(45)*cosd(ndegrees+90); + y2=pts(b,2)+(45)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + vpts=[]; + for h=1:length(cl) + if elk(cl(h),1)~=pts(b,1)&elk(cl(h),2)~=pts(b,2)&elk(cl(h),3)~=pts(b,1)&elk(cl(h),4)~=pts(b,2) + e2 = createEdge([elk(cl(h),1) elk(cl(h),2)], [elk(cl(h),3) elk(cl(h),4)]); + point = intersectEdges(e1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) && (abs(ndegrees-rad2deg(angle2Points([elk(cl(h),1) elk(cl(h),2)], [elk(cl(h),3) elk(cl(h),4)])))<=20||abs(ndegrees-rad2deg(angle2Points([elk(cl(h),1) elk(cl(h),2)], [elk(cl(h),3) elk(cl(h),4)])))>=340||abs(ndegrees-rad2deg(angle2Points([elk(cl(h),1) elk(cl(h),2)], [elk(cl(h),3) elk(cl(h),4)])))>=160&&abs(ndegrees-rad2deg(angle2Points([elk(cl(h),1) elk(cl(h),2)], [elk(cl(h),3) elk(cl(h),4)])))<=200) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + rv=find(vpts(:,1)==pts(b,1)&vpts(:,2)==pts(b,2)); + if isempty(rv) + vpts=vertcat(vpts,[pts(b,1) pts(b,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + end + + pseq=pts; + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c2,1) centre_pts(c2,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for k=1:length(SQ(:,:)) + SQ(k,k)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for h=1:length(idxk) + mindist=min(SQ(idxk(h),:)); + if mindist<=minip + minip=mindist; + index=h; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + ppseq=temp; + + if ~isempty(ppseq) + for h=1:length(ppseq(:,1)) + netsections=vertcat(netsections,[memid ppseq(h,1) ppseq(h,2) 0 0]); + + end + end + + + end + end + end + end + + if~isempty(ntoremove) + for i=1:length(ntoremove) + r=find(netnodes(:,1)==ntoremove(i)); + if ~isempty(r) + netnodes(r,:)=[]; + end + r=find(cluster_to_tr(:,3)==ntoremove(i)); + if ~isempty(r) + cluster_to_tr(r,:)=[]; + end + end + end + + % clean the same starting and ending nodes + ntoremove=[]; + nid=1; + + for i=1:length(netnodes(:,1)) + r=find(cluster_to_tr(:,3)==netnodes(i,1)); + if cluster_to_tr(r,1)==cluster_to_tr(r,2) + ntoremove(nid)=netnodes(i,1); + nid=nid+1; + end + end + + for i=1:length(ntoremove) + r=find(netnodes(:,1)==ntoremove(i)); + if ~isempty(r) + netnodes(r,:)=[]; + end + r=find(cluster_to_tr(:,3)==ntoremove(i)); + if ~isempty(r) + cluster_to_tr(r,:)=[]; + end + r=find(netsections(:,1)==ntoremove(i)); + r=unique(r); + h=length(r); + while h>=1 + netsections(r(h),:)=[]; + h=h-1; + end + end + + tt=cluster_to_tr; + [Ys id]=unique([cluster_to_tr(:,1) cluster_to_tr(:,2)],'rows','first'); + [Ys ii] = setdiff(Ys(:,:),[0 0], 'rows'); + clcluster=[cluster_to_tr(id(ii),1) cluster_to_tr(id(ii),2) cluster_to_tr(id(ii),3) cluster_to_tr(id(ii),4) cluster_to_tr(id(ii),5) cluster_to_tr(id(ii),6)] ; + clear cluster_to_tr; + cluster_to_tr = [clcluster(:,1) clcluster(:,2) clcluster(:,3) clcluster(:,4) clcluster(:,5) clcluster(:,6)] ; + clear clcluster; + + % merge and remove the same + for i=1:length(cluster_to_tr(:,1)) + r=find(tt(:,1)==cluster_to_tr(i,1) & tt(:,2)==cluster_to_tr(i,2)); + r1=find(netnodes(:,1)==cluster_to_tr(i,3)); + if length(r)>1 + netnodes(r1,2)=netnodes(r1,2)+length(r); + end + memid=cluster_to_tr(i,3); + c1=find(centre_pts(:,3)==cluster_to_tr(i,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(i,2)); + + respts=[]; + + for k=1:length(r) + n1=find(netsections(:,1)==tt(r(k),3)); + respts=vertcat(respts, [netsections(n1,2) netsections(n1,3)]); + netsections(n1,:)=[]; + end + + respts=unique(respts, 'rows'); + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + NP=vertcat(NP, [respts(:,1) respts(:,2)]); + NP=vertcat(NP, [centre_pts(c2,1) centre_pts(c2,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + + Mdist(:,3)=1; + for k=1:length(SQ(:,:)) + SQ(k,k)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + clusters=zeros(length(mclusters)-2, length(mclusters)-2); + Mdist(:,3)=1; + temp=Mdist(mclusters(2:length(mclusters)-1),:); + sequence=[temp(:,1) temp(:,2)]; + + if ~isempty(sequence) + for m=1:length(sequence(:,1)) + netsections=vertcat(netsections,[memid sequence(m,1) sequence(m,2) 0 0]); + end + end + end + + for g=1:length(netnodes) + r=find(cluster_to_tr(:,3)==netnodes(g,1)); + rs=find(netsections(:,1)==netnodes(g,1)); + if ~isempty(rs)&&~isempty(r) + c1=find(centre_pts(:,3)==cluster_to_tr(r,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(r,2)); + ds1=sqrt((centre_pts(c1,1)-netsections(rs(1),2))^2+(centre_pts(c1,2)-netsections(rs(1),3))^2); + if ds1<=20 + netsections(rs(1),:)=[]; + end + end + rs=find(netsections(:,1)==netnodes(g,1)); + if ~isempty(rs)&&~isempty(r) + c1=find(centre_pts(:,3)==cluster_to_tr(r,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(r,2)); + ds2=sqrt((centre_pts(c2,1)-netsections(rs(length(rs)),2))^2+(centre_pts(c2,2)-netsections(rs(length(rs)),3))^2); + if ds2<=20 + netsections(rs(length(rs)),:)=[]; + end + end + end + + % calculate ndegrees + for g=1:length(netnodes(:,1)) + res=find(netsections(:,1)==netnodes(g,1)); + sres=find(cluster_to_tr(:,3)==netnodes(g,1)); + if ~isempty(res) && ~isempty(sres) + + resc1=find(centre_pts(:,3)==cluster_to_tr(sres,1)); + resc2=find(centre_pts(:,3)==cluster_to_tr(sres,2)); + + st(1,1)=centre_pts(resc1,1); + st(1,2)=centre_pts(resc1,2); + en(1,1)=centre_pts(resc2,1); + en(1,2)=centre_pts(resc2,2); + + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(1),2), netsections(res(1),3)])); + netsections(res(1),4)=mdegrees1; + if length(res)>1 + for m=1:(length(res)-1) + if m==1 % outgoing direction + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + if length(res)>1 + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + else + mdegrees2=rad2deg(angle2Points([netsections(res(m),2),netsections(res(m),3)],[en(1,1), en(1,2)])); + netsections(res(m),5)=mdegrees2; + end + end + if m==(length(res)-1) + if m>1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + else + mdegrees1=rad2deg(angle2Points([st(1,1), st(1,2)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + end + + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + + mdegrees1=mdegrees2; + netsections(res(m+1),4)=mdegrees1; + end + if m1 + mdegrees1=rad2deg(angle2Points([netsections(res(m-1),2), netsections(res(m-1),3)],[netsections(res(m),2), netsections(res(m),3)])); + netsections(res(m),4)=mdegrees1; + mdegrees2=rad2deg(angle2Points([netsections(res(m),2), netsections(res(m),3)],[netsections(res(m+1),2), netsections(res(m+1),3)])); + netsections(res(m),5)=mdegrees2; + end + end + end + mdegrees2=rad2deg(angle2Points([netsections(res(length(res)),2),netsections(res(length(res)),3)],[en(1,1), en(1,2)])); + netsections(res(length(res)),5)=mdegrees2; + end + end + + toremove=[]; + rid=1; + for q=1:length(netnodes) + sres=find(cluster_to_tr(:,3)==netnodes(q,1)); + if isempty(sres) + toremove(rid)=netnodes(q,1); + rid=rid+1; + end + end + + for q=1:length(toremove) + r=find(netnodes(:,1)==toremove(q)); + if ~isempty(r) + netnodes(r,:)=[]; + end + end + + toremove=[]; + rid=1; + for q=1:length(cluster_to_tr(:,1)) + sres=find(netnodes(:,1)==cluster_to_tr(q,3)); + if isempty(sres) + toremove(rid)=cluster_to_tr(q,3); + rid=rid+1; + end + end + + for q=1:length(toremove) + r=find(cluster_to_tr(:,3)==toremove(q)); + if ~isempty(r) + cluster_to_tr(r,:)=[]; + end + end + + toremove=[]; + rid=1; + for q=1:length(netnodes) + sres=find(cluster_to_tr(:,3)==netnodes(q,1)); + if isempty(sres) + toremove(rid)=netnodes(q,1); + rid=rid+1; + end + end + + for q=1:length(toremove) + r=find(netnodes(:,1)==toremove(q)); + if ~isempty(r) + netnodes(r,:)=[]; + end + end + + % calculate polyline dist + for g=1:length(cluster_to_tr(:,1)) + rx=find(netsections(:,1)==cluster_to_tr(g,3)); + rc=find(netnodes(:,1)==cluster_to_tr(g,3)); + c1=find(centre_pts(:,3)==cluster_to_tr(g,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(g,2)); + d=0; + if isempty(rx) + xy=[centre_pts(c1,1) centre_pts(c1,2)]; + xy=vertcat(xy,[centre_pts(c2,1) centre_pts(c2,2)]); + d = polylineLength(xy,'open'); + cluster_to_tr(g,6)=d; + netnodes(rc,4)=d; + else + xy=[centre_pts(c1,1) centre_pts(c1,2)]; + xy=vertcat(xy,[netsections(rx,2) netsections(rx,3)]); + xy=vertcat(xy,[centre_pts(c2,1) centre_pts(c2,2)]); + d = polylineLength(xy,'open'); + cluster_to_tr(g,6)=d; + netnodes(rc,4)=d; + end + end + + tempnet=sortrows(netnodes,-4); + netnodes=tempnet; + rlen=length(netnodes(:,1)); + k=1; + + scounter=scounter+1; +end + + +dd=40; + +for g=1:length(cluster_to_tr(:,1)) + + c1=find(centre_pts(:,3)==cluster_to_tr(g,1)); + c2=find(centre_pts(:,3)==cluster_to_tr(g,2)); + res=find(netsections(:,1)==cluster_to_tr(g,3)); + + pts=[netsections(res,2) netsections(res,3)]; + if ~isempty(pts) + + for b=1:length(pts(:,1)) + if b==1 + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [pts(b,1) pts(b,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[pts(b,1) pts(b,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if slk(rss(h),1)~=centre_pts(c1,1)&slk(rss(h),2)~=centre_pts(c1,2)&slk(rss(h),3)~=centre_pts(c1,1)&slk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + end + if b==length(pts(:,1)) + ndegrees=rad2deg(angle2Points([pts(b,1) pts(b,2)], [centre_pts(c2,1) centre_pts(c2,2)])); + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c2,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c2,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c2,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c2,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([pts(b,1) pts(b,2)],[centre_pts(c2,1) centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c2,1) centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if slk(rss(h),1)~=centre_pts(c2,1)&slk(rss(h),2)~=centre_pts(c2,2)&slk(rss(h),3)~=centre_pts(c2,1)&slk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c2,1)&vpts(:,2)==centre_pts(c2,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + end + if b1 + aa=centroid(vpts); + pts(b,1)=aa(1,1); + pts(b,2)=aa(1,2); + end + end + end + + pseq=pts; + + circle = [[centre_pts(c1,1) centre_pts(c1,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + circle = [[centre_pts(c2,1) centre_pts(c2,2)] 15]; + idx=[]; + for l=1:length(pseq(:,1)) + if isPointInCircle([pseq(l,1), pseq(l,2)], circle) + idx=vertcat(idx,l); + end + end + pseq(idx,:)=[]; + + if ~isempty(pseq) + NP=[centre_pts(c1,1) centre_pts(c1,2)]; + [MP, n]=unique([pseq(:,1) pseq(:,2)], 'rows'); + NP=vertcat(NP, MP); + NP=vertcat(NP, [centre_pts(c2,1) centre_pts(c2,2)]); + Mdist=[NP(:,1) NP(:,2)]; + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + mclusters=zeros(length(Mdist), 1); + Mdist(:,3)=1; + for o=1:length(SQ(:,:)) + SQ(o,o)=100000.0; + end + + %finding sequence of point cloud + j=1; + idxk=1; + minip=100000.0; + while idxk<=length(SQ(idxk,:)) & j<=length(Mdist(:,1)) + if length(idxk)>1 + index=0; + for g=1:length(idxk) + mindist=min(SQ(idxk(g),:)); + if mindist<=minip + minip=mindist; + index=g; + end + end + resi=find(SQ(idxk(index),:)==minip); + mclusters(j)=idxk(index); + minip=100000.0; + j=j+1; + else + mindist=min(SQ(idxk,:)); + resi=find(SQ(idxk,:)==mindist); + mclusters(j)=idxk; + j=j+1; + end + + if length(NP(:,1))==idxk + break; + end + + SQ(idxk,:)=100000; + SQ(:,resi)=100000; + + if idxk==1 + SQ(:,idxk)=100000; + end + + curr=resi; + idxk=curr; + end + + f=mclusters~=0; + tempc=mclusters(f); + clear mclusters; + mclusters=tempc; + clear tempc; + + temp=Mdist(mclusters(2:length(mclusters)-1),:); + + if ~isempty(res) + netsections(res,:)=[]; + end + + for m=1:length(temp(:,1)) + netsections=vertcat(netsections,[cluster_to_tr(g,3),temp(m,1),temp(m,2),0,0]); + end + end + else + + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)])); + + x1=centre_pts(c1,1)+dd; + y1=centre_pts(c1,2)+dd; + x2=centre_pts(c1,1)+dd; + y2=centre_pts(c1,2)-dd; + x3=centre_pts(c1,1)-dd; + y3=centre_pts(c1,2)+dd; + x4=centre_pts(c1,1)-dd; + y4=centre_pts(c1,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c2,1) centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c1,1) centre_pts(c1,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], 0); + tr2 = createRotation([centre_pts(c1,1) centre_pts(c1,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if slk(rss(h),1)~=centre_pts(c1,1)&slk(rss(h),2)~=centre_pts(c1,2)&slk(rss(h),3)~=centre_pts(c1,1)&slk(rss(h),4)~=centre_pts(c1,2) + e2 = createEdge([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c1,1)&vpts(:,2)==centre_pts(c1,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c1,1) centre_pts(c1,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p1=length(vpts(:,1)); + + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c1,1) centre_pts(c1,2)], aa, 2)<=dd + centre_pts(c1,1)=aa(1,1); + centre_pts(c1,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c1,1) centre_pts(c1,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p3=max(SQ(1,:)); + centre_pts(c1,8)=p3; + end + end + end + + ndegrees=rad2deg(angle2Points([centre_pts(c1,1) centre_pts(c1,2)], [centre_pts(c2,1) centre_pts(c2,2)])); + + x1=centre_pts(c2,1)+dd; + y1=centre_pts(c2,2)+dd; + x2=centre_pts(c2,1)+dd; + y2=centre_pts(c2,2)-dd; + x3=centre_pts(c2,1)-dd; + y3=centre_pts(c2,2)+dd; + x4=centre_pts(c2,1)-dd; + y4=centre_pts(c2,2)-dd; + + x=[x1 x2 x3 x4]; + x=vertcat(x,[y1 y2 y3 y4]); + mb=minBoundingBox(x); + mb=horzcat(mb,[mb(1,1); mb(2,1)]); + + in1 = inpolygon(slk(:,1), slk(:,2),mb(1,:), mb(2,:)); + in2 = inpolygon(slk(:,3), slk(:,4),mb(1,:), mb(2,:)); + + rs1=find(in1==1); + rs2=find(in2==1); + rss=union(rs1,rs2,'rows'); + + x1=centre_pts(c2,1)+(dd)*cosd(ndegrees-90); + y1=centre_pts(c2,2)+(dd)*sind(ndegrees-90); + x2=centre_pts(c2,1)+(dd)*cosd(ndegrees+90); + y2=centre_pts(c2,2)+(dd)*sind(ndegrees+90); + e1 = createEdge([x1 y1], [x2 y2]); + + in = createLine([centre_pts(c1,1) centre_pts(c1,2)],[centre_pts(c2,1) centre_pts(c2,2)]); + e1 =orthogonalLine(in, [centre_pts(c2,1) centre_pts(c2,2)]); + ce1=createEdge(e1,dd); + tr1 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], 0); + tr2 = createRotation([centre_pts(c2,1) centre_pts(c2,2)], pi); + dest1 = transformEdge(ce1,tr1); + dest2 = transformEdge(ce1,tr2); + + ce1=[dest1(1,3) dest1(1,4) dest2(1,3) dest2(1,4)]; + + vpts=[]; + for h=1:length(rss) + if slk(rss(h),1)~=centre_pts(c2,1)&slk(rss(h),2)~=centre_pts(c2,2)&slk(rss(h),3)~=centre_pts(c2,1)&slk(rss(h),4)~=centre_pts(c2,2) + e2 = createEdge([slk(rss(h),1) slk(rss(h),2)], [slk(rss(h),3) slk(rss(h),4)]); + point = intersectEdges(ce1, e2); + if ~isnan(point(1,1)) && ~isinf(point(1,1)) + vpts=vertcat(vpts,point); + end + end + end + + if ~isempty(vpts) + + rv=find(vpts(:,1)==centre_pts(c2,1)&vpts(:,2)==centre_pts(c2,2)); + if isempty(rv) + vpts=vertcat(vpts,[centre_pts(c2,1) centre_pts(c2,2)]); + end + vpts=unique([vpts(:,1) vpts(:,2)],'rows'); + p2=length(vpts(:,1)); + if length(vpts(:,1))>1 + aa=centroid(vpts); + if distancePoints([centre_pts(c2,1) centre_pts(c2,2)], aa, 2)<=dd + centre_pts(c2,1)=aa(1,1); + centre_pts(c2,2)=aa(1,2); + + mb=vpts; + mb=unique(vpts,'rows'); + pd=[centre_pts(c2,1) centre_pts(c2,2)]; + pd=vertcat(pd,mb); + + Y = pdist(pd,'euclid'); + SQ=squareform(Y); + p4=max(SQ(1,:)); + centre_pts(c2,8)=p4; + end + end + end + end +end + +fprintf('Writing nodes and links to file\n'); + +idx=max(centre_pts(:,3))+1; +for k=1:length(netsections(:,1)) + netsections(k,6)=idx; + idx=idx+1; +end +n_edges=[]; +dir=0; +for k=1:length(cluster_to_tr(:,1)) + rnnx=find(netnodes(:,1)==cluster_to_tr(k,3)); + if netnodes(rnnx,3)==2 + dir=1; + else + dir=0; + end + res=find(netsections(:,1)==cluster_to_tr(k,3)); + if isempty(res) + n_edges=vertcat(n_edges,[cluster_to_tr(k,1) cluster_to_tr(k,2) dir]); + else + for i=1:length(res) + if i==1 + n_edges=vertcat(n_edges,[cluster_to_tr(k,1) netsections(res(i),6) dir]); + end + if i + + + + + diff --git a/evaluation/pathbaseddistance/MapMatching/.project b/evaluation/pathbaseddistance/MapMatching/.project new file mode 100644 index 0000000..dcb5f0d --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/.project @@ -0,0 +1,17 @@ + + + MapMatching + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/evaluation/pathbaseddistance/MapMatching/.settings/org.eclipse.jdt.core.prefs b/evaluation/pathbaseddistance/MapMatching/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..838bd9d --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkFrechetExperiments.java b/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkFrechetExperiments.java new file mode 100644 index 0000000..61b4dad --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkFrechetExperiments.java @@ -0,0 +1,136 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: BenchmarkFrechetExperiments.java + */ +package benchmarkexperiments; + +import generatepaths.GeneratePaths; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; + +import mapmatching.MapMatching; +import mapmatchingbasics.ReadFiles; +import mapmatchingbasics.Vertex; + +public class BenchmarkFrechetExperiments { + + /** + * @param args + */ + public static void main(String[] args) { + + GeneratePaths gp = new GeneratePaths(); + MapMatching mapMatching = new MapMatching(); + + HashMap map1 = new HashMap(); + HashMap map2 = new HashMap(); + + ArrayList graph1 = new ArrayList(); + ArrayList graph2 = new ArrayList(); + + String cityName = args[0]; + + String vertexFile1 = args[1]; + String edgeFile1 = args[2]; + boolean isDirected1 = Boolean.parseBoolean(args[3]); + + String vertexFile2 = args[4]; + String edgeFile2 = args[5]; + boolean isDirected2 = Boolean.parseBoolean(args[6]); + + if (args[7].length() == 2) { + graph1 = ReadFiles.loadBenchmarkMap(map1, vertexFile1, edgeFile1, + isDirected1); + graph2 = ReadFiles.loadBenchmarkMap(map2, vertexFile2, edgeFile2, + isDirected2); + } else { + ArrayList bounds = ReadFiles.getTokens( + args[7].substring(1, args[7].length() - 1), ","); + double XLow = Double.parseDouble(bounds.get(0)); + double XHigh = Double.parseDouble(bounds.get(1)); + double YLow = Double.parseDouble(bounds.get(2)); + double YHigh = Double.parseDouble(bounds.get(3)); + + graph1 = ReadFiles.loadBenchmarkMap(map1, vertexFile1, edgeFile1, + isDirected1, XLow, XHigh, YLow, YHigh); + graph2 = ReadFiles.loadBenchmarkMap(map2, vertexFile2, edgeFile2, + isDirected2, XLow, XHigh, YLow, YHigh); + } + + + String pathFolder = args[8]; + String resultFolder = args[9]; + + String linkLength = args[10]; + + File pathfile = new File(pathFolder); + + if (!pathfile.exists()) + pathfile.mkdirs(); + + gp.generatePathsLinkLength(graph1, pathFolder, linkLength); + + File folder = new File(pathFolder + linkLength); + + System.out.println("processing linkLength " + linkLength + " paths of " + + "..."); + Long start_time = System.currentTimeMillis(); + int count = 0; + for (int l = 0; l < 5; l++) { + File file2 = new File(pathFolder + folder.getName() + "//" + l); + + if (file2.exists()) { + mapMatching.pathSimilarity(graph2, file2, resultFolder + linkLength, + cityName, l); + count += (file2.listFiles()).length; + } else { + System.out.println("Folder doesn't exits..." + pathFolder + + linkLength); + } + + } + Long end_time = System.currentTimeMillis(); + try { + BufferedWriter bwways = new BufferedWriter(new FileWriter( + resultFolder + "log.txt", true)); + + bwways.write(cityName + " " + linkLength + " " + count + " " + + (end_time - start_time) / 60000.0 + "\n"); + + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkHausdorffExperiments.java b/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkHausdorffExperiments.java new file mode 100644 index 0000000..cb6b60f --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/benchmarkexperiments/BenchmarkHausdorffExperiments.java @@ -0,0 +1,139 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: BenchmarkHausdorffExperments.java + */ +package benchmarkexperiments; + +import generatepaths.GeneratePaths; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.ArrayList; +import java.util.HashMap; + +import mapmatching.HausdorffDistance; +import mapmatchingbasics.Edge; +import mapmatchingbasics.ReadFiles; +import mapmatchingbasics.Vertex; + +public class BenchmarkHausdorffExperiments { + + /** + * @param args + */ + public static void main(String[] args) { + + GeneratePaths gp = new GeneratePaths(); + HausdorffDistance hausdorffDistance = new HausdorffDistance(); + + HashMap map1 = new HashMap(); + HashMap map2 = new HashMap(); + + ArrayList graph1 = new ArrayList(); + ArrayList graph2 = new ArrayList(); + + String cityName = args[0]; + + String vertexFile1 = args[1]; + String edgeFile1 = args[2]; + boolean isDirected1 = Boolean.parseBoolean(args[3]); + + String vertexFile2 = args[4]; + String edgeFile2 = args[5]; + boolean isDirected2 = Boolean.parseBoolean(args[6]); + + if (args[7].length() == 2) { + graph1 = ReadFiles.loadBenchmarkMap(map1, vertexFile1, edgeFile1, + isDirected1); + graph2 = ReadFiles.loadBenchmarkMap(map2, vertexFile2, edgeFile2, + isDirected2); + } else { + ArrayList bounds = ReadFiles.getTokens( + args[7].substring(1, args[7].length() - 1), ","); + double XLow = Double.parseDouble(bounds.get(0)); + double XHigh = Double.parseDouble(bounds.get(1)); + double YLow = Double.parseDouble(bounds.get(2)); + double YHigh = Double.parseDouble(bounds.get(3)); + + graph1 = ReadFiles.loadBenchmarkMap(map1, vertexFile1, edgeFile1, + isDirected1, XLow, XHigh, YLow, YHigh); + graph2 = ReadFiles.loadBenchmarkMap(map2, vertexFile2, edgeFile2, + isDirected2, XLow, XHigh, YLow, YHigh); + } + + + String pathFolder = args[8]; + String resultFolder = args[9]; + + String linkLength = "LineSegment"; + File pathfile = new File(pathFolder); + + if (!pathfile.exists()) + pathfile.mkdirs(); + + gp.generatePathsLinkLength(graph1, pathFolder, linkLength); + + File folder = new File(pathFolder + linkLength); + + System.out.println("processing linkLength " + linkLength + " paths of " + + "..."); + Long start_time = System.currentTimeMillis(); + + ArrayList eGraph = hausdorffDistance.getGraphEdge(graph2); + + int count = 0; + for (int l = 0; l < 5; l++) { + File file2 = new File(pathFolder + folder.getName() + "//" + l); + + if (file2.exists()) { + hausdorffDistance.pathSimilarity(eGraph, file2, resultFolder + linkLength, + cityName, l); + count += (file2.listFiles()).length; + } else { + System.out.println("Folder doesn't exits..." + pathFolder + + linkLength); + } + + } + Long end_time = System.currentTimeMillis(); + try { + BufferedWriter bwways = new BufferedWriter(new FileWriter( + resultFolder + "log.txt", true)); + + bwways.write(cityName + " " + linkLength + " " + count + " " + + (end_time - start_time) / 60000.0 + "\n"); + + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/generatepaths/GeneratePaths.java b/evaluation/pathbaseddistance/MapMatching/src/generatepaths/GeneratePaths.java new file mode 100644 index 0000000..f39d555 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/generatepaths/GeneratePaths.java @@ -0,0 +1,1568 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: GeneratePaths.java + */ +package generatepaths; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.PriorityQueue; +import java.util.Stack; + +import mapmatchingbasics.PathLabelComparator; +import mapmatchingbasics.Vertex; + +public class GeneratePaths { + + public void generateLineSegmentPaths(ArrayList graph, + String filepath) { + try { + ArrayList vList = new ArrayList(); + + int maxdegree = -1, e = 0; + for (int i = 0; i < graph.size(); i++) { + graph.get(i).removeDuplicates(); + e = e + graph.get(i).degree; + vList.add(new Integer(i)); + if (maxdegree < graph.get(i).degree) + maxdegree = graph.get(i).degree; + + } + + @SuppressWarnings("unchecked") + ArrayList curves[][] = new ArrayList[vList.size()][maxdegree]; + double pathLength[][] = new double[vList.size()][maxdegree]; + + Vertex prev, cur; + int i = 0; + + while (i < vList.size()) { + + prev = graph.get(i); + + for (int j = 0; j < prev.degree; j++) { + curves[i][j] = new ArrayList(); + curves[i][j].add(prev); + cur = graph.get(prev.adjacencyList[j]); + pathLength[i][j] += Math + .sqrt((Math.pow(cur.x - prev.x, 2) + Math.pow(cur.y + - prev.y, 2))); + curves[i][j].add(cur); + //boolean found1=false,found2=false; + //if(prev.getKeyString().equals("390018.101 5817597.233"))found1=true; + //if(cur.getKeyString().equals("390294.625 5817341.91"))found2=true; + //if(found1&&found2)System.out.println("I have found you i="+i+" j="+prev.adjacencyList[j]+" "+prev.toString()+cur.toString()); + } + + i++; + + } + System.out.println("Vertex set size: " + vList.size() + + " max degree: " + maxdegree); + + Stack stack = new Stack(); + int no = 0, index1 = 0, index2 = 0; + Vertex v1; + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + System.out.println("Generating Line Segment paths: "); + for (int k = 0; k < vList.size(); k++) { + + v1 = graph.get(vList.get(k)); + index1 = k; + for (int j = 0; j < v1.degree; j++) { + stack = new Stack(); + index2 = v1.adjacencyList[j]; + if (index2 != -1) { + stack.push(index2); + if(stack.contains(index1))continue; + stack.push(index1); + printPath(graph, stack, vList, curves, filepath, no); + no++; + } + + } + + } + System.out.println("Total number of line segment paths: " + no); + + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + + public Object[] generatePaths(ArrayList graph) { + Object obj[] = new Object[3]; + try { + ArrayList vList = new ArrayList(); + + int maxdegree = -1, e = 0; + for (int i = 0; i < graph.size(); i++) { + graph.get(i).removeDuplicates(); + e = e + graph.get(i).degree; + if (graph.get(i).degree != 2) { + vList.add(new Integer(i)); + if (maxdegree < graph.get(i).degree) + maxdegree = graph.get(i).degree; + + } + } + + @SuppressWarnings("unchecked") + ArrayList curves[][] = new ArrayList[vList.size()][maxdegree]; + double pathLength[][] = new double[vList.size()][maxdegree]; + + Vertex v1, prev, cur; + int curVertexIndex, startVertexIndex; + int i = 0; + + while (i < vList.size()) { + startVertexIndex = vList.get(i).intValue();// index of prev + + v1 = graph.get(startVertexIndex); + + for (int j = 0; j < v1.degree; j++) { + + HashMap map = new HashMap(); + curves[i][j] = new ArrayList(); + map.put(startVertexIndex, startVertexIndex); + curves[i][j].add(v1); + prev = v1; + + curVertexIndex = v1.adjacencyList[j];// index of cur + cur = graph.get(curVertexIndex); + + while (cur.degree == 2) { + + pathLength[i][j] += Math.sqrt((Math.pow(cur.x - prev.x, + 2) + Math.pow(cur.y - prev.y, 2))); + + curves[i][j].add(cur); + map.put(curVertexIndex, curVertexIndex); + + if (map.get(cur.adjacencyList[0]) != null + && map.get(cur.adjacencyList[1]) != null) { + if (cur.adjacencyList[0] == startVertexIndex) + curVertexIndex = cur.adjacencyList[0]; + else if (cur.adjacencyList[1] == startVertexIndex) + curVertexIndex = cur.adjacencyList[1]; + else { + System.out.println("Error"); + break; + } + } else if (map.get(cur.adjacencyList[0]) != null) { + curVertexIndex = cur.adjacencyList[1]; + } else { + curVertexIndex = cur.adjacencyList[0]; + } + cur = graph.get(curVertexIndex); + v1.adjacencyList[j] = curVertexIndex; + + } + + pathLength[i][j] += Math + .sqrt((Math.pow(cur.x - prev.x, 2) + Math.pow(cur.y + - prev.y, 2))); + curves[i][j].add(cur); + v1.adjacencyList[j] = curVertexIndex; + } + + i++; + + } + /*System.out.println("Vertex set size: " + vList.size() + + " max degree: " + maxdegree); +*/ + obj[0] = vList; + obj[1] = curves; + obj[2] = pathLength; + return obj; + + } catch (Exception e) { + System.out.println(e.toString()); + } + return obj; + } + + public Object[] generateLengthOnePaths(ArrayList graph, + String filepath, Object obj[]) { + //Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1; + int no = 0, index1 = 0, index2 = 0; + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + System.out.println("Generating length one paths: "); + for (int i = 0; i < vList.size(); i++) { + + v1 = graph.get(vList.get(i)); + index1 = i; + for (int j = 0; j < v1.degree; j++) { + stack = new Stack(); + index2 = vList.indexOf(v1.adjacencyList[j]); + if (index2 != -1)// i!=k && + { + stack.push(index2); + stack.push(index1); + if(index1==index2 && curves[i][j].size()==2) continue; + printPath(graph, stack, vList, curves, filepath, no); + no++; + } + + } + + } + System.out.println("Total number length one of paths: " + no); + return obj; + } + + public void generateLengthTwoPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2; + int index1, index2, index3; + int no = 0; + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + System.out.println("Generating length Two paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + for (int k = 0; k < v2.degree; k++) { + stack = new Stack(); + index3 = vList.indexOf(v2.adjacencyList[k]); + + if (index1 != -1 && index2 != -1 && index3 != -1) { + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + printPath(graph, stack, vList, curves, filepath, no); + no++; + } + } + } + + } + + System.out.println("Total number length two of paths: " + no); + } + + public void generateLengthThreePaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3; + int index1, index2, index3, index4; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length Three paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + for (int l = 0; l < v3.degree; l++) { + stack = new Stack(); + index4 = vList.indexOf(v3.adjacencyList[l]); + if (index1 != -1 && index2 != -1 && index3 != -1 + && index4 != -1) { + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, curves, filepath, no); + no++; + } + } + } + } + + } + System.out.println("Total number length three of paths: " + no); + } + + public void generateLengthFourPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4; + int index1, index2, index3, index4, index5; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length four paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + stack = new Stack(); + index5 = vList.indexOf(v4.adjacencyList[m]); + if (index1 != -1 && index2 != -1 && index3 != -1 + && index4 != -1 && index5 != -1) { + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, curves, + filepath, no); + no++; + } + + } + } + } + } + + } + + System.out.println("Total number length four of paths: " + no); + } + + public void generateLengthFivePaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5; + int index1, index2, index3, index4, index5, index6; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length five paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + stack = new Stack(); + index6 = vList.indexOf(v5.adjacencyList[n]); + + if (index1 != -1 && index2 != -1 + && index3 != -1 && index4 != -1 + && index5 != -1 && index6 != -1) { + + stack.push(index6); + if (stack.contains(index5)) + continue; + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, curves, + filepath, no); + no++; + } + } + } + } + } + } + + } + + System.out.println("Total number length five of paths: " + no); + } + + public void generateLengthSixPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5, v6; + int index1, index2, index3, index4, index5, index6, index7; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length six paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + + index6 = vList.indexOf(v5.adjacencyList[n]); + v6 = graph.get(v5.adjacencyList[n]); + + for (int o = 0; o < v6.degree; o++) { + stack = new Stack(); + index7 = vList.indexOf(v6.adjacencyList[o]); + if (index1 != -1 && index2 != -1 + && index3 != -1 && index4 != -1 + && index5 != -1 && index6 != -1 + && index7 != -1) { + + stack.push(index7); + if (stack.contains(index6)) + continue; + stack.push(index6); + if (stack.contains(index5)) + continue; + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, curves, + filepath, no); + no++; + } + } + } + } + } + } + } + + } + + System.out.println("Total number length six of paths: " + no); + } + + public void generateLengthSevenPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5, v6, v7; + int index1, index2, index3, index4, index5, index6, index7, index8; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length seven paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + + index6 = vList.indexOf(v5.adjacencyList[n]); + v6 = graph.get(v5.adjacencyList[n]); + + for (int o = 0; o < v6.degree; o++) { + + index7 = vList.indexOf(v6.adjacencyList[o]); + v7 = graph.get(v6.adjacencyList[o]); + for (int p = 0; p < v7.degree; p++) { + index8 = vList + .indexOf(v7.adjacencyList[p]); + stack = new Stack(); + if (index1 != -1 && index2 != -1 + && index3 != -1 && index4 != -1 + && index5 != -1 && index6 != -1 + && index7 != -1 && index8 != -1) { + stack.push(index8); + if (stack.contains(index7)) + continue; + stack.push(index7); + if (stack.contains(index6)) + continue; + stack.push(index6); + if (stack.contains(index5)) + continue; + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, + curves, filepath, no); + no++; + } + } + } + } + } + } + } + } + + } + + System.out.println("Total number length seven of paths: " + no); + } + + public void generateLengthEightPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5, v6, v7, v8; + int index1, index2, index3, index4, index5, index6, index7, index8, index9; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length eight paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + + index6 = vList.indexOf(v5.adjacencyList[n]); + v6 = graph.get(v5.adjacencyList[n]); + + for (int o = 0; o < v6.degree; o++) { + + index7 = vList.indexOf(v6.adjacencyList[o]); + v7 = graph.get(v6.adjacencyList[o]); + for (int p = 0; p < v7.degree; p++) { + index8 = vList + .indexOf(v7.adjacencyList[p]); + v8 = graph.get(v7.adjacencyList[p]); + for (int q = 0; q < v8.degree; q++) { + index9 = vList + .indexOf(v8.adjacencyList[q]); + stack = new Stack(); + if (index1 != -1 && index2 != -1 + && index3 != -1 + && index4 != -1 + && index5 != -1 + && index6 != -1 + && index7 != -1 + && index8 != -1 + && index9 != -1) { + stack.push(index9); + if (stack.contains(index8)) + continue; + stack.push(index8); + if (stack.contains(index7)) + continue; + stack.push(index7); + if (stack.contains(index6)) + continue; + stack.push(index6); + if (stack.contains(index5)) + continue; + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, vList, + curves, filepath, no); + no++; + } + } + } + } + } + } + } + } + } + + } + + System.out.println("Total number length eight of paths: " + no); + } + + public void generateLengthNinePaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5, v6, v7, v8, v9; + int index1, index2, index3, index4, index5, index6, index7, index8, index9, index10; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length nine paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + + index6 = vList.indexOf(v5.adjacencyList[n]); + v6 = graph.get(v5.adjacencyList[n]); + + for (int o = 0; o < v6.degree; o++) { + + index7 = vList.indexOf(v6.adjacencyList[o]); + v7 = graph.get(v6.adjacencyList[o]); + for (int p = 0; p < v7.degree; p++) { + index8 = vList + .indexOf(v7.adjacencyList[p]); + v8 = graph.get(v7.adjacencyList[p]); + for (int q = 0; q < v8.degree; q++) { + index9 = vList + .indexOf(v8.adjacencyList[q]); + v9 = graph.get(v8.adjacencyList[q]); + for (int r = 0; r < v9.degree; r++) { + index10 = vList + .indexOf(v9.adjacencyList[r]); + stack = new Stack(); + if (index1 != -1 + && index2 != -1 + && index3 != -1 + && index4 != -1 + && index5 != -1 + && index6 != -1 + && index7 != -1 + && index8 != -1 + && index9 != -1 + && index10 != -1) { + stack.push(index10); + if (stack.contains(index9)) + continue; + stack.push(index9); + if (stack.contains(index8)) + continue; + stack.push(index8); + if (stack.contains(index7)) + continue; + stack.push(index7); + if (stack.contains(index6)) + continue; + stack.push(index6); + if (stack.contains(index5)) + continue; + stack.push(index5); + if (stack.contains(index4)) + continue; + stack.push(index4); + if (stack.contains(index3)) + continue; + stack.push(index3); + if (stack.contains(index2)) + continue; + stack.push(index2); + if (stack.contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, + vList, curves, + filepath, no); + no++; + } + } + } + } + } + } + } + } + } + } + + } + + System.out.println("Total number length nine of paths: " + no); + } + + public void generateLengthTenPaths(ArrayList graph, + String filepath, Object obj[]) { + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + Stack stack = new Stack(); + Vertex v1, v2, v3, v4, v5, v6, v7, v8, v9, v10; + int index1, index2, index3, index4, index5, index6, index7, index8, index9, index10, index11; + int no = 0; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + + System.out.println("Generating length ten paths: "); + for (int i = 0; i < vList.size(); i++) { + index1 = i; + v1 = graph.get(vList.get(i)); + + for (int j = 0; j < v1.degree; j++) { + + index2 = vList.indexOf(v1.adjacencyList[j]); + v2 = graph.get(v1.adjacencyList[j]); + + for (int k = 0; k < v2.degree; k++) { + index3 = vList.indexOf(v2.adjacencyList[k]); + v3 = graph.get(v2.adjacencyList[k]); + + for (int l = 0; l < v3.degree; l++) { + index4 = vList.indexOf(v3.adjacencyList[l]); + v4 = graph.get(v3.adjacencyList[l]); + for (int m = 0; m < v4.degree; m++) { + index5 = vList.indexOf(v4.adjacencyList[m]); + v5 = graph.get(v4.adjacencyList[m]); + for (int n = 0; n < v5.degree; n++) { + + index6 = vList.indexOf(v5.adjacencyList[n]); + v6 = graph.get(v5.adjacencyList[n]); + + for (int o = 0; o < v6.degree; o++) { + + index7 = vList.indexOf(v6.adjacencyList[o]); + v7 = graph.get(v6.adjacencyList[o]); + for (int p = 0; p < v7.degree; p++) { + index8 = vList + .indexOf(v7.adjacencyList[p]); + v8 = graph.get(v7.adjacencyList[p]); + for (int q = 0; q < v8.degree; q++) { + index9 = vList + .indexOf(v8.adjacencyList[q]); + v9 = graph.get(v8.adjacencyList[q]); + for (int r = 0; r < v9.degree; r++) { + index10 = vList + .indexOf(v9.adjacencyList[r]); + v10 = graph + .get(v9.adjacencyList[r]); + for (int s = 0; s < v10.degree; s++) { + index11 = vList + .indexOf(v10.adjacencyList[s]); + stack = new Stack(); + if (index1 != -1 + && index2 != -1 + && index3 != -1 + && index4 != -1 + && index5 != -1 + && index6 != -1 + && index7 != -1 + && index8 != -1 + && index9 != -1 + && index10 != -1 + && index11 != -1) { + stack.push(index11); + if (stack + .contains(index10)) + continue; + stack.push(index10); + if (stack + .contains(index9)) + continue; + stack.push(index9); + if (stack + .contains(index8)) + continue; + stack.push(index8); + if (stack + .contains(index7)) + continue; + stack.push(index7); + if (stack + .contains(index6)) + continue; + stack.push(index6); + if (stack + .contains(index5)) + continue; + stack.push(index5); + if (stack + .contains(index4)) + continue; + stack.push(index4); + if (stack + .contains(index3)) + continue; + stack.push(index3); + if (stack + .contains(index2)) + continue; + stack.push(index2); + if (stack + .contains(index1)) + continue; + stack.push(index1); + + printPath(graph, stack, + vList, curves, + filepath, no); + no++; + } + } + } + } + } + } + } + } + } + } + } + + } + + System.out.println("Total number length ten of paths: " + no); + } + + public void checkDegree(ArrayList vList, ArrayList graph) { + int i = 0; + int j = 0; + System.out.println("I am inside check degree."); + while (i < vList.size()) { + Vertex v = graph.get(vList.get(i).intValue()); + + if (v.degree == 2) + System.out.println("I am a problem"); + + if (vList.indexOf(vList.get(i)) == -1) + System.out.println("I am a problem " + i + " " + v.toString()); + j = 0; + while (j < v.degree) { + + Vertex v1 = graph.get(v.adjacencyList[j]); + if (v1.degree == 2) + System.out.println("I am a problem " + j + " " + + v.toString()); + if (vList.indexOf(new Integer(v.adjacencyList[j])) == -1) + System.out.println("I am a problem " + j + " " + + v.toString()); + + /* + * if(vList.get(i).intValue() == 1734) { + * System.out.println("I am a problem " + * +j+" "+v.adjacencyList[j]+" "+v1.toString()); } + */ + + j++; + } + i++; + } + } + + public void getShortestPaths(ArrayList graph, String filepath, + Object obj[]) { + + // Object obj[] = this.generatePaths(graph, filepath); + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + double pathLength[][] = (double[][]) obj[2]; + + System.out.println("I am deleting files...."); + File fin = new File(filepath); + + for (File file : fin.listFiles()) { + if (file.isDirectory()) { + for (File file2 : file.listFiles()) + file2.delete(); + } + } + int no = 0; + + for (int start = 0; start < vList.size(); start++) { + int parent[] = new int[vList.size()]; + Comparator comparator = new PathLabelComparator(graph); + PriorityQueue pq = new PriorityQueue(209884, + comparator); + + int i = 0; + int maxdegree = 0; + /* + * while(i < vList.size()) { + * + * graph.get(vList.get(i).intValue()).left = Double.MAX_VALUE; + * if(graph.get(vList.get(maxdegree)).degree < + * graph.get(vList.get(i)).degree) maxdegree = i; + * + * pq.add(vList.get(i)); + * + * + * i++; } + */ + + // checkDegree(vList,graph); + pq.remove(new Integer(vList.get(maxdegree))); + graph.get(vList.get(maxdegree)).left = 0; + pq.add(new Integer(vList.get(maxdegree))); + // pq has graph indices + Vertex v, v1; + int index1, index2; + int j = 0; + // int count = 0; + // start = maxdegree; + + // System.out.println("I am computing shortest Paths...."+graph.get(vList.get(maxdegree)).degree); + + boolean reachable[] = new boolean[vList.size()]; + + while (!pq.isEmpty()) { + // count++; + i = pq.poll().intValue(); + if (i == -1) { + continue; + } + index1 = vList.indexOf(new Integer(i)); + v = graph.get(i);// i contains index of graph and index1 + // contains index of vList + // System.out.println(i+" "+index1+" "+ + // v.left+" "+graph.get(i).toString()); + + // if(v.left == Double.MAX_VALUE)v.left = 0; + v.done = true; + if (v.left == Double.MAX_VALUE) { + reachable[index1] = false; + continue; + } else { + reachable[index1] = true; + } + + j = 0; + + while (j < v.degree) { + + v1 = graph.get(v.adjacencyList[j]); + + index2 = vList.indexOf(new Integer(v.adjacencyList[j])); + + if (index2 == -1) { + j++; + continue; + } + + if (!v1.done) { + // index2 = vList.indexOf(new + // Integer(v.adjacencyList[j])); + + if (v1.left > v.left + pathLength[index1][j]) { + // System.out.println(v.left + + // pathLength[index1][j]); + + pq.remove(new Integer(vList.get(index2))); + + v1.left = v.left + pathLength[index1][j]; + + pq.add(new Integer(vList.get(index2))); + // if(index2==29498){System.out.println("I was inserted here." + // +i);} + parent[index2] = i; + // if(index1==17)System.out.println(i+" "+index1+" "+index2+" "+parent[index2]); + } + } else { + // if(parent[index2] == + // 0)System.out.println("done "+v1.left+" "+v1.toString()); + } + j++; + } + + } + + // printVList(vList,graph,parent); + + // extract paths + + i = 0; + int cur = 0; + int length = 0; + Stack stack; + ArrayList generatePath = new ArrayList(); + + while (i < vList.size()) { + if (reachable[i]) + generatePath.add(i); + i++; + } + + // System.out.println("I am generating Paths...."); + // System.out.println("I am generating shortest Paths...."+maxdegree); + while (generatePath.size() != 0) { + stack = new Stack(); + cur = generatePath.remove(0).intValue(); + // System.out.println(no +"size of generatePath: " + + // generatePath.size()); + length = 0; + + while (cur != start && cur != -1) { + // if() + // { + // System.out.println("size of generatePath: " + + // generatePath.size()); + // } + if (generatePath.contains(new Integer(cur))) { + generatePath.remove(new Integer(cur)); + // System.out.println("size of generatePath: " + + // generatePath.size()); + } + if (stack.contains(new Integer(cur))) + break; + stack.push(new Integer(cur)); + // System.out.println(cur); + cur = vList.indexOf(new Integer(parent[cur])); + // if(cur==-1)System.out.println(stack.peek().intValue()+" "+parent[stack.peek().intValue()]+" "+graph.get(parent[stack.peek().intValue()])+" "+graph.get(vList.get(stack.peek().intValue()))); + length++; + } + + if (!stack.isEmpty())// && length > 1 + { + if (!stack.contains(new Integer(cur))) { + stack.push(new Integer(cur)); + length++; + } + // System.out.println("Write to file: "+ no +" "+ length); + if (length > 1) + printPath(graph, stack, vList, curves, filepath, no); + + no++; + } + + } + } + System.out.println("Total number shortest of paths: " + no); + } + + public void printPath(ArrayList graph, Stack stack, + ArrayList vList, ArrayList curves[][], + String filepath, int no) { + + try { + + int numf = 5;// number of folders to store files + + int index1 = stack.pop().intValue();// stack has indices of vList + if (index1 == -1) + return; + + File file = new File(filepath + no % numf + "//"); + if (!file.exists()) { + if (file.mkdir()) { + System.out.println("Directory is created!"); + } else { + System.out.println("Failed to create directory!"); + } + } + + String fileName = filepath + + no % numf + "//" + no + ".dat"; + + BufferedWriter bwways = new BufferedWriter(new FileWriter(fileName)); + + int p = vList.get(index1); + int q = 0; + + bwways.write(graph.get(p).getKeyString() + "\n"); + + while (!stack.isEmpty()) { + + int index3 = stack.pop().intValue(); + // System.out.println(index3); + q = graph.indexOf(graph.get(vList.get(index3))); + + int index2 = graph.get(p).getIndexAdjacent(q); + + // System.out.println("q = "+q+ " index1="+index1+ + // " index3="+index3); + + if (q != -1) { + int h = 1; + while (h < curves[index1][index2].size() - 1) { + bwways.write(curves[index1][index2].get(h).getKeyString()+ "\n"); + h++; + } + } else { + + System.out.println("I am break."); + break; + + } + p = q; + bwways.write(graph.get(p).getKeyString() + "\n"); + + index1 = index3; + } + //if(found1&&found2)System.out.println(fileName); + bwways.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public void printVList(ArrayList vList, ArrayList graph, + int parent[]) { + + Integer i = 17; + int count = 0; + while (i.intValue() < 18)// vList = (ArrayList) obj[0]; + double minDist[] = new double[vList.size()]; + try { + BufferedWriter bwways = new BufferedWriter(new FileWriter(filePath)); + for (int i = 0; i < vList.size(); i++) { + minDist[i] = Double.MAX_VALUE; + Vertex v1 = graph.get(vList.get(i)); + for (int j = 0; j < v1.degree; j++) { + Vertex v2 = graph.get(v1.adjacencyList[j]); + double dist = v1.dist(v2); + if (dist != 0 && minDist[i] > dist) + minDist[i] = dist; + } + if (minDist[i] < Double.MAX_VALUE) + bwways.write(v1.x + " " + v1.y + " " + v1.degree + " " + + minDist[i] + "\n"); + } + + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + + public void angle(Object obj[], ArrayList graph, String filePath) { + + @SuppressWarnings("unchecked") + ArrayList vList = (ArrayList) obj[0]; + @SuppressWarnings("unchecked") + ArrayList curves[][] = (ArrayList[][]) obj[1]; + + double minAngle[] = new double[vList.size()]; + try { + BufferedWriter bwways = new BufferedWriter(new FileWriter(filePath)); + for (int i = 0; i < vList.size(); i++) { + minAngle[i] = Double.MAX_VALUE; + Vertex v1 = graph.get(vList.get(i)); + for (int j = 0; j < v1.degree; j++) { + Vertex v2 = curves[i][j].get(1);// graph.get(v1.adjacencyList[j]); + + for (int k = j + 1; k < v1.degree; k++) { + + Vertex v3 = curves[i][k].get(1);// graph.get(v1.adjacencyList[k]); + if (v1.equals(v2) || v1.equals(v3) || v2.equals(v3)) + continue; + double dx1 = v2.x - v1.x; + double dx2 = v3.x - v1.x; + double dy1 = v2.y - v1.y; + double dy2 = v3.y - v1.y; + double angle = Math.acos((dx1 * dx2 + dy1 * dy2) + / (Math.sqrt(Math.pow(dx1, 2) + + Math.pow(dy1, 2)) * Math.sqrt(Math + .pow(dx2, 2) + Math.pow(dy2, 2)))); + if (minAngle[i] > angle) + minAngle[i] = angle; + } + + } + + if (minAngle[i] < Double.MAX_VALUE && minAngle[i] > 0) + bwways.write(v1.x + " " + v1.y + " " + v1.degree + " " + + minAngle[i] + "\n"); + } + + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + } + + public void generatePathsLinkLength(ArrayList graph, + String pathPath, String linkLength) { + + File pathfile = new File(pathPath); + + if (!pathfile.exists()) + pathfile.mkdirs(); + + if(linkLength.equals("LineSegment")){ + pathfile = new File(pathPath + "LineSegment//"); + if (!pathfile.exists()) + pathfile.mkdirs(); + this.generateLineSegmentPaths(graph, pathPath + linkLength + "//"); + return; + } + + /*pathfile = new File(pathPath + "LinkOne//"); + if (!pathfile.exists()) + pathfile.mkdirs(); + */ + Object obj1[] = this.generatePaths(graph); + + pathfile = new File(pathPath + linkLength + "//"); + if (!pathfile.exists()) + pathfile.mkdirs(); + if(linkLength.equals("LinkOne")){ + this.generateLengthOnePaths(graph, pathPath+ linkLength+"//", obj1); + } + else if (linkLength.equals("LinkTwo")) { + this.generateLengthTwoPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkThree")) { + this.generateLengthThreePaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkFour")) { + this.generateLengthFourPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkFive")) { + this.generateLengthFivePaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkSix")) { + this.generateLengthSixPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkSeven")) { + this.generateLengthSevenPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkEight")) { + this.generateLengthEightPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkNine")) { + this.generateLengthNinePaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("LinkTen")) { + this.generateLengthTenPaths(graph, pathPath + linkLength + "//", + obj1); + } else if (linkLength.equals("ShortestPaths")) { + this.getShortestPaths(graph, pathPath + linkLength + "//", obj1); + } + + } +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatching/HausdorffDistance.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatching/HausdorffDistance.java new file mode 100644 index 0000000..e25440a --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatching/HausdorffDistance.java @@ -0,0 +1,352 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: HausdorffDistance.java + */ +package mapmatching; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +import mapmatchingbasics.*; + +public class HausdorffDistance { + + public boolean found; + public double min; + + public ArrayList readFile(String fileName) { + + ArrayList curves = new ArrayList(); + try { + BufferedReader in = new BufferedReader(new FileReader(fileName)); + String str; + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str); + Double d = new Double(strToken.nextToken()); + double p1 = d.doubleValue(); + d = new Double(strToken.nextToken()); + double p2 = d.doubleValue(); + + curves.add(new Vertex(p1, p2)); + + } + in.close(); + + } catch (IOException e) { + System.out.println(e.toString()); + System.exit(0); + } + + return curves; + } + + public boolean computeInterval(Edge e, ArrayList curves, int cur, + double eps) { + + Line line = new Line(curves.get(cur - 1), curves.get(cur)); + return line.pIntersection(e, eps); + } + + public Edge computeNextInterval(Edge e, ArrayList curves, + int newstart, double eps) { + /**************************** startintex-----interval--------endindex *************************************/ + + boolean debug = false; + + boolean first = true; + + int startIndex = 0; + double cstart = 0, vstart = 0; + + if (newstart >= curves.size()) { + e.endIndex = curves.size(); + e.done = true; + return e; + } + + for (int i = newstart; i < curves.size(); i++) { + boolean result = computeInterval(e, curves, i, eps); + + if (debug && first && result) + System.out.println("i (next interval) = " + i + " " + + (i - 1 + e.cstart) + " " + (i - 1 + e.cend) + " " + + first + " " + result); + if (first && result) { + startIndex = i - 1; + cstart = e.cstart; + vstart = e.vstart; + + first = false; + + if (e.cend < 1) { + e.startIndex = startIndex; + e.cstart = startIndex + cstart; + e.vstart = vstart; + e.cend = i - 1 + e.cend; + e.endIndex = i; + return e; + } + } else if (!first && result) { + if (e.cend < 1) { + e.startIndex = startIndex; + e.cstart = startIndex + cstart; + e.vstart = vstart; + e.cend = i - 1 + e.cend; + e.endIndex = i; + return e; + } + } else if (!first && !result) { + e.startIndex = startIndex; + e.cstart = startIndex + cstart; + e.vstart = vstart; + e.cend = i - 1 + e.cend; + e.endIndex = i; + return e; + } + + } + + if (first) { + e.endIndex = curves.size(); + e.done = true; + } else { + e.startIndex = startIndex; + e.cstart = startIndex + cstart; + e.vstart = vstart; + + e.cend = curves.size() - 2 + e.cend; + e.endIndex = curves.size() - 2; + } + + return e; + } + + public boolean mapMatchingHausdorff(ArrayList graph, + ArrayList curves, String cityname, double eps) { + boolean debug = false; + + Comparator comparator = new IntervalComparatorEdge(); + PriorityQueue pq = new PriorityQueue(21282, comparator); + + for (int i = 0; i < graph.size(); i++) + + { + + this.computeNextInterval(graph.get(i), curves, 1, eps); + + if (!graph.get(i).done) { + + pq.add(graph.get(i)); + } + } + if (pq.isEmpty()) + return false; + + Edge e = pq.poll(); + if (debug) + System.out.println(curves.size() + " " + e.cstart + " " + e.cend); + double cend = e.cend; + if (e.cstart > 0) + return false; + while (cend < curves.size()) { + if (debug) + System.out.println("interval " + e.cstart + " " + e.cend + " " + + cend); + + if (cend < e.cend) { + cend = e.cend; + } + + if (e.cend == curves.size() - 1) + return true; + + this.computeNextInterval(e, curves, e.endIndex + 1, eps); + + if (!e.done) + pq.add(e); + + if (pq.isEmpty()) { + if (debug) + System.out.println(cend + " queue empty."); + return false; + } + + e = pq.poll(); + + if (e.cstart > cend) { + if (debug) + System.out.println("black interval " + e.cstart + " " + + cend); + return false; + } + + } + + return true; + } + + public void getEpsilon(ArrayList graph, ArrayList curves, + String cityname, int start, int end) { + int i; + Boolean bool1; + boolean debug = false; + + if (start >= end - 2) { + found = true; + for (i = start; i <= end; i++) { + int k = 0; + while (k < graph.size()) { + graph.get(k).reset(); + k++; + } + bool1 = this.mapMatchingHausdorff(graph, curves, cityname, i); + if (debug) + System.out.println("here " + start + ", " + end + " " + i + + " = " + bool1); + if (bool1) { + min = i; + return; + } + } + min = i; + return; + } else { + + i = 0; + while (i < graph.size()) { + graph.get(i).reset(); + i++; + } + bool1 = this.mapMatchingHausdorff(graph, curves, cityname, + (end + start) / 2); + if (debug) + System.out + .println("here2 " + start + ", " + end + " " + + (end + start) / 2 + " = " + bool1 + " found=" + + found); + + if (!bool1) { + getEpsilon(graph, curves, cityname, + (int) Math.ceil((end + start) / 2), end); + } else { + + getEpsilon(graph, curves, cityname, start, + (int) Math.ceil((end + start) / 2)); + } + } + + return; + } + + public void pathSimilarity(ArrayList graph, File fin, + String strInput, String cityname, int fileno) { + boolean debug = false; + ArrayList curves = new ArrayList(); + int min = 1, max = 1600; + File file1 = new File(strInput); + if (!file1.exists()) + file1.mkdirs(); + try { + + BufferedWriter bwways = new BufferedWriter(new FileWriter(strInput + + "//outputHausdorff" + fileno + ".txt")); + int count = 0; + for (File file : fin.listFiles()) { + + curves = this.readFile(file.getAbsolutePath()); + + if (debug) + System.out.println(curves.size() + + " :" + + this.mapMatchingHausdorff(graph, curves, + cityname, 8)); + else { + if (curves.size() < 2) { + continue; + } + + this.found = false; + this.getEpsilon(graph, curves, cityname, min, max); + + if (this.min == max + 1) { + this.found = false; + int i = 0; + while (i < graph.size()) { + graph.get(i).reset(); + i++; + } + this.getEpsilon(graph, curves, cityname, max, max + 800); + } + } + + double dist = Math.sqrt(Math.pow( + curves.get(0).x - curves.get(curves.size() - 1).x, 2) + + Math.pow( + curves.get(0).y + - curves.get(curves.size() - 1).y, 2)); + bwways.write(file.getName() + " " + curves.size() + " " + + this.min + " " + dist + "\n"); + + System.out.println(count + " " + file.getName() + " size = " + + curves.size() + " Hausdorff distance = " + this.min + + " length of path = " + dist); + count++; + } + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + + public ArrayList getGraphEdge(ArrayList vList) { + ArrayList graph = new ArrayList(); + + for (int i = 0; i < vList.size(); i++) { + Vertex v1 = vList.get(i); + for (int j = 0; j < v1.degree; j++) { + Vertex v2 = vList.get(v1.adjacencyList[j]); + if (!(v1.x == v2.x && v1.y == v2.y)) { + Edge e = new Edge(v1, v2); + graph.add(e); + } + } + } + + return graph; + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatching/MapMatching.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatching/MapMatching.java new file mode 100644 index 0000000..e87da01 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatching/MapMatching.java @@ -0,0 +1,728 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: MapMatching.java + */ +package mapmatching; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.Stack; +import java.util.StringTokenizer; + +import mapmatchingbasics.*; + +public class MapMatching { + public static String city = ""; + + public ArrayList readFile(String fileName) { + + ArrayList curves = new ArrayList(); + try { + BufferedReader in = new BufferedReader(new FileReader(fileName)); + String str; + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, " "); + Double d = new Double(strToken.nextToken()); + double p1 = d.doubleValue(); + d = new Double(strToken.nextToken()); + double p2 = d.doubleValue(); + + curves.add(new Vertex(p1, p2)); + + } + in.close(); + + } catch (IOException e) { + System.out.println(e.toString()); + System.exit(0); + } + + return curves; + } + + public void writeObjects(Object o, String file) { + try { + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeObject(o); + + oos.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + } + + public double[] computeReachabilityInterval(Vertex v1, Vertex v2, + ArrayList curves, double x, double eps) { + Line l1 = new Line(v1, v2); + double prevt[] = new double[2]; + double t[] = l1.pIntersection(curves.get(0), eps, false); + double interval[] = new double[2]; + boolean debug = false; + prevt[0] = -1; + if (debug) + System.out.println("x = " + x + " " + v1.startindex + " " + + v2.startindex); + if (x == 0)// initial situation + { + if (v2.startindex == 0) { + // intervals of v1 and v2 starts in same cell + interval[0] = v2.left; + interval[1] = v2.right; + return interval; + } else { + int cur = 1; + prevt = l1.pIntersection(curves.get(cur), eps, false); + while (cur <= v2.startindex) { + + t = l1.pIntersection(curves.get(cur), eps, false); + + if (t == null || t[0] > 1 || t[1] < 0) + return null; + + prevt[0] = Math.max(t[0], prevt[0]); + if (t[1] < prevt[0]) + return null; + else + prevt[1] = t[1]; + cur++; + } + interval[0] = v2.left; + interval[1] = v2.right; + return interval; + } + } else if (v1.startindex == v2.startindex)// In same cell + { + if (v1.left > v2.right) + return null; + interval[0] = Math.max(v2.left, v1.left); + interval[1] = v2.right; + return interval; + + } else { + + int cur = v1.startindex + 1; + + prevt = l1.pIntersection(curves.get(cur), eps, false); + + while (cur <= v2.startindex) { + t = l1.pIntersection(curves.get(cur), eps, false); + + if (t == null || t[0] > 1 || t[1] < 0) + return null; + + prevt[0] = Math.max(t[0], prevt[0]); + // might have to check again + if (t[1] < prevt[0]) + return null; + else { + prevt[1] = t[1]; + } + cur++; + + } + // modified 06.27.2013 + if (v2.startindex == curves.size() - 1) { + interval[0] = curves.size() - 1; + interval[1] = curves.size() - 1; + return interval; + } + interval[0] = v2.left; + interval[1] = v2.right; + return interval; + } + + } + + public ArrayList listStartVertices(ArrayList vList, + ArrayList curves, double eps) { + + Vertex point, vertex2, vertex; + ArrayList pq = new ArrayList(); + point = curves.get(0); + int i = 0; + boolean debug = false; + while (i < vList.size()) { + if (debug) + System.out + .println(i + " I was here before loop. " + + vList.get(i).toString() + " " + + vList.get(i).startindex + " " + + vList.get(i).endindex); + + this.computeNextInterval(vList.get(i), curves, 0, eps); + + if (debug) + System.out + .println(i + " I was here after loop. " + + vList.get(i).startindex + " " + + vList.get(i).endindex); + i++; + } + i = 0; + while (i < vList.size()) { + vertex = vList.get(i); + if (vertex.done)// && !vertex.done + { + + i++; + continue; + } + + for (int k = 0; k < vertex.degree; k++) { + vertex2 = vList.get(vertex.adjacencyList[k]); + Line l1 = new Line(vertex, vertex2); + double t[] = l1.pIntersection(point, eps, false); + + if (t != null && !(t[0] > 1 || t[1] < 0)) { + + if (!pq.contains(vertex)) { + if (this.computeReachabilityInterval(vertex2, vertex, + curves, 0, eps) != null) + pq.add(vertex); + + } + if (!pq.contains(vertex2)) { + if (this.computeReachabilityInterval(vertex, vertex2, + curves, 0, eps) != null) + pq.add(vertex2); + } + } + + } + i++; + + } + + return pq; + } + + public Vertex computeNextInterval(Vertex v1, ArrayList curves, + int index, double eps) { + /**************************** startintex-----interval--------endindex *************************************/ + Line l1; + v1.reachable = false; + boolean debug = false; + for (int i = index; i < curves.size() - 1; i++) { + + l1 = new Line(curves.get(i), curves.get(i + 1)); + + double t[] = l1.pIntersection(v1, eps, false); + + if (t != null && !(t[0] > 1 || t[1] < 0)) { + + if (t[0] < 0) + v1.left = i; + else + v1.left = i + t[0]; + v1.startindex = i; + + if (debug) + System.out.println(i + " I was here next before. " + + v1.startindex + " " + t[0] + " " + t[1]); + + if (t[1] >= 1) { + + int j = i; + while (t[1] >= 1 && j < curves.size() - 1) { + l1 = new Line(curves.get(j), curves.get(j + 1)); + t = l1.pIntersection(v1, eps, false); + if (debug) + System.out.println(j + " " + t[0] + " " + t[1]); + j++; + } + // made changes here + if (j < curves.size() - 1)// t[1] < 1 && + { + v1.right = j - 1 + Math.min(t[1], 1); + v1.endindex = j; + + } else if (t[1] < 1) { + v1.right = j + Math.min(t[1], 1); + v1.endindex = j + 1; + } else { + v1.right = j + 1; + v1.endindex = j + 1; + } + } else { + + v1.right = i + t[1]; + v1.endindex = i + 1; + + } + if (debug) + System.out.println("I was here next after. " + " " + + v1.left + " " + v1.right); + return v1; + } + + } + + v1.endindex = curves.size(); + v1.done = true; + + return v1; + } + + public Object readObject(String fileName) { + try { + FileInputStream fis = new FileInputStream("t.tmp"); + ObjectInputStream ois = new ObjectInputStream(fis); + + Object obj = ois.readObject(); + + ois.close(); + + return obj; + } catch (Exception e) { + System.out.println(e.toString()); + } + return null; + } + + public double nextX(PriorityQueue pq, double x) { + Stack stack = new Stack(); + double y = x; + + while (!pq.isEmpty() && pq.peek().left <= x) { + stack.push(pq.poll()); + } + + if (!pq.isEmpty()) + y = pq.peek().left; + else { + y = Double.MAX_VALUE; + } + + while (!stack.isEmpty()) { + pq.add(stack.pop()); + } + return y; + } + + public void print(Vertex v) { + System.out.println(v.toString() + " " + v.left + " " + v.right + " " + + v.startindex + " " + v.endindex); + } + + public ArrayList getFileNames(String fileName) { + ArrayList fileNames = new ArrayList(); + + try { + BufferedReader in = new BufferedReader(new FileReader(fileName)); + String str; + while ((str = in.readLine()) != null) { + fileNames.add(new String(str)); + + } + in.close(); + + } catch (IOException e) { + System.out.println(e.toString()); + System.exit(0); + } + + return fileNames; + + } + + public boolean mapMatching(ArrayList vList, + ArrayList curves, String cityname, double eps) { + + boolean debug = false, debugReturn = false; + + if (debug) + System.out + .println("*******************************************************************************"); + /****************************** Priority Queue *****************************************/ + Comparator comparator = new IntervalComparator(); + PriorityQueue pq = new PriorityQueue(1000, comparator); + + ArrayList startVertices = this.listStartVertices(vList, curves, + eps); + int i = 0; + while (i < startVertices.size()) { + if (debug && !startVertices.get(i).done) { + System.out.println(startVertices.get(i).toString() + + startVertices.get(i).startindex + " " + + startVertices.get(i).endindex); + + } + if (!startVertices.get(i).done) { + if (startVertices.get(i).left == 0) + startVertices.get(i).reachable = true; + pq.add(startVertices.get(i)); + } + i++; + } + + if (pq.size() == 0) + return false; + Vertex vertex = pq.poll(); + double x = vertex.left; + double interval[] = new double[2]; + while (vertex.right < curves.size()) { + if (debug) + System.out.println("\nCurrent Interval " + vertex.reachable + + " " + vertex.vertexID + " " + vertex.degree + " (" + + vertex.left + "," + vertex.right + ")"); + if (vertex.reachable && vertex.right >= curves.size() - 1) + return true; + for (int k = 0; k < vertex.degree; k++) { + Vertex adjacentVertex = vList.get(vertex.adjacencyList[k]); + + if (debug && vertex.vertexID == 220) + System.out.println("next Interval 0 " + + adjacentVertex.vertexID + " " + adjacentVertex.x + + " " + adjacentVertex.y + " " + + adjacentVertex.startindex + " " + + adjacentVertex.endindex + "(" + + adjacentVertex.left + "," + adjacentVertex.right + + ")"); + + if (!vertex.equals(adjacentVertex) + && adjacentVertex.left < adjacentVertex.right + && !adjacentVertex.done) {// + if (debug) + System.out.println("next Interval 1 " + + adjacentVertex.vertexID + " " + + adjacentVertex.startindex + " " + + adjacentVertex.endindex + "(" + + adjacentVertex.left + "," + + adjacentVertex.right + ")"); + interval = this.computeReachabilityInterval(vertex, + adjacentVertex, curves, x, eps); + if (interval != null) { + adjacentVertex.left = Math.max(interval[0], + adjacentVertex.left); + + adjacentVertex.startindex = (int) Math + .floor(adjacentVertex.left); + if (interval[0] > adjacentVertex.right) { + adjacentVertex.right = interval[1]; + adjacentVertex.endindex = (int) Math + .ceil(adjacentVertex.right); + } + pq.remove(adjacentVertex); + pq.add(adjacentVertex); + adjacentVertex.reachable = true; + if (debug) + System.out.println("next Interval 2 " + + adjacentVertex.left + "," + + adjacentVertex.right); + } else { + + if (debug) + System.out.println("null interval"); + } + } else if (!vertex.equals(adjacentVertex) + && adjacentVertex.done)// new + { + adjacentVertex.startindex = curves.size() - 1; + interval = this.computeReachabilityInterval(vertex, + adjacentVertex, curves, x, eps); + + if (interval != null && interval[0] == curves.size() - 1) { + + adjacentVertex.endindex = curves.size() - 1; + adjacentVertex.startindex = (int) Math + .floor(interval[0]); + adjacentVertex.left = interval[0]; + adjacentVertex.right = interval[1]; + pq.remove(adjacentVertex); + pq.add(adjacentVertex); + adjacentVertex.reachable = true; + } else { + // do nothing + } + + } else if (vertex.endindex == curves.size() - 1) { + Line l1 = new Line(vertex, adjacentVertex); + double t[] = l1.pIntersection( + curves.get(curves.size() - 1), eps, false); + if (t == null || t[0] > 1 || t[1] < 0) { + + } else { + if (debugReturn) + System.out.println("returned from case 4"); + return true; + } + } + } + + pq.remove(vertex); + if (!pq.isEmpty() && this.nextX(pq, vertex.left) < vertex.right) { + if (debug) + System.out.println("newly added " + !pq.isEmpty() + " " + + this.nextX(pq, vertex.left) + " " + vertex.right); + + vertex.left = this.nextX(pq, vertex.left); + vertex.startindex = (int) Math.floor(vertex.left); + + } + + else { + // x = vertex.right; + if (debug) + System.out.println("newly added " + !pq.isEmpty() + " " + + this.nextX(pq, vertex.left) + " " + vertex.right); + vertex = this.computeNextInterval(vertex, curves, + vertex.endindex, eps); + } + + if (!vertex.done) { + if (debug) + System.out.println("Inserted again: " + vertex.vertexID + + " " + vertex.degree + " (" + vertex.left + "," + + vertex.right + ")"); + pq.add(vertex); + } + + if (!pq.isEmpty()) { + vertex = pq.poll(); + x = vertex.left; + while (!vertex.reachable) { + if (debug) + System.out.println("Case 3: " + vertex.vertexID + " " + + vertex.degree + " " + vertex.reachable + " (" + + vertex.left + "," + vertex.right + ")"); + + if (!pq.isEmpty() + && this.nextX(pq, vertex.left) < vertex.right) { + + if (debug) + System.out.println("newly added in loop " + + !pq.isEmpty() + " " + + this.nextX(pq, vertex.left) + " " + + vertex.right); + + vertex.left = this.nextX(pq, vertex.left); + vertex.startindex = (int) Math.floor(vertex.left); + + } else { + if (debug) + System.out.println("newly added in loop " + + !pq.isEmpty() + " " + + this.nextX(pq, vertex.left) + " " + + vertex.right); + + vertex = this.computeNextInterval(vertex, curves, + vertex.endindex, eps); + } + if (!vertex.done) { + if (debug) + System.out.println("Inserted again in loop: " + + vertex.vertexID + " " + vertex.degree + + " (" + vertex.left + "," + vertex.right + + ")"); + pq.add(vertex); + } + + if (!pq.isEmpty()) { + vertex = pq.poll(); + x = vertex.left; + } else { + if (debugReturn) + System.out.println("returned from case 3"); + return false; + } + + } + } else { + if (debugReturn) + System.out.println("returned from case 1"); + return false; + } + + if (vertex.left > vertex.right) { + + if (debugReturn) { + System.out.println("returned from case 2"); + System.out.println(vertex.toString() + " " + vertex.left + + " " + vertex.right); + } + return false; + + } + + } + + if (vertex.right >= curves.size()) { + if (debugReturn) + System.out.println("I am returned from here " + + vertex.toString() + " " + vertex.left + " " + + vertex.right + " " + vertex.reachable); + return true; + } + + // break;//test + // } + // System.out.println(startVertices.toString()); + return false; + + } + + public int min = 10000000; + Boolean found = false; + public String curveName; + + public void getEpsilon(ArrayList graph, ArrayList curves, + String cityname, int start, int end) { + boolean debug = false; + /* + * if (curveName.equals("13.dat")) debug = true; + */ + + int i; + Boolean bool1; + if (start >= end - 2 && !found) { + found = true; + for (i = start; i <= end; i++) { + int k = 0; + while (k < graph.size()) { + graph.get(k).reset(); + k++; + } + bool1 = this.mapMatching(graph, curves, cityname, i); + if (debug) + System.out.println(start + ", " + end + " " + i + " = " + + bool1); + if (bool1) { + min = i; + return; + } + } + min = i; + return; + } else { + i = 0; + + while (i < graph.size()) { + graph.get(i).reset(); + i++; + } + bool1 = this + .mapMatching(graph, curves, cityname, (end + start) / 2); + if (debug) + System.out.println(start + ", " + end + " " + (end + start) / 2 + + " = " + bool1); + if (!bool1) { + getEpsilon(graph, curves, cityname, + (int) Math.ceil((end + start) / 2), end); + } else { + + getEpsilon(graph, curves, cityname, start, + (int) Math.ceil((end + start) / 2)); + } + } + return; + } + + public void pathSimilarity(ArrayList graph, File fin, + String strInput, String cityname, int fileno) { + boolean debug = false; + ArrayList curves = new ArrayList(); + int min = 1, max = 1600; + int count = 0; + try { + + File folder = new File(strInput + "//"); + + if (!folder.exists()) + folder.mkdirs(); + BufferedWriter bwways = new BufferedWriter(new FileWriter(strInput + + "//outputFrechet" + fileno + ".txt")); + + for (File file : fin.listFiles()) { + + curves = this.readFile(file.getAbsolutePath()); + this.curveName = file.getName(); + + if (debug) + System.out.println(curves.size() + " :" + + this.mapMatching(graph, curves, cityname, 225)); + else { + + if (curves.size() < 2) { + System.out.println("I was here with size less than 2."); + continue; + } + + this.found = false; + this.getEpsilon(graph, curves, cityname, min, max); + if (this.min == max + 1) { + this.found = false; + } + } + double dist = Math.sqrt(Math.pow( + curves.get(0).x - curves.get(curves.size() - 1).x, 2) + + Math.pow( + curves.get(0).y + - curves.get(curves.size() - 1).y, 2)); + bwways.write(file.getName() + " " + curves.size() + " " + + this.min + " " + dist + "\n"); + + System.out.println(count + " " + file.getName() + " size = " + + curves.size() + " Frechet distance = " + this.min + + " length of path = " + dist); + + count++; + } + bwways.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + } + + public ArrayList removeDuplicates(ArrayList curves) { + for (int i = 1; i < curves.size(); i++) { + Vertex prev = curves.get(i - 1); + Vertex cur = curves.get(i); + + if (prev.x == cur.x && prev.y == cur.y) { + curves.remove(i); + i--; + } + + } + return curves; + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Edge.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Edge.java new file mode 100644 index 0000000..1e876d1 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Edge.java @@ -0,0 +1,69 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: Edge.java + */ +package mapmatchingbasics; + +public class Edge { + + public Vertex v1,v2; + public double cstart,cend; + public double vstart,vend; + public Line line; + public boolean done; + public int startIndex, endIndex; + public Edge(Vertex v1,Vertex v2) + { + this.v1 = v1; + this.v2 = v2; + this.cstart = Double.MAX_VALUE; + this.cend = -1; + this.vstart = Double.MAX_VALUE; + this.vend = -1; + this.line = new Line(v1,v2); + this.done = false; + } + public void reset() + { + this.cstart = Double.MAX_VALUE; + this.cend = -1; + this.vstart = Double.MAX_VALUE; + this.vend = -1; + this.line = new Line(v1,v2); + this.done = false; + } + + public String toString() + { + return new String(this.line.toString()); + } + + public String getKeyString(){ + return v1.x+" "+v2.x+" "+v1.y+" "+v2.y; + } +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparator.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparator.java new file mode 100644 index 0000000..be26ff0 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparator.java @@ -0,0 +1,72 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: IntervalComparator.java + */ +package mapmatchingbasics; +import java.util.Comparator; + + +public class IntervalComparator implements Comparator{ + @Override + public int compare(Vertex x, Vertex y) + { + if(x.startindex < y.startindex) + { + return -1; + } + else if(x.startindex > y.startindex) + { + return 1; + } + else + { + if (x.left < y.left) + { + return -1; + } + else if (x.left > y.left) + { + return 1; + } + else if(x.left == y.left) + { + if (x.right < y.right) + { + return -1; + } + if (x.right > y.right) + { + return 1; + } + + } + return 0; + } + + } +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparatorEdge.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparatorEdge.java new file mode 100644 index 0000000..ced22f2 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/IntervalComparatorEdge.java @@ -0,0 +1,62 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: IntervalComparatorEdge.java + */ +package mapmatchingbasics; + +import java.util.Comparator; + +public class IntervalComparatorEdge implements Comparator{ + @Override + public int compare(Edge x, Edge y) + { + + if(x.cstart < y.cstart) + { + return -1; + } + else if(x.cstart > y.cstart) + { + return 1; + } + else + { + if (x.cend < y.cend) + { + return -1; + } + if (x.cend > y.cend) + { + return 1; + } + return 0; + } + + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Line.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Line.java new file mode 100644 index 0000000..b7a1156 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Line.java @@ -0,0 +1,492 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: Line.java + */ +package mapmatchingbasics; + +public class Line { + private Vertex p1; + private Vertex p2; + double xdiff, ydiff; + double c, m, theta; + + public Line(Vertex p1, Vertex p2) { + this.p1 = p1; + this.p2 = p2; + this.xdiff = p2.x - p1.x; + this.ydiff = p2.y - p1.y; + if (this.xdiff != 0) { + this.m = this.ydiff / this.xdiff; + this.c = ((p1.y + p2.y) - m * (p1.x + p2.x)) / 2; + this.theta = Math.atan2(this.ydiff, this.xdiff); + } else { + if (this.ydiff > 0) { + this.theta = Math.PI / 2.0; + } else { + this.theta = -Math.PI / 2.0; + } + this.c = 0; + } + + } + + public String toString() { + return "[" + this.p1.x + " " + this.p1.y + "; " + this.p2.x + " " + + this.p2.y + "]"; + } + + public double[] pIntersection(Vertex p, double eps, boolean precision) { + + double t[] = new double[2]; + /* + * Line 1: x1+(x2-x1)*t = x; x1+xdiff*t = x y1+(y2-y1)*t = y; y1+ydiff*t + * = y + * + * (x-a)^2+(y-b)^2=eps^2 (x1+xdiff*t-a)^2+(y1+ydiff*t-b)^2=eps^2 + * (xdiff^2+ydiff^2)t^2 + (2(x1-a)xdiff+2(y1-b)ydiff)t + + * (x1-a)^2+(y1-b)^2-eps^2=0 + * + * t = (-(2(x1-a)xdiff+2(y1-b)ydiff)) +- + * sqrt((2(x1-a)xdiff+2(y1-b)ydiff))^2 - + * 4(xdiff^2+ydiff^2)(x1^2+y1^2-eps^2)))/(2*(xdiff^2+ydiff^2)) + */ + + double b_t = 2 * ((p1.x - p.x) * this.xdiff + (p1.y - p.y) * this.ydiff); + double c_t = (p1.x - p.x) * (p1.x - p.x) + (p1.y - p.y) * (p1.y - p.y) + - eps * eps; + double a_t = this.xdiff * this.xdiff + this.ydiff * this.ydiff; + + double newEps = eps + 0.01; + double new_c_t = (p1.x - p.x) * (p1.x - p.x) + (p1.y - p.y) + * (p1.y - p.y) - newEps * newEps; + + if (a_t == 0) { + /* + * System.out.println("a_t="+a_t+",b_t="+b_t+", c_t="+c_t); + * System.out.println("disc="+ (b_t*b_t - 4*a_t*c_t)); + * System.out.println(p1.toString()+p2.toString()); + */ + return null; + } + + double determinant = b_t * b_t - 4 * a_t * c_t; + double newDeterminant = b_t * b_t - 4 * a_t * new_c_t; + + if (determinant >= 0) { + t[1] = (-b_t + Math.sqrt(determinant)) / (2 * a_t); + t[0] = (-b_t - Math.sqrt(determinant)) / (2 * a_t); + } else if (precision && newDeterminant >= 0) { + t[1] = (-b_t + Math.sqrt(0)) / (2 * a_t); + t[0] = (-b_t - Math.sqrt(0)) / (2 * a_t); + } else { + return null; + } + return t; + } + + public boolean pIntersection(Edge e, double eps) { + + /* + * Line 1: x1+(x2-x1)*t = x y1+(y2-y1)*t = y Line 2: y = mx + c + * y1+(y2-y1)*t = (x1+(x2-x1)*t)*m + c (y2-y1)*t - (x2-x1)*t*m = x1*m + + * c- y1 t = (x1*m + c - y1)/((y2-y1)-(x2-x1)*m) + */ + + Line vline = e.line; + + Line line[] = this.getEpsilonNeiborhood(vline, eps); + double startIntervalOnCurve, endIntervalOnCurve, startIntervalOnEdge, endIntervalOnEdge; + double vstart = -1, vend = -1; + + if (Math.abs(this.theta) == Math.abs(line[0].theta)) { + double t[] = this.getTParallel(vline, eps); + if (t == null) { + return false; + } + startIntervalOnCurve = t[0]; + endIntervalOnCurve = t[1]; + startIntervalOnEdge = 0; + endIntervalOnEdge = 1; + + } else { + + if (line[0].xdiff == 0) { + startIntervalOnCurve = this.m * line[0].p1.x + this.c; + endIntervalOnCurve = this.m * line[1].p1.x + this.c; + + startIntervalOnEdge = (startIntervalOnCurve - line[0].p1.y) + / (line[0].ydiff); + endIntervalOnEdge = (endIntervalOnCurve - line[1].p1.y) + / (line[1].ydiff); + + startIntervalOnCurve = (startIntervalOnCurve - this.p1.y) + / (this.ydiff); + endIntervalOnCurve = (endIntervalOnCurve - this.p1.y) + / (this.ydiff); + } else if (this.xdiff == 0) { + startIntervalOnCurve = line[0].m * this.p1.x + line[0].c; + endIntervalOnCurve = line[1].m * this.p1.x + line[1].c; + + startIntervalOnEdge = (startIntervalOnCurve - line[0].p1.y) + / (line[0].ydiff); + endIntervalOnEdge = (endIntervalOnCurve - line[1].p1.y) + / (line[1].ydiff); + + startIntervalOnCurve = (startIntervalOnCurve - this.p1.y) + / (this.ydiff); + endIntervalOnCurve = (endIntervalOnCurve - this.p1.y) + / (this.ydiff); + } else { + startIntervalOnCurve = -(this.c - line[0].c) + / (this.m - line[0].m); + endIntervalOnCurve = -(this.c - line[1].c) + / (this.m - line[1].m); + + startIntervalOnEdge = (startIntervalOnCurve - line[0].p1.x) + / (line[0].p2.x - line[0].p1.x); + endIntervalOnEdge = (endIntervalOnCurve - line[1].p1.x) + / (line[1].p2.x - line[1].p1.x); + + startIntervalOnCurve = (startIntervalOnCurve - this.p1.x) + / (this.p2.x - this.p1.x); + endIntervalOnCurve = (endIntervalOnCurve - this.p1.x) + / (this.p2.x - this.p1.x); + } + /*if (line[0].p2.x - line[0].p1.x == 0) { + + return false; + }*/ + + } + + double intersectionWithDiscOne[] = new double[2]; + double intersectionWithDiscTwo[] = new double[2]; + double interval[] = new double[2]; + + if (startIntervalOnCurve > endIntervalOnCurve) { + double temp = startIntervalOnCurve; + startIntervalOnCurve = endIntervalOnCurve; + endIntervalOnCurve = temp; + + temp = startIntervalOnEdge; + startIntervalOnEdge = endIntervalOnEdge; + endIntervalOnEdge = temp; + } + + intersectionWithDiscOne = this.pIntersection(vline.p1, eps, false); + + intersectionWithDiscTwo = this.pIntersection(vline.p2, eps, false); + + double min1 = 0, min2 = 0, max1 = 1, max2 = 1; + + // case one + + if (intersectionWithDiscOne == null && intersectionWithDiscTwo == null) { + // case one + if (startIntervalOnCurve > 1 || endIntervalOnCurve < 0) + return false; + // case two + if ((startIntervalOnEdge > 1 && endIntervalOnEdge > 1) + || (startIntervalOnEdge < 0 && endIntervalOnEdge < 0)) + return false; + + if (startIntervalOnEdge >= 0 && startIntervalOnEdge <= 1 + && endIntervalOnEdge >= 0 && endIntervalOnEdge <= 1) { + startIntervalOnCurve = Math.max(0, startIntervalOnCurve); + endIntervalOnCurve = Math.min(1, endIntervalOnCurve); + } else + return false; + } + + // case two + + if (intersectionWithDiscOne != null) { + + min1 = Math.min(intersectionWithDiscOne[0], intersectionWithDiscOne[1]); + max1 = Math.max(intersectionWithDiscOne[0], intersectionWithDiscOne[1]); + + if (((startIntervalOnEdge > 1 && endIntervalOnEdge > 1) || (startIntervalOnEdge < 0 && endIntervalOnEdge < 0)) + && (min1 > 1 || max1 < 0)) + return false; + + if (startIntervalOnEdge < 0) { + if (min1 <= 1) + startIntervalOnCurve = Math.max(startIntervalOnCurve, min1); + if (startIntervalOnCurve == min1) + vstart = 0; + } + + if (endIntervalOnEdge < 0) { + if (max1 >= 0) + endIntervalOnCurve = Math.min(endIntervalOnCurve, max1); + if (endIntervalOnCurve == max1) + vend = 0; + } + + + + } + // case three + if (intersectionWithDiscTwo != null) { + min2 = Math.min(intersectionWithDiscTwo[0], intersectionWithDiscTwo[1]); + max2 = Math.max(intersectionWithDiscTwo[0], intersectionWithDiscTwo[1]); + + if (((startIntervalOnEdge > 1 && endIntervalOnEdge > 1) || (startIntervalOnEdge < 0 && endIntervalOnEdge < 0)) + && (min2 > 1 || max2 < 0)) + return false; + + if (startIntervalOnEdge > 1) { + if (min2 <= 1) + startIntervalOnCurve = Math.max(startIntervalOnCurve, min2); + if (startIntervalOnCurve == min2) + vstart = 1; + } + + if (endIntervalOnEdge > 1) { + if (max2 >= 0) + endIntervalOnCurve = Math.min(endIntervalOnCurve, max2); + if (endIntervalOnCurve == max2) + vend = 1; + } + + } + + if (intersectionWithDiscOne == null && intersectionWithDiscTwo != null) { + if (startIntervalOnEdge >= 0 && startIntervalOnEdge <= 1 + && endIntervalOnEdge >= 0 && endIntervalOnEdge <= 1) { + + } else { + if (startIntervalOnEdge >= 0 && startIntervalOnEdge <= 1) { + if (startIntervalOnCurve > 1 && min2 > 1) + return false; + if (startIntervalOnCurve < 0 && max2 < 0) + return false; + } + if (endIntervalOnEdge >= 0 && endIntervalOnEdge <= 1) { + if (endIntervalOnCurve > 1 && min2 > 1) + return false; + if (endIntervalOnCurve < 0 && max2 < 0) + return false; + } + } + } + if (intersectionWithDiscOne != null && intersectionWithDiscTwo == null) { + if (startIntervalOnEdge >= 0 && startIntervalOnEdge <= 1 + && endIntervalOnEdge >= 0 && endIntervalOnEdge <= 1) { + + } else { + + if (startIntervalOnEdge >= 0 && startIntervalOnEdge <= 1) { + if (startIntervalOnCurve > 1 && min1 > 1) + return false; + if (startIntervalOnCurve < 0 && max1 < 0) + return false; + } + if (endIntervalOnEdge >= 0 && endIntervalOnEdge <= 1) { + if (endIntervalOnCurve > 1 && min1 > 1) + return false; + if (endIntervalOnCurve < 0 && max1 < 0) + return false; + } + } + } + + if (startIntervalOnCurve > endIntervalOnCurve) { + double temp = startIntervalOnCurve; + startIntervalOnCurve = endIntervalOnCurve; + endIntervalOnCurve = temp; + + temp = vend; + vend = vstart; + vstart = temp; + } + // case one + if (startIntervalOnCurve > 1 || endIntervalOnCurve < 0) + return false; + // case two + + if (Math.max(max1, max2) < 0 || Math.min(min1, min2) > 1) + return false; + + double in1[] = new double[2]; + double in2[] = new double[2]; + try { + interval[0] = Math.max(0, startIntervalOnCurve); + + if (vstart == -1) { + + in1 = vline.pIntersection(this.getVertex(interval[0]), eps, + true); + + if (in1[0] >= 0 && in1[0] <= 1 && in1[1] >= 0 && in1[1] <= 1) + vstart = (in1[0] + in1[1]) / 2; + else if (in1[0] >= 0 && in1[0] <= 1) + vstart = in1[0]; + else if (in1[1] >= 0 && in1[1] <= 1) + vstart = in1[1]; + else + vstart = 0; + } + + interval[1] = Math.min(1, endIntervalOnCurve); + + if (vend == -1) { + + in2 = vline.pIntersection(this.getVertex(interval[1]), eps, + true); + + if (in2[0] >= 0 && in2[0] <= 1 && in2[1] >= 0 && in2[1] <= 1) + vend = (in2[0] + in2[1]) / 2; + else if (in2[0] >= 0 && in2[0] <= 1) + vend = in2[0]; + else if (in2[1] >= 0 && in2[1] <= 1) + vend = in2[1]; + else + vend = 1; + } + e.cstart = interval[0]; + e.cend = interval[1]; + e.vstart = vstart; + e.vend = vend; + + return true; + } catch (Exception ex) { + System.out.println("eline: " + e.line.toString() + " " + e.line.m + + " " + e.line.theta); + System.out.println("this: " + this.toString() + " " + this.m + " " + + this.theta); + System.out.println(startIntervalOnCurve + " " + endIntervalOnCurve + + " " + startIntervalOnEdge + " " + endIntervalOnEdge); + System.out.println(min1 + " " + max1 + " " + min2 + " " + max2); + System.out.println(this.getVertex(interval[0]).toString()); + System.out.println(this.getVertex(interval[1]).toString()); + + System.out.println(ex.toString()); + System.exit(0); + return false; + } + } + + public Vertex getVertex(double t) { + return new Vertex(this.p1.x + this.xdiff * t, this.p1.y + this.ydiff + * t); + } + + public Line[] getEpsilonNeiborhood(Line vline, double eps) { + + Line line[] = new Line[2]; + double dx, dy; + dx = eps * Math.cos(vline.theta + Math.PI / 2); + dy = eps * Math.sin(vline.theta + Math.PI / 2); + // dx_l = eps*Math.cos(vline.theta + 3*Math.PI/2); + // dy_l = eps*Math.sin(vline.theta + 3*Math.PI/2); + + line[0] = new Line(new Vertex(vline.p1.x - dx, vline.p1.y - dy), + new Vertex(vline.p2.x - dx, vline.p2.y - dy)); + line[1] = new Line(new Vertex(vline.p1.x + dx, vline.p1.y + dy), + new Vertex(vline.p2.x + dx, vline.p2.y + dy)); + + if (line[0].theta != line[1].theta) { + + line[0].m = line[1].m; + line[0].theta = line[1].theta; + } + return line; + } + + public double[] getTParallel(Line line, double eps) { + double t[] = new double[2]; + double newm; + double x1, y1, x2, y2; + if (Math.abs(line.theta) == Math.PI / 2) { + newm = 0; + x1 = this.p1.x; + y1 = line.p1.y; + x2 = this.p2.x; + y2 = line.p2.y; + } else if (Math.abs(line.theta) == 0) { + newm = 0; + x1 = line.p1.x; + y1 = this.p1.y; + x2 = line.p2.x; + y2 = this.p2.y; + } else { + newm = 1 / line.m; + double c1 = line.p1.y + newm * line.p1.x; + double c2 = line.p2.y + newm * line.p2.x; + + x1 = (c1 - this.c) / (this.m + newm); + y1 = this.m * x1 + this.c; + + x2 = (c2 - this.c) / (this.m + newm); + y2 = this.m * x2 + this.c; + } + + if (Math.sqrt((line.p1.x - x1) * (line.p1.x - x1) + (line.p1.y - y1) + * (line.p1.y - y1)) > eps) + return null; + + if (this.xdiff != 0) { + t[0] = (x1 - this.p1.x) / this.xdiff; + t[1] = (x2 - this.p1.x) / this.xdiff; + } else { + t[0] = (y1 - this.p1.y) / this.ydiff; + t[1] = (y2 - this.p1.y) / this.ydiff; + } + + double min = Math.min(t[0], t[1]); + double max = Math.max(t[0], t[1]); + + if (min > 1 || max < 0) + return null; + t[0] = min; + t[1] = max; + + return t; + } + + public double distance(Vertex p) { + + double b_t = 2 * ((p1.x - p.x) * this.xdiff + (p1.y - p.y) * this.ydiff); + double c_t = (p1.x - p.x) * (p1.x - p.x) + (p1.y - p.y) * (p1.y - p.y);// - + // eps*eps; + double a_t = this.xdiff * this.xdiff + this.ydiff * this.ydiff; + double disc = Math.sqrt((b_t * b_t - 4 * a_t * c_t) / (4 * a_t)); + double t[] = this.pIntersection(p, disc, false); + if (t == null || t[0] > 1 || t[0] < 0) + return Math.min( + Math.sqrt((p1.x - p.y) * (p1.x - p.y) + (p1.y - p.y) + * (p1.y - p.y)), + Math.sqrt((p2.x - p.y) * (p2.x - p.y) + (p2.y - p.y) + * (p2.y - p.y))); + else + return disc; + } + + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/PathLabelComparator.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/PathLabelComparator.java new file mode 100644 index 0000000..e376c6e --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/PathLabelComparator.java @@ -0,0 +1,60 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: PathLabelComparator.java + */ +package mapmatchingbasics; + +import java.util.ArrayList; +import java.util.Comparator; + +public class PathLabelComparator implements Comparator{ + + ArrayList vList; + public PathLabelComparator(ArrayList vList) + { + this.vList = vList; + } + @Override + public int compare(Integer x, Integer y) + { + // Assume neither string is null. Real code should + // probably be more robust + + if (vList.get(x.intValue()).left< vList.get(y.intValue()).left) + { + return -1; + } + if (vList.get(x.intValue()).left > vList.get(y.intValue()).left) + { + return 1; + } + return 0; + + + } +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/ReadFiles.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/ReadFiles.java new file mode 100644 index 0000000..d712ba6 --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/ReadFiles.java @@ -0,0 +1,441 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: ReadFiles.java + */ +package mapmatchingbasics; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; + +public class ReadFiles { + + public static ArrayList getTokens(String data, String separator) { + StringTokenizer strToken = new StringTokenizer(data, separator); + ArrayList tokens = new ArrayList(); + while (strToken.hasMoreElements()) { + tokens.add(strToken.nextToken()); + } + return tokens; + } + + public ArrayList readVertexFiles(String fileName, double XLow, + double XHigh, double YLow, double YHigh) { + ArrayList vList = new ArrayList(); + + String str = ""; + try { + BufferedReader in = new BufferedReader(new FileReader(fileName)); + + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, " "); + Long id = new Long(strToken.nextToken()); + Double lat = new Double(strToken.nextToken()); + Double lon = new Double(strToken.nextToken()); + strToken.nextToken(); + strToken.nextToken(); + Double x = new Double(strToken.nextToken()); + Double y = new Double(strToken.nextToken()); + if (x >= XLow && x <= XHigh && y >= YLow && y <= YHigh) + vList.add(new Vertex(id, lat, lon, x, y)); + } + in.close(); + + } catch (Exception e) { + System.out.println(str + " I was here: " + e.toString()); + } + return vList; + } + + public HashMap getHashMap(ArrayList vList) { + HashMap map = new HashMap(); + int i = 0; + while (i < vList.size()) { + map.put(vList.get(i).vertexIDOnFile, new Integer(i)); + i++; + } + + return map; + } + + public ArrayList removeDegreeZero(ArrayList vList) { + int i = 0; + ArrayList vList2 = new ArrayList(); + Vertex v; + while (i < vList.size()) { + v = vList.get(i); + if (v.degree != 0) { + v.degree = 0; + vList2.add(v); + } + i++; + } + + return vList2; + } + + public ArrayList readEdgeFiles(String fileName, + ArrayList vList, HashMap map) { + try { + + BufferedWriter bwways = new BufferedWriter(new FileWriter(fileName + + "all")); + BufferedReader in = new BufferedReader(new FileReader(fileName)); + String str; + + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, " "); + + strToken.nextToken(); + Long node1 = new Long(strToken.nextToken()); + Long node2 = new Long(strToken.nextToken()); + if (map.get(node1) != null && map.get(node2) != null) { + int n1 = map.get(node1).intValue(); + int n2 = map.get(node2).intValue(); + + if (n1 != n2) { + vList.get(n1).addElementAdjList(n2); + vList.get(n2).addElementAdjList(n1); + bwways.write(vList.get(n1).x + " " + vList.get(n2).x + + " " + vList.get(n1).y + " " + vList.get(n2).y + + "\n"); + } + } + } + in.close(); + bwways.close(); + + } catch (Exception e) { + System.out.println(e.toString()); + return vList; + + } + return vList; + + } + + public static ArrayList loadBenchmarkMap( + HashMap map, String vertexfile, String edgefile, + boolean isDirected) { + ArrayList vList = new ArrayList(); + + try { + + BufferedReader in = new BufferedReader(new FileReader(vertexfile)); + String str; + + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, ","); + Long node = new Long(strToken.nextToken()); + double x = Double.parseDouble(strToken.nextToken()); + double y = Double.parseDouble(strToken.nextToken()); + + if (map.get(node) == null) { + Vertex v = new Vertex(node, x, y); + vList.add(v); + int index = vList.indexOf(v); + map.put(node, index); + + } + } + in.close(); + + } catch (Exception e) { + System.out.println(vertexfile + e.toString()); + System.exit(0); + + } + + try { + + BufferedReader in = new BufferedReader(new FileReader(edgefile)); + String str; + + while ((str = in.readLine()) != null) { + if (str.trim().equals("")) + continue; + StringTokenizer strToken = new StringTokenizer(str, ","); + strToken.nextToken(); + Long node1 = new Long(strToken.nextToken()); + Long node2 = new Long(strToken.nextToken()); + + int index1 = -1, index2 = -1; + if (map.get(node1) != null && map.get(node2) != null) { + index1 = map.get(node1); + index2 = map.get(node2); + vList.get(index1).addElementAdjList(index2); + if (!isDirected) + vList.get(index2).addElementAdjList(index1); + } + } + in.close(); + + } catch (Exception e) { + System.out.println(edgefile + e.toString()); + System.exit(0); + + } + + return vList; + + } + + /** + * Load map with defined bounding box + * */ + public static ArrayList loadBenchmarkMap( + HashMap map, String vertexfile, String edgefile, + boolean isDirected, double XLow, double XHigh, double YLow, + double YHigh) { + ArrayList vList = new ArrayList(); + + try { + + BufferedReader in = new BufferedReader(new FileReader(vertexfile)); + String str; + + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, ","); + Long node = new Long(strToken.nextToken()); + double x = Double.parseDouble(strToken.nextToken()); + double y = Double.parseDouble(strToken.nextToken()); + + if (x >= XLow && x <= XHigh && y >= YLow && y <= YHigh) { + + if (map.get(node) == null) { + Vertex v = new Vertex(node, x, y); + vList.add(v); + int index = vList.indexOf(v); + map.put(node, index); + + } + } + + } + in.close(); + + } catch (Exception e) { + System.out.println(vertexfile + e.toString()); + System.exit(0); + + } + + try { + + BufferedReader in = new BufferedReader(new FileReader(edgefile)); + String str; + + while ((str = in.readLine()) != null) { + if (str.trim().equals("")) + continue; + StringTokenizer strToken = new StringTokenizer(str, ","); + strToken.nextToken(); + Long node1 = new Long(strToken.nextToken()); + Long node2 = new Long(strToken.nextToken()); + + int index1 = -1, index2 = -1; + if (map.get(node1) != null && map.get(node2) != null) { + index1 = map.get(node1); + index2 = map.get(node2); + vList.get(index1).addElementAdjList(index2); + if (!isDirected) + vList.get(index2).addElementAdjList(index1); + } + } + in.close(); + + } catch (Exception e) { + System.out.println(edgefile + e.toString()); + System.exit(0); + + } + + return vList; + + } + + public ArrayList readTeleAtlasVertices(String fileName, + double XLow, double XHigh, double YLow, double YHigh) { + + ArrayList vList = new ArrayList(); + try { + BufferedReader in = new BufferedReader(new FileReader(fileName)); + String str; + + while ((str = in.readLine()) != null) { + StringTokenizer strToken = new StringTokenizer(str, " "); + Long id = new Long(strToken.nextToken()); + Double x = new Double(strToken.nextToken()); + Double y = new Double(strToken.nextToken()); + if (x >= XLow && x <= XHigh && y >= YLow && y <= YHigh) { + vList.add(new Vertex(id, x, y)); + } + str = in.readLine(); + int lines = Integer.parseInt(str); + int i = 0; + while (i < lines) { + in.readLine(); + i++; + } + + } + in.close(); + + } catch (Exception e) { + System.out.println("readTeleAtlasVertices " + e.toString()); + + System.exit(0); + } + + return vList; + } + + public ArrayList readTeleAtlasGraph(String vertexFile, + String edgeFile, double XLow, double XHigh, double YLow, + double YHigh) { + + String str = new String(); + + String vid1, vid2; + Integer index1, index2; + + ArrayList vList = this.readTeleAtlasVertices(vertexFile, XLow, + XHigh, YLow, YHigh); + + HashMap map = this.getHashMap(vList); + + try { + + BufferedReader in = new BufferedReader(new FileReader(edgeFile)); + + while ((str = in.readLine()) != null) { + try { + + StringTokenizer strToken = new StringTokenizer(str, " "); + strToken.nextToken();// eid + strToken.nextToken();// eid + strToken.nextToken();// number + + vid1 = strToken.nextToken(); + vid2 = strToken.nextToken(); + index1 = map.get(new Long(vid1)); + index2 = map.get(new Long(vid2)); + + if (index1 != null && index2 != null) { + vList.get(index1.intValue()).addElementAdjList( + index2.intValue()); + vList.get(index2.intValue()).addElementAdjList( + index1.intValue()); + + } + + } catch (Exception e) { + System.out.println(e.toString()); + } + + } + in.close(); + } catch (IOException e) { + + System.out.println("EXCEPTION HERE:" + e.toString()); + System.exit(0); + + } + + return vList; + + } + + public ArrayList loadOpenStreetMapGraph(String vertexFile, + String edgeFile, double XLow, double XHigh, double YLow, + double YHigh) { + + ArrayList vList = this.readVertexFiles(vertexFile, XLow, XHigh, + YLow, YHigh); + HashMap map = this.getHashMap(vList); + + vList = this.readEdgeFiles(edgeFile, vList, map); + + vList = this.removeDegreeZero(vList); + map = this.getHashMap(vList); + + HashMap mapDuplicate = new HashMap(); + int i = 0; + + Integer index; + while (i < vList.size()) { + + boolean contains = mapDuplicate.containsKey(vList.get(i) + .getKeyString()); + + if (!contains) { + mapDuplicate.put(vList.get(i).getKeyString(), + vList.get(i).vertexIDOnFile); + } else { + Long id = mapDuplicate.get(vList.get(i).getKeyString()); + index = map.get(id); + map.put(vList.get(i).vertexIDOnFile, index); + } + + i++; + } + + vList = this.readEdgeFiles(edgeFile, vList, map); + return vList; + } + + public ArrayList loadTeleAtlasGraph(String vertexFile, + String edgeFile, double XLow, double XHigh, double YLow, + double YHigh) { + ReadFiles readFiles = new ReadFiles(); + ArrayList vList = readFiles.readTeleAtlasGraph(vertexFile, + edgeFile, XLow, XHigh, YLow, YHigh); + return vList; + } + + public void writeObjects(Object o, String file) { + try { + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeObject(o); + + oos.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + } + +} diff --git a/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Vertex.java b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Vertex.java new file mode 100644 index 0000000..79ec7db --- /dev/null +++ b/evaluation/pathbaseddistance/MapMatching/src/mapmatchingbasics/Vertex.java @@ -0,0 +1,179 @@ +/* +Path-based graph distance 1.0 +Copyright 2014 Mahmuda Ahmed, K. S. Hickmann and Carola Wenk + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------ + +This software is based on the following article. Please cite this +article when using this code as part of a research publication: + +M. Ahmed, K. S. Hickmann, and C. Wenk. +Path-based distance for street map comparison. +arXiv:1309.6131, 2013. +------------------------------------------------------------------------ + +Author: Mahmuda Ahmed +Filename: Vertex.java + */ +package mapmatchingbasics; + +import java.io.Serializable; + +public class Vertex implements Serializable{ + + /** + * + */ + private static final long serialVersionUID = 1L; + public Long vertexIDOnFile; + public int vertexID; + public double x, y, lat, lon; + public int degree=0; + public int adjacencyList[]=new int[15]; + public double left=Double.MAX_VALUE, right=-1;//left and right endpoint of recheability interval or left is used as path label while computing shortest Paths. + public int startindex = -1; + public int endindex = 0; + public boolean done = false; + public boolean reachable = false; + // int paths[] = new int[10]; + + public Vertex(){ + + } + public Vertex(Long vertexIDOnFile, double lat, double lon, double x,double y) + { + this.vertexIDOnFile = vertexIDOnFile; + this.lat = lat; + this.lon = lon; + this.x = x; + this.y = y; + reachable = false; + } + public Vertex(Long vertexIDOnFile,double x,double y) + { + this.vertexIDOnFile = vertexIDOnFile; + this.x = x; + this.y = y; + } + + + public Vertex(double x,double y) + { + this.x = x; + this.y = y; + } + void addElementAdjList(int v) + { + for(int i=0;i-1 + % don't update CA in this case + CAij = CA(i,j); + elseif i==1 && j==1 + CA(i,j) = dfcn(P(1,:),Q(1,:)); % update the CA perminent + CAij = CA(i,j); % set the current relevant value + elseif i>1 && j==1 + CA(i,j) = max( c(i-1,1,P,Q,dfcn), dfcn(P(i,:),Q(1,:)) ); + CAij = CA(i,j); + elseif i==1 && j>1 + CA(i,j) = max( c(1,j-1,P,Q,dfcn), dfcn(P(1,:),Q(j,:)) ); + CAij = CA(i,j); + elseif i>1 && j>1 + CA(i,j) = max( min([c(i-1,j,P,Q,dfcn), ... + c(i-1,j-1,P,Q,dfcn), c(i,j-1,P,Q,dfcn)]),... + dfcn(P(i,:),Q(j,:)) ); + CAij = CA(i,j); + else + CA(i,j) = inf; + end +end % end function, c + + +end % end main function + diff --git a/evaluation/shortest_path_evaluation/libraries/HausdorffDist.m b/evaluation/shortest_path_evaluation/libraries/HausdorffDist.m new file mode 100644 index 0000000..700f033 --- /dev/null +++ b/evaluation/shortest_path_evaluation/libraries/HausdorffDist.m @@ -0,0 +1,59 @@ +function [hd D] = HausdorffDist(P,Q) +% Calculates the Hausdorff Distance between P and Q +% +% hd = HausdorffDist(P,Q) +% [hd D] = HausdorffDist(P,Q) +% +% Calculates the Hausdorff Distance, hd, between two sets of points, P and Q +% (which could be two trajectories) in two dimensions. Sets P and Q must, +% therefore, be matricies with an equal number of columns (dimensions), +% though not necessarily an equal number of rows (observations). +% +% The Directional Hausdorff Distance (dhd) is defined as: +% dhd(P,Q) = max p c P [ min q c Q [ ||p-q|| ] ]. +% Intuitively dhd finds the point p from the set P that is farthest from any +% point in Q and measures the distance from p to its nearest neighbor in Q. +% +% The Hausdorff Distance is defined as max{dhd(P,Q),dhd(Q,P)} +% +% D is the matrix of distances where D(n,m) is the distance of the nth +% point in P from the mth point in Q. +% +% +% +% %%% ZCD Oct 2009 %%% +% Edits ZCD: Added the matrix of distances as an output. Fixed bug that +% would cause an error if one of the sets was a single point. Removed +% excess calls to "size" and "length". - May 2010 +% Edits ZCD: Allowed for comparisons of N-dimensions. - June 2010 +% + +sP = size(P); sQ = size(Q); + +if ~(sP(2)==sQ(2)) + error('Inputs P and Q must have the same number of columns') +end + +% obtain all possible point comparisons +iP = repmat(1:sP(1),[1,sQ(1)])'; +iQ = repmat(1:sQ(1),[sP(1),1]); +combos = [iP,iQ(:)]; + +% get distances for each point combination +cP=P(combos(:,1),:); cQ=Q(combos(:,2),:); +dists = sqrt(sum((cP - cQ).^2,2)); + +% Now create a matrix of distances where D(n,m) is the distance of the nth +% point in P from the mth point in Q. The maximum distance from any point +% in Q from P will be max(D,[],1) and the maximum distance from any point +% in P from Q will be max(D,[],1); +D = reshape(dists,sP(1),[]); + +% Obtain the value of the point, p, in P with the largest minimum distance +% to any point in Q. +vp = max(min(D,[],2)); +% Obtain the value of the point, q, in Q with the largets minimum distance +% to any point in P. +vq = max(min(D,[],1)); + +hd = max(vp,vq); \ No newline at end of file diff --git a/evaluation/shortest_path_evaluation/libraries/ModAvgDistance.m b/evaluation/shortest_path_evaluation/libraries/ModAvgDistance.m new file mode 100644 index 0000000..b7d31ef --- /dev/null +++ b/evaluation/shortest_path_evaluation/libraries/ModAvgDistance.m @@ -0,0 +1,85 @@ +function [ mhd ] = ModAvgDistance( A, B ) + +% Code Written by B S SasiKanth, Indian Institute of Technology Guwahati. +% Website: www.bsasikanth.com +% E-Mail: bsasikanth@gmail.com +% +% This function computes the Modified Hausdorff Distance (MHD) which is +% proven to function better than the directed HD as per Dubuisson et al. +% in the following work: +% +% M. P. Dubuisson and A. K. Jain. A Modified Hausdorff distance for object +% matching. In ICPR94, pages A:566-568, Jerusalem, Israel, 1994. +% http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=576361 +% +% The function computed the forward and reverse distances and outputs the +% minimum of both. +% +% Format for calling function: +% +% MHD = ModHausdorffDist(A,B); +% +% where +% MHD = Modified Hausdorff Distance. +% A -> Point set 1 +% B -> Point set 2 +% +% No. of samples of each point set may be different but the dimension of +% the points must be the same. + +% BEGINNING OF CODE + +% Compute the sizes of the input point sets +Asize = size(A); +Bsize = size(B); + +% Check if the points have the same dimensions +if Asize(2) ~= Bsize(2) + error('The dimensions of points in the two sets are not equal'); +end + +% Calculating the forward HD + +fhd = 0; % Initialize forward distance to 0 +for a = 1:Asize(1) % Travel the set A to find avg of d(A,B) + mindist = Inf; % Initialize minimum distance to Inf + for b = 1:Bsize(1)-1 % Travel set B to find the min(d(a,B)) + %tempdist = sqrt((A(a,1)-B(b,1))^2+(A(a,2)-B(b,2))^2); + + point=[A(a,1) A(a,2)]; + edge=[B(b,1) B(b,2) B(b+1,1) B(b+1,2)]; + tempdist=distancePointEdge(point, edge); + if tempdist < mindist + mindist = tempdist; + end + end + fhd = fhd + mindist; % Sum the forward distances +end +fhd = fhd/Asize(1); % Divide by the total no to get average + +% Calculating the reverse HD + +rhd = 0; % Initialize reverse distance to 0 +for b = 1:Bsize(1) % Travel the set B to find avg of d(B,A) + mindist = Inf; % Initialize minimum distance to Inf + for a = 1:Asize(1)-1 % Travel set A to find the min(d(b,A)) + %tempdist = sqrt((A(a,1)-B(b,1))^2+(A(a,2)-B(b,2))^2); + + point=[B(b,1) B(b,2)]; + edge=[A(a,1) A(a,2) A(a+1,1) A(a+1,2)]; + tempdist=distancePointEdge(point, edge); + + if tempdist < mindist + mindist = tempdist; + end + end + rhd = rhd + mindist; % Sum the reverse distances +end +rhd = rhd/Bsize(1); % Divide by the total no. to get average + +mhd = max(fhd,rhd); % Find the minimum of fhd/rhd as + % the mod hausdorff dist + + +end + diff --git a/evaluation/shortest_path_evaluation/libraries/ModHausdorffDist.m b/evaluation/shortest_path_evaluation/libraries/ModHausdorffDist.m new file mode 100644 index 0000000..957a776 --- /dev/null +++ b/evaluation/shortest_path_evaluation/libraries/ModHausdorffDist.m @@ -0,0 +1,76 @@ +function [ mhd ] = ModHausdorffDist( A, B ) + +% Code Written by B S SasiKanth, Indian Institute of Technology Guwahati. +% Website: www.bsasikanth.com +% E-Mail: bsasikanth@gmail.com +% +% This function computes the Modified Hausdorff Distance (MHD) which is +% proven to function better than the directed HD as per Dubuisson et al. +% in the following work: +% +% M. P. Dubuisson and A. K. Jain. A Modified Hausdorff distance for object +% matching. In ICPR94, pages A:566-568, Jerusalem, Israel, 1994. +% http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=576361 +% +% The function computed the forward and reverse distances and outputs the +% minimum of both. +% +% Format for calling function: +% +% MHD = ModHausdorffDist(A,B); +% +% where +% MHD = Modified Hausdorff Distance. +% A -> Point set 1 +% B -> Point set 2 +% +% No. of samples of each point set may be different but the dimension of +% the points must be the same. + +% BEGINNING OF CODE + +% Compute the sizes of the input point sets +Asize = size(A); +Bsize = size(B); + +% Check if the points have the same dimensions +if Asize(2) ~= Bsize(2) + error('The dimensions of points in the two sets are not equal'); +end + +% Calculating the forward HD + +fhd = 0; % Initialize forward distance to 0 +for a = 1:Asize(1) % Travel the set A to find avg of d(A,B) + mindist = Inf; % Initialize minimum distance to Inf + for b = 1:Bsize(1) % Travel set B to find the min(d(a,B)) + tempdist = norm(A(a,:)-B(b,:)); + if tempdist < mindist + mindist = tempdist; + end + end + fhd = fhd + mindist; % Sum the forward distances +end +fhd = fhd/Asize(1); % Divide by the total no to get average + +% Calculating the reverse HD + +rhd = 0; % Initialize reverse distance to 0 +for b = 1:Bsize(1) % Travel the set B to find avg of d(B,A) + mindist = Inf; % Initialize minimum distance to Inf + for a = 1:Asize(1) % Travel set A to find the min(d(b,A)) + tempdist = norm(A(a,:)-B(b,:)); + if tempdist < mindist + mindist = tempdist; + end + end + rhd = rhd + mindist; % Sum the reverse distances +end +rhd = rhd/Bsize(1); % Divide by the total no. to get average + +mhd = max(fhd,rhd); % Find the minimum of fhd/rhd as + % the mod hausdorff dist + + +end + diff --git a/evaluation/shortest_path_evaluation/libraries/timestamp.m b/evaluation/shortest_path_evaluation/libraries/timestamp.m new file mode 100644 index 0000000..536852c --- /dev/null +++ b/evaluation/shortest_path_evaluation/libraries/timestamp.m @@ -0,0 +1,8 @@ +function ts = timestamp() +% +% TIMESTAMP returns the current system time. +% The output is type string and without EOL. +% (LB 9'02) + +TempTime=clock; +ts = ['(' num2str(TempTime(4),'%02.0f') ':' num2str(TempTime(5),'%02.0f') ':' num2str(TempTime(6),'%02.0f') ')']; diff --git a/evaluation/shortest_path_evaluation/source/edges_original_osm.txt b/evaluation/shortest_path_evaluation/source/edges_original_osm.txt new file mode 100644 index 0000000..735b39a --- /dev/null +++ b/evaluation/shortest_path_evaluation/source/edges_original_osm.txt @@ -0,0 +1,39699 @@ +2739,35487978,155864697,0 +121639,35487981,1540881852,0 +2803,35487986,1540773385,0 +121642,35487986,1540881863,0 +149065,35487995,911998377,0 +46132,35487997,360226557,0 +2642,35487997,1540772356,0 +2752,35494034,1540773267,0 +2751,35494035,1540773264,0 +386,35839639,549775642,0 +98707,35839642,800140499,0 +388,35839642,1540770085,0 +389,35839643,1540770086,0 +395,35839948,936804097,0 +40479,35839960,360008922,1 +40316,35839960,1540810014,0 +24113,35840454,295773042,0 +98717,35840828,800140503,0 +400,35840828,1540770111,0 +115662,35840949,359997469,1 +98711,35840949,1540861538,0 +24128,35840952,1540794415,1 +98712,35840952,1540861539,0 +24114,35841643,35839948,0 +98714,36231496,359999163,0 +543,36231496,1540770199,1 +5846,36243626,592380963,0 +81627,36243628,1540845071,0 +5848,36243712,1540775955,0 +2261,36243995,1540771774,0 +80339,36244001,577419537,0 +80340,36244140,152943266,0 +51688,36244146,1540816208,0 +51689,36244147,1540816212,0 +35616,36244148,1540804922,0 +82574,36244671,1540846374,0 +51704,36245082,36245085,0 +82575,36245085,599162326,0 +82005,36245092,1540845764,0 +81623,36245102,1540845063,0 +81622,36245103,1540845057,0 +40207,36643959,1540809953,0 +81780,36643968,1540845695,0 +31223,36643971,347781699,1 +81781,36643971,1540845595,0 +137795,36645001,583229699,0 +75733,36645010,1013434025,1 +1623,38830930,1540771123,0 +2461,38830930,1540772056,0 +49932,38840240,38842554,1 +17692,38840240,302660617,1 +17699,38840244,1540787781,1 +92198,38840254,745984375,1 +50141,38840254,1520838821,0 +81978,38840263,1540845752,0 +92208,38840263,1540856199,1 +82533,38842542,360728582,0 +51670,38842542,1540816145,0 +82537,38842545,360730849,0 +49933,38842554,1540814972,1 +82544,38842554,1540846334,0 +82552,38842561,360469553,0 +48026,38842561,360469556,1 +24947,38842565,302363454,0 +82554,38842565,1540846346,0 +106905,84568354,1540868657,0 +81963,130197703,417277348,0 +84015,130197784,600930492,0 +134872,150563575,150563576,1 +134873,150563575,559590429,1 +2025,150563681,1540771410,1 +127468,150563681,1540885172,0 +29620,150563682,360474544,0 +56194,150563682,365122620,1 +2027,150563682,694829012,1 +2029,150563683,360476027,1 +29651,150563683,1493227230,1 +2036,150563687,678158747,1 +92220,150563687,678158888,1 +2460,152800568,1540772055,0 +73502,152800568,1540839663,0 +51657,152801180,360015847,1 +41121,152801180,1540810246,1 +98732,152801591,800150278,1 +75572,152802117,559564585,1 +40094,152802117,985946126,0 +2171,152802341,359996135,1 +40106,152802341,984726008,1 +40096,152802868,152802869,1 +115447,152802868,1540874565,1 +115439,152802869,984725721,1 +40097,152802869,984726062,1 +40099,152802872,152802874,1 +40100,152802874,359996114,1 +135119,152803459,581286089,1 +51677,152803459,1540816149,1 +135115,152803460,361198785,1 +97363,152803614,793781696,1 +51481,152803614,793781799,1 +2174,152803614,937216389,1 +84007,152803614,1540846824,1 +84020,152803615,793781809,1 +106805,152803983,937216053,1 +83977,152803983,937216333,1 +83951,152804209,793810036,1 +2176,152804209,937216520,1 +83971,152804211,937216608,1 +83966,152804436,355921423,1 +106885,152804436,600924197,0 +106907,152804436,1540868661,1 +106890,152805029,937378131,1 +84026,152805030,372800259,1 +106908,152805030,937378278,1 +81187,152805376,584361276,0 +81208,152805378,152805376,0 +81186,152805894,272564576,0 +138908,152805894,1308321659,1 +2260,152937997,250929194,0 +5776,152938166,1540775586,0 +2259,152938759,152938166,0 +80347,152939465,152938759,0 +51649,152939864,152939867,1 +97560,152939864,795263039,1 +51650,152939867,361220005,1 +97546,152939867,795263044,1 +78907,152940375,1540841122,0 +51632,152941274,361406381,0 +5798,152941465,361409655,1 +40111,152942456,152942590,1 +2271,152942456,985921411,1 +75583,152942457,359997264,1 +40120,152942457,985921425,1 +75582,152942587,152942457,1 +40113,152942587,985921486,1 +75603,152942590,559564650,1 +40112,152942590,1540809891,1 +51692,152943266,1540816214,0 +51694,152943683,36244001,0 +83943,152946871,417279548,0 +84016,152946871,1540846860,1 +2272,152946877,152946871,0 +83973,152946877,937216014,1 +2274,152947902,1540771799,0 +81182,152947902,1540844383,0 +5777,153874050,1540775588,0 +73474,153874050,1540839640,0 +5784,153874640,1540775621,0 +51634,153875447,1540816089,0 +2462,153879588,1540772069,0 +73504,153879592,1540839665,0 +75724,153884112,559591331,1 +2173,153884112,1540771647,1 +2639,155578062,1540772345,0 +46130,155578062,1540812380,0 +46163,155585179,1540812432,1 +2643,155587359,973017470,0 +149058,155587524,1540950739,0 +149054,155587662,973017307,0 +2738,155864697,1540773179,0 +2734,155864941,1540773176,0 +2737,155864979,155864941,0 +2741,155866226,1540773182,1 +46237,155866226,1540812498,1 +2740,155867041,1540773181,1 +2742,155867053,1540773190,1 +2744,155867053,1540773196,1 +2746,155869169,1540773216,0 +2750,155869226,1540773263,0 +2839,175678152,579805525,0 +96819,175678152,1145564253,1 +2852,175678282,246588490,1 +93017,175678289,694820297,1 +2859,175678289,694820375,1 +2864,175678297,1493262720,1 +29617,175678297,1540798989,0 +51674,175678407,360728379,0 +51662,175678407,361434463,0 +2882,175678407,361434733,1 +29616,175678410,175678297,0 +2887,175678410,1540773442,1 +2913,175678456,360468012,1 +31599,175678456,1540802520,1 +30750,175678477,1540800294,1 +125331,175678477,1540884066,1 +137779,175702450,1193464654,0 +2926,175702450,1540773464,0 +2932,175702471,527804364,0 +76095,175702471,1540840536,1 +2938,175702481,352725090,0 +76098,175702571,560712682,0 +68177,175702571,1540838087,0 +68178,175702585,352712087,0 +31310,175702585,352712183,1 +68180,175702594,1540838089,0 +2973,176173984,1540773484,1 +2975,176173989,176178421,1 +31243,176173994,352706872,1 +2978,176173994,1540773490,1 +30924,176173997,352705319,1 +2980,176173997,1540773491,1 +2982,176175856,352709199,1 +31284,176175856,352709206,1 +31297,176176671,352715163,1 +76036,176176671,1540840509,1 +2976,176178421,1540773487,1 +51716,246588460,1540816232,0 +53358,246588462,1540820159,0 +80471,246588462,1540843197,0 +80470,246588466,1540843194,0 +82578,246588469,246588470,0 +51691,246588470,1540816213,0 +134543,246588478,353250872,0 +92230,246588478,678168474,1 +31713,246588482,353246576,1 +134523,246588482,678178637,0 +134522,246588486,246588482,0 +29597,246588486,683297768,1 +3597,246588490,361197410,0 +2853,246588490,683301102,1 +3596,246588491,246588490,0 +2896,246588491,704832204,1 +127443,246588551,338485125,0 +29628,246588551,1540798993,1 +127446,246588552,338484427,0 +94838,246588552,1540857361,0 +127449,246588553,683290561,0 +29612,246588553,1540798988,0 +134542,246588554,246588478,0 +80301,246588555,246588554,0 +29689,246588555,1540799001,1 +80298,246588557,338484637,0 +31721,246588557,1540802544,1 +3632,247151318,600917292,1 +29711,247151320,797375590,1 +51352,247151320,797375879,1 +134559,247151604,683916511,1 +48363,247151604,683916579,1 +51354,247151814,361198717,1 +51360,247151814,797375563,1 +3645,247152813,1540774163,0 +3648,247152817,1540774173,0 +1622,250929194,38830930,0 +5799,250929227,152801591,1 +69885,250929227,528505102,1 +5800,250929229,1540775625,1 +75411,250929231,558998793,1 +75385,250929231,1540840141,1 +75433,250929231,1540840184,1 +16889,272498944,1540787203,1 +16901,272499019,1540787218,1 +68962,272499028,272560940,1 +16826,272499074,1540787140,1 +16892,272499222,272554600,1 +16891,272499261,1540787207,1 +16843,272499414,272554946,1 +16900,272499414,1540787211,1 +16890,272499416,1540787206,1 +16823,272499517,272554949,1 +104341,272499517,1540866041,0 +47716,272499525,272554903,1 +104339,272499525,272554952,0 +104337,272499526,272560548,0 +16895,272499526,347783946,1 +104335,272499528,347783404,0 +16885,272499528,1285491905,1 +96279,272499530,272499222,1 +104334,272499530,1540866039,0 +96278,272554420,272499530,1 +136340,272554421,272554420,0 +134999,272554478,1540905492,0 +16884,272554571,272499528,1 +16887,272554571,1540787199,1 +16886,272554600,272554571,1 +16893,272554602,272560609,1 +16888,272554602,1540787200,1 +135007,272554677,1540905503,0 +16934,272554678,695578773,1 +135005,272554678,1285491835,0 +30886,272554680,1540800307,1 +135003,272554680,1540905502,0 +16846,272554684,272560464,1 +135002,272554684,1540905499,0 +16897,272554689,272560466,1 +135001,272554689,1540905495,0 +30902,272554693,1540800327,1 +30899,272554695,1540800319,1 +30900,272554703,347777730,1 +16906,272554713,272554958,1 +16899,272554778,1540787209,1 +47717,272554903,272499019,1 +16902,272554903,1540787221,1 +16932,272554942,272560545,1 +16935,272554942,272560606,1 +16904,272554942,1540787226,1 +16844,272554946,272560541,1 +16905,272554946,1540787228,1 +16824,272554949,272560836,1 +16908,272554949,1540787230,1 +104340,272554952,272499517,0 +16909,272554952,272554958,1 +16907,272554958,272554949,1 +16911,272554977,1540787232,1 +16913,272560240,1540787235,1 +16917,272560240,1540787243,1 +30897,272560242,347777350,1 +16914,272560242,1540787238,1 +16915,272560244,1540787240,1 +16925,272560244,1540787250,1 +16910,272560247,1540787231,1 +16922,272560305,347777405,1 +16920,272560345,272560346,1 +30909,272560345,347780182,1 +16921,272560346,272560305,1 +30908,272560346,347780116,1 +16924,272560350,272560351,1 +30883,272560350,347777052,1 +16926,272560351,1540787252,1 +16847,272560464,1540787156,1 +16898,272560466,272554713,1 +16927,272560466,1540787254,1 +16845,272560541,272554684,1 +16928,272560541,1540787256,1 +16933,272560545,272554678,1 +16929,272560545,1540787259,1 +104338,272560548,272499525,0 +16930,272560606,272561547,1 +16936,272560606,347783946,1 +16894,272560609,272499526,1 +16939,272560609,272560647,0 +47715,272560647,272499525,1 +16825,272560836,272499074,1 +16965,272560836,1540787285,1 +16972,272560905,272560906,1 +16812,272560905,272561327,1 +16974,272560906,272560940,1 +16973,272560906,1540787300,1 +16975,272560940,272560961,1 +16919,272560961,272560345,1 +16976,272560961,351950742,1 +16813,272561327,272499028,1 +17027,272561421,351950051,1 +31040,272561421,351951160,1 +16918,272561421,1540787246,1 +16903,272561524,1540787223,1 +17012,272561524,1540787366,1 +16931,272561547,272560548,1 +97111,272562878,793428512,1 +81203,272562878,1540844392,0 +81201,272562879,417277347,0 +63929,272562879,417278830,1 +81192,272562885,603748692,0 +84192,272562885,1540847173,1 +81966,272562941,1540845748,0 +81971,272562944,1540845749,0 +100688,272562944,1540862802,1 +81972,272562945,603748702,0 +100683,272562945,813097843,1 +81184,272564576,272564577,1 +81185,272564577,445393419,1 +106882,272564577,1540868597,0 +83964,272564781,1540846793,0 +84011,272564781,1540846835,0 +2835,272565046,1540773411,0 +81633,272567305,1540845106,0 +99146,272567305,1540861866,0 +81653,272567307,1540845179,0 +81205,272567334,793279595,0 +97093,272567334,793385727,1 +81621,272567495,1540845049,0 +98875,272567908,800448656,1 +17079,272567908,801062783,0 +99286,272567910,801062997,1 +17078,272567910,1540787549,0 +82054,272568020,800448713,0 +98764,272568020,1540861609,1 +82053,272568021,272568020,0 +98854,272568021,800448984,1 +17593,273143706,360022641,1 +46155,273143707,273143708,1 +2640,273143707,1540772349,0 +17596,273143708,1540787694,1 +46156,273143708,1540812418,1 +17595,273143897,360229064,1 +109047,273143897,1540870350,0 +20315,278007870,1540790469,1 +149220,278007870,1540950933,1 +149739,278007878,1540953209,1 +149741,278007900,1540953230,1 +149742,278008163,1540953233,1 +149743,278008182,1540953250,1 +20192,278008196,1540790216,1 +149744,278008196,1540953261,1 +20199,278008200,1540790235,1 +149745,278008200,1540953264,1 +20197,278008204,1540790228,1 +149746,278008204,1540953267,1 +149747,278008208,278009540,1 +20189,278008208,278010401,1 +20188,278008681,1540790207,1 +79048,278009537,1540841189,0 +45064,278009538,360205629,1 +149347,278009538,1030313274,1 +149748,278009540,278009541,1 +20251,278009540,1540790338,1 +20203,278009541,1540790251,1 +149749,278009541,1540953270,1 +149750,278009544,278009545,1 +20211,278009545,278010565,1 +149751,278009545,1540953272,1 +20247,278009550,1540790310,1 +149752,278009550,1540953276,1 +149753,278009554,278009555,1 +20248,278009554,1540790313,1 +148668,278009555,1540950117,1 +149754,278009555,1540953280,1 +149756,278009557,278009558,1 +149757,278009558,1540953281,1 +149760,278009568,278009569,1 +20297,278009568,1540790441,1 +149761,278009569,1371043802,1 +20311,278009569,1371125115,1 +149763,278009570,1037131191,1 +100571,278009570,1540862734,1 +120056,278009571,1037131027,1 +149767,278009571,1540953298,1 +120013,278009575,1037130927,1 +149768,278009575,1540953301,1 +119984,278009577,1540879778,1 +149769,278009577,1540953302,1 +149771,278009580,278009581,1 +119820,278009580,1037130993,1 +149772,278009581,278009582,1 +119902,278009581,1036627902,1 +119932,278009582,1540879690,1 +149773,278009582,1540953305,1 +149775,278009586,1036628267,1 +119878,278009587,1036627856,1 +149777,278009587,1540953308,1 +149778,278009589,278009590,1 +119830,278009589,1036627955,1 +119831,278009590,1036628025,1 +149779,278009590,1036628271,1 +149781,278009592,1036415731,1 +149784,278009594,1540953311,1 +119890,278009596,1036628043,1 +149786,278009596,1540953312,1 +119935,278009599,1540879692,1 +149787,278009599,1540953314,1 +119866,278009600,1036627867,1 +149788,278009600,1036628278,1 +119862,278009601,1540879608,0 +142553,278009603,1036627875,1 +119860,278009603,1540879605,0 +119867,278009603,1540879615,0 +119845,278009609,1540879571,1 +142556,278009609,1540934753,1 +76134,278009613,1540840563,1 +142559,278009613,1540934756,1 +142561,278009614,278009615,1 +76148,278009614,1540840590,1 +119682,278009614,1540879288,1 +142562,278009615,1036415812,1 +76144,278009615,1540840585,1 +76119,278009616,560945008,1 +119706,278009616,1540879338,0 +142564,278009616,1540934761,1 +142565,278009617,1540934762,1 +119761,278009618,1036415320,1 +142566,278009618,1540934764,1 +76198,278009619,1540840636,1 +142567,278009619,1540934765,1 +142568,278009620,278009621,1 +107968,278009621,1030974870,1 +142569,278009621,1540934766,1 +142571,278009624,278009625,1 +107942,278009624,1030975344,1 +107986,278009625,952161209,1 +142572,278009625,1540934769,1 +142573,278009627,1540934771,1 +119400,278009629,1030974914,1 +142574,278009629,1540934772,1 +142578,278009630,278009631,1 +119447,278009630,1540878910,1 +142579,278009631,278009632,1 +119414,278009631,1030974704,1 +142580,278009632,278009633,1 +119351,278009633,1540878846,1 +142581,278009633,1540934773,1 +119190,278009636,1030974506,0 +142583,278009636,1030975335,1 +142585,278009637,360201326,1 +119395,278009637,1540878873,0 +142530,278009638,1540934710,1 +142531,278009641,1540934711,1 +142532,278009643,278009644,1 +119258,278009643,1030689412,1 +121638,278009644,1540881851,1 +142533,278009644,1540934715,1 +142535,278009645,1540934716,1 +118885,278009648,1030313253,1 +142538,278009648,1540934720,1 +142539,278009650,278009651,1 +93505,278009650,1030313096,1 +142540,278009651,278009652,1 +118880,278009651,1030313118,1 +45566,278009652,1030313108,1 +142541,278009652,1540934722,1 +45626,278009654,1540812107,0 +142542,278009654,1540934725,1 +20194,278010102,278010692,1 +20193,278010346,1540790224,1 +20196,278010352,278010353,1 +20206,278010353,1540790256,1 +20198,278010401,278010402,1 +20190,278010401,278010455,1 +20204,278010402,1540790253,1 +20191,278010455,278010102,1 +20200,278010455,1540790246,1 +20202,278010459,1540790249,1 +20239,278010459,1540790307,1 +20201,278010532,1540790247,1 +20205,278010532,1540790254,1 +20214,278010538,278010566,1 +20207,278010538,1540790259,1 +20208,278010542,278010543,1 +20209,278010543,278010544,1 +20268,278010543,278011471,1 +20210,278010544,278010545,1 +20244,278010545,278011908,1 +20212,278010565,278011472,1 +20272,278010565,1540790389,1 +20215,278010566,278010567,1 +20218,278010566,1540790261,1 +20216,278010567,278010620,1 +20229,278010567,1540790281,1 +131623,278010568,1540889959,1 +20219,278010577,1540790264,1 +20220,278010577,1540790265,1 +20221,278010590,278010591,1 +20228,278010590,1540790278,1 +20222,278010591,278010592,1 +20233,278010591,1540790294,1 +20223,278010592,1540790267,1 +20224,278010592,1540790270,1 +20235,278010596,1172638693,1 +20231,278010596,1540790286,1 +131622,278010596,1540889955,1 +20217,278010620,278010568,1 +20225,278010620,1540790272,1 +20262,278010623,278011402,1 +20226,278010623,1540790274,1 +20241,278010626,278010656,1 +20227,278010626,1540790276,1 +20277,278010629,1540790392,1 +20281,278010629,1540790401,1 +20261,278010652,278010623,1 +20230,278010652,1540790283,1 +20242,278010656,278010959,1 +20278,278010656,1540790393,1 +20232,278010687,1540790290,1 +20234,278010687,1540790295,1 +20195,278010692,278010352,1 +20238,278010746,278010346,1 +20237,278010746,1540790300,1 +20243,278010959,278010545,1 +20263,278010959,1540790382,1 +20285,278010959,1540790407,1 +20246,278010960,278009550,1 +20257,278011279,278011373,1 +20252,278011279,1540790339,1 +20258,278011285,278011373,1 +20253,278011285,1540790344,1 +20321,278011304,278013035,1 +20254,278011304,1540790362,1 +20255,278011306,1540790363,1 +20319,278011306,1540790525,1 +20256,278011309,1540790365,1 +20259,278011373,278011380,1 +20260,278011401,278010652,1 +20265,278011401,278011423,1 +131624,278011402,1540889963,1 +20269,278011422,278010544,1 +20264,278011422,278011401,1 +20267,278011423,278010542,1 +20266,278011423,1540790384,1 +20213,278011472,278010538,1 +20270,278011472,1540790386,1 +20273,278011504,278010960,1 +20274,278011504,278011536,1 +20271,278011536,278011471,1 +20275,278011627,278011628,1 +20287,278011627,1540790410,1 +20276,278011628,278010629,1 +20279,278011628,1540790396,1 +20284,278011722,278011736,1 +20280,278011722,1540790400,1 +20282,278011736,1540790404,1 +20283,278011742,278011722,1 +20288,278011742,1540790415,1 +20286,278011835,278011627,1 +20291,278011835,1540790438,1 +20293,278011847,278012136,1 +20289,278011847,1540790421,1 +20292,278011906,1540790440,1 +20245,278011908,278010960,1 +20304,278011908,1540790454,1 +20295,278011997,278011998,1 +20314,278011997,1540790463,1 +20296,278011998,601643782,1 +20306,278011998,1540790455,1 +20298,278012063,1540790442,1 +20300,278012066,1540790443,1 +20301,278012067,1540790444,1 +20307,278012067,1540790457,1 +20305,278012081,278011906,1 +20303,278012081,1540790452,1 +20308,278012122,1540790459,1 +148601,278012122,1540950000,1 +20302,278012128,1540790451,1 +20310,278012134,278009569,1 +20312,278012134,278012063,1 +20294,278012136,278011997,1 +20313,278012136,1540790460,1 +20316,278012479,1540790473,1 +20320,278013033,278011304,1 +20322,278013033,278013088,1 +45061,279589608,279591485,1 +79046,279589608,1540841184,0 +93490,279589608,1540856553,1 +112151,279589614,716888908,1 +79044,279589614,1540841179,0 +21424,279589617,360205939,1 +79041,279589617,1540841178,0 +142502,279589619,279589686,1 +79042,279589619,974030708,0 +93512,279589624,429286593,1 +79047,279589624,1540841186,0 +142503,279589686,974030859,1 +21423,279589686,1540790975,0 +112150,279589687,279589614,1 +21422,279589687,279589686,0 +21426,279589950,279589951,1 +93456,279589950,716888550,1 +21427,279589951,279589952,1 +45672,279589951,360206315,1 +21428,279589952,360206035,1 +149326,279589956,360207510,1 +45798,279589956,360209471,0 +149328,279589957,1540951383,1 +149329,279589959,279591059,1 +45793,279590056,360208993,0 +21432,279590056,1540790976,1 +21440,279590064,279590065,1 +21441,279590065,985968655,1 +21431,279590087,279590056,1 +45750,279590088,360208055,1 +21433,279590088,891523958,1 +45777,279590089,360208083,0 +21435,279590089,360208650,1 +115708,279590089,985968666,0 +21439,279590090,279590064,1 +115705,279590090,985968818,1 +21430,279590130,279590087,1 +112129,279590130,974031171,1 +133832,279590131,279590132,1 +53838,279590132,968962559,1 +45704,279590300,360207474,1 +135186,279590300,1540905576,0 +45698,279590303,360207366,1 +135185,279590303,1540905575,0 +135180,279590306,279590307,1 +45803,279590306,583434225,1 +135181,279590307,279590308,1 +45799,279590307,583434227,1 +21443,279590308,279590361,1 +135182,279590308,1345509354,1 +143885,279590313,737998278,1 +94667,279590314,737998273,1 +143887,279590314,737998290,1 +135174,279590317,737998498,1 +94684,279590317,1540857303,1 +94670,279590321,737998282,1 +135177,279590321,1540905572,1 +152195,279590323,1540961407,1 +143853,279590357,1540937864,0 +143895,279590357,1540937902,0 +21444,279590361,360209881,1 +143866,279590361,1540937870,0 +143871,279590361,1540937877,0 +21446,279590362,279590357,1 +45735,279590362,360207812,1 +40326,279590687,1540810021,0 +40501,279590737,360008921,1 +40318,279590737,1540810016,0 +143857,279591052,279591053,0 +135167,279591052,360206848,0 +143858,279591053,279591054,0 +45694,279591053,360207363,1 +143859,279591054,279591055,0 +45708,279591054,360207557,1 +149323,279591055,360207816,1 +143843,279591055,974030619,0 +143847,279591056,279591057,0 +135204,279591056,974030729,0 +143848,279591057,279591058,0 +29731,279591057,338487216,1 +143849,279591058,972481633,0 +21459,279591058,1540790990,1 +149330,279591059,279591060,1 +53860,279591059,360207471,1 +149331,279591060,279591061,1 +135159,279591060,974030610,1 +112183,279591061,974030870,1 +149332,279591061,1540951384,1 +112131,279591062,974030962,1 +149333,279591062,1540951385,1 +21448,279591116,363974809,0 +21454,279591116,363975202,1 +21452,279591120,1540790982,0 +24089,279591124,973983340,0 +24091,279591129,1540794238,0 +53882,279591129,1540820536,1 +24092,279591134,1038214221,0 +112081,279591134,1540872752,1 +112119,279591135,360010766,1 +24094,279591135,973983605,0 +24096,279591136,1540794242,0 +120587,279591139,536579356,1 +24097,279591139,1540794244,0 +24100,279591152,360006242,0 +24104,279591155,279591156,0 +110078,279591155,932361993,0 +40267,279591156,549785230,1 +24105,279591156,1540794256,0 +24106,279591159,279591160,0 +24107,279591160,279591161,0 +71606,279591160,549785230,1 +24108,279591161,1291955687,0 +120586,279591274,1038214120,1 +40328,279591274,1540810036,0 +40330,279591275,1540810039,0 +112082,279591275,1540872755,1 +40332,279591280,1540810043,0 +112051,279591283,363971023,0 +112153,279591398,974030964,1 +21457,279591398,1540790986,1 +29733,279591415,338487217,1 +149342,279591415,1540951400,1 +112147,279591424,974031041,1 +149345,279591424,1540951407,1 +21460,279591449,1540790992,1 +135215,279591449,1540905587,0 +111823,279591451,974030797,1 +149340,279591451,1540951394,1 +111880,279591454,972481687,1 +149341,279591454,1540951397,1 +45654,279591457,360205872,1 +149343,279591457,1540951403,1 +45630,279591459,360205333,1 +149346,279591459,1540951408,1 +45062,279591485,360205311,1 +21420,279591485,1540790972,0 +45632,279591486,360205411,1 +21421,279591486,1540790973,0 +21462,279591653,279591654,1 +45623,279591653,1540812099,0 +118881,279591654,1030313231,1 +21463,279591654,1540790993,1 +21464,279591656,360205477,1 +45592,279591656,1540812077,1 +21466,279591658,279591659,1 +21467,279591659,1540790995,1 +21469,279591659,1540790996,1 +21468,279591660,972481984,1 +45046,279591660,1540811945,1 +45603,279591661,972481801,1 +111897,279591661,1540872338,0 +44970,279591663,972481605,1 +111896,279591663,1540872336,0 +111895,279591664,279591663,0 +44938,279591664,972481669,1 +111894,279591665,279591664,0 +44945,279591665,972481726,1 +44922,279591666,972481725,1 +111892,279591666,1540872335,0 +111891,279591667,279591666,0 +46113,279591667,972481734,0 +45090,279591764,360193042,1 +21470,279591764,360193235,1 +21473,279591766,1540790999,1 +21478,279591769,279591843,1 +152332,279591769,360191959,1 +21479,279591843,1540791001,1 +45255,279591848,360199069,1 +21481,279591848,1540791006,1 +46106,279591857,360223131,0 +21484,279591857,1540791017,1 +79039,279591863,360195248,1 +21486,279591863,1540791027,1 +21487,279591881,360196239,1 +21480,279591881,1540791004,1 +21492,279591918,1540791034,1 +21493,279591921,279591922,1 +21494,279591922,279591923,1 +45545,279591922,1540812067,1 +45328,279591923,360200255,1 +21495,279591923,1540791038,1 +45271,279591926,360199245,1 +21496,279591926,1540791042,1 +21499,279591973,360210536,1 +21483,279591973,1540791013,1 +21503,279591975,279591980,1 +45818,279591975,360196302,1 +21506,279591977,360214769,1 +46028,279591977,360214772,1 +21504,279591980,360196122,1 +45114,279591980,360196303,1 +45266,279592059,360199117,1 +21482,279592059,1540791009,1 +21485,279592064,1540791023,1 +21507,279592091,360195249,0 +21509,279592091,360222781,0 +45828,279592206,360210399,1 +21512,279592206,360217045,0 +21525,279592213,360222688,0 +21517,279592213,1540791055,0 +21518,279592280,1540791056,0 +21514,279592283,360221717,0 +46093,279592283,360221953,0 +21516,279592285,1540791054,0 +45941,279592453,1540812256,1 +45945,279592453,1540812260,1 +46096,279592453,1540812334,1 +90627,279592725,1540855371,1 +90629,279592736,1540855382,1 +58354,279592740,614381224,1 +112009,279592740,1540872626,0 +90626,279596073,279592725,1 +149759,286077933,278009568,1 +22942,286367654,286369860,1 +40476,286367654,360008745,1 +22960,286367654,985946029,0 +40090,286367654,1540809883,0 +22948,286367801,985946167,1 +22952,286367804,359997064,1 +40141,286367804,1025767741,1 +137775,286367976,1540920274,0 +22943,286369860,985946401,1 +115644,286369860,1540874775,1 +115665,286369862,985946025,1 +22947,286369862,1540792792,1 +22951,286369864,286367804,1 +115639,286369864,985946420,1 +22966,286535484,1540792807,0 +22980,286535486,286541740,0 +22964,286535645,1540792806,1 +64374,286537115,286537519,0 +22974,286537115,286541126,0 +70241,286537120,360720796,1 +64389,286537122,1540834232,1 +64390,286537125,1540834233,1 +64382,286537128,286537129,1 +22975,286537128,745985497,0 +64383,286537129,360720111,1 +24039,286537129,745986934,0 +64385,286537130,360719851,1 +50109,286537130,360719917,0 +50254,286537277,360731137,0 +92194,286537277,677410917,1 +64368,286537366,360718713,0 +22968,286537366,1540792810,0 +22970,286537369,286537115,0 +22971,286537519,286541126,0 +22973,286537519,677411010,1 +17706,286538932,1540787788,1 +22967,286538932,1540792808,0 +22972,286541126,1540792811,0 +100776,286541739,745985496,1 +22977,286541739,745986937,0 +22981,286541740,1540792812,0 +22982,286541742,1540792813,0 +50134,286541743,745988394,1 +22983,286541743,1540792814,0 +50138,286541743,1540815054,1 +22985,286541745,1540792818,0 +82523,286541749,746691654,0 +64436,286541787,745988435,0 +22986,286541787,1540792819,0 +1625,294112227,1540771136,0 +23870,294112227,1540793750,0 +23871,294112451,1540793752,0 +100518,294112451,1540862655,0 +398,294113203,360008695,0 +137777,294113203,1540920276,0 +115291,294113934,1540874465,1 +115428,294113934,1540874552,1 +149683,294113937,1411198170,1 +115426,294113937,1540874547,1 +115425,294113938,294113937,1 +23875,294114237,984364205,1 +23938,294114238,1540793847,0 +23885,294114430,1540793430,1 +23881,294114443,294114430,1 +23890,294114600,294138057,1 +23883,294114600,737308371,1 +23873,294114683,984332560,1 +23917,294114683,1540793808,0 +115134,294114683,1540874279,1 +23926,294114688,984634628,0 +89060,294138005,1540852136,0 +94553,294138005,1540857166,1 +89061,294138057,1540852139,0 +115309,294144482,984633979,1 +23945,294144482,1540793859,0 +115403,294144491,984634447,0 +23944,294144491,1540793857,0 +23937,294144525,1540793844,0 +115230,294144525,1540874400,1 +115257,294144611,984606596,1 +23929,294144611,1540793836,0 +89056,294144767,1540852128,0 +115142,294144767,1540874306,1 +115161,294144919,737656882,0 +89057,294144919,1540852132,0 +23923,294144924,1540793828,0 +23924,294145134,294162457,0 +107500,294145134,1540869008,0 +23957,294145226,294162457,0 +89051,294145226,1540852120,0 +107480,294162342,938502187,0 +89062,294162342,1540852142,0 +23925,294162457,294162342,0 +23958,294162457,938502038,0 +89065,294162875,803745164,0 +99955,294162875,1540862333,0 +99954,294163207,294162875,0 +23912,294163207,1540793803,0 +107558,294163209,938502105,1 +23915,294163209,1540793806,0 +107502,294163284,938502280,1 +23913,294163284,1540793804,0 +98065,294163564,653316931,0 +89070,294163564,803745135,0 +23902,294163568,803745138,0 +89073,294163697,1540852159,0 +107586,294163697,1540869053,1 +107585,294163738,294163697,1 +23899,294163738,1540793793,0 +89077,294163842,938501961,0 +23895,294163854,938502337,0 +23893,294184231,1540793778,0 +23900,294184327,938502224,0 +143214,294184327,1540936650,1 +23891,294184359,1540793770,0 +23960,294184359,1540793873,1 +23963,294184526,1540793874,1 +23970,294202628,1540793876,1 +107223,294202628,1540868945,1 +107276,294202629,938142969,1 +23967,294202629,938143091,1 +106862,294203207,937365390,1 +23985,294203207,1540793884,1 +23982,294203208,937365460,1 +107007,294203214,361199498,1 +23975,294203214,938140742,1 +23974,294203215,1540793878,1 +23966,294203217,294202629,1 +107271,294203217,938142898,1 +97147,294203269,745092397,1 +24002,294203269,937216329,1 +97314,294203269,1540859920,1 +24001,294203310,294203269,1 +97117,294203310,793428423,1 +23989,294203944,793385663,1 +24027,294203944,1540793923,0 +23995,294203947,745090951,1 +24003,294206988,1540793891,0 +24004,294207130,599162400,0 +24006,294207609,1540793900,0 +24007,294207775,1540793907,0 +97006,294243377,793479405,0 +97220,294243377,793479409,1 +97010,294243379,360731674,0 +97208,294243379,793479416,1 +24025,294244346,294244956,0 +97003,294244346,294244999,0 +95029,294244346,793279599,1 +97151,294244884,793428462,1 +23997,294244884,793529738,1 +24022,294244956,1540793916,0 +24021,294244984,294244956,0 +24026,294244984,1540793922,0 +97004,294244999,745990622,0 +64366,294248195,1540834215,0 +96948,294248195,1540859839,1 +24036,294250113,745988378,1 +100787,294250113,1540862915,1 +50118,294250794,360719791,1 +24029,294250794,1540793924,1 +95133,294250799,745988415,1 +24030,294250799,1540793927,1 +24032,294250800,363860850,1 +96881,294250800,793252719,0 +64356,294251017,1540834149,1 +133479,294251017,1540894462,1 +50091,294253327,1540815043,0 +24042,294253784,294253327,1 +24088,295771556,1540794233,0 +73509,295773042,936804227,0 +391,295775157,1540770090,0 +1626,295775659,1540771148,0 +24115,295776661,1540794262,0 +80344,295776661,1540843122,0 +24116,295776873,1540794265,0 +73511,295776873,1540839677,0 +24130,295865926,985946472,1 +24134,295865928,295865936,1 +24136,295865928,1540794418,1 +115652,295865936,985946472,1 +138648,297562141,559590853,1 +75611,297562141,559940462,0 +2167,297562149,1540771639,0 +75578,297562149,1540840247,1 +625,301343710,1540770254,0 +81619,301343729,1540845043,0 +24276,302044723,982077240,1 +17689,302044723,1540787777,1 +17687,302045960,1540787768,1 +24948,302363454,982077213,0 +17686,302363454,1540787762,1 +24940,302552971,1540796186,1 +114725,302552972,973777017,0 +24404,302552972,1540795741,0 +64396,302553819,360713269,0 +49960,302553819,360714111,0 +24409,302555197,360713625,0 +24536,302555197,1540795762,0 +133447,302555199,360712202,1 +24405,302555199,1540795742,0 +24535,302555271,302555197,0 +24415,302555271,1540795748,0 +133446,302555273,302555199,1 +24544,302656261,302656918,0 +24545,302656918,302661527,0 +24528,302656918,360712811,0 +24531,302656919,302656921,0 +24279,302656919,1540795531,1 +24532,302656921,302656922,0 +49926,302656921,360713136,1 +24600,302656922,302687557,1 +24533,302656922,360713127,0 +49942,302656927,360713757,0 +133428,302656927,360713829,0 +49953,302656927,360713960,0 +89050,302660583,302660584,1 +24411,302660583,1540795744,0 +24414,302660584,302555271,0 +89041,302660584,360713160,0 +17693,302660617,302660640,1 +24413,302660617,1540795746,0 +17694,302660640,360713231,1 +89048,302661527,302661729,0 +24546,302661527,982077259,0 +17688,302661528,1540787771,1 +24527,302661728,302656261,1 +24550,302661728,302661729,1 +89049,302661729,302552972,0 +24551,302661729,982077243,1 +89043,302687557,360713136,0 +24601,302687557,982077203,1 +126082,302689432,360714251,0 +133449,302689432,360714287,1 +133453,302689433,360716521,1 +17691,302897535,38840240,1 +24941,303698831,1540796187,1 +2909,338484169,365117118,1 +56012,338484169,365117377,0 +2900,338484231,338484240,1 +56062,338484231,365118450,1 +80981,338484231,1540844147,0 +2872,338484240,1540773429,0 +2901,338484240,1540773453,1 +2902,338484242,338484243,1 +134898,338484242,353244834,1 +31600,338484242,1540802521,0 +31618,338484243,353244640,1 +2903,338484243,1540773454,1 +29583,338484351,360475281,1 +2031,338484351,360475311,1 +127447,338484427,683287852,0 +29589,338484427,1227739218,1 +29591,338484429,683301441,1 +127451,338484489,246588554,0 +127419,338484489,683287907,0 +31706,338484525,1142694906,0 +127416,338484525,1540885151,0 +48321,338484527,360476152,1 +127410,338484527,683301333,0 +29596,338484589,246588486,1 +127412,338484589,353246572,0 +48492,338484590,360477598,1 +135110,338484590,683295964,1 +29603,338484611,338484590,1 +80612,338484611,360476153,0 +80299,338484637,338485257,0 +80606,338484637,1540843303,0 +80603,338484638,353250869,0 +29648,338484638,678168452,0 +80602,338484639,338484638,0 +2042,338484639,353250820,1 +29697,338484712,338484713,1 +134530,338484712,360476197,1 +51299,338484713,360476193,1 +29698,338484713,683297760,1 +51314,338484715,361197616,1 +29701,338484715,581291044,1 +29595,338484933,338484589,1 +48287,338485009,360475567,1 +29619,338485009,1540798990,0 +29622,338485094,338485152,0 +134513,338485094,360475277,1 +134509,338485095,246588551,0 +29624,338485101,338485095,0 +48282,338485101,1540813896,0 +48277,338485114,338485129,0 +29587,338485114,360476008,1 +134545,338485115,338485161,0 +48274,338485115,353246790,0 +48281,338485123,338485101,0 +29630,338485125,338485127,1 +127444,338485125,694820345,0 +48279,338485127,694820744,0 +48278,338485129,338485127,0 +29634,338485129,683287842,0 +29623,338485152,338485101,0 +29636,338485152,360475363,0 +29633,338485158,338485129,0 +29639,338485158,338485159,0 +29586,338485159,338485114,1 +29640,338485159,1540798996,0 +29642,338485160,338485161,0 +127422,338485160,1540885154,0 +29643,338485161,678168471,0 +134546,338485161,1540904931,0 +133744,338485185,338485186,1 +133745,338485186,338485187,1 +133746,338485187,559590882,1 +134885,338485188,559590449,1 +98584,338485188,1144177918,1 +2041,338485256,338484639,1 +29654,338485256,353250800,1 +80300,338485257,246588555,0 +29657,338485257,1540798998,1 +29601,338485258,360476207,1 +29664,338485278,683290495,0 +29614,338485278,1236188092,0 +29666,338485291,338485292,0 +127417,338485291,338485325,0 +29667,338485292,338485293,0 +134526,338485292,338485326,0 +29668,338485293,360476276,0 +29691,338485293,1540799002,1 +29670,338485294,360476237,0 +29659,338485294,360476238,1 +29672,338485295,338485296,0 +80608,338485295,360476247,0 +92236,338485296,338485330,0 +29673,338485296,678178654,0 +135095,338485309,1227739218,0 +29613,338485324,338485278,0 +29685,338485324,338485309,0 +29683,338485325,683290545,0 +127418,338485325,1540885152,0 +29682,338485326,338485325,0 +134527,338485326,1540904928,0 +29690,338485327,338485293,1 +29681,338485327,338485326,0 +29658,338485328,338485294,1 +29680,338485328,1540799000,0 +80607,338485329,338485295,0 +29678,338485329,678178656,0 +29676,338485330,353246458,0 +92237,338485330,1540856224,0 +2040,338485358,338485256,1 +29686,338485358,353250796,1 +135134,338485737,797375664,0 +98116,338485737,1140945527,1 +95536,338485737,1540857493,0 +51431,338485738,361198998,1 +127139,338485738,803745022,0 +126466,338485787,797375690,0 +29710,338485829,338485787,0 +135124,338485829,365310391,0 +95538,338485830,746981320,0 +134580,338485830,797375638,0 +107138,338485831,1119354090,1 +51429,338485831,1145611269,1 +107133,338485833,938149080,1 +2820,338485833,1540773403,0 +107442,338485834,938149074,1 +2823,338485834,938149158,0 +51449,338485974,797375803,1 +2828,338485974,797375840,0 +29720,338485976,600205187,1 +2830,338485976,792071823,0 +51371,338485978,792071787,1 +2832,338485978,1540773408,0 +29714,338486506,361198875,1 +143846,338487126,279591056,0 +29725,338487126,363976091,1 +53855,338487127,974030726,1 +149320,338487216,974030797,1 +45676,338487216,1540812128,1 +29734,338487217,360205943,1 +149351,338487217,974030555,1 +149356,338487310,360206315,0 +45653,338487319,279591457,1 +149353,338487319,1030294078,1 +29738,338487579,360233631,1 +46042,338487579,1540812318,1 +29740,338487581,360216931,1 +46080,338487581,360220456,1 +29748,338487582,338487583,1 +29750,338487582,338487955,1 +29749,338487583,338487584,1 +104729,338487583,338488021,1 +29762,338487584,360218097,1 +29756,338487728,1540799023,1 +29754,338487804,338487805,1 +29775,338487804,338487848,1 +29777,338487805,338487936,1 +29755,338487805,1540799019,1 +29757,338487814,338487815,1 +29758,338487815,1540799024,1 +29759,338487817,338488023,1 +29767,338487818,913575820,1 +45891,338487818,1540812213,1 +29776,338487848,338487815,1 +104732,338487848,338487936,1 +104733,338487936,338487728,1 +29778,338487936,338487814,1 +29785,338487955,338488021,1 +29751,338487955,338488119,1 +29779,338487955,360217924,1 +46179,338487957,1540812445,1 +29786,338488021,338488023,1 +104730,338488021,338488095,1 +29760,338488023,360233657,1 +46092,338488095,338487817,1 +104731,338488095,338487848,1 +46091,338488119,338488095,1 +29752,338488119,360232840,1 +30704,347500819,360467165,0 +122950,347500819,1540882895,1 +122949,347501719,347500819,1 +30740,347501719,347502212,0 +30746,347501749,360467373,0 +30820,347501749,706854103,0 +30752,347501750,347503863,1 +30754,347502144,347503177,1 +127248,347502147,347502637,1 +30757,347502147,360467889,1 +30741,347502212,347502242,0 +134978,347502212,360467240,0 +30785,347502242,347502820,0 +30742,347502242,360467480,0 +30745,347502370,347501749,0 +30808,347502370,347502822,0 +127258,347502388,360468755,1 +30814,347502444,347503645,0 +127254,347502444,360468424,1 +30748,347502525,347502579,0 +30833,347502525,347502825,0 +127251,347502539,778677126,1 +30749,347502579,347501750,0 +30841,347502579,347502826,0 +127249,347502637,360467886,1 +134977,347502819,347502212,0 +30852,347502820,347502819,0 +30786,347502820,347502984,0 +30851,347502821,347502820,0 +30796,347502821,360467525,0 +30850,347502822,347502821,0 +30809,347502822,347502986,0 +30819,347502823,347501749,0 +30849,347502823,347502822,0 +30848,347502825,347502823,0 +30834,347502825,347502989,0 +30847,347502826,347502825,0 +30842,347502826,347502990,0 +30859,347502984,347502985,0 +30787,347502984,347503170,0 +30795,347502985,347502821,0 +30860,347502985,347502986,0 +30861,347502986,347502988,0 +30810,347502986,347503172,0 +30818,347502988,347502823,0 +30862,347502988,347502989,0 +30863,347502989,347502990,0 +30835,347502989,347503174,0 +30843,347502990,347503175,0 +30866,347503170,347503171,0 +30794,347503171,347502985,0 +30867,347503171,347503172,0 +30868,347503172,347503173,0 +30811,347503172,347503400,0 +30817,347503173,347502988,0 +30869,347503173,347503174,0 +30870,347503174,347503175,0 +30836,347503174,347503403,0 +30871,347503175,347503177,0 +30844,347503175,347503404,0 +30755,347503177,1540800297,1 +30793,347503399,347503171,0 +30875,347503400,347503399,0 +30812,347503400,347503643,0 +30816,347503402,347503173,0 +30874,347503402,347503400,0 +30837,347503403,347502539,0 +30873,347503403,347503402,0 +30845,347503404,347502637,0 +30872,347503404,347503403,0 +30792,347503640,347503399,0 +30881,347503640,347503643,0 +30813,347503643,347502388,0 +30882,347503643,347503645,0 +30815,347503645,347503402,0 +30846,347503863,347502826,0 +30753,347503863,1540800296,1 +30885,347769466,597693501,1 +30888,347769466,1540800311,1 +30887,347774612,1540800309,1 +30889,347774803,347776938,1 +30893,347774803,347777001,1 +126325,347774804,347776931,1 +30913,347774804,1540800343,1 +126320,347775564,1540884412,1 +126324,347776878,347774804,1 +137784,347776878,1540920288,0 +126326,347776931,347777152,1 +30890,347776938,347774804,1 +30892,347776938,1540800313,1 +30896,347777001,347777152,1 +30884,347777052,347769466,1 +30894,347777052,347777331,1 +126327,347777152,347781006,1 +30923,347777152,1540800344,1 +30895,347777331,347777001,1 +30898,347777331,1540800317,1 +16923,347777405,1540787247,1 +30901,347777730,272554695,1 +30904,347777730,1540800334,1 +30906,347778141,272554695,1 +30903,347778141,1540800329,1 +30907,347778153,272554703,1 +30905,347778153,1540800339,1 +31042,347780182,351950743,1 +126329,347780182,1540884417,1 +126313,347780192,347780193,1 +126315,347780193,347780807,1 +30961,347780193,1540800368,1 +30962,347780795,347775564,1 +30910,347780795,347780807,1 +126316,347780807,347780990,1 +30911,347780807,1540800342,1 +126319,347780901,347780903,1 +30916,347780901,347781363,1 +30939,347780903,347782458,1 +30963,347780925,352705317,1 +30919,347780925,352705318,1 +30947,347780925,1540800352,0 +2981,347780926,1540773492,1 +30922,347780990,347781006,1 +126317,347780990,347781494,1 +126328,347781006,347775564,1 +30915,347781137,347780901,1 +30936,347781363,347781478,1 +30917,347781363,352705352,1 +30958,347781383,352683321,1 +30933,347781383,352702861,1 +30935,347781387,1540800348,1 +31303,347781394,352679189,1 +30937,347781478,347781494,1 +30929,347781478,352705337,1 +126318,347781494,347780901,1 +30914,347781598,347781137,1 +30938,347781598,1540800349,1 +31229,347781699,352705946,1 +31224,347781699,1540800655,1 +30941,347782177,347781699,1 +30944,347782177,347782208,0 +30927,347782208,347782472,1 +30945,347782208,352705354,0 +30943,347782338,347782177,0 +137782,347782338,347782523,0 +30940,347782458,347782177,1 +30950,347782458,347782523,0 +30949,347782472,347782458,0 +30928,347782472,1540800347,1 +30951,347782523,597693485,0 +137783,347782523,1540920286,0 +16938,347783337,272499528,1 +30952,347783337,347783404,1 +104336,347783404,1540866040,0 +16937,347783946,347783337,1 +16896,347783946,1540787208,1 +30957,347784872,347781383,1 +30953,347784872,1540800353,1 +30954,347784875,1540800359,1 +31059,347784875,1540800465,1 +30955,347784877,1540800361,1 +30912,347784880,347780192,1 +30956,347784880,1540800365,1 +31191,347785539,1540800616,1 +31008,351948867,1540800426,1 +31102,351948869,351953704,1 +31009,351948869,351953838,1 +31028,351949127,1540800442,1 +31029,351949742,1540800444,1 +31030,351949745,351949746,1 +31299,351949745,351953544,1 +31086,351949746,597688045,1 +31031,351949746,1540800446,1 +31084,351949750,351948867,1 +31032,351949750,1540800448,1 +31037,351950051,351950052,1 +17028,351950051,351950260,1 +31053,351950052,351951179,1 +31021,351950260,351951179,1 +17029,351950260,1540787383,1 +31081,351950262,351953290,1 +31044,351950580,351951291,1 +31057,351950580,1540800464,1 +31045,351950701,347784877,1 +31046,351950701,351950735,1 +31043,351950735,1540800451,1 +31047,351950735,1540800452,1 +31048,351950737,1540800454,1 +31049,351950739,1540800455,1 +31050,351950742,1540800458,1 +31051,351950743,1540800459,1 +31052,351951160,351950052,1 +31041,351951160,351950739,1 +31022,351951179,351950737,1 +31054,351951179,351952593,1 +31071,351951291,351952239,1 +31063,351951291,351952417,1 +31060,351951722,351952164,1 +31062,351951844,351951291,1 +31067,351951844,351952236,1 +31058,351952159,351951722,1 +31066,351952159,351952164,1 +31061,351952164,351951844,1 +31068,351952236,1540800467,1 +31070,351952236,1540800468,1 +31072,351952239,1540800470,1 +31069,351952253,351952239,1 +31073,351952392,351952393,1 +31075,351952392,351952417,1 +31074,351952393,351952395,1 +31076,351952393,351952523,1 +31085,351952393,351953544,1 +31301,351952395,351953588,1 +31096,351952395,351953606,1 +31064,351952417,1540800466,1 +31065,351952523,351949742,1 +31077,351952523,351952525,1 +31078,351952525,351952526,1 +31080,351952526,351950262,1 +31079,351952593,351952526,1 +31055,351952593,351952634,1 +31056,351952634,351951291,1 +31083,351952634,351952525,1 +31082,351953290,351948867,1 +31027,351953290,351949127,1 +31186,351953504,352679509,1 +31209,351953504,352704476,1 +31306,351953504,352709181,1 +31309,351953505,175702585,1 +31300,351953544,351952395,1 +31111,351953572,351953838,1 +31089,351953572,351953869,1 +31315,351953573,1540800783,1 +31302,351953588,347781394,1 +31093,351953588,351953606,1 +31097,351953606,351953607,1 +31094,351953606,597688045,1 +31098,351953607,351953902,1 +31104,351953607,1540800474,1 +31100,351953608,351953609,1 +31108,351953608,351953802,1 +31113,351953609,351954004,1 +31101,351953609,1540800472,1 +31088,351953704,351953572,1 +31103,351953704,351953607,1 +31105,351953801,351953802,1 +31109,351953801,351953902,1 +31112,351953802,1540800476,1 +31010,351953838,1540800427,1 +31106,351953840,351953869,1 +31011,351953840,1540800428,1 +31121,351953844,351954130,1 +31013,351953844,1540800431,1 +31169,351953846,351954135,1 +31014,351953846,352678752,1 +31107,351953869,351953608,1 +31090,351953869,351954004,1 +31110,351953902,351953572,1 +31099,351953902,351953608,1 +31180,351953949,1540800609,1 +31114,351954004,351954011,1 +31091,351954004,351954157,1 +31012,351954011,351953844,1 +31115,351954011,1540800483,1 +31183,351954078,1540800612,1 +31122,351954130,351954157,1 +31116,351954130,1540800484,1 +31117,351954135,1540800487,1 +31170,351954135,1540800602,1 +31092,351954157,351953573,1 +31123,351954157,1540800489,1 +31161,352678176,1540800593,0 +31162,352678239,1540800594,0 +31163,352678241,1540800595,0 +31172,352678241,1540800603,1 +31164,352678244,1540800597,0 +31171,352678752,352678853,1 +31015,352678752,1540800432,1 +31174,352678853,1540800606,1 +31305,352678982,351953504,1 +31176,352678982,352679508,1 +31181,352679008,1540800611,1 +31182,352679010,351954078,1 +31304,352679189,352678982,1 +31184,352679189,352679476,1 +31178,352679259,352679523,1 +31188,352679400,1540800615,1 +31189,352679476,352679508,1 +31185,352679476,1540800613,1 +31177,352679508,352679259,1 +31190,352679508,352679509,1 +31187,352679509,352679400,1 +31179,352679523,1540800607,1 +30960,352683317,176173984,1 +31192,352683317,352683318,1 +31213,352683318,352704837,1 +31193,352683318,1540800617,1 +31197,352683319,352702664,1 +31194,352683319,1540800618,1 +31195,352683320,352683321,1 +31208,352683320,352702992,0 +30959,352683321,352683317,1 +31196,352683321,1540800619,1 +2974,352701561,176173989,1 +31259,352701565,352707070,1 +2977,352701565,1540773489,1 +2979,352701572,176173997,1 +31199,352702468,352678982,1 +31202,352702468,352702555,1 +31200,352702555,1540800620,0 +31198,352702664,352702468,1 +31204,352702664,352702713,1 +31205,352702713,1540800637,0 +30934,352702861,347781387,1 +31206,352702861,1540800653,0 +31207,352702992,1540800654,0 +31203,352704402,352702664,1 +31211,352704402,352704837,1 +31201,352704476,352702468,1 +31210,352704476,352704402,1 +31212,352704837,352701561,1 +30932,352705224,347781383,1 +31214,352705224,352705247,1 +30965,352705247,347785539,1 +31215,352705247,352705248,1 +30921,352705248,347780926,1 +30931,352705267,352705224,1 +31216,352705267,352705317,1 +30964,352705317,352705247,1 +31217,352705317,352705318,1 +30920,352705318,352705248,1 +31218,352705318,352705319,1 +30925,352705319,352705604,1 +30930,352705337,352705267,1 +31219,352705337,352705352,1 +30918,352705352,347780925,1 +31220,352705352,352705353,1 +30948,352705353,347782472,0 +31221,352705353,352705354,1 +31222,352705354,352705604,1 +30946,352705354,1540800351,0 +30926,352705604,1540800345,1 +31230,352705946,352705947,1 +31234,352705946,352706146,1 +31231,352705947,1540800656,1 +31235,352706146,1540800663,0 +31225,352706476,352706518,1 +31236,352706476,1540800681,0 +31237,352706516,1540800682,0 +31238,352706516,1540800683,1 +31226,352706518,352706664,1 +31239,352706544,1540800684,0 +31240,352706574,1540800691,0 +31241,352706574,1540800700,1 +31245,352706581,352705947,1 +31242,352706581,1540800701,1 +31255,352706584,1540800715,1 +31232,352706645,1540800657,1 +137792,352706645,1540920305,0 +31233,352706650,1540800660,1 +31227,352706664,352706700,1 +31246,352706664,1540800702,0 +31247,352706697,1540800703,0 +31248,352706697,1540800705,1 +31228,352706700,352701572,1 +31244,352706872,352706581,1 +31249,352706872,1540800707,1 +31252,352706874,1540800710,1 +31250,352706890,352707070,1 +31261,352706896,352707071,1 +31253,352706896,1540800711,1 +31254,352706987,1540800713,1 +31263,352707053,352706650,1 +31256,352707053,1540800717,1 +31257,352707056,1540800719,1 +31260,352707070,352706896,1 +31251,352707070,1540800708,1 +31262,352707071,352707053,1 +31258,352707071,1540800721,1 +31264,352707216,1540800723,0 +31265,352707228,1540800731,0 +31266,352707228,1540800738,1 +31271,352708531,352708657,1 +31268,352708531,1540800742,0 +31270,352708533,352708549,1 +31269,352708533,1540800744,0 +31274,352708630,1540800757,1 +76042,352708630,1540840510,1 +31275,352708636,1540800758,1 +31276,352708636,1540800760,1 +76041,352708639,352708630,1 +31272,352708657,352708902,1 +31277,352708657,1540800761,1 +76039,352708731,352709241,1 +31278,352708731,1540800762,1 +31279,352708777,1540800763,1 +31280,352708777,1540800766,1 +76038,352708786,352708731,1 +31273,352708902,175702594,1 +31281,352708902,1540800767,1 +31283,352709181,176175856,1 +31307,352709181,352709508,1 +31288,352709189,1540800772,1 +2983,352709199,176173989,1 +31286,352709199,352709206,1 +31285,352709206,352709189,1 +76040,352709241,352708639,1 +31287,352709241,1540800771,1 +76037,352709360,352708786,1 +31289,352709360,1540800774,1 +31291,352709387,352715198,1 +31290,352709387,1540800775,1 +31293,352709508,352715653,1 +31308,352709508,1540800782,1 +31295,352709510,352715465,1 +31282,352709510,1540800768,1 +76035,352712087,176176671,1 +68179,352712087,1540838088,0 +76034,352712089,352712087,1 +2928,352712089,352712183,0 +2929,352712183,1540773469,0 +31298,352715163,351953505,1 +31311,352715163,352715198,1 +31312,352715198,176175856,1 +31292,352715198,352709508,1 +31313,352715465,352715485,1 +31296,352715465,1540800777,1 +31294,352715653,352709510,1 +31314,352715653,352715667,1 +31319,352723284,352723346,1 +31317,352723284,1540800787,1 +31318,352723286,352723320,1 +68173,352723286,352723638,0 +2934,352723320,352723348,0 +68172,352723346,352723286,0 +31320,352723346,352723348,1 +2935,352723348,352724913,0 +31352,352723520,352723630,1 +31316,352723520,1540800784,1 +68176,352723567,175702571,0 +31353,352723630,352723661,1 +31322,352723630,1540800789,1 +68174,352723638,352723692,0 +31323,352723661,1540800790,1 +31354,352723661,1540800806,1 +68175,352723692,352723567,0 +68171,352724109,352723346,0 +31324,352724109,352724124,1 +31351,352724124,352723520,1 +31347,352724179,352724180,1 +31345,352724179,352725210,1 +31348,352724180,352724181,1 +31343,352724180,352725089,1 +31349,352724181,352724183,1 +31326,352724181,352724449,1 +31350,352724183,352724124,1 +31325,352724183,1540800791,0 +31336,352724386,352724913,0 +68170,352724386,1540838086,0 +68169,352724449,352724386,0 +2937,352724693,175702481,0 +130237,352724693,352724449,0 +130232,352724694,559488968,0 +76013,352724696,560712609,1 +31333,352724696,560712694,0 +76061,352724702,560712616,1 +31332,352724702,1540800800,0 +76080,352724713,560712661,1 +31330,352724713,560712676,0 +2989,352724720,352724978,1 +31329,352724720,1540800792,0 +2936,352724913,352724693,0 +31337,352724913,559489055,0 +76097,352724958,560712444,1 +130244,352724958,560712684,0 +76012,352724959,352724696,1 +130247,352724959,1540886542,0 +76060,352724965,352724702,1 +130248,352724965,1540886546,0 +130249,352724970,352724972,0 +76066,352724970,560712676,1 +76079,352724972,352724713,1 +130250,352724972,1540886550,0 +130251,352724978,528510373,0 +2990,352724978,560712704,1 +68168,352725089,352724449,0 +31344,352725089,352725090,1 +2939,352725090,1540773470,0 +68167,352725111,352725089,0 +31321,352725111,1540800788,1 +31173,352725210,352678853,1 +31346,352725257,1540800804,1 +68166,352725257,1540838085,0 +31570,353243056,353243057,1 +31588,353243056,353243305,1 +31571,353243057,353243058,1 +31591,353243057,353243546,1 +31572,353243058,353243059,1 +31581,353243059,353243278,1 +31573,353243059,695556358,1 +31579,353243175,353243304,1 +56022,353243175,353243671,1 +31578,353243177,353243175,1 +31593,353243177,353243670,1 +31577,353243178,353243177,1 +2920,353243178,360468231,1 +31583,353243217,353243257,1 +56024,353243217,353244015,1 +127243,353243219,353244211,1 +56026,353243219,365117487,1 +56001,353243220,353243803,0 +56028,353243220,365117357,1 +55995,353243221,353243805,0 +56031,353243221,365117568,1 +31584,353243257,353243258,1 +31595,353243257,353243802,1 +2916,353243258,706804573,1 +31582,353243278,353243217,1 +127231,353243278,353243304,1 +31580,353243304,353243058,1 +127232,353243304,353243546,1 +31589,353243305,353243341,1 +56020,353243341,353243547,1 +31590,353243341,1540802518,1 +125332,353243344,365308966,1 +127233,353243546,353243305,1 +31592,353243546,353243547,1 +56021,353243547,353243175,1 +31597,353243658,353243670,1 +2918,353243658,360468245,1 +31594,353243670,353243257,1 +31598,353243670,353243671,1 +56023,353243671,353243217,1 +31596,353243802,353243956,1 +127221,353243802,353244015,1 +56002,353243803,365117281,0 +127234,353243803,695552921,1 +127238,353243805,353244382,1 +55996,353243805,365117353,0 +127242,353243956,353243219,1 +127225,353243956,365117421,1 +31575,353243957,1540802517,1 +56025,353244015,353243219,1 +127222,353244015,353244016,1 +127230,353244016,353243278,1 +127223,353244016,695556358,1 +127244,353244211,353243957,1 +127229,353244211,353244016,1 +55994,353244212,353243221,0 +31586,353244212,365117305,1 +56000,353244213,353243220,0 +127227,353244213,365117458,1 +31603,353244322,353244513,0 +31626,353244322,353244762,0 +31606,353244323,365117516,1 +56032,353244323,365117660,0 +127239,353244382,353244585,1 +127269,353244382,1540885063,1 +127270,353244385,353244386,1 +31629,353244385,365116983,0 +31613,353244386,353244639,1 +127271,353244386,1540885065,1 +2906,353244388,360473545,1 +31604,353244513,365117904,0 +31609,353244556,353244585,1 +31608,353244556,1540802522,1 +127240,353244585,353244670,1 +31610,353244585,1540802524,1 +31628,353244587,353244385,0 +31611,353244587,353244639,1 +50155,353244588,353246108,0 +2904,353244588,1540773455,1 +31612,353244639,353244588,1 +31614,353244639,353244640,1 +31615,353244640,353244641,1 +31619,353244640,353244762,1 +31602,353244641,353244322,0 +31616,353244641,365117876,1 +127241,353244670,353244513,1 +31627,353244762,353244587,0 +31620,353244762,353244670,1 +50170,353244826,175678407,1 +31634,353244826,353245939,0 +31639,353244827,1142420555,0 +127342,353244827,1540885128,0 +31641,353244828,705990476,0 +134842,353244828,1540905142,1 +48158,353244829,360472856,0 +31644,353244829,360473814,0 +152353,353244833,360473622,1 +134899,353244834,353244833,1 +134843,353244893,353244894,1 +134844,353244894,353244895,1 +93366,353244894,1142356880,1 +56478,353244895,705979282,1 +134845,353244895,1540905143,1 +134846,353244898,705979188,1 +50162,353244898,1540815073,0 +50154,353244899,1540815069,0 +135092,353244968,353244893,0 +127345,353244968,705979280,0 +135091,353244969,353244968,0 +31656,353244969,353245109,0 +127349,353244971,353244972,1 +31651,353244971,353245534,0 +127350,353244972,353244973,1 +31687,353244972,353245938,0 +127351,353244973,353244974,1 +50166,353244973,353245398,1 +127352,353244974,353244976,1 +31674,353244974,353245604,1 +31680,353244976,353245604,1 +31648,353244985,353245027,0 +31637,353244985,360473975,0 +31649,353245027,353245028,0 +31665,353245027,353245108,0 +31650,353245028,353244971,0 +127371,353245028,353245938,0 +31653,353245029,360728029,0 +134919,353245029,1540905168,0 +31658,353245108,1540802529,0 +31657,353245109,353245108,0 +127369,353245109,705979304,0 +31655,353245112,353244969,0 +134917,353245112,353246135,0 +31654,353245113,353245112,0 +93386,353245113,1540856504,1 +93363,353245362,1540856493,1 +127343,353245362,1540885129,0 +127344,353245364,353244968,0 +127367,353245364,705979263,0 +127347,353245365,1142305233,0 +134914,353245366,353246130,0 +50167,353245398,353245462,1 +31664,353245460,353245027,0 +31663,353245461,353245460,0 +31689,353245461,353245943,0 +31662,353245462,353245461,0 +50168,353245462,353245944,1 +93388,353245525,353245600,1 +50163,353245525,353245877,1 +31652,353245534,353245029,0 +31666,353245534,353245552,1 +31686,353245552,353244972,0 +31667,353245552,353245553,1 +50165,353245553,353244973,1 +31668,353245553,353245554,1 +31673,353245554,353244974,1 +31669,353245554,353245555,1 +31683,353245555,705970929,1 +31670,353245555,1540802530,1 +31678,353245557,353245633,1 +31671,353245600,1540802531,1 +93389,353245600,1540856506,1 +31672,353245603,353245554,1 +134921,353245603,705970935,0 +127323,353245604,353245605,0 +31681,353245604,1540802534,1 +31661,353245605,353245462,0 +134900,353245605,353245464,1 +127324,353245605,353245606,0 +50188,353245606,360728687,1 +127325,353245606,360728698,0 +31679,353245633,353244976,1 +31682,353245633,1540802536,1 +31677,353245634,1540802533,1 +93349,353245634,1540856486,1 +31685,353245713,1540802538,1 +134923,353245713,1540905170,0 +134896,353245716,1540905155,1 +50164,353245877,353245553,1 +134920,353245877,353245603,0 +127372,353245938,353245398,0 +31688,353245938,353245461,0 +31635,353245939,705979298,0 +31691,353245939,1540802539,0 +31690,353245943,353245939,0 +31692,353245943,353245944,1 +50169,353245944,353244826,1 +48181,353246108,1540813878,1 +50156,353246108,1540815071,0 +50158,353246112,353246114,0 +48179,353246112,353246172,1 +50159,353246114,353246116,0 +134930,353246114,353246252,0 +48155,353246116,583223031,0 +50160,353246116,1540815072,0 +50161,353246120,353244898,0 +48172,353246120,705990576,1 +134912,353246125,1540905166,0 +134915,353246130,353246132,0 +134916,353246132,353245112,0 +93361,353246132,1540856490,1 +134918,353246135,1540905167,0 +31697,353246170,338484243,0 +48182,353246170,353244834,1 +31694,353246172,1141192202,0 +31693,353246173,353246172,0 +134928,353246173,365308199,0 +134933,353246173,1540905174,1 +134931,353246252,360472605,0 +48165,353246252,360472853,0 +48013,353246253,360469891,1 +152364,353246253,360727836,1 +152361,353246255,706821674,1 +152360,353246256,353246255,1 +152359,353246257,353246256,1 +127245,353246257,360469890,1 +48040,353246260,360469616,1 +48190,353246260,1540813879,1 +48036,353246262,360469315,1 +48187,353246262,706002877,1 +31704,353246385,683290453,0 +134525,353246385,1540904927,0 +29661,353246387,353246578,1 +31701,353246387,360476272,0 +80610,353246389,353246401,0 +31699,353246389,360476250,0 +31698,353246390,353246389,0 +92234,353246390,1540856223,0 +80611,353246401,338484611,0 +31718,353246401,360476225,1 +80297,353246430,246588557,0 +92238,353246430,678168522,0 +29677,353246458,338485329,0 +134891,353246570,338484933,0 +31710,353246570,1540802543,1 +31712,353246572,246588482,1 +127413,353246572,683290444,0 +31714,353246576,360476255,1 +29695,353246576,599162413,1 +29662,353246578,338485258,1 +31716,353246578,360476236,1 +2034,353246658,353250758,1 +127427,353246658,1540885157,1 +127421,353246790,338485160,0 +48275,353246790,360475937,0 +2035,353250758,150563687,1 +31722,353250758,1540802545,1 +29646,353250796,353250800,0 +29687,353250796,353250871,1 +29655,353250800,353250870,1 +29647,353250800,1540798997,0 +92241,353250804,353250820,0 +29650,353250804,581267843,0 +80322,353250820,577419445,0 +92240,353250844,353250804,0 +31723,353250844,678168453,1 +31725,353250869,353250870,1 +80604,353250869,678168457,0 +29656,353250870,338485257,1 +31726,353250870,353250871,1 +29688,353250871,246588555,1 +31727,353250871,599162437,1 +134544,353250872,338485115,0 +96579,355920392,355920394,1 +96494,355920392,788870546,1 +96580,355920394,625904125,1 +96532,355920394,788870656,1 +96561,355920394,788870705,1 +87981,355921354,1307354452,1 +33703,355921355,1540803256,1 +87985,355921355,1540851149,1 +59354,355921358,372787082,1 +87990,355921358,1540851151,1 +59343,355921360,372789199,1 +87991,355921360,1540851154,1 +59357,355921423,1540831981,0 +33729,355929051,355929669,0 +17073,355929051,592561673,0 +33728,355929053,355929051,0 +82057,355929053,462754120,0 +81624,355929441,36245103,0 +33730,355929669,1540803271,0 +40107,359995915,559591668,1 +40101,359995915,984725789,1 +75688,359995915,1540840275,1 +40103,359995958,359998230,1 +75588,359995958,1540840253,1 +40110,359996135,1540809889,1 +40143,359996726,1540809913,1 +118616,359996726,1540877518,1 +118603,359996729,359996730,1 +118623,359996729,1025767708,1 +118604,359996730,360009885,1 +40576,359996730,360009936,1 +118606,359996731,359996732,1 +40570,359996731,1540810113,1 +118607,359996732,360009643,1 +40562,359996732,360009784,1 +118609,359996734,359996735,1 +40560,359996734,360009720,1 +40133,359996735,1540809899,1 +40134,359997003,1540809901,1 +40135,359997013,359997014,1 +89939,359997013,1540853766,1 +40136,359997014,1540809910,1 +115596,359997014,1540874757,1 +89936,359997016,984752822,1 +40137,359997016,1540809911,1 +40138,359997018,359997063,1 +115440,359997018,1540874559,1 +40139,359997063,1540809912,1 +22953,359997064,359997381,1 +22955,359997065,359997066,1 +118614,359997065,1540877515,1 +22956,359997066,359997910,1 +115630,359997066,985921504,1 +115638,359997067,985921497,1 +22958,359997067,1540792794,1 +115637,359997070,985921420,1 +22959,359997070,1540792797,1 +40122,359997133,985946343,1 +40145,359997133,1540809916,1 +40124,359997134,359997135,1 +40170,359997134,1540809928,1 +40125,359997135,1540809896,1 +40115,359997138,985945940,1 +40146,359997138,985946280,1 +40092,359997152,985946374,0 +40149,359997153,985945923,1 +40118,359997153,1540809892,1 +24135,359997195,295865928,1 +40156,359997195,1540809922,1 +24132,359997196,359997152,1 +40157,359997264,359997376,1 +75584,359997264,1540840248,1 +75585,359997265,359997266,1 +115625,359997265,359997811,1 +75586,359997266,359997267,1 +40176,359997266,359997885,1 +40178,359997267,1540809932,1 +75587,359997267,1540840249,1 +40162,359997376,359997133,1 +40158,359997376,359997378,1 +40169,359997378,359997134,1 +40159,359997378,359997380,1 +40175,359997380,359997135,1 +40160,359997380,359997381,1 +22954,359997381,359997065,1 +40151,359997466,359997467,1 +24127,359997466,1540794414,1 +24129,359997467,295865926,1 +40152,359997467,359997469,1 +115663,359997469,985946045,1 +40153,359997469,985946150,1 +397,359997700,1540770106,0 +24126,359997700,1540794412,1 +115661,359997705,1540874799,1 +40161,359997811,359997376,1 +115626,359997811,359997886,1 +40166,359997885,359997886,1 +40177,359997885,359997910,1 +40167,359997886,985921385,1 +115627,359997886,985921498,1 +22957,359997910,359997067,1 +40165,359997940,1540809927,1 +40104,359998230,984726104,1 +40163,359998230,985921499,1 +2166,359998262,297562149,0 +75607,359998262,559564592,1 +119658,359998407,961664491,1 +40185,359998407,1540809937,1 +108611,359998480,961664710,1 +40186,359998480,1540809938,1 +40188,359998484,359998485,1 +108670,359998485,961664690,1 +40189,359998485,1540809940,1 +108629,359998489,961664610,1 +40190,359998489,1540809943,1 +95789,359998581,559591303,1 +64078,359998581,559591347,1 +40192,359998581,1540809946,1 +40194,359998585,559564601,1 +75597,359998585,559564766,1 +134887,359998587,359998588,1 +94799,359998587,359999110,0 +134888,359998588,559939030,1 +75716,359998622,559591383,1 +95792,359998622,559591449,1 +95794,359998626,1540858418,1 +40196,359998684,359998685,1 +40202,359998684,1540809949,1 +94798,359998685,1540857336,0 +40198,359998809,560582733,1 +94802,359998809,1540857341,0 +40182,359998944,559939042,1 +40200,359998944,560582736,1 +75920,359998944,1540840449,1 +75918,359998946,359998947,1 +94801,359998947,1540857340,0 +40203,359999110,1540809950,1 +94800,359999110,1540857339,0 +75743,359999162,359998588,0 +40180,359999162,549775695,1 +75742,359999163,359999162,0 +98715,359999163,1540861544,0 +40204,359999214,359999662,1 +75754,359999214,1540840347,0 +118041,359999214,1540876362,0 +40205,359999662,360000546,1 +108661,359999662,360000565,1 +40247,359999663,1540809973,1 +108664,359999663,1540870110,1 +40211,359999720,36643959,0 +51533,359999824,359999826,0 +75738,359999824,1540840308,0 +51534,359999826,1013433945,0 +75737,360000002,1540840307,0 +127573,360000002,1540885220,0 +75526,360000003,1013433900,0 +118024,360000003,1540876330,0 +127553,360000058,360000059,0 +40253,360000058,1540809978,1 +40255,360000059,1540809984,1 +127554,360000059,1540885192,0 +40252,360000101,360000058,1 +40254,360000101,360000059,1 +75523,360000101,1540840239,0 +108663,360000112,359999663,1 +40214,360000112,360000208,1 +40215,360000208,360000209,1 +40217,360000208,360000368,1 +40219,360000368,360000417,1 +40218,360000369,360000368,1 +108665,360000369,1540870111,1 +40220,360000417,1540809963,1 +40221,360000521,1540809967,1 +118044,360000521,1540876370,0 +75748,360000523,1013433856,0 +40222,360000540,1540809969,1 +108666,360000540,1540870112,1 +40223,360000546,360000417,1 +40206,360000546,1540809952,1 +108662,360000565,360000112,1 +40224,360000565,360003310,1 +40212,360000951,559939059,1 +94787,360000951,1540857326,1 +40231,360001267,360001613,0 +127545,360001267,560576565,1 +102770,360001348,365969993,0 +40226,360001348,365970357,0 +102771,360001348,560576481,0 +102754,360001413,360002312,1 +127543,360001413,365970095,1 +102753,360001612,360001413,1 +40238,360001612,365970096,1 +40232,360001613,360001659,0 +40240,360001613,560576569,1 +40233,360001659,559597237,0 +134881,360001659,560576572,1 +102752,360001817,360001612,1 +134879,360001817,365970097,1 +40230,360001881,360001267,0 +40245,360001881,560576557,1 +40243,360002312,365970094,1 +102755,360002312,365970147,1 +137798,360002692,1540920318,0 +75525,360002696,360000003,0 +40246,360002696,1540809970,0 +127552,360002721,1540885188,0 +118022,360002862,1013433831,0 +118042,360002862,1540876366,0 +75762,360003280,1540840358,1 +40251,360003281,360003280,0 +75777,360003281,559939070,0 +40250,360003283,360003281,0 +75778,360003283,559939069,1 +40249,360003285,1540809977,0 +40216,360003310,360000208,1 +40225,360003310,961664540,1 +40256,360003406,360003653,1 +40257,360003653,1540809988,1 +108617,360003715,961664608,1 +40258,360004887,360004889,1 +41061,360004887,360015403,1 +40260,360004889,360004934,1 +40259,360004889,360015396,1 +99483,360004890,360004891,1 +110088,360004890,1540871256,1 +98685,360004891,1540861514,1 +40279,360004934,360005227,1 +41060,360005227,360004887,1 +40280,360005227,1540809992,1 +41059,360005228,360005227,1 +40908,360005228,360013435,1 +41058,360005229,360005228,1 +124925,360005229,1540883940,1 +40261,360005626,360005627,1 +40126,360005626,360009076,1 +40524,360005626,360009200,1 +40584,360005626,360010188,1 +40262,360005627,360005964,1 +40339,360005627,360006032,1 +40496,360005628,360006033,1 +40264,360005628,360010242,1 +40266,360005629,279591156,1 +40320,360005629,360006036,0 +40273,360005634,360008388,1 +40462,360005634,360008433,1 +40275,360005635,966666289,1 +98683,360005635,1540861512,1 +41051,360005637,360013240,1 +40283,360005637,360014162,1 +40915,360005638,360014313,1 +40285,360005638,1113233818,1 +40483,360005960,360009046,1 +40305,360005961,360005960,1 +40504,360005961,360008916,1 +40304,360005962,360005961,1 +40520,360005962,360008826,1 +40263,360005964,360005628,1 +40303,360005964,360005962,1 +40302,360005965,360005964,1 +136468,360005965,360006033,1 +40301,360005966,360005965,1 +136467,360006032,360005965,1 +40340,360006032,360006657,1 +136469,360006033,360006034,1 +40497,360006033,360008828,1 +136470,360006034,360006035,1 +40443,360006034,360008004,1 +136471,360006035,360006036,1 +40321,360006036,360006263,0 +40300,360006049,360005966,1 +40356,360006049,360006658,1 +40587,360006049,1540810123,1 +40308,360006210,360006211,1 +40546,360006210,360009330,1 +40309,360006211,360009079,1 +40523,360006211,1540810089,1 +40311,360006212,1411198112,1 +40527,360006212,1540810090,1 +40333,360006242,360006264,1 +71581,360006242,536578831,1 +24101,360006242,932361970,0 +40458,360006263,360008073,0 +40322,360006263,360010197,0 +40324,360006264,360007170,0 +40334,360006264,360008076,1 +40385,360006477,360007206,1 +149722,360006477,1540953200,0 +40299,360006480,360006049,1 +149724,360006480,1540953201,0 +149725,360006483,549785183,0 +149727,360006484,1411198139,0 +40363,360006484,1411198143,1 +149729,360006486,360009080,0 +149412,360006487,549785171,1 +149731,360006487,1540953203,0 +40382,360006599,360006660,1 +40297,360006599,1411198158,1 +40295,360006600,360007173,1 +40344,360006600,1540810047,1 +40294,360006601,360006600,1 +40351,360006601,360006823,1 +40293,360006602,360006601,1 +40401,360006602,360007068,1 +40586,360006657,360006049,1 +40341,360006657,360006658,1 +40357,360006658,1411198110,1 +40342,360006658,1540810045,1 +149691,360006660,360006688,1 +40383,360006660,360007057,1 +40343,360006688,1540810046,1 +40350,360006740,360006601,1 +40375,360006823,360007098,1 +40352,360006823,1540810049,1 +40353,360006825,360006827,1 +40367,360006825,360007059,1 +40354,360006827,360006828,1 +40355,360006828,360006830,1 +40414,360006830,360007597,1 +149415,360006879,1540951574,1 +40365,360007057,360007058,1 +40366,360007058,360006825,1 +149654,360007058,360007094,1 +40368,360007059,360007060,1 +40369,360007060,1540810052,1 +84033,360007060,1540846864,1 +40370,360007062,360007063,1 +40373,360007063,1540810053,1 +40402,360007068,360007098,1 +40371,360007068,601027558,1 +149655,360007094,360006688,1 +40374,360007094,1540810054,1 +40403,360007098,360007060,1 +40376,360007098,603093036,1 +40379,360007169,360007206,1 +40406,360007169,1540810061,1 +40325,360007170,279590687,0 +40378,360007170,360007169,1 +40296,360007173,360006599,1 +40384,360007173,360007177,1 +40387,360007177,360007207,1 +40386,360007206,360007177,1 +40380,360007206,1540810055,1 +40349,360007207,360006740,1 +40388,360007207,360007209,1 +40400,360007209,360006602,1 +40389,360007209,360007210,1 +40390,360007210,360007211,1 +40396,360007210,1540810058,1 +40391,360007211,1540810056,1 +40291,360007214,1540809993,1 +40392,360007214,1540810057,1 +40394,360007323,360007324,1 +84035,360007323,1178910002,1 +40395,360007324,360007210,1 +84031,360007324,601004557,1 +40292,360007327,1540809994,1 +40397,360007327,1540810060,1 +40398,360007349,360007350,1 +84037,360007349,600999900,1 +40399,360007350,360007209,1 +84030,360007350,360007324,1 +40327,360007391,1540810022,0 +40345,360007391,1540810048,1 +84041,360007392,600999900,1 +40347,360007392,601002970,1 +40404,360007392,601025200,1 +40381,360007510,360006599,1 +149687,360007537,360006828,1 +40410,360007537,360007556,1 +149653,360007552,360007058,1 +40408,360007552,1540810062,1 +40411,360007554,360006827,1 +40409,360007554,1540810063,1 +40413,360007556,360006830,1 +40415,360007597,360007598,1 +40441,360007597,360007818,1 +40421,360007598,360007719,1 +40416,360007598,360007740,1 +40428,360007599,360007811,1 +40419,360007717,360007718,1 +40422,360007717,981693532,1 +40420,360007718,360007598,1 +40424,360007718,360007731,1 +40439,360007719,360007818,1 +40431,360007723,360007813,1 +40425,360007731,360007732,1 +40426,360007731,360007740,1 +40430,360007732,360007723,1 +40417,360007740,360007599,1 +40427,360007810,360007599,1 +40438,360007810,360007719,1 +40429,360007811,360007732,1 +114708,360007811,981693501,1 +115372,360007813,1411198170,1 +40442,360007818,360007059,1 +114706,360007910,981693524,1 +40433,360007910,981693572,1 +40444,360008004,360008005,1 +40460,360008004,360008828,0 +40445,360008005,360006477,1 +40589,360008005,360008075,1 +40448,360008073,360006035,1 +40459,360008073,360008004,0 +40447,360008075,360008073,1 +40590,360008075,360010197,1 +40335,360008076,360006477,1 +40446,360008076,360008075,1 +40452,360008265,360008506,0 +71582,360008265,932361992,1 +40456,360008268,583432487,0 +71578,360008268,932361990,1 +105165,360008281,360008265,1 +40985,360008281,932361972,1 +40603,360008371,966666274,1 +40274,360008388,360005635,1 +40468,360008388,360008433,1 +40463,360008433,360008495,1 +40469,360008433,1540810076,1 +40471,360008436,932361964,1 +40449,360008437,360014969,0 +40473,360008437,1540810077,1 +40464,360008495,360011588,1 +110086,360008495,966666258,0 +40270,360008505,583432485,1 +40474,360008505,583432488,1 +40453,360008506,932361981,0 +399,360008695,1540770109,0 +98742,360008695,1540861594,0 +40477,360008745,1540810078,1 +115645,360008745,1540874780,1 +40478,360008750,360008752,1 +40481,360008752,360008774,1 +40482,360008774,360005960,1 +40493,360008774,1540810085,1 +40503,360008825,360005961,1 +40494,360008825,360008826,1 +40495,360008826,360005628,1 +40521,360008826,360008929,1 +40461,360008828,360005966,0 +40498,360008828,360008829,1 +40499,360008829,360008830,1 +40588,360008829,1540810124,1 +149723,360008830,360006480,0 +40500,360008830,1411198160,1 +40337,360008916,360009034,1 +40505,360008916,360010311,1 +40487,360008917,360009028,1 +40507,360008917,1025767738,1 +40502,360008921,360008825,1 +40513,360008921,360008929,1 +40480,360008922,360008752,1 +40511,360008922,360008928,1 +40512,360008928,360008921,1 +40516,360008928,360008931,1 +40522,360008929,360009036,1 +40514,360008929,360010242,1 +40317,360008931,1540810015,0 +40488,360009028,360009076,1 +40517,360009028,1540810087,1 +40338,360009034,360005627,1 +40519,360009034,360005962,1 +40319,360009036,1540810018,0 +40336,360009046,360008916,1 +40484,360009046,360009072,1 +40485,360009072,1540810081,1 +40591,360009072,1540810125,1 +40489,360009076,360009077,1 +40127,360009076,360009517,1 +40490,360009077,360009078,1 +40532,360009077,360009200,1 +40491,360009078,360009079,1 +40361,360009078,360009255,1 +40310,360009079,360006212,1 +40492,360009079,1540810084,1 +149730,360009080,1540953202,0 +40526,360009117,360006212,1 +40360,360009117,360009078,1 +40539,360009196,360009233,1 +40528,360009196,360009988,1 +40533,360009197,360009517,1 +40531,360009197,1540810091,1 +40525,360009200,360009117,1 +40530,360009226,360009197,1 +40535,360009228,360009226,1 +40538,360009231,360009196,1 +40536,360009231,360009541,1 +40555,360009231,1540810106,1 +40542,360009233,360009997,1 +40545,360009255,360006211,1 +40362,360009255,360006920,1 +40306,360009330,1540809995,1 +40547,360009330,1540810102,1 +40307,360009333,1540809997,1 +115286,360009333,1540874448,1 +40548,360009421,360009422,1 +115277,360009421,1540874443,1 +40549,360009422,981693507,1 +115281,360009422,1540874446,1 +40128,360009517,360009519,1 +40129,360009519,360009520,1 +40550,360009519,1540810104,1 +40130,360009520,360009591,1 +40132,360009523,359996735,1 +40551,360009523,360009572,1 +40537,360009541,360009228,1 +40534,360009554,360009228,1 +40554,360009554,360009561,1 +40553,360009561,360009541,1 +40552,360009572,360009561,1 +40556,360009572,1540810110,1 +40131,360009591,360009523,1 +118608,360009643,359996734,1 +40558,360009643,1540810111,1 +40557,360009657,360009643,1 +40565,360009658,360009720,1 +40559,360009715,359996734,1 +40566,360009720,360009520,1 +40561,360009781,359996732,1 +40563,360009784,1025767698,1 +40567,360009784,1540810112,1 +40569,360009843,359996731,1 +40571,360009848,1540810115,1 +40486,360009853,1540810083,1 +40573,360009884,360009885,1 +118605,360009885,359996731,1 +40574,360009885,360009887,1 +40575,360009934,359996730,1 +40577,360009936,360009937,1 +118626,360009936,1025767708,1 +118621,360009937,1025767735,1 +40578,360009937,1540810121,1 +40529,360009988,360009226,1 +40579,360009988,360010009,1 +40543,360009997,360010050,1 +40580,360010009,360009997,1 +40581,360010009,360010035,1 +40582,360010035,360010036,1 +40583,360010035,360010050,1 +40544,360010050,1540810097,1 +40585,360010188,360006657,1 +40323,360010197,360006264,0 +40265,360010242,360005629,1 +40515,360010242,360006035,1 +40593,360010296,360005626,1 +40518,360010296,360009034,1 +40506,360010311,360008917,1 +40592,360010311,360010296,1 +105169,360010425,360014630,1 +40601,360010425,1540810129,1 +40602,360010440,360008371,1 +40981,360010440,360014630,1 +105168,360010537,360010425,1 +40618,360010537,1540810131,1 +105167,360010538,360010537,1 +40596,360010538,966653557,1 +40605,360010541,360010599,1 +111626,360010541,1540872129,1 +40612,360010599,360010797,1 +40606,360010599,536579356,1 +40595,360010600,360010538,1 +40610,360010600,360010647,1 +40607,360010644,360010645,1 +40984,360010644,1540810221,1 +40600,360010645,360010425,1 +40608,360010645,360010646,1 +40609,360010646,360010600,1 +40619,360010646,360010681,1 +40611,360010647,360010599,1 +40713,360010647,536579351,1 +40614,360010648,360010951,1 +110070,360010649,360010648,1 +111625,360010649,1540872126,1 +40617,360010675,360010537,1 +110072,360010675,1540871253,1 +105177,360010681,536579350,1 +112120,360010766,973983414,1 +40620,360010796,360010797,1 +40613,360010797,360010648,1 +111624,360010948,1540872123,1 +112067,360010948,1540872744,1 +112069,360010951,279591136,1 +40615,360010951,973983694,1 +40819,360011078,972316243,1 +124891,360011239,360011078,1 +64025,360011239,360012714,1 +124890,360011241,360011239,1 +124879,360011241,360012423,1 +40642,360011300,360011302,1 +71771,360011300,1540839004,1 +40735,360011302,360011361,1 +40643,360011302,575189658,1 +124936,360011306,360011308,1 +69864,360011306,1540838609,0 +124903,360011308,360011311,1 +111628,360011308,1540872135,1 +78908,360011311,1540841123,0 +40665,360011361,360011416,1 +40797,360011364,360012370,1 +40662,360011364,360013079,1 +40863,360011369,360012371,1 +40661,360011369,1540810139,1 +40666,360011416,1540810142,1 +111609,360011416,1540872109,1 +124920,360011578,360011579,1 +40918,360011578,360013476,1 +124921,360011579,360011580,1 +41053,360011579,360013239,1 +124922,360011580,360011581,1 +41016,360011580,360013675,1 +99524,360011581,360013678,1 +124923,360011581,360013970,1 +124926,360011585,360011586,1 +40691,360011585,966666250,1 +110091,360011586,360014627,1 +110094,360011586,1540871263,1 +124927,360011586,1540883942,1 +40465,360011588,360014629,1 +40278,360011597,360004934,1 +40690,360011597,1540810155,1 +40694,360011644,360011645,1 +40658,360011644,360011954,1 +78936,360011644,360011956,1 +40695,360011645,360011646,1 +40708,360011645,583433054,1 +40696,360011646,360011647,1 +95779,360011646,767358945,1 +40697,360011647,360011648,1 +40767,360011647,360012359,1 +40698,360011648,360011649,1 +78918,360011648,360012652,0 +40699,360011649,360011651,1 +118860,360011649,1540877998,1 +149649,360011651,966653599,1 +40700,360011651,1540810158,1 +40706,360011673,360012189,1 +40739,360011673,1030300203,1 +105166,360011675,360010538,1 +40712,360011675,360010647,1 +40693,360011680,360011644,1 +40660,360011952,360011369,1 +40738,360011952,360011673,1 +40659,360011954,360011952,1 +40747,360011954,360012193,1 +110093,360011956,966666270,1 +78937,360011956,1540841161,1 +78938,360011965,1540841167,1 +81016,360011969,583433054,0 +78939,360011969,1540841168,1 +40737,360012038,360011952,1 +40872,360012038,360012899,1 +40766,360012185,360011647,1 +40814,360012185,360012537,1 +40745,360012185,1540810162,1 +40707,360012189,360011645,1 +40746,360012189,1540810163,1 +40871,360012193,360012038,1 +40761,360012348,360012350,1 +111610,360012348,972315570,1 +40762,360012350,360012352,1 +40837,360012350,360012650,1 +40763,360012352,360012354,1 +40799,360012352,360012415,1 +40865,360012354,360012651,1 +40764,360012354,1030300203,1 +81019,360012359,360012652,0 +40768,360012359,1030300201,1 +40798,360012370,360012352,1 +40704,360012370,360012371,1 +40705,360012371,360011673,1 +40864,360012371,360012354,1 +40800,360012415,360012416,1 +118856,360012415,1030300217,1 +40801,360012416,360012417,1 +78913,360012416,1030300217,0 +40802,360012417,360012418,1 +40844,360012417,360012746,1 +40803,360012418,360012419,1 +149645,360012418,360012817,1 +124889,360012419,360011241,1 +40804,360012419,360012420,1 +124895,360012420,360012423,1 +124896,360012423,360012424,1 +124880,360012423,1540883926,1 +64024,360012424,360011239,1 +124915,360012424,1540883938,1 +124888,360012479,360012419,1 +124908,360012479,1113195801,1 +40841,360012483,536600579,1 +111692,360012483,972316169,1 +124887,360012483,1540883930,1 +111616,360012485,972315425,1 +111803,360012487,972315231,1 +71748,360012487,1540838992,1 +78917,360012537,360011648,0 +40815,360012537,360012538,1 +118859,360012538,360011649,1 +40816,360012538,1030300202,1 +149648,360012539,360011651,1 +40818,360012539,1540810177,1 +78910,360012649,972315570,0 +124885,360012649,1540883928,0 +78912,360012650,360012416,0 +40838,360012650,360012661,1 +40866,360012651,360012833,1 +78915,360012651,1030300209,0 +78919,360012652,1540841134,0 +81020,360012652,1540844161,0 +40843,360012661,360012417,1 +40839,360012661,360012663,1 +149644,360012663,360012418,1 +124907,360012663,360012479,1 +64026,360012714,1540833570,1 +149647,360012714,1540952667,1 +112109,360012718,973983399,1 +40846,360012742,360012833,1 +118854,360012743,966653599,1 +40845,360012746,360012742,1 +124877,360012746,360012817,1 +124878,360012817,360011241,1 +149646,360012817,360012714,1 +124881,360012820,360012822,1 +64017,360012820,583433337,1 +124882,360012822,1030300207,1 +110076,360012824,966653508,1 +40867,360012833,360012912,1 +40847,360012833,1540810180,1 +40862,360012899,1540810183,1 +40873,360012899,1540810186,1 +40875,360013062,360013063,1 +40876,360013063,360013064,1 +40878,360013063,360013165,1 +40877,360013064,360011300,1 +40663,360013079,1540810141,1 +40879,360013165,360013079,1 +40835,360013165,360013175,1 +40664,360013175,360011361,1 +40836,360013175,360012350,1 +41054,360013239,360013064,1 +40925,360013239,360013675,1 +41052,360013240,360011579,1 +40904,360013240,360013432,1 +40897,360013423,360013425,1 +71824,360013423,536600905,1 +40898,360013425,575189660,1 +71812,360013425,1540839017,1 +71805,360013428,575189652,1 +40900,360013428,1113233855,1 +40917,360013431,360011578,1 +40903,360013431,360013240,1 +41015,360013432,360011580,1 +40905,360013432,360013940,1 +40907,360013433,360005228,1 +40949,360013433,360013970,1 +40924,360013476,360013239,1 +71806,360013476,1113233852,1 +40919,360013476,1540810201,1 +40641,360013486,360011300,1 +124940,360013486,1540883947,1 +41017,360013675,360013062,1 +40926,360013675,360013678,1 +99525,360013678,360013769,1 +40927,360013678,1540810203,1 +40874,360013769,1540810188,1 +99522,360013939,360013940,1 +40281,360013939,360014097,1 +99523,360013940,360011581,1 +40906,360013940,360013433,1 +124924,360013970,360005229,1 +40282,360014097,360005637,1 +41014,360014097,360013432,1 +40284,360014162,360005638,1 +40961,360014162,1540810213,1 +40916,360014313,360013431,1 +40979,360014627,1540810218,1 +110092,360014627,1540871260,1 +40980,360014629,360010440,1 +40466,360014629,1540810072,1 +40982,360014630,360014631,1 +105161,360014631,932361985,1 +40983,360014631,1540810220,1 +40450,360014969,932361985,0 +99517,360015125,360015126,1 +99518,360015126,360015127,1 +69876,360015126,528490597,1 +99519,360015127,360015128,1 +41002,360015127,360015156,1 +99520,360015128,360015129,1 +99512,360015128,360015231,1 +41028,360015129,360004887,1 +99521,360015129,360013939,1 +41001,360015143,360015127,1 +97622,360015143,360015400,1 +41048,360015144,360015154,1 +41004,360015144,360015303,1 +41049,360015154,360015254,1 +99514,360015154,360015282,1 +41003,360015156,360015144,1 +41011,360015156,360015231,1 +99513,360015231,360015154,1 +41012,360015231,360015232,1 +41013,360015232,360014097,1 +41027,360015232,360015129,1 +41025,360015253,360015254,1 +41040,360015253,1540810228,0 +41050,360015254,360005637,1 +41026,360015254,360015232,1 +41039,360015282,360015253,0 +41038,360015303,360015282,0 +40277,360015394,360011597,1 +41005,360015394,1540810224,1 +41006,360015396,1540810225,1 +99510,360015400,1540862159,1 +99511,360015403,360015128,1 +41097,360015510,360015806,1 +108186,360015510,961664543,1 +2266,360015510,1540771784,1 +96756,360015806,1540859765,1 +96758,360015806,1540859771,1 +107728,360015812,1540869407,1 +107726,360015818,1015274270,1 +107729,360015818,1540869410,0 +107724,360015820,1540869400,0 +107741,360015820,1540869446,0 +107738,360015837,512543974,1 +65121,360015838,1540835019,1 +98698,360015847,961664464,1 +51658,360015847,1540816130,1 +98719,360016036,1540861552,0 +98737,360016038,800150275,1 +98738,360016038,1540861582,1 +41125,360016242,360016243,1 +99452,360016242,1540862125,1 +41126,360016243,801467949,1 +41128,360016244,360016245,1 +99503,360016244,1540862153,1 +99460,360016245,801467971,1 +41129,360016245,801468012,1 +99485,360016247,801480001,1 +41131,360016247,1540810249,1 +41133,360016249,360016250,1 +99474,360016249,801480004,1 +41134,360016250,360005634,1 +108188,360016390,956787111,1 +2268,360016390,1540771786,1 +2269,360016392,360016393,1 +108607,360016392,1540870083,1 +108655,360016393,961664431,1 +2270,360016393,1540771787,1 +108608,360016395,1540870086,1 +110167,360018879,360019570,1 +41191,360018879,1540810272,1 +75317,360019192,558969704,1 +41176,360019192,1540810262,1 +75339,360019195,558969677,1 +41177,360019195,1540810264,1 +41179,360019197,360019198,1 +75315,360019197,1540840130,1 +75312,360019198,558969627,1 +75313,360019198,558969635,1 +41180,360019198,558969639,1 +41182,360019201,536580314,1 +41184,360019414,967331693,1 +97566,360019414,1540860165,1 +110176,360019418,967240511,0 +110242,360019418,1540871352,1 +110243,360019427,575187220,1 +110224,360019427,1540871341,1 +110245,360019429,360019431,1 +110124,360019429,967199670,1 +110246,360019431,1382818844,1 +110146,360019431,1540871291,1 +110248,360019433,360019434,1 +41225,360019434,360019760,1 +110249,360019434,1540871358,1 +71699,360019438,1540838982,1 +71698,360019460,360019438,1 +41187,360019460,1540810270,1 +41194,360019461,360019567,1 +41190,360019461,1540810271,1 +110161,360019567,967199431,1 +41195,360019567,1540810278,1 +41196,360019570,360019571,1 +110149,360019571,967199595,1 +41197,360019571,1540810279,1 +41211,360019574,966279531,1 +41213,360019602,966278600,1 +109853,360019602,967199582,1 +73616,360019603,967199661,1 +71696,360019718,967199509,1 +71695,360019719,360019718,1 +73625,360019721,967240665,1 +71693,360019721,1540838981,1 +71692,360019722,360019721,1 +41235,360019724,360019881,1 +71689,360019724,1540838980,1 +110281,360019727,967331663,1 +71688,360019727,1540838979,1 +71687,360019730,1540838977,1 +71686,360019732,1540838976,1 +110137,360019732,1540871286,1 +41227,360019759,360019760,1 +110250,360019759,1540871359,1 +41228,360019760,360019773,1 +41226,360019760,1540810290,1 +41230,360019773,360019791,1 +41229,360019773,1540810291,1 +71694,360019791,360019719,1 +41242,360019812,967240833,1 +41231,360019812,1540810292,1 +41232,360019822,360019823,1 +41244,360019822,967240594,1 +71690,360019823,967331615,1 +41233,360019841,360019842,1 +41246,360019841,360019970,1 +41234,360019842,360019724,1 +41240,360019842,1540810296,1 +41249,360019863,360019730,1 +41236,360019881,360019882,1 +41237,360019882,967331635,1 +110290,360019882,1540871374,1 +41239,360019884,1540810294,1 +41241,360019968,360019812,1 +73627,360019968,967241101,1 +110252,360019970,967240535,1 +41247,360019970,1540810300,1 +41248,360019972,1540810301,1 +41203,360020007,1540810285,1 +41251,360020007,1540810306,1 +109828,360020008,363984897,1 +41206,360020008,1540810286,1 +41208,360020010,360020011,1 +110104,360020010,967199395,1 +109885,360020011,1540871128,1 +41216,360020043,967199650,1 +41250,360020043,1540810305,1 +17594,360022641,273143897,1 +41368,360022641,360022642,1 +46157,360024126,1540812423,1 +44846,360189243,360189244,1 +44847,360189243,1540811884,1 +44850,360189244,1540811886,1 +44848,360189339,1540811885,1 +64012,360189339,1540833557,1 +111795,360189339,1540872203,1 +44849,360189342,360189343,1 +64014,360189342,418771177,1 +53888,360189343,1540820543,1 +44851,360189449,1540811888,1 +64015,360189449,1540833563,1 +44857,360189453,360189540,1 +44852,360189453,1540811890,1 +44856,360189460,418771211,1 +44855,360189540,360189460,1 +44858,360189540,360189631,1 +110061,360189542,360189543,1 +53899,360189543,363973753,1 +44859,360189631,360189632,1 +73612,360189632,418771207,1 +44860,360189632,972481783,1 +73545,360189633,576508600,1 +44862,360189633,1540811896,1 +111865,360189635,972481932,1 +44863,360189635,1540811897,1 +73602,360189871,549791283,1 +73605,360189872,360190150,1 +44867,360189872,972482009,1 +44882,360189873,549791271,1 +73608,360189873,1540839713,1 +73609,360189874,972481624,1 +73525,360189874,972481803,1 +73611,360189875,360189632,1 +64041,360189875,972481797,1 +44869,360190107,972481750,1 +111811,360190107,1540872216,1 +44871,360190108,360190109,1 +111629,360190108,972315846,1 +44872,360190109,360190111,1 +111598,360190109,972315887,1 +111685,360190111,972316198,1 +44873,360190150,360190246,1 +73606,360190150,549791277,1 +44874,360190246,972315604,1 +44876,360190246,1540811908,1 +111587,360190247,1540872102,1 +44879,360190380,583433293,1 +44881,360190664,360189873,1 +81028,360190664,583433288,1 +73542,360190665,549787375,1 +44885,360190665,549791302,1 +73600,360190667,600396750,1 +44888,360190667,600396751,1 +44890,360190668,360190669,1 +44891,360190669,973983407,1 +44894,360190670,973983396,1 +44899,360190670,1540811914,1 +44898,360190671,1540811912,1 +44900,360190684,360190711,1 +44903,360190684,360190871,1 +44902,360190711,360190738,1 +44893,360190738,360190670,1 +44907,360190819,360190835,1 +44905,360190819,1540811916,1 +44916,360190821,1540811919,1 +44908,360190835,360190671,1 +44910,360190835,360190869,1 +44897,360190868,360190671,1 +44909,360190868,360190835,1 +44915,360190869,360190821,1 +44920,360190869,360191085,1 +45648,360190871,360190887,1 +44904,360190871,1540811915,1 +44896,360190887,360190868,1 +44912,360190895,360190929,1 +44906,360190895,1540811917,1 +44911,360190928,360190895,1 +44917,360190928,972481981,1 +45647,360190929,1540812122,1 +111889,360190999,972481982,0 +44913,360190999,1540811918,1 +44914,360191001,360190869,1 +44926,360191001,1540811922,1 +53803,360191004,1540820479,1 +111847,360191004,1540872277,1 +44921,360191085,279591666,1 +44927,360191085,360191193,1 +44944,360191086,279591665,1 +44929,360191086,360191087,1 +44930,360191087,360191088,1 +44935,360191087,972481914,1 +44931,360191088,360191089,1 +44967,360191088,972481613,1 +142519,360191089,360191090,1 +45602,360191089,1540812087,1 +45045,360191090,279591660,1 +142520,360191090,360193780,1 +44958,360191121,360191192,1 +44942,360191121,360194867,1 +45068,360191192,360191193,1 +44959,360191192,1540811926,1 +44928,360191193,360191086,1 +45069,360191193,360191195,1 +111893,360191195,279591665,0 +45070,360191195,972481858,1 +45084,360191196,360191240,1 +45074,360191196,360191253,1 +44949,360191240,360191241,1 +45085,360191240,360191411,1 +44950,360191241,360191242,1 +44962,360191241,1540811927,1 +44951,360191242,360192132,1 +44976,360191242,1540811928,1 +44961,360191253,360191241,1 +45075,360191253,360191535,1 +44973,360191297,360191533,1 +45605,360191384,360191564,1 +45088,360191384,360193230,1 +44972,360191385,360191297,1 +45087,360191385,360191384,1 +45083,360191386,360191196,1 +44925,360191386,360194966,1 +45082,360191387,360191386,1 +152327,360191387,360195049,1 +45081,360191388,360191387,1 +111990,360191388,360195050,1 +45086,360191411,360191385,1 +44940,360191411,360191413,1 +44963,360191413,360191297,1 +44941,360191413,360191414,1 +44975,360191414,360191242,1 +45000,360191414,360192121,1 +44974,360191533,360191414,1 +44978,360191533,1540811929,1 +45026,360191533,1540811939,1 +44977,360191535,360191536,1 +152331,360191536,279591769,1 +45606,360191564,360191585,1 +45607,360191585,360191586,1 +21474,360191585,360192258,1 +44979,360191586,360191652,0 +45608,360191586,1540812089,1 +44980,360191652,360204881,0 +45030,360191652,1540811941,1 +44982,360191654,360191705,1 +135254,360191654,1030323853,0 +118872,360191655,360204929,1 +44988,360191655,1540811932,1 +135250,360191655,1540905613,1 +45054,360191657,360191826,1 +135251,360191657,1030323791,1 +135238,360191658,1540905606,0 +44983,360191705,360191706,1 +44990,360191705,360193014,1 +45056,360191706,360193007,1 +45055,360191826,360191706,1 +44985,360191826,360204680,1 +44989,360191909,360191705,1 +44984,360191909,1540811931,1 +135240,360191911,1030323776,0 +44998,360191958,360192139,1 +45003,360191958,1540811936,1 +152333,360191959,360196238,1 +45001,360192121,360192122,1 +21476,360192121,360192132,1 +45002,360192122,360191958,1 +45008,360192122,360192175,1 +152321,360192126,360196645,1 +44952,360192132,360192175,1 +21477,360192132,1540791000,1 +44999,360192139,360191959,1 +45609,360192174,360192222,1 +45005,360192174,360192439,1 +44953,360192175,360192139,1 +44994,360192222,360192492,1 +45610,360192222,360193010,1 +45015,360192247,360192304,1 +45542,360192247,1540812066,1 +21475,360192258,360192121,1 +45009,360192258,360192264,1 +45007,360192264,360192122,1 +45010,360192264,360192268,1 +44996,360192268,360192414,1 +45011,360192268,360192436,1 +45013,360192303,360192304,1 +45020,360192303,360192389,1 +45014,360192304,360192306,1 +45016,360192304,360192407,1 +152324,360192306,360196620,1 +45004,360192310,360192126,1 +45018,360192310,360192313,1 +152320,360192313,360192126,1 +45019,360192385,360192303,1 +45023,360192385,360192407,1 +45612,360192389,360192247,1 +45017,360192407,360192310,1 +44997,360192414,360191958,1 +45021,360192414,360192418,1 +45022,360192418,360192385,1 +45024,360192418,360192436,1 +45012,360192436,360192303,1 +45006,360192439,360192264,1 +45025,360192439,1540811938,1 +44995,360192492,360192268,1 +44993,360192594,360192222,1 +45031,360192594,360192885,1 +135264,360192885,360204834,1 +45057,360193007,360193008,1 +118982,360193007,1540878074,1 +135266,360193008,360193009,1 +45032,360193008,360193014,1 +45554,360193009,360204792,1 +135262,360193009,360204872,1 +45611,360193010,360192389,1 +45033,360193014,360193041,1 +44991,360193014,360204865,1 +135253,360193041,360191654,0 +135256,360193041,360193212,1 +45091,360193042,360193070,1 +45034,360193070,360193315,1 +45092,360193070,360205161,1 +118898,360193110,360205112,1 +45094,360193110,1540811949,1 +45027,360193153,360193155,1 +21472,360193153,1540790998,1 +45028,360193155,360193157,1 +45038,360193155,360193175,1 +45043,360193157,279591766,1 +45029,360193157,360191652,1 +45039,360193175,360193181,1 +135258,360193175,360193314,1 +45040,360193181,360193189,1 +45036,360193181,360193211,1 +118896,360193189,360193316,1 +45037,360193211,360191654,1 +45041,360193211,360193212,1 +45042,360193212,360193157,1 +135257,360193212,360193175,1 +45089,360193230,279591764,1 +45047,360193230,360193235,1 +21471,360193235,360193153,1 +45048,360193235,360193312,1 +142521,360193312,360193314,1 +135259,360193314,360193042,1 +142522,360193314,360193315,1 +45035,360193315,360193181,1 +142523,360193315,360193316,1 +118897,360193316,360193110,1 +142524,360193316,1540934708,1 +142526,360193318,360193319,1 +45573,360193318,360204928,1 +142527,360193319,360193320,1 +45052,360193319,360204942,1 +118911,360193320,1540878029,0 +45049,360193341,1540811947,1 +118876,360193341,1540878016,1 +45588,360193343,360193611,1 +45050,360193343,360205150,1 +45589,360193611,360205038,1 +45571,360193611,360205148,1 +118907,360193613,1030323792,0 +45587,360193613,1540812075,1 +45067,360193671,279591658,1 +45628,360194052,1540812111,1 +45643,360194052,1540812119,1 +45615,360194055,360205443,1 +45627,360194055,1540812110,1 +45599,360194057,360194926,1 +111828,360194057,1540872270,1 +45601,360194059,360191089,1 +44964,360194109,360194110,1 +111848,360194109,1540872278,1 +44965,360194110,360194111,1 +44956,360194110,360194178,1 +44966,360194111,360191088,1 +45078,360194111,360194925,1 +44919,360194177,1540811921,1 +44932,360194177,1540811923,1 +44957,360194178,360191121,1 +44933,360194178,360194179,1 +44934,360194179,360191087,1 +45077,360194179,360194111,1 +44954,360194250,360194251,1 +45597,360194250,1540812080,1 +44955,360194251,1540811925,1 +44943,360194867,360191086,1 +45076,360194867,360194179,1 +45079,360194925,360194926,1 +111857,360194925,1540872300,1 +45600,360194926,360194059,1 +152329,360194966,360195005,1 +44960,360195005,360191253,1 +152330,360195005,360191536,1 +152328,360195049,360194966,1 +45080,360195049,360195050,1 +111991,360195050,360195083,1 +111992,360195083,279592064,1 +45099,360195083,360222347,1 +111989,360195141,360191388,1 +21521,360195141,1540791059,0 +111988,360195142,360195141,1 +21528,360195142,1540791061,0 +45098,360195248,360195083,1 +79040,360195248,1540841177,1 +21508,360195249,279591857,0 +45102,360195249,360222888,1 +46109,360195249,360223131,1 +111987,360195552,360195142,1 +111840,360195555,360215957,1 +111986,360195555,1540872599,1 +83912,360195557,1540846746,1 +111985,360195557,1540872598,1 +111846,360195687,360195843,1 +45105,360195687,360221715,1 +104702,360195690,360195691,1 +45107,360195690,360216881,1 +104703,360195691,360216896,1 +45958,360195691,1540812273,1 +109048,360195843,1540870354,1 +45106,360195888,360195690,1 +45939,360195888,1540812254,1 +21505,360196122,279591977,1 +104708,360196122,360196123,1 +104709,360196123,360196124,1 +29747,360196123,913523106,1 +45917,360196124,360213895,1 +45109,360196238,360196239,1 +152334,360196238,360223361,1 +45110,360196239,360196240,1 +21488,360196239,600397449,1 +45257,360196240,360196431,1 +29742,360196300,360219408,1 +79052,360196300,1540841197,1 +29744,360196301,360196302,1 +45123,360196301,360196428,1 +29745,360196302,360196303,1 +45819,360196302,360196478,1 +29746,360196303,360196123,1 +45115,360196303,360196426,1 +104749,360196426,360213895,1 +104747,360196428,360196478,1 +45124,360196428,360196534,1 +104746,360196429,360196428,1 +45228,360196429,360198849,1 +45220,360196430,360198698,1 +104744,360196430,360199227,1 +45258,360196431,360198914,1 +104742,360196431,360199205,1 +104740,360196432,360198954,1 +21490,360196432,360223375,1 +104748,360196478,360196426,1 +45820,360196478,360196479,1 +45821,360196479,360196481,1 +45237,360196479,360198874,1 +45908,360196481,360196507,1 +45909,360196507,360196537,1 +45116,360196507,1540811951,1 +45118,360196509,360196510,1 +45222,360196509,360196613,1 +45119,360196510,360196511,1 +45260,360196510,360196827,1 +45241,360196511,360196617,1 +45120,360196511,360196644,1 +152323,360196512,1540962694,1 +21502,360196515,279591975,1 +45122,360196515,360196301,1 +45236,360196534,360196479,1 +45125,360196534,360198850,1 +45117,360196535,360196509,1 +45127,360196535,360196537,1 +45910,360196537,360196612,1 +45148,360196612,360196613,1 +45911,360196612,360213989,1 +45223,360196613,360200293,1 +45149,360196613,1540811952,1 +45151,360196617,360196619,1 +45242,360196617,360200315,1 +45152,360196619,360196620,1 +45131,360196619,360196644,1 +152325,360196620,279591918,1 +45121,360196644,360196512,1 +45132,360196644,360196645,1 +152322,360196645,360196512,1 +45245,360196732,360196733,1 +45846,360196732,360198635,1 +45246,360196733,360196734,1 +45135,360196733,360196805,1 +104737,360196734,360196805,1 +45247,360196734,360197080,1 +45249,360196736,360196737,1 +45302,360196736,360199520,1 +45250,360196737,360196738,1 +45300,360196737,360199436,1 +45298,360196738,360197261,1 +45251,360196738,360199803,1 +45133,360196803,360196850,1 +45921,360196803,360197077,1 +45136,360196805,360196806,1 +104738,360196805,360200219,1 +45280,360196806,360197082,1 +45137,360196806,360199270,1 +45261,360196827,360200314,1 +45150,360196827,1540811953,1 +45134,360196850,360196733,1 +45265,360196850,360196892,1 +45141,360196892,360197078,1 +45140,360197077,360196892,1 +45922,360197077,1540812240,1 +104736,360197078,360196734,1 +45142,360197078,360197080,1 +45248,360197080,360196736,1 +45143,360197080,360197082,1 +45144,360197082,360197083,1 +45281,360197082,360199519,1 +45145,360197083,360203509,1 +45332,360197083,1540812003,1 +45147,360197085,360197086,1 +45333,360197085,360200379,1 +45275,360197086,360203410,1 +45303,360197259,918272749,1 +45305,360197260,360199495,1 +45307,360197261,360199800,1 +45930,360197433,360197730,1 +45931,360197730,360197731,1 +45164,360197730,360198322,1 +45153,360197731,360198332,1 +45932,360197731,1540812242,1 +45933,360197739,1540812249,1 +45155,360197956,1540811954,1 +45157,360197965,360198122,1 +45866,360197965,360198320,1 +45173,360197978,360197956,1 +45168,360198003,360233907,1 +45179,360198004,360198192,1 +45170,360198004,360233954,1 +45176,360198121,360198122,1 +45865,360198121,1540812199,1 +45177,360198122,360198123,1 +45158,360198122,360233910,1 +45178,360198123,360198004,1 +45198,360198123,360234085,1 +45927,360198189,360198190,1 +45838,360198189,360212448,1 +45167,360198190,360198003,1 +45928,360198190,1540812241,1 +45929,360198192,360197433,1 +45903,360198245,360198003,1 +45196,360198245,360233827,1 +45902,360198246,360198245,1 +45160,360198246,360212471,1 +45864,360198247,360198121,1 +45901,360198247,360198246,1 +45900,360198248,360198247,1 +45870,360198248,360213096,1 +45878,360198248,360213207,1 +45899,360198249,360198248,1 +45174,360198249,1540811959,1 +45867,360198320,360198321,1 +45200,360198320,360198456,1 +45172,360198321,360197978,1 +45868,360198321,360198353,1 +45165,360198322,360198352,1 +45154,360198332,360197956,1 +45191,360198332,360198352,1 +45166,360198352,360197978,1 +45192,360198352,360198353,1 +45869,360198353,360198322,1 +45202,360198455,360212499,1 +45193,360198455,360212623,1 +45156,360198456,1540811955,1 +45201,360198504,360198455,1 +45208,360198504,360200289,1 +45920,360198530,360196803,1 +45210,360198547,360198530,1 +45844,360198547,360198634,1 +45845,360198634,360196732,1 +45264,360198634,360196850,1 +45317,360198635,1540811999,1 +45219,360198697,360196430,1 +45226,360198697,360199226,1 +45221,360198698,360196509,1 +45234,360198698,360198849,1 +45225,360198847,360198697,1 +79051,360198847,1540841195,1 +45235,360198849,360196534,1 +45229,360198849,360198850,1 +45230,360198850,360196507,1 +45126,360198850,360196535,1 +45907,360198874,360196481,1 +152319,360198912,360192313,1 +45231,360198912,360198913,1 +45240,360198913,360196511,1 +45232,360198913,360198914,1 +45259,360198914,360196510,1 +45233,360198914,360198698,1 +104741,360198954,360196431,1 +45239,360198954,360198913,1 +45253,360198977,360198978,1 +79050,360198977,1540841192,1 +45267,360198978,360199205,1 +45254,360198978,1540811968,1 +45256,360199069,360196240,1 +79049,360199117,1540841190,1 +104743,360199205,360196430,1 +45227,360199226,360196429,1 +45270,360199226,360199227,1 +104745,360199227,360196429,1 +45313,360199245,1540811992,1 +45331,360199270,360197083,1 +45138,360199270,360199271,1 +45139,360199271,360199272,1 +45495,360199271,360203509,1 +45272,360199272,360199280,1 +45273,360199272,360203344,1 +45513,360199280,1540812045,1 +45337,360199327,360200379,1 +45278,360199327,1540811971,1 +45279,360199435,360196806,1 +45315,360199435,1540811996,1 +45283,360199436,360199438,1 +45297,360199438,360196738,1 +45284,360199438,360199439,1 +45285,360199439,360203097,1 +45311,360199439,1540811990,1 +46215,360199440,360235010,1 +45287,360199440,1540811972,1 +45299,360199495,360196737,1 +45306,360199495,360197261,1 +45301,360199519,360196736,1 +45282,360199519,360199436,1 +104735,360199520,360197078,1 +45310,360199588,1540811989,0 +45309,360199663,1540811988,0 +45308,360199800,1540811987,1 +45252,360199803,360199800,1 +45312,360199803,360199843,1 +45291,360200086,1540811978,1 +46235,360200098,360237078,1 +45295,360200098,1540811986,1 +45296,360200101,155867041,1 +76169,360200101,560944982,1 +45319,360200214,360200255,1 +45314,360200214,1540811993,1 +45316,360200219,1540811998,1 +45128,360200223,360200286,1 +45318,360200223,1540812001,1 +45329,360200255,360204120,1 +45320,360200258,360200286,1 +21497,360200258,1540791043,1 +45321,360200286,360200287,1 +45129,360200286,360200317,1 +45244,360200287,360196732,1 +45322,360200287,360200288,1 +45263,360200288,360198634,1 +45323,360200288,360200289,1 +45209,360200289,360198547,1 +45224,360200293,360198504,1 +45324,360200293,360200314,1 +45262,360200314,360200288,1 +45325,360200314,360200315,1 +45243,360200315,360200287,1 +45326,360200315,360200317,1 +45130,360200317,360196619,1 +45327,360200317,360200318,1 +21498,360200318,1540791044,1 +45338,360200379,360199436,1 +45334,360200444,360200445,1 +45434,360200444,360202924,0 +45472,360200445,360203093,1 +45335,360200445,1540812004,1 +45340,360200485,360200486,1 +45341,360200486,1540812006,1 +45288,360200488,1540811974,1 +2732,360200591,1540773175,0 +45289,360200591,1540811975,1 +2733,360200612,360201192,0 +83882,360200612,1540846671,0 +45343,360200725,360201148,0 +45290,360200725,1540811976,1 +83883,360200740,360200612,1 +45344,360200740,360201148,0 +45345,360200740,1540812007,0 +2647,360200750,1540772367,0 +46238,360200750,1540812504,1 +83874,360200750,1540846650,1 +2804,360201148,1540773389,0 +2731,360201192,360200591,0 +81435,360201192,360201148,1 +45342,360201218,360200725,0 +45346,360201218,360201316,1 +45347,360201316,1540812008,1 +45357,360201316,1540812012,1 +45339,360201318,1540812005,1 +45348,360201318,1540812009,1 +45366,360201319,360201628,1 +45349,360201319,360202166,1 +135236,360201321,360201853,1 +45351,360201321,1540812010,1 +45352,360201323,1030974504,1 +45408,360201323,1030975228,1 +45354,360201324,1030975482,1 +119437,360201324,1030975489,1 +142528,360201326,1540934709,1 +45358,360201420,360203006,1 +45438,360201420,360203120,0 +45360,360201460,360202152,1 +45363,360201460,1540812015,1 +45364,360201490,360203051,1 +119370,360201490,1540878856,1 +45367,360201628,360201629,1 +45370,360201628,1540812018,1 +45368,360201629,360201630,1 +45369,360201629,360201639,1 +45373,360201630,360201677,1 +45372,360201639,360201677,1 +45371,360201676,360201639,1 +119360,360201676,360201853,1 +45374,360201677,360201708,1 +46216,360201708,360235260,1 +45375,360201708,1030975499,1 +45378,360201709,360201710,1 +45379,360201710,1030974753,1 +45527,360201847,1030323795,1 +45384,360201847,1540812023,1 +45385,360201850,360203947,1 +119361,360201853,1030974448,1 +135237,360201853,1540905605,1 +45393,360201910,360201911,1 +45395,360201911,360203708,1 +45394,360201911,1540812026,1 +83857,360201912,360203788,1 +45400,360201919,1030974515,1 +45397,360201942,360201943,1 +45391,360201942,360202111,1 +45404,360201943,1030975238,1 +45398,360201943,1030975397,1 +45403,360201944,1540812027,1 +45410,360202039,360202041,1 +119443,360202039,1030975352,1 +45411,360202041,360201709,1 +45412,360202052,360202107,0 +45436,360202052,360203239,0 +45413,360202107,360202109,0 +45467,360202107,360203006,1 +45414,360202109,360202137,0 +45456,360202109,1540812034,1 +135232,360202111,1030974544,1 +135235,360202117,360201321,1 +45416,360202117,1540812029,1 +135234,360202135,360202117,1 +45415,360202137,360202111,0 +45417,360202137,360202814,1 +45362,360202146,360202135,1 +45361,360202152,360202146,1 +45419,360202152,360202166,1 +45350,360202166,360201321,1 +45420,360202276,360202277,1 +45431,360202276,360203296,0 +45453,360202277,360202804,1 +45421,360202277,1540812030,1 +45389,360202278,360203626,1 +45392,360202278,1540812025,1 +45423,360202501,360202502,0 +118985,360202501,1030323801,1 +45424,360202502,360202504,0 +45441,360202502,360202578,1 +45425,360202504,360202506,0 +45426,360202506,360202509,0 +45427,360202509,360203254,0 +45491,360202509,360203398,1 +45442,360202578,360202579,1 +45450,360202579,360202609,1 +45443,360202579,1030323768,1 +45445,360202580,360201850,1 +45446,360202580,1540812031,1 +45451,360202609,360202610,1 +45447,360202609,1030323708,1 +45452,360202610,360202277,1 +45459,360202610,360202618,1 +45388,360202618,360202278,1 +45460,360202618,360203784,1 +45465,360202804,360202850,1 +45454,360202804,360202889,1 +45418,360202814,360202146,1 +45433,360202850,360200444,0 +45455,360202889,360202109,1 +45466,360202889,360202924,1 +45435,360202924,360202052,0 +45359,360203006,360201460,1 +45365,360203051,1540812016,1 +45468,360203051,1540812035,1 +45440,360203053,360200485,0 +45473,360203093,360203094,1 +45478,360203093,1540812039,1 +45475,360203094,360203117,1 +45474,360203094,1540812036,1 +45286,360203097,360199440,1 +45476,360203117,360203120,1 +45477,360203117,1540812038,1 +45439,360203120,360203053,0 +45437,360203239,360201420,0 +45481,360203248,360203254,1 +45469,360203248,360203336,1 +45428,360203254,360203547,0 +45277,360203271,360199327,1 +45479,360203271,360203272,1 +45480,360203272,360203248,1 +45482,360203272,1540812040,1 +45336,360203285,360199327,1 +45471,360203287,360200445,1 +45483,360203287,360203296,1 +45432,360203296,360202850,0 +45430,360203299,360202276,0 +45484,360203299,360203336,1 +45470,360203336,360203287,1 +45485,360203344,360203356,1 +45274,360203344,1540811970,1 +45486,360203356,360203357,1 +45487,360203357,360202504,1 +45488,360203357,360203377,1 +45489,360203377,1540812041,1 +45490,360203377,1540812042,1 +45493,360203379,1540812043,1 +45492,360203398,360203379,1 +45276,360203410,360203271,1 +45494,360203508,360199271,1 +45511,360203508,1030323830,1 +45146,360203509,360197085,1 +45429,360203547,360203299,0 +45457,360203547,1030323808,1 +45449,360203555,360202506,1 +45496,360203555,360203617,1 +45390,360203626,360201942,1 +45498,360203626,360203654,1 +45499,360203654,360202137,1 +45396,360203708,360201919,1 +45497,360203708,1540812044,1 +45461,360203784,360203785,1 +45501,360203785,360201910,1 +45462,360203785,360203786,1 +45463,360203786,360203787,1 +45464,360203787,360203788,1 +83858,360203788,1030323833,1 +45502,360203835,360203784,1 +45507,360203835,360203947,1 +45503,360203933,1030323861,1 +83860,360203933,1060029297,1 +45505,360203940,360203943,1 +45508,360203940,1030323825,1 +45500,360203943,360203786,1 +45506,360203943,360203835,1 +45386,360203947,1030323851,1 +45330,360204120,360199270,1 +45510,360204120,360203508,1 +45514,360204332,1540812047,1 +45547,360204332,1540812069,1 +45422,360204339,360202501,0 +135243,360204341,360204437,0 +135242,360204350,360204341,0 +45518,360204350,1540812052,1 +45520,360204362,360202578,1 +45524,360204362,360204401,1 +45525,360204401,1540812055,1 +45526,360204402,360201847,1 +118961,360204402,1540878064,1 +45521,360204435,360204436,1 +45551,360204435,360204716,1 +45522,360204436,360204437,1 +45538,360204436,360204455,1 +135244,360204437,360204339,0 +45523,360204437,1540812054,1 +45539,360204455,360204456,1 +135261,360204455,360204585,1 +45541,360204456,360204494,1 +45540,360204456,1540812065,1 +45515,360204457,1540812050,1 +45553,360204494,1540812071,1 +45516,360204585,1030323801,1 +45546,360204671,1540812068,1 +45548,360204680,1030323735,1 +44986,360204680,1030323757,1 +135260,360204716,360204455,1 +45552,360204716,360204494,1 +45555,360204792,360204716,1 +45557,360204792,360204815,1 +45558,360204815,360204844,1 +45560,360204815,360204849,1 +135265,360204834,360193010,1 +45559,360204834,360204815,1 +45543,360204844,360204859,1 +45561,360204849,360204671,1 +45562,360204849,360204859,1 +45544,360204859,279591921,1 +44992,360204865,360192594,1 +45564,360204865,360204872,1 +135263,360204872,360192885,1 +44981,360204881,1540811930,0 +45563,360204881,1540812073,1 +45574,360204928,360204929,1 +45576,360204928,360204942,1 +118894,360204929,1030313211,1 +45053,360204942,360191657,1 +45577,360204942,360204943,1 +118913,360204943,360191658,0 +45569,360204997,360204998,1 +45581,360204998,360193341,1 +45570,360204998,360193611,1 +118900,360205015,279591654,1 +45578,360205015,1030313257,1 +45580,360205016,360204998,1 +45583,360205016,360205038,1 +45584,360205038,360205146,1 +45590,360205038,1030313215,1 +45586,360205039,360193189,1 +142525,360205039,360193318,1 +118899,360205112,360205015,1 +45585,360205146,360205039,1 +45095,360205146,360205148,1 +45572,360205148,360193318,1 +45096,360205148,360205150,1 +45051,360205150,360193319,1 +45097,360205150,1030323829,1 +45093,360205161,360193110,1 +45058,360205302,360205304,1 +93475,360205302,716888455,1 +45059,360205304,360205305,1 +93500,360205304,360205415,1 +93488,360205305,360205413,1 +45060,360205305,1540811948,1 +45063,360205311,278009538,1 +45066,360205320,360193671,1 +45638,360205320,1540812115,1 +45631,360205333,279591486,1 +45593,360205333,360205311,1 +45633,360205411,1540812112,1 +79045,360205411,1540841182,0 +93489,360205413,716888908,1 +45634,360205413,1540812113,1 +45635,360205415,360205417,1 +93501,360205415,716889049,1 +93469,360205417,1540856539,1 +45044,360205443,1540811942,1 +45616,360205443,1540812091,1 +21465,360205477,1540790994,1 +45617,360205519,360205618,0 +45613,360205519,1540812090,1 +111808,360205519,1540872214,1 +45614,360205522,360194055,1 +45645,360205522,360205718,1 +45641,360205618,360205718,1 +45618,360205618,1540812092,0 +45629,360205625,279591459,1 +45620,360205625,360205626,0 +45636,360205626,360205693,1 +45621,360205626,1540812097,0 +45622,360205629,279591653,0 +45065,360205629,360205320,1 +45637,360205693,1540812114,1 +45642,360205718,360194052,1 +45646,360205718,1540812121,1 +45644,360205801,360205522,1 +45598,360205801,1540812086,1 +45619,360205803,1540812096,0 +29732,360205869,279591415,1 +45639,360205869,1540812117,1 +45640,360205872,360205618,1 +21425,360205939,279589950,1 +45650,360205939,1030294074,1 +45652,360205940,338487319,1 +112291,360205940,974030859,1 +112289,360205943,974030875,1 +29735,360205943,1030294080,1 +45655,360206030,360206031,1 +112136,360206030,1540872806,1 +45659,360206031,360206057,1 +45656,360206031,1540812123,1 +45657,360206034,360206035,1 +45665,360206034,360206058,1 +21429,360206035,1387915847,1 +45658,360206035,1540812125,1 +149354,360206038,974030382,0 +111825,360206039,360206038,1 +112286,360206039,360206373,1 +112288,360206040,360205943,1 +45674,360206040,360206360,1 +45668,360206057,360206058,1 +45660,360206057,360206236,1 +45669,360206058,279589952,1 +45666,360206058,360206100,1 +45671,360206100,279589951,1 +45667,360206100,360206101,1 +93458,360206101,360206238,1 +45670,360206236,360206100,1 +45661,360206236,360206238,1 +93459,360206238,974030790,1 +45662,360206238,974066906,1 +93465,360206238,1540856536,1 +149357,360206315,279589950,0 +149350,360206360,338487217,1 +112287,360206373,360206040,1 +45675,360206373,360206478,1 +45677,360206842,360209695,1 +135206,360206842,974031208,0 +143840,360206846,360207557,0 +149322,360206846,1540951382,1 +45693,360206847,279591053,1 +143842,360206847,360206848,0 +143838,360206848,360206849,0 +135168,360206848,360207028,0 +143839,360206849,360206850,0 +45761,360206849,360207971,1 +142508,360206850,1540934702,1 +143896,360206850,1540937904,1 +143897,360206852,974066369,1 +112196,360206852,974066820,1 +45809,360206854,1291955947,1 +152602,360206854,1540963213,1 +152603,360206868,1291956623,1 +143862,360206870,360206871,1 +45743,360206870,1540812157,1 +143863,360206871,360206872,1 +112217,360206871,974066255,1 +112233,360206872,974066614,1 +45683,360207023,974066470,1 +135172,360207025,360207023,0 +45687,360207025,360207235,1 +135171,360207026,360207025,0 +45689,360207026,360207254,1 +45679,360207026,360207928,1 +135170,360207027,360207026,0 +45773,360207027,360208002,1 +135169,360207028,360207027,0 +45686,360207173,360207025,1 +45766,360207173,360207175,1 +45682,360207175,360207023,1 +45767,360207175,974066783,1 +45769,360207177,360207178,1 +112220,360207177,974066899,1 +45770,360207178,1540812169,1 +142518,360207182,974067028,1 +45681,360207196,360207175,1 +112222,360207196,1540872884,1 +45691,360207235,360207255,1 +45688,360207235,1540812134,1 +45692,360207254,360206847,1 +45690,360207254,360207235,1 +45695,360207363,360207364,1 +45730,360207363,360207609,1 +45696,360207364,360207365,1 +45725,360207364,360207555,1 +45697,360207365,279590303,1 +45712,360207365,360207511,1 +45699,360207366,360207368,1 +53862,360207366,360208994,1 +45700,360207368,279590087,1 +135157,360207368,360207421,0 +135158,360207421,279591060,0 +45702,360207421,360207471,1 +45703,360207471,279590300,1 +53861,360207471,1540820529,1 +45711,360207474,360207365,1 +45705,360207474,360207555,1 +149327,360207510,279589957,1 +45710,360207510,360207474,1 +45713,360207511,360207512,1 +135164,360207511,360207591,0 +45757,360207512,360207590,1 +45714,360207512,583434225,1 +45706,360207555,360207556,1 +45726,360207555,360207562,1 +45707,360207556,279591054,1 +45729,360207556,360207363,1 +143841,360207557,360206847,0 +45709,360207557,974066878,1 +149325,360207562,279589956,1 +45723,360207590,360207591,1 +45758,360207590,360207815,1 +45724,360207591,360207364,1 +135165,360207591,360207609,0 +135166,360207609,279591052,0 +45731,360207609,360207815,1 +45808,360207810,360209995,1 +45737,360207810,360210159,1 +45814,360207812,360210092,1 +45736,360207812,1540812150,1 +45734,360207813,279590362,1 +45802,360207813,1345509870,1 +45733,360207814,360207813,1 +45742,360207814,360207820,1 +45732,360207815,360207814,1 +45759,360207815,360207924,1 +45728,360207816,360207556,1 +149324,360207816,360207562,1 +143864,360207820,360206850,1 +143855,360207820,360207924,0 +143893,360207820,1540937898,0 +142510,360207867,360207868,1 +45748,360207867,974067410,1 +142511,360207868,974067575,1 +45765,360207888,360207173,1 +143856,360207924,279591052,0 +45760,360207924,360206849,1 +45764,360207928,360207888,1 +112218,360207928,1540872881,1 +45771,360207971,360207028,1 +45762,360207971,360208002,1 +45772,360207998,1540812172,1 +45763,360208002,1540812167,1 +45774,360208055,360208083,1 +45751,360208055,360208307,1 +45701,360208056,360208993,0 +45754,360208056,360209043,1 +45756,360208057,360207512,1 +135179,360208057,1540905573,1 +45775,360208083,360208084,1 +45778,360208083,360208107,0 +45776,360208084,360208085,1 +45785,360208084,360208306,1 +135154,360208085,360208587,1 +45779,360208107,360208109,0 +45783,360208107,360208307,1 +45780,360208109,360208492,0 +45792,360208109,360208521,1 +135153,360208304,360208085,1 +45781,360208304,360208306,1 +45782,360208306,360208107,1 +45786,360208306,360208375,1 +45752,360208307,360208521,1 +45791,360208375,360208109,1 +45787,360208375,360208377,1 +45789,360208377,360208492,0 +135155,360208492,360208056,0 +45788,360208493,360208377,0 +135151,360208493,1540905568,1 +135152,360208495,360208304,1 +45790,360208495,360208375,1 +45753,360208521,360208056,1 +21437,360208587,1540790977,1 +45784,360208650,360208084,1 +21436,360208650,360208587,1 +135156,360208993,360207368,0 +135161,360208993,360208994,0 +135162,360208994,360208996,0 +53863,360208994,360209043,1 +135163,360208996,360207511,0 +135178,360208996,360208057,1 +135184,360208996,1540905574,0 +45755,360209043,360208057,1 +135183,360209399,279589959,0 +135187,360209399,974030526,0 +45795,360209448,279589957,1 +45797,360209448,1540812180,0 +45796,360209471,360209448,0 +29728,360209532,974030505,1 +45794,360209640,1540812175,1 +45678,360209695,1540812129,1 +112176,360209695,1540872833,1 +45727,360209723,360207816,1 +45801,360209774,360207813,1 +45721,360209774,360209795,1 +45722,360209795,360207590,1 +45805,360209795,360207814,1 +45740,360209873,360209900,1 +45716,360209873,1540812146,1 +45717,360209875,360209876,1 +143891,360209875,360209955,1 +45807,360209876,360207810,1 +45718,360209876,1540812147,1 +45719,360209880,360209881,1 +45813,360209880,1540812185,1 +21445,360209881,1540790978,1 +45720,360209881,1540812149,1 +45741,360209900,279590313,1 +143877,360209900,360209957,1 +81033,360209953,1540844165,1 +143874,360209953,1540937879,1 +45806,360209954,360209876,1 +143875,360209954,1540937881,1 +143876,360209955,1540937882,1 +143892,360209955,1540937895,1 +143860,360209995,360206854,1 +143851,360209995,360210092,0 +143852,360210092,1540937862,0 +21447,360210093,360209995,1 +45715,360210151,1540812136,1 +45739,360210151,1540812155,1 +45738,360210159,1540812151,1 +143890,360210159,1540937893,1 +45747,360210340,1540812162,1 +45104,360210375,360210377,1 +45824,360210375,1540812186,1 +45817,360210377,279591975,1 +45829,360210399,360217132,1 +45815,360210399,360217429,1 +45822,360210533,360217425,1 +21511,360210533,1540791047,0 +21500,360210536,1540791045,1 +45826,360210536,1540812188,1 +79053,360210541,1540841199,1 +104705,360211126,360217192,1 +45831,360211126,1540812192,1 +45833,360211146,338487582,1 +46050,360211146,360232442,1 +45834,360211404,360211405,1 +45937,360211404,360217073,1 +45912,360211405,360217197,1 +45835,360211595,360211597,1 +45180,360211597,360212250,1 +2073,360211713,1540771479,0 +45836,360211732,360211713,0 +45905,360211826,1540812226,0 +45837,360211857,360211826,0 +45183,360212067,360212240,1 +104724,360212067,360218763,1 +45184,360212240,1540811965,1 +45182,360212244,1540811962,1 +45181,360212250,1540811960,1 +46189,360212250,1540812454,0 +45925,360212427,360212702,1 +45924,360212428,360212427,1 +45880,360212429,360212979,1 +45189,360212429,360213307,1 +45188,360212430,360212429,1 +45195,360212448,360198245,1 +45839,360212448,360212471,1 +45161,360212471,360212621,1 +45840,360212471,360212981,1 +45898,360212472,1540812214,1 +45203,360212499,360212980,1 +45163,360212499,360213307,1 +45216,360212619,360212621,1 +45862,360212619,360212981,1 +45162,360212621,360212499,1 +45217,360212621,360212623,1 +45194,360212623,360212448,1 +45218,360212623,360212702,1 +45926,360212702,360198189,1 +45919,360212708,360198530,1 +45843,360212708,360198547,1 +45187,360212924,360212430,1 +45847,360212924,360212935,1 +45857,360212935,360212947,1 +45848,360212935,360234611,1 +45858,360212947,360212430,1 +45859,360212947,360212979,1 +45860,360212979,360212980,1 +45873,360212979,360213097,1 +45861,360212980,360212619,1 +45204,360212980,360213097,1 +45863,360212981,360198247,1 +45841,360212981,360213096,1 +45211,360213042,360213602,1 +45897,360213043,360212472,1 +45214,360213043,360213044,1 +45215,360213044,360212619,1 +45872,360213044,360213097,1 +45886,360213072,1540812211,1 +45842,360213096,360212472,1 +45871,360213096,360213044,1 +45205,360213097,360213754,1 +45874,360213097,360213755,1 +45213,360213147,360213043,1 +45876,360213147,1540812203,1 +45175,360213207,360198121,1 +45879,360213207,360213208,1 +45190,360213307,360212428,1 +45854,360213532,360213533,1 +45884,360213532,360213557,1 +45855,360213533,360213534,1 +46069,360213533,360213655,1 +45856,360213534,360212935,1 +45892,360213534,360213656,1 +45885,360213557,360213072,1 +45888,360213557,360213655,1 +45207,360213562,360213072,1 +46071,360213562,360213602,1 +29766,360213600,338487818,1 +46068,360213600,360213533,1 +45212,360213602,360213147,1 +46072,360213602,360213603,1 +45877,360213603,1540812206,1 +45883,360213621,360213532,1 +29765,360213621,360213600,1 +45887,360213653,360213557,1 +46063,360213653,360218574,1 +45889,360213655,360213656,1 +46070,360213655,1540812327,1 +45893,360213656,360234710,1 +45206,360213754,360213562,1 +45895,360213754,360213755,1 +45896,360213755,360213043,1 +45875,360213755,360213147,1 +2088,360213838,1540771526,0 +45904,360213853,1540812216,0 +45906,360213895,360198874,1 +45918,360213985,360212708,1 +45923,360213989,360213985,1 +2641,360214016,1540772355,0 +45934,360214031,360214016,0 +45935,360214080,1540812251,0 +45936,360214094,360214080,0 +45914,360214769,1540812235,1 +45915,360214772,1540812236,1 +45940,360214904,360214905,1 +136479,360214905,1540909248,0 +46032,360215023,360217461,1 +45943,360215023,1540812259,1 +149067,360215100,1540950775,0 +45946,360215586,1540812266,1 +111980,360215600,973018627,0 +46133,360215600,1540812393,1 +83905,360215725,360215726,1 +45970,360215725,360216219,1 +83906,360215726,360215727,1 +45952,360215726,360215734,1 +83907,360215727,360215728,1 +45959,360215727,360215762,1 +83908,360215728,360215729,1 +45961,360215728,360215806,1 +83909,360215729,360215730,1 +46010,360215730,360216480,1 +83910,360215730,360216703,1 +111845,360215734,360195687,1 +45953,360215734,1540812271,1 +111844,360215762,360215734,1 +45960,360215762,360215771,1 +45965,360215771,360215807,1 +111843,360215806,360215762,1 +45962,360215806,360215807,1 +45963,360215807,279592285,1 +45966,360215807,360216012,1 +46007,360215908,360215958,1 +46102,360215908,360222534,1 +111841,360215957,360215984,1 +46009,360215957,1540812294,1 +45968,360215958,360195552,1 +46008,360215958,360215957,1 +111842,360215984,360215806,1 +45969,360215984,1540812277,1 +45967,360216012,360215908,1 +45975,360216074,360216186,1 +45972,360216074,360216299,1 +45999,360216075,1540812292,1 +45976,360216186,360216187,1 +45989,360216186,360216284,1 +45977,360216187,360216189,1 +45995,360216187,360216324,1 +46001,360216189,360216409,1 +45978,360216189,1540812278,1 +45980,360216194,360216198,1 +46003,360216194,360216480,1 +45981,360216198,360215729,1 +45982,360216198,360216409,1 +45971,360216219,360216074,1 +45986,360216219,360216220,1 +45950,360216220,600629272,1 +45998,360216282,360216075,1 +45987,360216282,360216283,1 +45988,360216283,360216186,1 +45991,360216283,360216299,1 +45990,360216284,360215726,1 +45985,360216284,360216219,1 +45973,360216299,360216075,1 +45992,360216299,360216300,1 +45948,360216300,360216319,1 +45974,360216319,360216074,1 +45949,360216319,360216220,1 +45996,360216324,360215727,1 +45984,360216324,360216284,1 +45997,360216351,360216282,1 +45994,360216351,1540812290,1 +45947,360216387,360216300,1 +46000,360216407,1540812293,1 +46122,360216407,1540812367,1 +46002,360216409,360215728,1 +45983,360216409,360216324,1 +46011,360216480,360216670,1 +46004,360216480,360216677,1 +46006,360216481,360216482,1 +83913,360216482,973054037,1 +46119,360216670,973053979,1 +46005,360216677,360216481,1 +46014,360216677,360216703,1 +83911,360216703,360195557,1 +45108,360216881,360195889,1 +45956,360216881,360216882,1 +45957,360216882,360195691,1 +46019,360216882,1540812300,1 +104704,360216896,360211126,1 +46016,360216896,1540812295,1 +29741,360216931,338487582,1 +46049,360216931,360217924,1 +46015,360217045,360216896,1 +21513,360217045,1540791049,0 +45938,360217073,1540812253,1 +45111,360217132,360217134,1 +45830,360217132,1540812191,1 +46022,360217134,360217192,1 +45112,360217134,360217345,1 +46023,360217192,360217193,1 +104706,360217192,1540866365,1 +46026,360217193,360217235,1 +46024,360217193,1540812307,1 +46025,360217196,360217197,1 +46029,360217196,1540812309,1 +45913,360217197,1540812233,1 +46027,360217235,279591977,1 +46030,360217235,360217342,1 +104707,360217342,360196122,1 +46031,360217342,360217345,1 +45113,360217345,279591980,1 +45823,360217425,360210375,1 +46020,360217425,1540812304,1 +45816,360217429,360210377,1 +46021,360217429,360217134,1 +46033,360217461,360217462,1 +46037,360217461,360232115,1 +46046,360217462,360217654,1 +46034,360217462,1540812310,1 +46035,360217503,1540812312,1 +46048,360217503,1540812321,1 +46036,360217511,360217461,1 +46039,360217511,360217651,1 +46040,360217651,1540812316,1 +46041,360217654,338487579,1 +46047,360217654,1540812319,1 +29784,360217657,338487957,1 +46043,360217657,360217693,1 +46044,360217693,360217694,1 +46087,360217693,360220607,1 +46197,360217694,360219889,1 +46199,360217694,1540812460,1 +46181,360217713,360217503,1 +29737,360217752,338487579,1 +46180,360217752,360217713,1 +29780,360217924,360220496,1 +104728,360218096,338487583,1 +46052,360218096,360218097,1 +29763,360218097,360218141,1 +46053,360218097,360233812,1 +46056,360218099,360218101,1 +45852,360218099,360218149,1 +46208,360218101,1540812482,1 +29764,360218141,360213621,1 +46061,360218141,360218149,1 +45853,360218149,360213532,1 +46062,360218149,360213653,1 +45832,360218565,360211146,1 +46057,360218565,360232441,1 +46059,360218568,360218570,1 +46073,360218568,360218901,1 +104727,360218570,360218096,1 +46060,360218570,360218141,1 +46207,360218574,360218101,1 +46064,360218574,1540812322,1 +46190,360218756,360232441,0 +46065,360218756,1540812324,1 +46067,360218763,360213600,1 +104725,360218763,360218902,1 +45881,360218901,360218902,1 +46074,360218901,360219202,1 +45882,360218902,360213621,1 +104726,360218902,360218570,1 +46075,360219202,360212244,1 +46066,360219202,1540812325,1 +45890,360219367,338487818,1 +45185,360219367,1540811966,1 +29743,360219408,360196301,1 +45269,360219408,1540811969,1 +45268,360219439,360219408,1 +45827,360219439,1540812189,1 +29768,360219888,360219889,1 +46089,360219888,360220545,1 +29769,360219889,360219890,1 +46198,360219889,360232840,1 +46200,360219890,360232912,1 +29770,360219890,1540799025,1 +29771,360219894,360232646,1 +46194,360219894,1540812459,1 +29774,360219896,338487804,1 +46192,360219896,360232620,1 +46076,360220151,360220153,1 +46017,360220151,360220237,1 +46077,360220153,360220154,1 +46187,360220153,1540812450,0 +46078,360220154,360220155,1 +46079,360220155,338487581,1 +46045,360220155,360217462,1 +46081,360220155,360220234,1 +46186,360220234,360220153,0 +46082,360220234,360220237,1 +46018,360220237,360216931,1 +29782,360220456,360220563,1 +29781,360220496,360220456,1 +46083,360220496,360220545,1 +46090,360220545,1540812333,1 +29783,360220563,360217657,1 +46084,360220563,360220607,1 +46088,360220607,360219888,1 +46178,360221291,338487957,1 +46085,360221291,1540812328,1 +46086,360221296,1540812331,1 +136480,360221447,1540909252,0 +136481,360221715,1540909254,0 +136482,360221716,360221717,0 +45954,360221716,360221953,1 +45964,360221716,1540812276,1 +21515,360221717,1540791052,0 +46094,360221953,360221954,0 +45955,360221953,1540812272,1 +104701,360221954,360195690,1 +46095,360221954,360214905,0 +21524,360222209,279592280,0 +46097,360222209,360222355,1 +45101,360222268,360195249,1 +46099,360222287,360222416,1 +21522,360222287,360222537,0 +45100,360222347,360222268,1 +46098,360222355,360222268,1 +46101,360222355,360222416,1 +46100,360222416,360222347,1 +46103,360222534,360222535,1 +46105,360222534,1540812361,1 +46104,360222535,360222537,1 +21527,360222535,1540791060,0 +21523,360222537,360222209,0 +21526,360222688,360222535,0 +21510,360222781,1540791046,0 +46108,360222888,360222781,0 +45103,360222888,1540811950,1 +46107,360223131,360222888,0 +46110,360223131,360223133,1 +45825,360223133,360210536,1 +46111,360223133,360223134,1 +21501,360223134,360196515,1 +152335,360223361,360223363,1 +152318,360223363,360198912,1 +46112,360223375,360223361,1 +21491,360223375,360223363,1 +21529,360224583,360190999,0 +152600,360224583,600396798,0 +46115,360224599,973053981,1 +111873,360224599,973983429,1 +111872,360224995,1540872315,1 +152336,360224995,1540962696,0 +104711,360225518,912014335,1 +45993,360225518,1540812280,1 +46126,360225518,1540812368,1 +46123,360225738,973054001,1 +46117,360225738,1540812365,1 +81256,360226000,1540844621,0 +83899,360226000,1540846726,0 +149064,360226475,35487995,0 +149055,360226491,360226683,0 +149056,360226557,360226475,0 +149057,360226683,1540950738,0 +46134,360227132,1540812395,1 +46143,360227132,1540812405,1 +83888,360227132,1540846694,1 +46141,360227135,360227312,1 +46142,360227312,1540812403,1 +46137,360227482,360231624,1 +46145,360227482,1540812406,1 +46140,360227483,1540812401,1 +46144,360227597,360227482,1 +46151,360227597,360228465,1 +46135,360227859,1540812396,1 +46136,360227863,1540812399,1 +46146,360228265,1540812407,1 +46148,360228271,360228272,1 +46150,360228271,1540812414,1 +46149,360228272,1540812411,1 +46177,360228272,1540812441,1 +46152,360228465,360227863,1 +46176,360228465,1540812439,1 +46165,360228857,1540812437,1 +83894,360228857,1540846715,1 +46153,360229064,360229090,1 +46154,360229090,273143707,1 +83893,360230284,360228857,1 +46164,360230284,360230307,1 +46166,360230603,360230606,1 +46171,360230603,360230967,1 +46170,360230606,360228265,1 +46167,360230753,360230969,1 +46174,360230967,360231174,1 +46172,360230967,1540812438,1 +46173,360230969,360230970,1 +46168,360230969,360231174,1 +46169,360231174,360230606,1 +46175,360231174,360231175,1 +46147,360231279,360228271,1 +46138,360231624,973017196,1 +46182,360231844,1540812447,1 +46185,360232071,360220154,1 +46183,360232071,360232073,1 +46188,360232073,1540812451,0 +46184,360232115,360232071,1 +46038,360232115,1540812315,1 +45944,360232131,360211595,1 +46058,360232441,360218568,1 +46191,360232441,360232442,0 +46051,360232442,360218096,1 +46193,360232646,360232692,1 +29772,360232646,1540799027,1 +29753,360232840,338487804,1 +29773,360232912,360219896,1 +46195,360233048,360233051,1 +46196,360233051,360217694,1 +46202,360233051,1540812477,1 +46201,360233387,1540812462,1 +29739,360233631,338487581,1 +29761,360233657,338487584,1 +46203,360233657,1540812479,1 +46054,360233812,360234487,1 +45197,360233827,360198123,1 +46205,360233827,360233910,1 +45169,360233907,360198004,1 +46204,360233907,360233827,1 +45159,360233910,360198246,1 +45171,360233954,360198321,1 +46206,360233954,1540812481,1 +45199,360234085,360198320,1 +46209,360234459,360234461,1 +45850,360234461,360234498,1 +46210,360234461,1540812483,1 +46212,360234481,360234498,1 +46211,360234481,1540812490,1 +46055,360234487,360218099,1 +45851,360234498,360218099,1 +46213,360234498,360234459,1 +45849,360234611,360213097,1 +46214,360234611,360234710,1 +45894,360234710,360213754,1 +46217,360235260,360235261,1 +46221,360235260,1540812493,1 +46218,360235261,360235263,1 +46223,360235261,360235421,1 +46226,360235263,360235473,1 +135224,360235263,1030974821,1 +46228,360235264,360235545,1 +135226,360235264,360235557,1 +135228,360235265,360235266,1 +46231,360235265,360235706,1 +135229,360235266,360235267,1 +46232,360235266,360235745,1 +46233,360235267,360235809,1 +135230,360235267,1030975092,1 +119378,360235363,1540878860,1 +119448,360235421,360235473,1 +46224,360235421,1030975444,1 +46227,360235473,360235475,1 +83866,360235475,360235545,1 +46234,360235475,1540812494,1 +83867,360235545,600398870,1 +135227,360235557,360235265,1 +46229,360235557,600398870,1 +83869,360235706,360235745,1 +83870,360235745,360235809,1 +83871,360235809,360236022,1 +83872,360236022,1540846641,1 +119367,360236022,1540878853,1 +83862,360236026,1030974636,1 +45293,360236026,1030974818,1 +83873,360236187,1540846649,1 +119377,360236494,360235363,1 +83865,360236494,360235475,1 +46236,360237154,360237155,1 +46241,360237154,1540812534,1 +46240,360241191,1540812529,1 +46239,360241349,1540812508,1 +46242,360241349,1540812538,1 +30664,360466621,1540800285,1 +47719,360466669,360467139,1 +134990,360466669,1285491892,0 +47723,360466722,360466723,0 +47726,360466722,1285491939,0 +47797,360466723,360467207,0 +122951,360466723,360467643,1 +47789,360467123,360467124,1 +47722,360467124,360466722,0 +47790,360467124,360467139,1 +47791,360467139,1285491831,1 +47725,360467165,360466722,0 +30705,360467165,360467123,0 +47798,360467207,360467470,0 +30703,360467240,347500819,0 +134979,360467240,360467207,0 +30699,360467242,360467485,0 +30798,360467242,360467524,0 +30697,360467243,360467392,0 +30823,360467243,706854098,0 +30694,360467245,360467262,0 +30839,360467245,360467365,0 +30830,360467262,360467383,0 +30695,360467262,1540800289,0 +30832,360467335,347502525,0 +47792,360467335,360467365,0 +30840,360467365,347502579,0 +47793,360467365,360467366,0 +30751,360467366,347501750,1 +30747,360467373,347502525,0 +47794,360467378,360467373,0 +47796,360467378,360467380,0 +30822,360467380,360467243,0 +30831,360467383,360467335,0 +47795,360467383,360467378,0 +30698,360467392,360467242,0 +30806,360467392,706854101,0 +47803,360467394,360467410,0 +30804,360467394,706854097,0 +30825,360467410,360467600,0 +30783,360467470,360467471,0 +47799,360467470,360467559,0 +30784,360467471,347502242,0 +30702,360467471,1540800290,0 +30743,360467480,360467525,0 +47807,360467485,360467480,0 +30700,360467485,360467558,0 +47806,360467486,360467485,0 +47801,360467486,360467524,0 +47802,360467524,360467394,0 +30799,360467524,360467531,0 +30797,360467525,360467242,0 +30744,360467525,1540800293,0 +47805,360467530,360467486,0 +134982,360467531,360467530,0 +30800,360467531,706854255,0 +30701,360467558,360467471,0 +47800,360467559,360467486,0 +30829,360467599,360467262,0 +47812,360467599,365309005,0 +47809,360467600,360467623,0 +30838,360467604,360467245,0 +47814,360467604,1540813600,0 +30696,360467606,360467243,0 +47815,360467606,360467614,1 +47811,360467614,360467599,0 +30803,360467621,360467394,0 +134981,360467621,360467531,0 +47810,360467623,360467614,0 +47816,360467623,574839086,0 +122952,360467643,1285491894,1 +30781,360467643,1540800302,1 +47834,360467832,360468857,0 +47828,360467832,360469002,0 +127274,360467834,360468600,1 +30761,360467834,360468858,1 +127278,360467835,360469467,1 +47858,360467835,959695087,1 +47846,360467884,360467904,1 +47832,360467884,360469013,0 +47831,360467885,360467884,0 +47841,360467885,778677125,0 +127250,360467886,347502539,1 +47830,360467886,360467885,0 +47840,360467889,360467885,0 +30758,360467889,360467904,1 +127286,360467904,360468342,1 +30759,360467904,360469014,1 +47861,360467905,360467919,1 +127289,360467905,360468059,1 +47862,360467919,360467920,1 +30777,360467919,1141159308,1 +47909,360467920,360468282,1 +47863,360467920,1540813612,1 +2922,360467922,1540773460,1 +30768,360467987,360467988,1 +2908,360467987,1540773456,1 +30769,360467988,1540800298,1 +134936,360467988,1540905177,1 +30771,360467991,360467992,1 +47865,360467991,360468012,1 +30772,360467992,360467993,1 +47869,360467992,360468055,1 +30773,360467993,360467994,1 +93412,360467993,706804573,1 +47901,360467994,360468213,1 +30774,360467994,1540800299,1 +30775,360467997,360467998,1 +30776,360467998,1540800301,1 +30770,360468011,360467991,1 +47867,360468011,360468017,1 +2914,360468012,1540773458,1 +47897,360468017,360468201,1 +2912,360468018,175678456,1 +47866,360468018,360468011,1 +152340,360468049,360469868,1 +127247,360468050,360468049,1 +152345,360468050,360469863,1 +48012,360468053,360469373,1 +47876,360468053,706821434,1 +47895,360468055,360468131,1 +47870,360468055,360468311,1 +2915,360468057,353243258,1 +47868,360468057,1540813613,1 +47881,360468059,360468199,1 +127290,360468059,360468212,1 +127280,360468062,360468110,1 +47879,360468062,360468284,1 +152349,360468108,360468113,1 +47873,360468108,1141269207,1 +127281,360468110,360469591,1 +127285,360468111,360468108,1 +93413,360468111,360469372,1 +152350,360468113,360468114,1 +47915,360468113,360468308,1 +47886,360468114,360468133,1 +152351,360468114,1540962703,1 +47896,360468131,360468017,1 +47883,360468131,360468325,1 +47885,360468132,360468114,1 +47914,360468132,360468306,1 +47887,360468133,360469373,1 +47882,360468199,360467998,1 +47892,360468199,360468213,1 +127291,360468212,360468226,1 +47902,360468213,360468212,1 +47893,360468213,360468225,1 +93411,360468225,360467993,1 +47894,360468225,360468055,1 +93410,360468226,360468225,1 +47903,360468231,360468240,1 +2921,360468231,1540773459,1 +47904,360468240,360468282,1 +47907,360468240,1540813615,1 +47906,360468243,360468240,1 +47899,360468243,360468244,1 +47900,360468244,360467994,1 +2919,360468245,353243178,1 +47898,360468245,360468243,1 +47905,360468282,360467997,1 +47910,360468282,360468244,1 +47880,360468284,360468059,1 +108426,360468284,360468289,1 +93409,360468289,360468226,1 +108427,360468289,360468290,1 +47912,360468290,360468308,1 +47872,360468290,1540813614,1 +93425,360468306,1141269211,0 +47913,360468308,360468132,1 +47871,360468311,360468290,1 +47916,360468311,360468325,1 +47884,360468325,360468132,1 +47917,360468325,360468326,1 +93424,360468326,360468306,0 +47864,360468331,360467922,1 +47918,360468331,1141159312,1 +127276,360468332,360468347,1 +47922,360468332,360469017,1 +47924,360468342,360468343,1 +127287,360468342,360468370,1 +30780,360468343,347502147,1 +127277,360468347,360467835,1 +47911,360468347,1540813616,1 +127273,360468369,360468347,1 +127288,360468370,360467905,1 +127292,360468370,360468371,1 +30779,360468371,360468343,1 +47847,360468380,1540813607,1 +47857,360468381,360467835,1 +48005,360468381,1141269279,1 +47997,360468404,360469197,1 +47921,360468404,1540813617,1 +114738,360468406,360468424,0 +47845,360468409,360467884,1 +114737,360468409,360468406,0 +127255,360468424,360468674,1 +127294,360468507,360468509,1 +30765,360468507,360469246,1 +127295,360468509,360468511,1 +47931,360468509,1540813622,1 +47852,360468511,360469044,1 +127275,360468600,360468332,1 +47927,360468600,1540813619,1 +47946,360468648,360468654,1 +127257,360468654,347502388,1 +127256,360468674,360468654,1 +47844,360468714,360468409,1 +47948,360468714,360468674,1 +127259,360468755,360468814,1 +47956,360468857,360468858,1 +47835,360468857,360468861,0 +30762,360468858,360468868,1 +47958,360468861,360468868,1 +30763,360468868,778677132,1 +47974,360469002,360469012,1 +47829,360469002,1540813604,0 +47975,360469012,360469013,1 +96270,360469012,778677128,1 +47833,360469013,360467832,0 +30760,360469014,360467834,1 +47976,360469014,360469017,1 +47923,360469017,360468342,1 +47930,360469018,360468509,1 +47994,360469018,1540813780,1 +47853,360469044,1540813609,1 +47995,360469061,360469063,1 +47929,360469061,1540813621,1 +47854,360469063,706830630,1 +47996,360469107,360468404,1 +47928,360469107,1540813620,1 +47856,360469197,1540813611,1 +47999,360469239,360469244,1 +47848,360469244,360469286,1 +48000,360469246,360469281,1 +47934,360469281,360469239,1 +47933,360469282,360469281,1 +48001,360469282,360469286,1 +47849,360469286,360469290,1 +47932,360469288,360469282,1 +48002,360469288,360469290,1 +47850,360469290,1540813608,1 +93428,360469313,360469314,1 +48025,360469313,360469468,1 +93429,360469314,360469315,1 +93418,360469314,360469369,1 +93430,360469315,706821447,1 +48037,360469315,1540813842,1 +48003,360469316,1540813781,1 +93433,360469316,1540856522,1 +47878,360469320,353246257,1 +48004,360469345,360469347,1 +48010,360469345,360469372,1 +127284,360469347,360468111,1 +48024,360469368,360469313,1 +48007,360469368,360469369,1 +93419,360469369,360468110,1 +48008,360469369,360469590,1 +48011,360469372,360468053,1 +93414,360469372,1540856516,1 +47888,360469373,706821618,1 +48031,360469442,360470973,0 +152346,360469442,706002907,1 +93416,360469442,1540856518,1 +48186,360469447,353246262,1 +93417,360469447,360469314,1 +127279,360469467,360468062,1 +48023,360469467,360469368,1 +48185,360469468,360469447,1 +47851,360469483,360468511,1 +48183,360469483,360469484,1 +48184,360469484,360469468,1 +48030,360469484,706830627,1 +48105,360469544,360469561,0 +48028,360469544,1540813839,1 +93427,360469548,360469290,1 +48029,360469548,360469484,1 +82553,360469553,1540846342,0 +48034,360469556,360469553,0 +48027,360469556,1540813836,1 +48033,360469561,360469556,0 +48106,360469561,360471091,0 +48035,360469562,353246262,1 +152348,360469562,1540962702,1 +48038,360469590,360469591,1 +48009,360469590,1540813782,1 +127282,360469591,706821410,1 +48039,360469614,1540813843,1 +152343,360469614,1540962700,1 +93432,360469616,360469316,1 +127304,360469631,360469700,1 +134906,360469652,360469631,0 +48102,360469652,360470974,0 +134905,360469653,360469652,0 +48109,360469653,360471253,0 +134904,360469654,360469653,0 +82549,360469654,360469676,0 +82550,360469676,360471072,0 +127305,360469700,360469795,1 +48054,360469700,360470974,0 +152338,360469700,706002916,1 +127306,360469795,360469442,1 +152341,360469795,360469859,1 +93405,360469859,706002916,1 +152342,360469859,1540962699,1 +93401,360469863,706002664,1 +93399,360469868,360469921,1 +93403,360469872,353246255,1 +48075,360469872,360469891,1 +48073,360469889,360469890,1 +48077,360469889,1540813853,1 +127246,360469890,360468050,1 +48074,360469890,360469872,1 +48014,360469891,706002667,1 +48076,360469893,1540813852,1 +152344,360469893,1540962701,1 +93400,360469921,360469863,1 +48078,360469921,360469934,1 +48017,360469934,360469939,1 +48128,360469939,360472070,1 +48018,360469939,706002678,1 +127313,360470135,1540885074,0 +48020,360470138,360472497,1 +82548,360470197,1540846340,0 +127303,360470219,360469631,1 +134901,360470219,360470318,1 +48087,360470219,360470977,0 +93396,360470318,1540856513,1 +134902,360470318,1540905160,1 +134903,360470321,360470138,1 +48090,360470321,1540813859,1 +127314,360470377,1540885075,0 +48091,360470594,360470595,1 +134908,360470594,1540905162,1 +127315,360470595,360470597,0 +127301,360470597,360470800,1 +48092,360470597,1540813860,0 +93395,360470597,1540856511,1 +93397,360470601,360472067,1 +48048,360470601,1540813845,1 +24275,360470694,302044723,1 +82546,360470694,1540846336,0 +48095,360470729,360471255,0 +82547,360470729,1540846339,0 +48097,360470799,360470800,0 +48100,360470799,360470977,0 +127302,360470800,360470219,1 +48032,360470973,360469561,0 +48103,360470974,360471049,0 +48055,360470974,360471252,0 +48101,360470977,360469652,0 +48088,360470977,360471253,0 +48099,360470978,360470799,0 +48093,360470978,360471256,0 +48098,360470979,360470978,0 +93407,360470979,706002989,1 +134907,360470979,1540905161,1 +48072,360471049,360469795,0 +48104,360471049,360470973,0 +82551,360471072,38842561,0 +48070,360471072,360471091,0 +48071,360471091,360471049,0 +48107,360471091,360471252,0 +48108,360471252,360469653,0 +48056,360471252,360469676,0 +48089,360471253,360470197,0 +48110,360471253,360471255,0 +48096,360471255,360470799,0 +48111,360471255,360471256,0 +48094,360471256,360470694,0 +48112,360471256,360471257,0 +48115,360471257,706003065,0 +48114,360471305,360471257,0 +82545,360471305,1540846335,0 +134909,360471442,360471443,1 +48135,360471442,360472363,1 +48133,360471443,360471732,1 +134910,360471443,1540905165,1 +48119,360471732,360470135,1 +48118,360471733,360471732,1 +48120,360471733,1540813862,1 +48126,360471785,360471854,1 +48016,360471788,360469934,1 +48125,360471788,360471785,1 +50152,360471854,360473293,0 +93398,360472067,360469868,1 +48127,360472067,360469939,1 +48124,360472070,360471785,1 +48129,360472070,360472071,1 +93371,360472071,360472743,1 +48130,360472122,706002947,1 +48141,360472122,1540813865,0 +93392,360472241,1540856510,0 +48122,360472261,706002675,1 +48134,360472261,1540813863,1 +93390,360472354,1540856508,0 +48132,360472363,360471443,1 +48136,360472363,706002941,1 +93384,360472426,360472487,1 +50153,360472426,1540815067,0 +93385,360472487,1540856503,1 +48021,360472497,1540813783,1 +134932,360472605,360727836,0 +48146,360472605,1540813866,0 +48145,360472696,360472605,0 +48152,360472696,360472853,0 +93372,360472743,360472354,1 +48142,360472743,360473295,0 +48153,360472853,705990364,0 +48166,360472853,705990402,0 +48159,360472856,365119464,0 +2875,360472856,705990478,0 +48170,360473095,705990368,1 +48178,360473097,353246112,1 +48164,360473097,353246252,0 +152356,360473100,360473550,1 +48162,360473100,705990489,0 +2905,360473103,353244388,1 +48160,360473103,1540813870,0 +48168,360473293,360473295,1 +93370,360473293,1540856498,1 +93373,360473293,1540856499,0 +48169,360473295,360473095,1 +48143,360473295,705990399,0 +48151,360473428,360472696,0 +93375,360473428,1540856501,0 +2907,360473545,360467987,1 +48173,360473547,360473559,1 +48149,360473547,1540813869,0 +152357,360473550,360473620,1 +48148,360473550,1540813867,0 +134937,360473559,1540905178,1 +48174,360473619,360473725,0 +127268,360473620,360468326,1 +152358,360473620,1540962704,0 +50157,360473621,353246112,0 +152355,360473621,360473100,1 +152354,360473622,360473621,1 +31696,360473622,1540802540,0 +152352,360473623,353244833,1 +2873,360473623,1540773431,0 +48175,360473725,1540813873,0 +93381,360473766,360727832,1 +127266,360473790,360727832,1 +48180,360473806,353246108,1 +48161,360473806,1540813871,0 +134926,360473814,705990469,0 +31645,360473814,1540802527,0 +134925,360473825,360473814,0 +2874,360473825,1540773433,0 +134841,360473834,353244828,1 +2877,360473834,1540773434,0 +48192,360473933,353244827,0 +134839,360473933,360473934,1 +2878,360473933,360473974,0 +2846,360473934,360473978,0 +134864,360473934,1540905148,0 +134866,360473937,360473938,0 +48243,360473937,360474736,0 +134867,360473938,360473939,0 +50180,360473938,360474043,0 +134868,360473939,360473940,0 +134869,360473940,360473941,0 +48201,360473940,360474337,0 +134870,360473941,360474608,0 +92999,360473941,360474649,0 +2844,360473964,360474646,0 +31660,360473974,360473964,0 +2879,360473974,705979338,0 +31638,360473975,353244827,0 +31659,360473975,360473974,0 +134840,360473978,360473834,1 +2847,360473978,365119494,0 +56098,360473994,365119552,0 +127365,360473994,694738240,0 +50179,360473995,360473938,0 +127362,360473995,360474736,0 +50171,360474036,360474037,0 +56070,360474036,360474678,1 +50172,360474037,694738264,0 +50174,360474038,360474039,0 +56122,360474038,1540824347,0 +50175,360474039,694738331,0 +48193,360474041,360474177,0 +50177,360474041,694738009,0 +50181,360474043,360474044,0 +48238,360474043,360474647,0 +48253,360474044,360474336,0 +50182,360474044,360474744,0 +50184,360474045,360474047,0 +50185,360474047,360728394,0 +48194,360474177,360474179,0 +48195,360474179,360474220,0 +48203,360474179,694758812,0 +127355,360474181,360474220,0 +2017,360474181,360474611,1 +127354,360474182,360474181,0 +56187,360474182,1540824354,0 +127463,360474182,1540885165,0 +92997,360474220,360474296,0 +50209,360474220,360474610,0 +92998,360474296,360473941,0 +127359,360474296,360474337,0 +48206,360474297,360474540,0 +93004,360474297,694769841,0 +93006,360474298,360474300,0 +48225,360474298,360474588,0 +93007,360474300,360474301,0 +2868,360474300,360474588,1 +2885,360474301,360730493,1 +127361,360474314,360473995,0 +48237,360474315,360474043,0 +48205,360474335,360474297,0 +48196,360474335,360475894,0 +48199,360474336,360474648,0 +48254,360474336,360474761,0 +48202,360474337,360474179,0 +127360,360474337,360474314,0 +48207,360474540,360475199,0 +127432,360474540,360475889,0 +48209,360474541,360475821,0 +48218,360474541,360475885,0 +29621,360474544,338485094,0 +48213,360474544,360474545,0 +94837,360474545,150563683,1 +48214,360474545,360474546,0 +134890,360474546,1540905152,0 +48215,360474566,360474567,0 +48292,360474566,1540813903,0 +48216,360474567,360474568,0 +48222,360474567,360474586,0 +48258,360474567,1540813890,1 +48217,360474568,360474541,0 +134992,360474568,360475795,0 +48223,360474586,360474587,0 +96339,360474586,360475200,0 +48224,360474587,360474298,0 +127430,360474587,1540885159,0 +2869,360474588,694770163,1 +2884,360474589,360474301,1 +122639,360474589,360729906,1 +127437,360474608,360474609,0 +48226,360474608,360474618,0 +127358,360474609,360474296,0 +127438,360474609,360474610,0 +127439,360474610,360474611,0 +2018,360474611,365122312,1 +127464,360474611,1540885167,1 +127357,360474616,360474609,0 +48229,360474616,360474618,0 +48230,360474618,360474623,0 +48227,360474618,694758723,0 +48233,360474623,360474650,0 +2845,360474646,360473934,0 +48242,360474647,360473937,0 +48239,360474647,365119576,0 +48200,360474648,360473940,0 +48236,360474648,360474315,0 +48235,360474649,360474648,0 +93000,360474649,360474761,0 +127436,360474650,360474608,0 +48234,360474650,360474649,0 +2022,360474653,360475871,1 +48231,360474653,1540813888,0 +56071,360474678,365118467,1 +48241,360474735,360474647,0 +48252,360474735,360474744,0 +48244,360474736,694737976,0 +127363,360474736,694738030,0 +56135,360474737,694738050,0 +48246,360474737,694738327,0 +56123,360474739,365119377,0 +48248,360474739,694738261,0 +48250,360474740,360474741,0 +131629,360474741,365118708,0 +56068,360474741,1540824335,1 +50183,360474744,360474045,0 +93001,360474761,360474878,0 +48198,360474876,360474336,0 +134853,360474876,360474878,0 +134854,360474878,360474880,0 +93002,360474878,360475905,0 +134855,360474880,360474883,0 +127434,360474880,360474947,0 +134856,360474883,360474884,0 +96335,360474883,360475198,0 +134857,360474884,360474886,0 +48220,360474884,360475071,0 +134858,360474886,360474887,0 +134939,360474886,360475882,0 +2024,360474887,150563681,1 +127435,360474947,360474650,0 +48255,360474947,360475069,0 +96334,360475069,360474883,0 +48256,360475069,360475071,0 +48257,360475071,360475852,0 +48221,360475071,1540813886,0 +96336,360475198,360475199,0 +48298,360475198,360475889,0 +48208,360475199,360474541,0 +96337,360475199,360475795,0 +48291,360475200,360474566,0 +133750,360475200,1540896939,1 +133749,360475202,360475201,1 +48271,360475228,360475419,1 +48294,360475228,1540813904,0 +48295,360475229,338485152,0 +134519,360475229,1540904925,0 +134514,360475277,360475278,1 +48269,360475277,1540813895,0 +134871,360475278,360475279,1 +48267,360475278,360475339,0 +92925,360475279,683287850,1 +48305,360475279,683287855,1 +92928,360475281,360475282,1 +29584,360475281,360475315,1 +48260,360475282,360475311,1 +92927,360475285,360475281,1 +29631,360475285,360475320,0 +48259,360475310,360475282,1 +48264,360475310,1540813891,0 +2032,360475311,1540771412,1 +29585,360475315,338485159,1 +48265,360475315,360475320,0 +29632,360475320,338485158,0 +48266,360475320,1540813892,0 +48270,360475339,360474545,0 +29637,360475363,694820751,0 +48268,360475363,1540813894,0 +127469,360475371,694789258,0 +48211,360475371,1540813884,0 +134515,360475399,1540904924,1 +48272,360475450,360475618,1 +134508,360475451,338485095,0 +134516,360475451,1260448674,0 +134518,360475452,360475229,0 +48283,360475452,1540813897,0 +134512,360475454,338485094,1 +134510,360475454,360475455,0 +48212,360475455,360474544,0 +134511,360475455,360475456,0 +2026,360475456,150563682,1 +48293,360475521,360475228,0 +48284,360475521,360475563,1 +48285,360475563,694789743,1 +133747,360475563,1493262724,1 +127453,360475567,360475618,1 +48273,360475618,360475451,1 +127454,360475618,360475634,1 +127455,360475634,694820786,1 +93022,360475634,1540856396,1 +29618,360475636,338485009,0 +48288,360475636,694789922,1 +2867,360475780,360474300,1 +48289,360475780,1540813901,0 +127429,360475785,360474587,0 +48290,360475785,360475200,0 +96338,360475795,360474586,0 +48210,360475821,1540813882,0 +134938,360475852,360474886,0 +134859,360475871,360475852,1 +127471,360475871,1143979807,0 +2023,360475871,1540771408,1 +134940,360475882,360475821,0 +48296,360475882,1540813905,0 +48219,360475885,360474884,0 +48297,360475885,360475198,0 +127433,360475889,360474880,0 +48299,360475889,360475905,0 +48301,360475894,360474047,0 +48197,360475894,360474876,0 +93003,360475905,360474297,0 +48300,360475905,360475894,0 +134547,360475935,150563687,0 +48261,360475935,360475936,0 +48262,360475936,360475938,0 +127423,360475936,360476020,0 +48276,360475937,338485114,0 +29610,360475937,360476023,0 +48263,360475938,360475310,0 +29608,360475938,360475953,0 +29641,360475953,338485160,0 +29609,360475953,360475937,0 +29606,360476002,360476017,0 +2033,360476002,1540771413,1 +29588,360476008,338484427,1 +48304,360476008,360476023,1 +29607,360476017,360475938,0 +127424,360476020,353246658,0 +48302,360476020,360476017,0 +29611,360476023,246588553,0 +2030,360476027,1540771411,1 +29663,360476033,338485278,0 +135094,360476033,338485309,0 +2862,360476071,694789798,1 +134892,360476090,360476091,1 +127460,360476091,694820349,1 +127462,360476096,338485309,1 +94839,360476096,1236188089,0 +48313,360476120,694820219,0 +2857,360476120,694820526,1 +48317,360476137,360476138,1 +51291,360476137,683301823,1 +48320,360476138,338484527,1 +48318,360476138,683301343,1 +29594,360476139,338484933,1 +134528,360476152,683297772,1 +134520,360476152,683301332,0 +134533,360476153,599162771,1 +80613,360476153,683295953,0 +51309,360476177,581291051,0 +80617,360476177,1540843305,0 +80616,360476178,360476177,0 +127404,360476178,683295956,1 +100338,360476193,360476197,1 +51300,360476193,360476215,1 +134531,360476197,360476199,1 +134532,360476199,360476153,1 +29602,360476207,338484611,1 +51301,360476215,361197369,1 +31719,360476225,678178641,1 +48323,360476225,797347644,1 +31717,360476236,353246401,1 +29671,360476237,338485295,0 +48324,360476238,360476263,1 +29660,360476238,1540798999,1 +80609,360476247,1540843304,0 +31700,360476250,353246387,0 +31715,360476255,353246578,1 +48325,360476263,360476247,1 +31702,360476272,599162412,0 +29669,360476276,338485294,0 +29600,360476280,338485258,1 +134553,360476306,361198821,1 +96809,360476306,361198844,0 +134555,360476329,360476332,1 +51336,360476329,361198865,0 +134548,360476332,360477495,1 +134567,360476332,360477595,0 +48329,360476333,360476338,0 +134550,360476333,360476344,1 +56487,360476335,1540824876,0 +125359,360476335,1540884074,1 +127114,360476336,360476963,0 +48330,360476338,360476341,0 +127089,360476338,360476353,1 +48331,360476341,360476683,0 +3637,360476341,360477497,1 +134551,360476344,360476356,1 +48491,360476344,360477512,0 +127090,360476353,360476358,1 +48490,360476353,1540813923,0 +48334,360476356,1540813909,0 +134552,360476356,1540904932,1 +48335,360476358,360476715,0 +127091,360476358,360476866,1 +80306,360476528,577419475,0 +80316,360476528,577419524,0 +80338,360476528,1540843090,0 +23951,360476538,600918109,1 +106593,360476538,1540868480,0 +106595,360476538,1540868487,1 +118629,360476549,360477158,1 +134557,360476556,361198639,1 +48358,360476556,797375839,0 +48360,360476616,360476619,0 +98037,360476616,361198642,1 +51345,360476619,1540815940,1 +48365,360476642,360476644,1 +51329,360476642,683916600,0 +134570,360476644,360477466,0 +48366,360476644,360477498,1 +48369,360476646,360476719,1 +48488,360476646,360477401,0 +48371,360476647,360476648,1 +48406,360476647,360476867,0 +83934,360476648,1540846764,0 +48368,360476683,360476646,1 +48332,360476683,360476697,0 +48354,360476697,360477367,0 +48336,360476715,360476719,0 +3635,360476715,360477401,1 +48370,360476719,360476647,1 +48337,360476719,360476781,0 +48338,360476781,360476803,0 +48351,360476781,360477388,0 +135131,360476794,797375848,0 +48341,360476800,360476804,0 +134583,360476800,797375606,0 +48394,360476803,360476817,0 +48339,360476803,360477342,0 +48378,360476804,797375874,1 +48342,360476804,803749499,0 +95540,360476807,746981321,0 +48372,360476807,797375816,1 +135121,360476809,1540905566,0 +48404,360476817,360476868,0 +48395,360476817,600917288,0 +48392,360476819,360477396,0 +48483,360476819,797375727,0 +134556,360476820,360476556,1 +48388,360476820,361198612,0 +48402,360476827,360476870,0 +134586,360476827,938502218,0 +48401,360476828,360476827,0 +48381,360476828,797375555,1 +125351,360476863,523553316,1 +127092,360476866,247152813,1 +48408,360476866,1540813911,0 +48407,360476867,360476866,0 +3634,360476867,1540774162,1 +48405,360476868,360476647,0 +48350,360476868,360476781,0 +48403,360476870,360476817,0 +48460,360476870,797375704,0 +48409,360476887,653279465,1 +3647,360476887,1540774170,0 +103031,360476907,360476963,1 +56486,360476907,1540824873,0 +106600,360476907,1540868488,1 +48411,360476914,360476920,1 +106601,360476914,1540868489,1 +48419,360476920,360476930,0 +48412,360476920,1540813912,1 +48414,360476926,1540813913,1 +106602,360476926,1540868490,1 +48416,360476930,1540813915,1 +48418,360476963,360476920,0 +103032,360476963,1139689411,1 +106603,360476991,360477067,1 +48423,360477014,360476991,0 +48421,360477015,984752878,0 +48420,360477016,360477015,0 +127113,360477016,360477017,1 +48436,360477016,360477151,0 +48424,360477041,360477072,0 +106605,360477041,360477315,1 +127111,360477067,936853776,0 +106604,360477067,1540868492,1 +48433,360477072,360477075,0 +48425,360477072,360477155,0 +48434,360477075,360477015,0 +127110,360477075,360477067,0 +48426,360477078,360477151,1 +48429,360477085,360477211,0 +127099,360477085,984752524,0 +48428,360477145,360477085,0 +48448,360477145,360477182,0 +48427,360477147,360477145,0 +127109,360477151,360477075,0 +48437,360477151,360477155,0 +48438,360477155,984752502,0 +127105,360477155,1540884973,1 +127098,360477158,360477085,0 +48441,360477158,360477182,0 +127106,360477182,984752591,1 +48442,360477182,1540813917,0 +48443,360477184,360477189,0 +48447,360477184,984752911,1 +48444,360477189,984752875,0 +48446,360477189,1540813919,0 +48430,360477211,360477249,0 +48449,360477211,1540813920,1 +48440,360477223,360477158,0 +48450,360477223,1540813921,1 +48431,360477249,360477278,0 +48345,360477261,1540813910,1 +48432,360477278,360477072,0 +48451,360477278,360477315,0 +48452,360477308,360477249,0 +106607,360477308,1540868494,1 +106606,360477315,360477308,1 +48340,360477342,360476800,0 +48462,360477342,797375775,0 +48472,360477360,797375634,0 +48475,360477363,360477370,0 +48467,360477363,360477469,0 +2805,360477365,360476820,1 +48470,360477365,797375576,0 +48355,360477367,360477466,0 +48477,360477367,360477498,0 +48391,360477370,360476819,0 +48476,360477370,360477367,0 +48353,360477381,360476697,0 +48482,360477381,360476819,0 +48487,360477388,360476646,0 +48352,360477388,360477381,0 +48393,360477396,360476803,0 +48486,360477396,360477388,0 +3636,360477401,360476341,1 +48489,360477401,360476353,0 +134569,360477403,360476644,0 +3639,360477403,361198641,1 +134571,360477466,360477468,0 +48356,360477466,361198627,0 +48390,360477468,360477370,0 +134572,360477468,360477469,0 +48468,360477469,797375662,0 +134573,360477469,797375782,0 +51712,360477494,360477505,1 +134549,360477495,360476333,1 +48481,360477495,360477494,0 +127088,360477496,360476338,1 +48480,360477496,360477495,0 +3638,360477497,360477403,1 +48479,360477497,360477496,0 +48367,360477498,360476683,1 +48478,360477498,360477497,0 +48328,360477505,360476333,0 +51713,360477505,360477512,1 +51714,360477512,360477530,1 +48333,360477530,360476356,0 +51715,360477530,1540816231,1 +134568,360477595,360477403,0 +127087,360477595,360477496,1 +127097,360477598,360476332,0 +51711,360477598,360477494,1 +133448,360712202,302689432,1 +24529,360712811,360712898,0 +49923,360712811,360713056,1 +24530,360712898,302656919,0 +49914,360712926,360713087,1 +24407,360712926,360713646,0 +49913,360712973,360712926,1 +24416,360712973,1540795749,0 +49911,360713021,360713177,1 +24599,360713021,1540795785,1 +89047,360713056,302661527,0 +49924,360713056,982077189,1 +49925,360713077,302656921,1 +49910,360713077,360713021,1 +24604,360713081,302555273,0 +49928,360713081,360713177,1 +49920,360713082,360712898,1 +89046,360713082,360713056,0 +126084,360713087,360713720,0 +24534,360713127,302555271,0 +49930,360713127,360713160,1 +89044,360713136,982077226,0 +24598,360713141,1540795784,1 +49931,360713160,38840240,1 +89042,360713160,302687557,0 +49912,360713177,360712973,1 +49929,360713177,360713127,1 +64398,360713211,302660583,0 +49934,360713211,360713231,1 +17695,360713231,1540787778,1 +126091,360713245,1239786760,0 +17696,360713245,1540787779,1 +64397,360713269,360713211,0 +126089,360713269,360713838,0 +126087,360713284,360713640,0 +24538,360713284,360714131,0 +24410,360713625,302660583,0 +49937,360713625,360713640,0 +126088,360713640,360713269,0 +24408,360713646,302555197,0 +49938,360713646,360713689,1 +126086,360713661,360713284,0 +49939,360713689,360713661,1 +49940,360713689,360713719,1 +24537,360713719,360713284,0 +126085,360713720,360713661,0 +49941,360713720,360713757,1 +49943,360713757,360713827,0 +49944,360713827,302689432,0 +133429,360713829,360717012,0 +126090,360713838,360713245,0 +133431,360713889,38840244,0 +49947,360713889,1540814977,0 +49946,360713891,360713889,0 +49950,360713891,360717010,1 +49977,360713894,360715006,1 +49945,360713894,1540814976,0 +49952,360713960,360713922,1 +49954,360713960,360714686,0 +49980,360713961,360716311,1 +49948,360713984,360714111,0 +49957,360713984,360717049,0 +49956,360714102,360713984,0 +17698,360714102,1540787780,1 +49949,360714111,360713838,0 +49961,360714111,360714124,0 +17697,360714124,360714102,1 +49959,360714131,302553819,0 +24539,360714131,302656927,0 +49962,360714198,360714251,1 +24406,360714198,1540795743,0 +126083,360714251,360713087,0 +49963,360714251,360713827,1 +133450,360714287,360714635,1 +49974,360714635,360714686,1 +133451,360714635,360716308,1 +49955,360714686,360713961,0 +17700,360714725,1540787783,1 +49975,360714725,1540814988,1 +49976,360714800,360713894,1 +50042,360714800,1540815013,0 +133464,360714800,1540894453,1 +133466,360714804,360714805,1 +50048,360714804,360717480,1 +50046,360714805,360717441,1 +133467,360714805,1540894456,1 +50024,360714807,360717346,1 +49978,360715006,360716861,1 +50039,360715006,1540815011,1 +50011,360716050,360716052,1 +50012,360716052,360714807,1 +50064,360716052,1540815031,1 +133452,360716308,302689433,1 +50014,360716308,1540815002,1 +49981,360716311,302689433,1 +50033,360716315,360716731,0 +133427,360716315,1540894448,0 +133454,360716521,360716727,0 +50016,360716521,1540815004,1 +50019,360716552,360719526,1 +50026,360716628,360716629,1 +64407,360716628,1540834248,0 +50051,360716629,360716821,0 +50018,360716650,360716552,1 +50027,360716650,360716727,1 +50017,360716731,360716650,1 +50032,360716814,360716315,0 +50035,360716814,1540815007,0 +50030,360716816,360717003,0 +133465,360716816,1540894455,1 +50029,360716820,360716816,0 +64405,360716820,360717317,1 +50028,360716821,360716820,0 +50065,360716821,360718554,0 +64351,360716822,360716821,0 +50072,360716822,599162160,0 +49979,360716861,360713961,1 +50034,360716861,1540815005,0 +50036,360716923,360717002,1 +50021,360716923,1037172821,1 +50037,360717002,360717003,1 +50047,360717002,1540815022,1 +50031,360717003,360716814,0 +50038,360717003,1540815008,1 +49951,360717010,360713960,1 +50040,360717010,360717012,1 +133430,360717012,360713889,0 +49958,360717049,302656927,0 +50041,360717049,360713829,1 +17701,360717180,360717268,1 +17702,360717268,1540787784,1 +50043,360717268,1540815018,0 +50045,360717317,360717346,0 +50025,360717346,360716628,1 +64406,360717346,1540834245,0 +50023,360717441,360714807,1 +133470,360717589,360718318,1 +50052,360717589,360718500,0 +50049,360717589,360719404,0 +64373,360717589,1540834222,1 +64404,360718318,1540834242,0 +50077,360718500,745985513,0 +133774,360718527,38842545,1 +17703,360718527,1540787785,1 +50066,360718554,1540815036,0 +64353,360718554,1540834147,0 +50067,360718557,360718554,0 +50044,360718557,1540815020,0 +64352,360718711,360718713,0 +50069,360718711,457420810,0 +64372,360718713,360718714,0 +64369,360718713,1540834218,0 +22969,360718714,286537369,0 +50068,360718737,360718711,0 +17704,360718737,745984391,1 +50075,360718926,360719255,0 +64378,360718926,360719404,0 +50080,360718927,294253327,0 +64354,360718927,1540834148,0 +64355,360719138,286537128,0 +50082,360719138,457248427,0 +64377,360719250,360718926,0 +50076,360719255,360718500,0 +50088,360719255,360719268,1 +50087,360719268,360719250,0 +50089,360719401,360719402,0 +70244,360719401,360720324,1 +64376,360719402,360719250,0 +50050,360719404,360716629,0 +50020,360719526,360716923,1 +50097,360719790,286537377,0 +50108,360719790,360719893,0 +50094,360719791,745986935,0 +50119,360719791,1540815047,1 +24041,360719794,1540793931,0 +50106,360719850,745986934,0 +64386,360719851,286537377,1 +50101,360719851,360719850,0 +133476,360719893,1540894459,1 +50107,360719917,360719790,0 +50110,360719917,360720094,0 +50120,360719961,1540815048,1 +50112,360719963,360720093,1 +133477,360719963,1540894461,1 +50096,360720093,360719790,0 +50113,360720093,360720094,1 +50114,360720094,360720095,1 +50111,360720094,1540815045,0 +50115,360720095,286541739,1 +50117,360720095,360720111,0 +50122,360720097,360720293,0 +64384,360720111,286537130,1 +50116,360720195,1540815046,0 +100784,360720195,1540862913,1 +64375,360720293,360720726,1 +133439,360720293,745988709,0 +64388,360720324,286537122,1 +64379,360720324,360719402,0 +50121,360720324,360720097,0 +133435,360720401,360720726,0 +133432,360720402,745984376,0 +92200,360720402,1540856195,1 +133436,360720465,360720466,1 +50123,360720465,1540815049,0 +92201,360720466,745988758,1 +22987,360720505,286541742,0 +50125,360720505,1540815050,0 +92204,360720516,597897429,1 +50130,360720516,745988713,0 +50132,360720525,597897428,0 +50127,360720525,745988757,0 +50137,360720578,1540815053,1 +95132,360720578,1540857413,1 +24031,360720581,294250800,1 +50140,360720623,360720629,1 +50126,360720623,1540815051,0 +133443,360720629,286541740,0 +50145,360720713,745984400,0 +50143,360720726,745984373,0 +64400,360720758,360720794,0 +50147,360720794,286537120,0 +64399,360720795,360720758,0 +64401,360720796,360720795,0 +133438,360720796,360720797,1 +70242,360720796,745984396,1 +50148,360727493,1540815059,1 +82541,360727493,1540846332,0 +127267,360727832,360473620,1 +93382,360727832,360473725,1 +50150,360727836,1540815065,0 +127265,360727836,1540885062,1 +134911,360727918,353244899,1 +93391,360727918,360472241,0 +48117,360727918,1540813861,1 +93383,360727947,360472426,1 +48150,360727951,360473428,0 +50151,360727951,1540815066,0 +93387,360728029,1540856505,1 +134897,360728170,1540905159,1 +93346,360728174,360728176,1 +31675,360728174,360728291,1 +80596,360728176,360730828,1 +127317,360728176,1540885076,0 +31676,360728291,1540802532,1 +127320,360728291,1540885079,1 +2841,360728379,1540773419,0 +51675,360728379,1540816148,0 +50187,360728394,1540815076,1 +51676,360728403,360474335,0 +104439,360728582,361435845,0 +82534,360728582,1540846322,0 +50189,360728698,353244826,1 +127326,360728698,361434464,0 +134895,360728698,1540905154,1 +50194,360728839,360728840,1 +93352,360728839,705971016,1 +50195,360728840,1540815081,1 +93356,360728846,705971082,1 +127321,360728846,1540885081,1 +135088,360728936,360714725,1 +50196,360728936,1540815083,1 +82539,360728936,1540846327,0 +134805,360729189,705062338,1 +50214,360729189,1540815086,0 +134809,360729191,705062353,1 +134814,360729193,1540905137,1 +134821,360729197,361194268,1 +93315,360729197,705073928,1 +134832,360729203,360729204,1 +51195,360729203,361196091,1 +134833,360729204,361197325,1 +93191,360729204,704832181,1 +127384,360729807,360474301,0 +127394,360729900,1540885136,1 +122640,360729906,361434500,1 +127382,360729958,1093091310,0 +50202,360730002,1093091270,1 +50199,360730002,1093091279,1 +50204,360730004,1142507821,1 +50211,360730040,360730171,1 +50206,360730116,360730040,1 +50208,360730116,360730138,1 +127378,360730138,1142507846,0 +127377,360730171,360730138,0 +50219,360730174,360730446,1 +127374,360730174,705073952,0 +50213,360730299,361434510,0 +127376,360730300,360730171,0 +50212,360730300,360730299,0 +50215,360730443,360730299,0 +50218,360730443,1540815088,1 +50220,360730449,1540815089,1 +93321,360730449,1540856477,1 +93322,360730453,705073951,1 +127396,360730453,1540885141,1 +2886,360730493,1540773440,1 +127387,360730493,1540885132,1 +127390,360730592,705073954,1 +93327,360730592,705073963,1 +127392,360730594,705073951,1 +93316,360730594,1540856470,1 +134815,360730598,1540905138,1 +2866,360730614,360475780,1 +50222,360730614,360730493,1 +50221,360730625,360730614,1 +127428,360730625,1540885158,0 +134817,360730673,705073947,1 +50223,360730673,1540815091,1 +50225,360730697,705060400,1 +50268,360730698,361193798,1 +93337,360730756,360730950,1 +93264,360730756,705063792,0 +51092,360730761,361194348,1 +93217,360730761,361195482,1 +93221,360730763,361194988,1 +51182,360730763,361195948,0 +93223,360730765,361196176,1 +94814,360730765,361196799,0 +93174,360730767,581290422,1 +94806,360730767,1540857342,1 +50230,360730828,360730849,0 +50231,360730828,705971109,0 +133410,360730830,457256020,0 +50258,360730830,705971093,0 +82538,360730849,1540846325,0 +50234,360730889,705971097,0 +50238,360730892,360729191,0 +133418,360730892,705062357,1 +50240,360730895,360731006,1 +133422,360730895,361193542,1 +50239,360730912,360730895,1 +134812,360730912,705060331,1 +93338,360730950,360731357,1 +50237,360730987,360730892,0 +50248,360730987,705062341,0 +50236,360730989,360730987,0 +93334,360730989,360731119,1 +50241,360731006,361193198,1 +50244,360731006,705062356,0 +93333,360731050,1540856485,1 +93335,360731119,360731301,1 +50255,360731137,360731155,0 +82532,360731137,1540846321,0 +50256,360731155,360731119,0 +50251,360731155,705063792,0 +82535,360731219,360731244,0 +50257,360731244,1540815097,0 +82536,360731244,1540846323,0 +93336,360731301,360730756,1 +50260,360731301,705062330,1 +50243,360731319,360730950,1 +50264,360731319,360731334,1 +50262,360731332,705062360,1 +93263,360731332,705062361,1 +50265,360731334,705060360,1 +94781,360731338,361194645,1 +93231,360731338,1540856461,1 +94786,360731340,360731342,1 +51139,360731340,361194828,1 +51120,360731342,705059089,0 +93339,360731357,705060362,1 +50271,360731357,1540815099,0 +50293,360731402,361195711,1 +50278,360731402,746691680,0 +50283,360731407,746691469,1 +50282,360731454,360731407,1 +82521,360731454,1540846317,0 +95207,360731510,746691490,1 +50286,360731510,746691638,1 +50289,360731512,360731513,1 +51268,360731512,1540815933,1 +95198,360731513,360731515,1 +50304,360731513,705066620,1 +51226,360731515,705065823,0 +50290,360731577,705066778,1 +82526,360731577,1540846319,0 +50297,360731665,705066624,1 +50299,360731667,705066626,1 +95204,360731667,746691586,1 +50301,360731668,705066627,1 +50309,360731671,360731672,1 +50310,360731672,360731674,1 +24016,360731672,745990564,0 +97011,360731674,793479429,0 +133578,360731674,793479435,1 +133580,360731675,360731678,1 +97236,360731675,793479416,1 +97228,360731678,793479449,1 +133581,360731678,793529855,1 +133583,360731679,793529793,1 +133588,360731679,1540895696,1 +50242,361193198,360731319,1 +51048,361193198,361193554,1 +50227,361193220,361193666,1 +51051,361193220,705060346,1 +51097,361193309,361194196,1 +133426,361193397,360730697,1 +51053,361193397,361193403,1 +51050,361193403,361193220,1 +51054,361193403,705060326,1 +51057,361193542,361193554,1 +133423,361193542,705060332,1 +51049,361193554,361193403,1 +51058,361193666,361193779,1 +50228,361193666,705060377,1 +94784,361193751,361193754,1 +51095,361193751,361194561,1 +94785,361193754,1540857325,1 +51106,361193758,361194407,1 +51059,361193779,361193751,1 +51060,361193779,361193798,1 +51061,361193798,361193835,1 +50269,361193798,705060352,1 +51062,361193835,361193837,1 +93343,361193835,361193989,1 +51063,361193837,360731157,1 +50273,361193837,361194058,0 +93342,361193892,361193835,1 +51066,361193892,361193913,1 +50272,361193913,361193837,0 +51064,361193927,361193929,1 +51072,361193927,361193983,0 +51065,361193929,361193931,1 +51067,361193929,361194184,1 +51087,361193931,361194180,1 +82529,361193983,1540846320,0 +93344,361193989,705060354,1 +51068,361193989,705063796,0 +51071,361194058,361193927,0 +50274,361194058,361194180,0 +134819,361194122,705073924,1 +50275,361194180,361195065,0 +51088,361194180,705063795,1 +82528,361194184,361193983,0 +51098,361194196,361194620,1 +51073,361194198,361194388,0 +51108,361194198,361194563,0 +51086,361194245,361193931,1 +82527,361194245,361194184,0 +51084,361194259,361194639,1 +51077,361194259,705059081,0 +134822,361194268,361194300,1 +51080,361194268,361194307,1 +51076,361194285,361194259,0 +127398,361194300,705059078,1 +134823,361194300,1142507856,1 +51081,361194307,361194581,1 +104408,361194307,705059079,1 +51075,361194319,361194285,0 +51104,361194319,361194402,1 +94780,361194348,360731338,1 +51093,361194348,361194480,1 +134825,361194353,361194472,1 +51102,361194353,705059091,1 +51074,361194388,361194319,0 +51105,361194402,361193758,1 +51128,361194402,705059086,1 +51119,361194407,360731342,0 +94808,361194472,704832150,0 +134826,361194472,1540905140,1 +51107,361194477,361194198,0 +134827,361194477,361194568,1 +93188,361194477,1540856458,1 +51094,361194480,361193751,1 +51116,361194480,361196065,0 +51122,361194497,361194548,0 +51110,361194497,361194829,0 +51112,361194500,704832192,0 +51178,361194506,704877193,0 +94820,361194506,704877339,0 +51198,361194523,361196118,1 +51123,361194548,361196136,0 +51096,361194561,361193309,1 +51126,361194561,361194639,1 +51109,361194563,361194497,0 +51130,361194568,361194548,1 +134828,361194568,704832134,1 +51082,361194581,705059082,1 +51131,361194620,705059080,1 +51099,361194620,705059084,1 +93254,361194620,1540856466,1 +51085,361194639,361193754,1 +51127,361194639,361194402,1 +94782,361194645,705059071,1 +51134,361194645,705059074,1 +51136,361194792,705059077,1 +93232,361194792,1540856462,1 +95911,361194797,360730763,1 +51138,361194797,361194799,1 +93213,361194799,705059049,1 +51140,361194828,361194829,1 +51141,361194828,361194986,1 +51111,361194829,361194500,0 +51142,361194986,705059076,1 +93222,361194988,360730765,1 +93212,361194988,361194799,1 +51177,361194990,361194506,0 +93207,361194990,361195985,1 +93203,361194993,361195031,1 +50295,361194993,1540815102,1 +50277,361195006,360731402,0 +51144,361195006,1540815926,1 +51146,361195030,361195031,1 +51187,361195030,361195711,0 +93204,361195031,361195395,1 +51147,361195031,361196420,1 +50276,361195065,361195006,0 +51165,361195393,361195065,1 +51167,361195393,705063990,1 +51164,361195394,361195393,1 +51181,361195394,361195695,1 +51162,361195395,361195768,1 +93205,361195395,705063972,1 +51233,361195400,704877200,0 +51156,361195400,705066602,1 +93218,361195482,361195544,1 +93219,361195544,705059053,1 +51174,361195557,361195640,0 +51170,361195557,361195915,0 +51166,361195571,361195393,1 +51173,361195571,361195557,0 +51180,361195640,361195394,1 +51175,361195640,361195750,0 +51145,361195695,361195030,1 +50294,361195711,361194993,1 +51176,361195750,361194990,0 +51185,361195750,361195768,0 +51186,361195768,361195030,0 +51163,361195768,361195394,1 +51171,361195915,361195955,0 +51206,361195915,1540815928,0 +51183,361195948,736618839,0 +51172,361195955,361195544,0 +51188,361195955,361195948,0 +93208,361195985,705063986,1 +94819,361196026,361194506,0 +51191,361196026,705063970,0 +51133,361196065,361194645,1 +51117,361196065,705059070,0 +94810,361196091,361196109,0 +95746,361196091,361197247,0 +93226,361196106,704826156,1 +51197,361196109,361194523,1 +94811,361196109,704832186,0 +134831,361196118,360729203,1 +51200,361196136,361196143,1 +51124,361196136,704832185,0 +94813,361196143,361194500,0 +51201,361196143,704832190,1 +51199,361196161,361196136,1 +134830,361196161,1540905141,1 +93224,361196176,704877139,1 +94817,361196178,704877151,0 +51210,361196178,704877172,0 +51214,361196194,361196599,0 +51237,361196194,1540815931,0 +51222,361196285,705065791,0 +93309,361196285,705066617,1 +51239,361196354,361196420,1 +51161,361196354,1540815927,1 +50296,361196370,360731665,1 +51242,361196370,746691688,1 +51148,361196420,361196448,1 +51240,361196420,361196504,1 +51160,361196438,361196354,1 +51245,361196438,705066599,1 +51248,361196448,361196499,1 +51250,361196499,705066598,0 +51241,361196504,361196370,1 +51249,361196504,361196499,0 +51254,361196555,361197158,0 +51230,361196555,705065822,0 +24009,361196558,705065837,0 +94167,361196599,361196608,0 +51215,361196599,704826069,0 +51155,361196608,361195400,1 +51238,361196747,361196106,0 +51259,361196747,704877127,0 +94815,361196799,705063967,0 +51263,361196799,705063987,0 +51212,361196814,704877131,0 +51264,361196814,704877155,0 +51158,361196847,704877160,1 +51271,361197034,745990402,1 +51273,361197038,361197140,1 +95203,361197038,746691570,1 +51283,361197057,745990599,1 +51276,361197140,360731671,1 +51274,361197140,745990575,1 +51255,361197158,704826082,0 +51280,361197158,705065841,0 +51154,361197188,361196608,1 +51277,361197188,705065819,0 +51294,361197210,361197327,0 +51217,361197210,704826182,0 +51293,361197240,361197210,0 +51152,361197240,704826074,1 +51296,361197244,361197325,0 +51289,361197247,704826210,0 +95747,361197247,704832187,0 +135109,361197312,360476152,0 +134834,361197325,581288213,1 +51295,361197327,361197244,0 +93228,361197327,704826158,1 +135108,361197354,361197312,0 +51297,361197354,683297775,1 +80615,361197369,360476178,0 +51302,361197369,683295966,1 +51303,361197410,361197473,0 +135106,361197410,683301787,0 +51311,361197473,361197503,1 +51304,361197473,599162414,0 +51313,361197503,338484715,1 +51312,361197503,361197505,1 +51320,361197588,581291046,1 +100339,361197588,1142589018,1 +51316,361197598,361197616,1 +51306,361197598,361197657,0 +51315,361197616,361197588,1 +51317,361197616,581291045,1 +51307,361197657,683297616,0 +51318,361197657,683297730,1 +127093,361198104,792054066,1 +98221,361198104,792056455,1 +48326,361198161,361198799,1 +135112,361198161,361198862,1 +127072,361198161,792056424,1 +127078,361198217,792056420,1 +96818,361198217,792056426,1 +127080,361198220,361198224,1 +96824,361198220,792056479,1 +127081,361198224,361198229,1 +96831,361198224,792056452,1 +127082,361198229,272565046,1 +96802,361198229,792056456,1 +51339,361198448,938502321,1 +125360,361198448,1139714834,0 +125365,361198448,1139744366,1 +48361,361198459,600915597,1 +51348,361198459,797375759,1 +51341,361198461,797375711,1 +89962,361198466,797375746,0 +51356,361198491,361198520,0 +134563,361198491,600915596,1 +51333,361198520,361198659,0 +48389,361198612,360477468,0 +51326,361198612,361198627,0 +48357,361198627,360476556,0 +51327,361198627,361198637,0 +51328,361198637,360476642,0 +134558,361198639,247151604,1 +51359,361198639,361198637,0 +51331,361198641,368356453,0 +3640,361198641,600915595,1 +98038,361198642,600915597,1 +51357,361198642,797375578,0 +127086,361198659,360477595,1 +51334,361198659,361198816,0 +51375,361198697,792056464,1 +51366,361198697,792056474,1 +96781,361198710,361198711,1 +96826,361198711,361198734,1 +51377,361198717,792056454,1 +51355,361198717,1540815941,1 +96827,361198734,361198864,1 +96797,361198734,792056464,1 +135114,361198770,152803460,1 +51385,361198770,792056433,1 +96823,361198772,361198220,1 +135116,361198785,792056473,1 +51393,361198785,1540815944,1 +2836,361198788,579794583,0 +51388,361198796,792056439,1 +96786,361198796,792056445,1 +96822,361198797,361198772,1 +51391,361198797,792056442,1 +48327,361198799,360476306,1 +51400,361198799,1139689445,0 +3644,361198813,247151814,0 +51403,361198813,797375623,0 +51335,361198816,360476329,0 +51396,361198816,361198824,1 +96793,361198819,792056444,1 +51394,361198819,792056470,1 +51398,361198820,361198836,1 +134565,361198820,1139689430,1 +51410,361198821,361198884,1 +134554,361198821,1540904933,1 +51397,361198824,361198820,1 +51408,361198824,1139689426,1 +3642,361198828,247151320,1 +51405,361198828,1540815945,0 +51402,361198836,361198813,0 +51399,361198836,797375601,1 +96810,361198844,361198104,0 +51414,361198844,361198884,1 +127085,361198849,361198659,1 +51407,361198849,361198824,1 +135113,361198862,361198770,1 +51412,361198862,792056448,1 +51365,361198864,361198697,1 +51416,361198864,797375738,1 +51337,361198865,1540815937,0 +51418,361198875,361198929,1 +29715,361198875,797375630,1 +51415,361198884,361198865,1 +51411,361198884,792054054,1 +51419,361198929,361199444,1 +98104,361198929,797375603,1 +51423,361198931,938149076,1 +51425,361198932,938149168,1 +107410,361198932,938149184,1 +51428,361198936,338485831,1 +107447,361198936,938149160,1 +107620,361198939,938501962,1 +127691,361198939,1540885260,1 +127130,361198943,938502250,1 +23969,361198981,294202628,1 +127157,361198998,803745125,0 +51432,361198998,1140945504,1 +127132,361199000,938501975,1 +107543,361199000,938502238,1 +107113,361199003,938142919,1 +127653,361199003,938142932,1 +127655,361199004,938142901,1 +51434,361199004,938143012,1 +127658,361199006,938142994,1 +107404,361199006,938143017,1 +51440,361199010,938142807,1 +107211,361199010,938143081,1 +98186,361199271,797394771,1 +127621,361199271,797394807,1 +127627,361199273,938143058,1 +23984,361199274,294203207,1 +106753,361199380,938143147,1 +23981,361199380,1540793882,1 +2825,361199410,797375861,0 +51420,361199444,797375877,1 +51444,361199477,937216375,1 +106735,361199477,937216579,1 +51447,361199478,1540815948,1 +106699,361199479,938140746,1 +51448,361199479,1540815949,1 +106750,361199485,361199486,1 +51455,361199485,938140816,1 +106751,361199486,361199487,1 +106824,361199486,1540868583,1 +106752,361199487,1540868560,1 +106831,361199487,1540868586,1 +51458,361199497,938140769,1 +107008,361199498,938140768,1 +51461,361199498,938140815,1 +51465,361199499,938142907,1 +23972,361199504,938140802,1 +51464,361199504,1540815953,1 +51468,361199622,938140736,1 +51470,361199622,938140748,1 +83994,361199623,600927591,1 +107011,361199623,938142906,1 +107364,361199624,938143154,1 +107015,361199624,1343076833,1 +107017,361199625,1540868891,1 +107210,361199625,1540868940,1 +143428,361199627,1343067314,1 +107019,361199627,1540868897,1 +107022,361199635,1540868902,1 +107046,361199745,938140772,1 +51477,361199745,1540815959,1 +51478,361199746,937216440,1 +107050,361199746,1540868909,1 +106740,361199750,937216507,1 +51484,361199832,745090717,1 +94970,361199832,1540857379,1 +95017,361199833,793781741,1 +51491,361199833,1540815962,1 +51493,361199837,793781767,1 +94845,361199837,1540857367,1 +51495,361199839,1540815964,1 +94850,361199839,1540857368,1 +51497,361199840,745090272,1 +97413,361199841,793781762,1 +51500,361199841,793781807,1 +51504,361199842,793781666,1 +97403,361200008,793781736,1 +51526,361200008,1540815967,1 +51527,361200011,793781815,1 +63918,361200013,793428420,1 +97459,361200013,793799844,1 +97458,361200016,417278006,1 +97477,361200016,417278011,0 +73508,361215419,1540839674,0 +75450,361215419,1540840197,0 +75468,361215543,536580184,0 +75418,361215543,558998818,1 +69809,361217683,527804408,1 +75520,361217683,1540840221,0 +75536,361217690,510958690,1 +75513,361217690,559547580,0 +127555,361217711,1540885212,0 +127558,361217718,512543904,0 +65910,361217718,1113756031,1 +97540,361220005,795263009,1 +51651,361220005,1540816104,1 +51539,361224674,1540815975,0 +80346,361224674,1540843147,0 +51540,361224781,1540815993,0 +51654,361227771,1540816115,0 +1624,361227781,1540771124,0 +51635,361227927,1540816092,1 +71725,361405791,536580430,1 +71702,361405791,558969988,1 +71701,361405794,361405791,1 +75353,361405794,558970108,1 +75189,361405857,536580565,1 +71706,361405857,1540838983,1 +71705,361405858,361405857,1 +71681,361405858,536580441,1 +71704,361405859,361405858,1 +75349,361405859,536580568,1 +110178,361406126,361406227,0 +51629,361406126,967240601,0 +110174,361406194,361406195,0 +110175,361406195,360019418,0 +110216,361406197,967240676,0 +110180,361406197,1540871304,0 +110183,361406198,1540871305,0 +73868,361406202,1540839732,1 +110202,361406202,1540871320,0 +79940,361406203,795263233,1 +73867,361406203,1540839730,1 +73866,361406204,361406203,1 +71843,361406204,536601223,1 +73872,361406205,795263015,1 +97543,361406205,1540860162,1 +97544,361406207,795263038,1 +97548,361406207,795263237,1 +110179,361406227,361406197,0 +51536,361406227,1540815970,0 +51633,361406381,1540816079,0 +75470,361407391,558986366,0 +51537,361407391,1540815971,1 +51653,361407397,558986366,1 +75388,361407397,558998565,1 +51538,361407397,1540815974,1 +75404,361407397,1540840160,1 +51652,361407935,1540816106,1 +97558,361407935,1540860164,1 +110182,361407943,361406198,0 +51642,361409654,361409655,1 +96768,361409654,536580021,1 +51643,361409655,1540816102,1 +96770,361409655,1540859776,1 +96765,361409658,792049842,1 +51644,361409658,1540816103,1 +51645,361409660,361409661,1 +97587,361409660,528490471,1 +51646,361409661,361409662,1 +40928,361409661,528490467,1 +51647,361409662,361409663,1 +97592,361409662,795263247,1 +51648,361409663,152939864,1 +51655,361423237,1540816117,0 +99440,361424117,801467948,1 +99448,361424117,1540862123,1 +99449,361424352,1540862124,1 +127577,361433594,365970310,1 +51663,361434463,361434464,0 +31633,361434464,353244826,0 +51664,361434464,1540816141,0 +51665,361434467,361434469,0 +50191,361434467,1540815078,1 +51666,361434469,1540816142,0 +50216,361434474,361434511,1 +51668,361434474,1540816144,0 +133413,361434477,361434514,1 +104436,361434477,583222432,0 +50253,361434479,1540815095,0 +104438,361434479,1540866217,0 +122641,361434500,361434464,1 +104451,361434500,1540866223,0 +104450,361434503,361434500,0 +50197,361434503,1540815085,1 +50190,361434504,361434467,1 +104449,361434504,361434503,0 +50198,361434505,360730002,1 +104447,361434505,1093091298,0 +122644,361434507,361434469,1 +104446,361434507,361434505,0 +50207,361434508,360730116,1 +104444,361434508,1142507815,0 +50210,361434509,360730040,1 +104443,361434509,361434508,0 +104442,361434510,361434509,0 +50217,361434511,1540815087,1 +104441,361434511,1540866222,0 +51673,361434514,597897195,0 +133414,361434514,705062339,1 +50250,361434518,1540815093,0 +51671,361434518,1540816147,0 +64409,361434733,360728379,0 +2883,361434733,1540773437,1 +122647,361434733,1540882661,0 +2871,361435530,360728379,1 +122646,361435530,1540882660,0 +2842,361435532,694738742,0 +50186,361435532,1540815075,1 +17707,361435845,361435863,1 +51669,361435863,38842542,0 +17708,361435863,1540787789,1 +96828,361440808,1145564254,1 +2838,361440808,1540773413,0 +80542,361441551,1540843258,0 +80543,361441552,579805328,0 +51683,361441552,1540816175,0 +80545,361441554,361444098,0 +80483,361441554,579805525,0 +80549,361441560,792071826,0 +51687,361442460,1540816205,0 +51695,361442462,797347625,0 +51697,361442465,1540816219,0 +51705,361442465,1540816228,0 +51717,361442466,1540816238,0 +51682,361442902,1540816165,0 +51684,361444006,1540816183,0 +2264,361444012,1540771783,0 +2262,361444021,1540771776,0 +51685,361444021,1540816196,0 +51686,361444085,1540816197,0 +80482,361444085,1540843220,0 +80546,361444098,1540843260,0 +51690,361445222,246588470,0 +51702,361445756,1540816221,0 +51718,361447140,1540816246,0 +51707,361447852,792054063,1 +53492,363860788,363860850,0 +95118,363860788,793252719,0 +100785,363860850,1540862914,1 +53891,363970039,363973550,1 +64049,363970039,363974791,1 +53816,363970045,972481814,1 +53815,363970702,363970045,1 +111863,363970702,1540872302,0 +53818,363970709,974031162,1 +21458,363970709,1540790987,1 +135203,363970711,279591056,0 +29721,363970914,1540799011,1 +53831,363970914,1540820512,1 +29722,363970923,1540799013,1 +112172,363970923,1540872828,1 +53820,363971023,1540820501,1 +112052,363971023,1540872725,0 +53824,363971068,363973197,1 +53822,363971068,1540820509,1 +112101,363971113,279591283,0 +53828,363971317,363971319,1 +53874,363971317,363972551,1 +53829,363971319,363971320,1 +110447,363971319,1540871451,1 +53830,363971335,363970914,1 +53821,363971335,1540820508,1 +53833,363971710,1540820516,1 +110443,363971710,1540871448,1 +53834,363971715,363972544,1 +110455,363971715,968962546,1 +110450,363971719,968962560,1 +53836,363971719,968962568,1 +53842,363971772,974030906,1 +112185,363971818,974030549,1 +53844,363971818,974031014,1 +112146,363971821,974031084,1 +53846,363971821,1540820517,1 +53858,363971828,1540820527,1 +53851,363971995,363971998,1 +110440,363971995,968962566,1 +53852,363971998,1540820523,1 +135189,363972022,974031084,0 +53859,363972022,1540820528,1 +53864,363972226,968962566,1 +53869,363972228,968962557,1 +53867,363972283,363972537,1 +53853,363972283,974030515,1 +53868,363972537,363972228,1 +53835,363972544,363971719,1 +53872,363972544,968962578,1 +53878,363972551,1540820532,1 +40331,363972646,1540810041,0 +53875,363972646,1540820531,1 +53879,363973117,549787401,1 +112166,363973123,363973128,1 +53827,363973128,363971317,1 +53825,363973197,1015275358,1 +53881,363973197,1540820535,1 +53832,363973219,1540820514,1 +53883,363973302,1540820538,1 +53885,363973306,1540820540,1 +112102,363973306,1540872774,1 +111798,363973310,973983132,1 +53887,363973310,1540820542,1 +53890,363973318,1540820547,1 +64048,363973322,363970039,1 +21451,363973406,1540790980,0 +53889,363973416,363973318,1 +53894,363973416,1540820548,1 +53895,363973496,363973753,1 +53905,363973498,363974188,1 +53897,363973498,1540820549,1 +53898,363973550,360189543,1 +53892,363973550,363973939,1 +53896,363973753,363973498,1 +53900,363973753,1540820552,1 +53903,363973757,1540820553,1 +53901,363973774,363974188,1 +21453,363973774,973983639,0 +53893,363973939,363973406,1 +53904,363973939,363973498,1 +53902,363974188,363973757,1 +53906,363974188,1540820554,1 +64050,363974791,363970045,1 +53909,363974791,1242034859,1 +21449,363974809,1540790979,0 +112054,363974816,1540872730,0 +112157,363975093,974030958,1 +135196,363975095,1540905585,0 +135197,363975098,363975104,0 +135198,363975104,363975106,0 +112181,363975104,974030638,1 +135199,363975106,363975108,0 +29730,363975108,338487127,1 +53911,363975202,363975263,0 +21455,363975202,1540790985,1 +135200,363975263,974030673,0 +135202,363975777,363970711,0 +53912,363975777,1540820558,1 +29726,363976091,974030358,1 +109810,363984889,1540871084,1 +41207,363984892,360020010,1 +51631,363984892,1540816075,1 +73613,363984892,1540839714,1 +73615,363984897,360019603,1 +110114,363984901,967199403,1 +73619,363984901,967199712,1 +73621,363984903,363984905,1 +110139,363984903,967199653,1 +110097,363984905,967199357,1 +73622,363984905,1540839717,1 +73623,363984910,967331618,1 +110299,363984910,1540871380,1 +110103,363986457,360020010,1 +109811,363986457,1540871087,1 +109884,363986460,360020011,1 +109812,363986460,966294340,1 +109815,363986466,966153870,1 +109818,363986467,363986469,1 +109736,363986467,966154073,1 +109742,363986469,1540871039,1 +109819,363986469,1540871093,1 +109820,363986473,966315404,1 +109958,363986473,1540871181,1 +109825,363986997,1540871102,1 +37561,363988496,966303920,1 +109672,363988496,1540870991,1 +37566,363988499,1540806333,1 +65795,363989204,509733023,0 +65809,363989204,509823023,1 +65798,363989206,363989210,0 +65703,363989206,509819581,1 +65801,363989206,509829008,1 +65802,363989210,509822990,1 +65799,363989210,1540837229,0 +124979,363989215,363989221,1 +71657,363989215,509820552,1 +125002,363989221,558986620,1 +65781,363989221,1540837214,1 +53928,363990269,363990271,0 +65710,363990269,509731423,1 +53929,363990271,509792008,0 +65752,363990272,509799513,1 +31585,365116937,353244212,1 +55998,365116983,360473545,0 +31630,365116983,1540802526,0 +31632,365117073,365117074,0 +56005,365117073,365117350,0 +127219,365117073,365117353,1 +56004,365117074,365117118,0 +93046,365117074,1540856403,1 +2910,365117118,695556395,1 +50149,365117118,1540815063,0 +56007,365117279,365117357,0 +127236,365117279,695552915,1 +56003,365117281,365117074,0 +31587,365117305,353244213,1 +56009,365117305,1540824323,0 +56006,365117350,365117281,0 +93042,365117350,1540856400,1 +55997,365117353,365116983,0 +56008,365117357,365117305,0 +56029,365117357,695552912,1 +31631,365117377,365117073,0 +127226,365117421,353243803,1 +56013,365117421,365117487,1 +127228,365117458,353244211,1 +56027,365117487,353243220,1 +56014,365117487,365117458,1 +31607,365117516,353244556,1 +56019,365117568,365117516,1 +56033,365117660,365117789,0 +56043,365117660,365117793,1 +2947,365117670,1540773480,0 +56036,365117721,365117748,1 +31622,365117721,365118157,0 +31621,365117724,365117721,0 +2949,365117724,1540773481,0 +56054,365117748,365118108,0 +56037,365117748,583229697,1 +56039,365117752,365117989,1 +56041,365117752,695549704,1 +56034,365117789,597692637,0 +56044,365117793,583229697,1 +56047,365117793,695549705,1 +56050,365117875,365117876,1 +31624,365117875,695549708,0 +56051,365117876,365117878,1 +31617,365117876,1540802525,1 +56061,365117878,365118300,1 +31605,365117904,353244323,0 +56052,365117904,365117918,0 +56053,365117918,365117748,0 +56049,365117918,365117875,1 +2948,365117964,365117724,0 +127309,365117964,365119749,0 +56056,365117989,365118045,1 +56040,365117989,1540824334,1 +56057,365118045,1307601640,1 +93036,365118045,1540856399,1 +56046,365118106,365117670,1 +93037,365118106,365118108,1 +56055,365118108,365117964,0 +31623,365118157,365117875,0 +56059,365118157,695549730,1 +2950,365118244,365118300,0 +31601,365118255,353244641,0 +56060,365118255,365117878,1 +2951,365118300,1540773482,0 +56082,365118450,365118704,0 +56063,365118450,365118827,1 +56065,365118453,365118787,1 +56084,365118453,365119324,0 +56067,365118456,360474741,1 +56094,365118456,694738257,0 +56162,365118467,365120329,1 +56072,365118467,1540824336,1 +134941,365118564,365119980,0 +56073,365118564,561406961,0 +102734,365118569,365120945,0 +134950,365118569,1540905180,0 +81778,365118578,597692642,0 +56083,365118704,561406865,0 +56079,365118704,1540824338,0 +56078,365118705,365118704,0 +127480,365118705,561406856,0 +56077,365118707,365118705,0 +56089,365118707,365118787,0 +56075,365118708,365118928,0 +56105,365118708,365119215,0 +56066,365118787,365118456,1 +56086,365118825,365118910,0 +80983,365118825,561407112,0 +56064,365118827,365118453,1 +127479,365118827,365118705,0 +56080,365118875,365119351,0 +56128,365118875,365119398,0 +56125,365118906,365119491,0 +56087,365118910,365118914,0 +56157,365118914,365119882,1 +56088,365118914,1540824340,0 +56093,365118928,365118456,0 +56076,365118928,365118707,0 +56127,365118952,365118875,0 +127486,365118952,365119334,0 +56130,365118955,694738235,0 +127485,365118955,1540885178,0 +56097,365118967,360473994,0 +56133,365118967,694738024,0 +56104,365118971,365119029,0 +56090,365118971,365119058,1 +80986,365119029,1540844149,0 +56091,365119058,365119108,1 +56117,365119058,365119869,0 +56102,365119083,365119839,0 +56112,365119083,561406845,0 +56092,365119108,365118910,1 +56108,365119108,561407112,0 +80985,365119199,365119029,0 +56116,365119199,365119058,0 +56110,365119215,365118707,0 +56106,365119215,365119882,0 +56109,365119239,365119215,0 +56114,365119239,365120002,0 +56119,365119318,365119351,0 +2851,365119318,1540773423,0 +56085,365119324,365118906,0 +134934,365119324,694738420,1 +127487,365119334,365118827,0 +56121,365119334,365119324,0 +56081,365119351,365118450,0 +56120,365119351,365119334,0 +56124,365119377,365118906,0 +56096,365119377,365118967,0 +134924,365119398,360473825,0 +2850,365119398,1540773421,0 +56129,365119464,365118955,0 +2849,365119464,1540773420,0 +56126,365119491,365118952,0 +56137,365119491,365119512,0 +127484,365119494,365118955,0 +2848,365119494,365119464,0 +56132,365119512,365118967,0 +134865,365119552,360473937,0 +56099,365119552,365119576,0 +48240,365119576,360474646,0 +56100,365119576,1540824345,0 +127478,365119620,365118564,0 +56166,365119620,365120421,0 +127475,365119623,1540885177,0 +127474,365119625,365119623,0 +134943,365119650,365119683,0 +134862,365119673,365119650,1 +56168,365119673,365119713,0 +134944,365119683,365119735,0 +149366,365119683,561406956,0 +56111,365119686,365119083,0 +56139,365119686,561406954,0 +149365,365119713,365119683,0 +56169,365119713,365119799,0 +134945,365119735,365119796,0 +56141,365119735,365119799,0 +56138,365119749,1540824348,0 +56152,365119749,1540824349,0 +80987,365119749,1540844150,0 +56155,365119796,365119892,1 +134946,365119796,560576613,0 +56170,365119799,365119892,0 +56142,365119799,1144045162,0 +56103,365119839,365118971,0 +56153,365119860,561406952,1 +80988,365119860,1540844151,0 +56118,365119869,1540824346,0 +56107,365119882,365119108,0 +56158,365119882,365119869,1 +56171,365119892,365120913,0 +56156,365119892,1144045155,1 +127491,365119893,365970038,1 +57805,365119893,365970041,0 +127500,365119895,365970340,1 +57854,365119895,559590175,1 +127503,365119897,365970409,1 +57849,365119897,559590178,0 +75610,365119897,1540840264,1 +138645,365119899,559590219,1 +134882,365119899,559590499,1 +134942,365119980,365119650,0 +56161,365119980,365120421,0 +56115,365120002,365118708,0 +56159,365120002,561406960,0 +127476,365120060,562865819,0 +76447,365120060,1143999566,0 +127498,365120079,365970140,1 +134850,365120166,365119625,0 +93033,365120166,365120332,0 +127473,365120329,365119625,0 +56163,365120329,365120332,1 +93034,365120332,360474182,0 +56164,365120332,1540824350,1 +56165,365120338,1307599921,1 +134849,365120338,1540905144,0 +138635,365120340,365122653,1 +138642,365120351,365120352,1 +57852,365120351,365970426,0 +138643,365120352,365970566,1 +57864,365120352,1540827685,0 +56167,365120421,365119673,0 +56058,365120476,1307601639,1 +76453,365120855,365970171,0 +127517,365120855,365970174,1 +57803,365120883,365970402,0 +149367,365120883,1144045151,0 +57807,365120903,365120906,0 +57829,365120906,365970302,1 +57808,365120906,560576488,0 +102766,365120907,365120940,1 +57810,365120907,561407905,0 +56172,365120913,365121140,0 +127522,365120913,560576807,1 +56180,365120938,365121140,1 +127511,365120938,560576807,0 +57828,365120938,1540827682,1 +56176,365120940,365121050,1 +127510,365120940,1540885185,0 +56175,365120945,560576521,0 +102735,365120945,1540864434,0 +134949,365121026,365118569,0 +56178,365121026,561406948,1 +102751,365121036,360001817,1 +127580,365121036,1013433973,1 +56174,365121050,365120945,0 +56177,365121050,365121026,1 +56173,365121140,365121050,0 +56181,365121140,561407060,1 +56184,365121235,562865810,0 +138637,365121235,1540923520,1 +56186,365121964,365120340,0 +138654,365121964,562865754,0 +127472,365122021,365120329,0 +2015,365122021,1540771404,1 +56192,365122254,360474182,0 +127465,365122254,360474613,1 +2019,365122312,1540771406,1 +127356,365122312,1540885130,0 +56191,365122325,365122254,0 +56193,365122325,365122312,0 +56190,365122328,365122325,0 +56195,365122579,365122328,0 +2021,365122579,1540771407,1 +138636,365122653,365121235,1 +56196,365122653,365970500,0 +57874,365122684,365970555,0 +56198,365122684,1540824356,0 +56201,365122693,559590716,0 +75653,365122695,559590746,1 +75650,365122695,1540840267,0 +134929,365308199,353246114,0 +56474,365308199,365308200,1 +56475,365308200,583223031,1 +125333,365308966,695578756,1 +56481,365308966,1540824872,0 +47808,365308986,360467600,0 +134980,365308986,1540905483,0 +56485,365309005,365309031,0 +47813,365309005,1540813599,0 +56482,365309031,574839084,0 +2813,365309669,938502152,0 +2809,365309670,938502319,0 +107481,365309670,938502359,1 +89074,365309671,600205127,0 +2807,365309671,1540773396,0 +23955,365310391,1139689432,1 +107524,365310981,938502346,1 +115141,365310981,1540874302,0 +126447,365310990,1540884446,1 +90062,365310995,1540853857,1 +126449,365310995,1540884450,1 +115518,365310996,653318226,1 +126450,365310996,984771986,1 +115531,365310997,984771562,1 +126459,365310997,1540884452,1 +126461,365311002,1540884466,1 +143181,365311005,984771495,1 +126462,365311005,1540884468,1 +98646,365311007,365311008,0 +98647,365311008,365311009,0 +98648,365311009,1540861498,0 +98640,365311012,365311013,1 +57763,365311012,1540827649,1 +87977,365311013,1540851133,1 +98641,365311013,1540861492,1 +98642,365311016,1540861494,1 +57761,365311020,1540827631,1 +98645,365311020,1540861497,1 +56923,365377172,1540824941,1 +98643,365377172,1540861495,1 +56924,365378192,1540824942,1 +56925,365378203,1172607848,1 +57760,365378203,1540827626,1 +56928,365378211,1172576871,1 +56945,365388273,1038253611,1 +56949,365388274,1371044549,1 +56951,365388275,1038225039,1 +120624,365388275,1540880471,1 +56953,365388276,1540825069,1 +56954,365388278,1371044384,1 +120616,365388278,1540880458,1 +142543,365388286,365388287,1 +142544,365388287,1037361932,1 +119926,365388298,1540879686,1 +142547,365388298,1540934736,1 +119863,365388304,1540879609,1 +142549,365388304,1540934737,1 +142551,365388314,1036628172,1 +119879,365388314,1540879625,0 +98644,365925014,1540861496,1 +57765,365925632,1540827651,1 +57771,365925662,1343039237,1 +76451,365969981,562865799,0 +76435,365969981,1540840720,0 +127515,365969989,365120883,0 +127549,365969989,1540885186,0 +127493,365969990,365970190,1 +127547,365969990,365970401,0 +102762,365969992,560576483,1 +57781,365969992,560576485,0 +57780,365969993,365969992,0 +102777,365969993,365970356,0 +127508,365970002,560576491,0 +57786,365970003,365970014,0 +118020,365970003,560576540,0 +102764,365970012,365970037,1 +118015,365970012,365970039,0 +57787,365970014,365970002,0 +57792,365970014,560576498,1 +57796,365970037,560576487,1 +102765,365970037,1540864438,1 +127492,365970038,365969990,1 +102775,365970039,560576482,0 +118016,365970039,832461836,0 +127527,365970040,365970044,1 +118011,365970040,560576476,0 +127525,365970041,365970042,1 +57806,365970041,1540827680,0 +57800,365970042,365970038,1 +127526,365970042,365970040,1 +57785,365970044,365969990,0 +127528,365970044,365970189,1 +127531,365970045,365970159,1 +57816,365970045,561406793,1 +127541,365970046,365970139,1 +127533,365970046,560576636,1 +134877,365970047,365970309,1 +134875,365970047,1540905150,1 +95906,365970048,559939134,0 +57795,365970093,365970037,1 +102774,365970093,365970039,0 +40244,365970094,360001881,1 +102781,365970094,365970095,0 +127544,365970095,360001267,1 +102782,365970095,365970096,0 +40239,365970096,360001613,1 +102783,365970096,365970097,0 +134880,365970097,360001659,1 +118021,365970097,560576800,1 +127542,365970139,360001413,1 +57836,365970139,560576628,1 +127499,365970140,365119895,1 +127539,365970140,560576480,1 +40234,365970141,562865808,1 +138639,365970141,1540923521,1 +57811,365970147,365970308,1 +102756,365970147,365970344,1 +127532,365970159,365970046,1 +57813,365970159,365970160,1 +127496,365970160,562865845,1 +57814,365970161,365970307,1 +102758,365970161,365970354,1 +127495,365970169,365970160,1 +57818,365970169,365970400,1 +57821,365970171,365970174,1 +127518,365970174,365970406,1 +102760,365970187,365970359,1 +57822,365970187,560576484,1 +127530,365970188,365970045,1 +127529,365970189,365970188,1 +57826,365970189,561406790,1 +127494,365970190,365970169,1 +57830,365970302,365970303,1 +57798,365970302,560576477,1 +57831,365970303,365970305,1 +118013,365970303,560576486,0 +57832,365970305,365970306,1 +57783,365970305,560576475,0 +57833,365970306,365970307,1 +57824,365970306,560576474,1 +57815,365970307,365970045,1 +57834,365970307,365970308,1 +57835,365970308,365970139,1 +57812,365970308,365970159,1 +134878,365970309,360001817,1 +57838,365970309,365970310,1 +127578,365970310,559939202,1 +127501,365970340,365970427,1 +40241,365970340,560576479,0 +102757,365970344,365970161,1 +57839,365970344,365970345,1 +102780,365970345,365970094,0 +57840,365970345,365970346,1 +40229,365970346,360001881,0 +57841,365970346,560576554,1 +102779,365970352,365970345,0 +57844,365970352,365970354,1 +40228,365970353,365970346,0 +57843,365970353,365970352,1 +102759,365970354,1540864437,1 +102778,365970356,365970352,0 +57846,365970356,365970357,1 +40227,365970357,365970353,0 +57847,365970357,560576548,1 +102761,365970359,365969992,1 +57845,365970359,365970356,1 +57791,365970379,365970014,1 +57848,365970379,365970381,1 +127512,365970381,560576525,1 +76401,365970381,1540840703,1 +57819,365970400,562865789,1 +56146,365970400,562865848,0 +127548,365970401,365969989,0 +56145,365970401,365970400,0 +57804,365970402,365119893,0 +56144,365970402,365970401,0 +127519,365970406,365970408,1 +40236,365970406,562865879,1 +127535,365970408,365970425,1 +57856,365970408,365970492,1 +127504,365970409,365970503,1 +127537,365970409,562865689,1 +57851,365970425,365120351,0 +127536,365970425,365970409,1 +57885,365970426,559590145,1 +127502,365970427,365119897,1 +57853,365970427,365970433,1 +56151,365970433,559590178,0 +57857,365970492,365970666,1 +138640,365970492,559590155,1 +57859,365970493,1540827683,1 +127588,365970493,1540885222,0 +56200,365970495,365122693,0 +56197,365970500,365122684,0 +75637,365970500,1236109583,1 +127585,365970502,365970583,0 +2011,365970502,559591651,1 +57863,365970503,365120352,0 +127505,365970503,365970565,1 +127587,365970526,365970493,0 +57866,365970526,1540827687,0 +57868,365970532,365122693,0 +57869,365970532,1540827688,0 +95781,365970554,559565020,0 +40193,365970554,1540809947,1 +57860,365970555,365970495,1 +57875,365970555,365970557,0 +57871,365970556,365970559,0 +2013,365970556,365970604,1 +57867,365970557,365970532,0 +57876,365970557,365970564,0 +57872,365970559,365970560,0 +75647,365970559,559590851,0 +75664,365970560,559590407,0 +57873,365970560,1144177921,0 +75669,365970562,559590910,0 +95786,365970562,559590932,0 +95784,365970563,559564605,0 +76430,365970564,365970584,1 +57877,365970564,559591651,0 +127506,365970565,365119899,1 +57878,365970565,365970566,1 +138644,365970566,365119899,1 +134876,365970566,562866044,1 +127586,365970583,365970526,0 +76429,365970583,365970564,1 +57870,365970584,365970556,0 +76431,365970584,365970603,1 +75651,365970585,559590298,0 +76433,365970585,559591489,1 +56203,365970586,365122695,0 +76432,365970603,365970585,1 +125034,365970603,365970586,0 +2014,365970604,150563575,1 +125033,365970604,365970603,0 +75666,365970605,338485188,0 +125030,365970605,559590851,0 +125026,365970607,559590866,0 +125022,365970607,559590877,0 +57883,365970608,365970607,1 +75682,365970608,559590955,1 +64080,365970610,428468059,1 +57879,365970610,559591192,1 +57884,365970638,365970426,1 +57865,365970638,1540827686,0 +75632,365970638,1540840266,0 +57858,365970666,365970493,1 +57887,365970666,365970667,1 +138638,365970667,365970141,1 +79037,366360713,1041566398,1 +87444,366360714,1540850041,1 +134562,368356447,361198491,1 +51332,368356453,361198520,0 +58844,368356453,368356447,0 +83935,368362870,1540846768,0 +83936,368362871,653281576,1 +83932,368362871,1540846757,0 +83938,368362872,1540846771,0 +83939,368362874,1540846775,0 +83924,368362875,1540846755,1 +83940,368362875,1540846779,0 +59345,372786481,372788603,1 +59353,372786481,1540831976,1 +59342,372786538,372786607,1 +59352,372786538,1540831974,1 +87986,372786607,372787887,1 +59355,372787082,1307354329,1 +138207,372787082,1307354373,1 +138172,372787085,1540922547,1 +138404,372787664,372788601,1 +87987,372787887,1307354505,1 +59348,372788363,372788365,1 +138406,372788363,372789204,1 +59347,372788365,372787887,1 +138405,372788601,372788363,1 +59349,372788601,372788603,1 +59346,372788603,372788365,1 +59344,372789199,372787664,1 +59350,372789199,1540831968,1 +138407,372789204,355921358,1 +33704,372799421,355921423,1 +59351,372799421,1540831970,1 +87983,372800259,1345665604,1 +81969,417276274,417279721,0 +100709,417276274,801451957,1 +81200,417276966,272562879,0 +63911,417276966,417278831,1 +63914,417276967,417276968,1 +97479,417276967,1540859984,0 +63915,417276968,793799882,1 +97449,417276968,793799968,1 +81202,417277347,272562878,0 +63923,417277347,417277348,1 +81964,417277348,801062735,0 +81198,417278005,417278773,0 +63928,417278006,417278005,0 +63913,417278008,417276967,1 +63926,417278008,417278772,0 +63924,417278010,417278561,0 +63920,417278010,793428417,1 +97471,417278011,793799872,1 +97478,417278011,1540859983,0 +63925,417278561,417278008,0 +63931,417278772,417278833,1 +63927,417278772,1540833519,0 +81199,417278773,1540844390,0 +63922,417278829,417277347,1 +63933,417278829,417278830,1 +63930,417278830,417278561,1 +63934,417278830,417278831,1 +63912,417278831,417278008,1 +63935,417278831,1540833521,1 +63932,417278833,417278773,1 +83946,417279548,600924052,1 +97482,417279548,793804785,0 +97484,417279549,745090595,0 +63936,417279714,1540833522,0 +63950,417279714,1540833526,1 +84125,417279714,1540847162,0 +84137,417279716,417279717,1 +84127,417279716,603748691,1 +84138,417279717,603753179,1 +84112,417279717,1540847161,0 +84144,417279718,603753273,1 +97464,417279718,793799999,1 +81197,417279720,417278005,0 +84149,417279720,417279721,1 +81970,417279721,272562944,0 +64013,418771177,363973318,1 +64038,418771179,418771205,1 +111748,418771179,972315602,1 +111689,418771179,972315878,1 +81026,418771181,418771184,1 +111751,418771181,1540872197,1 +81025,418771182,418771181,1 +81030,418771182,1540844162,1 +81031,418771183,418771202,1 +111770,418771183,972315734,1 +81027,418771184,418771185,1 +64019,418771184,1540833564,1 +64029,418771192,1540833572,1 +112076,418771193,973983436,1 +64032,418771193,1540833578,1 +64035,418771196,1540833579,1 +111777,418771196,1540872201,1 +111755,418771199,966653587,1 +64037,418771199,1540833588,1 +64022,418771201,966653522,1 +81032,418771202,1540844163,1 +111750,418771204,1540872196,1 +64039,418771205,583433288,1 +44854,418771205,1540811895,1 +73524,418771207,1540839685,1 +73531,418771212,549791372,1 +104721,418771212,1540866377,1 +104719,418771213,549791374,1 +17598,418771215,1540787701,1 +44866,418771215,1540811902,1 +98588,428468059,559591299,1 +64081,428468059,559591441,1 +64084,428468061,428468062,1 +95904,428468061,559591323,1 +64085,428468062,428468063,1 +75696,428468062,559591242,1 +2172,428468063,153884112,1 +64086,428468063,559591336,1 +75687,428468066,1540840269,1 +134889,428468066,1540905151,1 +75692,428468592,559591120,0 +95795,428468592,559591129,0 +125020,428468592,559591199,0 +98580,428468594,559590832,1 +125036,428468594,559590878,1 +93477,429286578,1030313266,0 +64111,429286578,1540833658,0 +93492,429286579,1030323712,1 +64112,429286579,1540833660,0 +93486,429286582,429286591,1 +64113,429286582,1540833661,0 +64114,429286584,1540833663,0 +93498,429286584,1540856555,1 +64115,429286588,429286590,1 +93451,429286588,1540856529,1 +93499,429286590,360205304,1 +64116,429286590,429286591,1 +93487,429286591,360205305,1 +64117,429286591,429286592,1 +93491,429286592,429286579,1 +64118,429286592,429286593,1 +93513,429286593,716888818,1 +17053,445393419,445393420,0 +81165,445393419,1540844350,0 +81163,445393420,584358264,0 +106904,445393429,1540868647,0 +106883,445393431,1540868619,0 +64245,445393446,584358284,0 +36829,445393446,1540805338,0 +64357,457230371,1540834170,1 +82017,457230371,1540845827,1 +64370,457240513,457240515,0 +64371,457240515,1540834219,0 +64403,457240515,1540834239,0 +95103,457248414,286537125,1 +64381,457248414,1540834228,0 +50083,457248427,745985508,0 +64380,457248427,1540834223,0 +50233,457256017,360730889,0 +64393,457256017,705971107,0 +133411,457256020,705971111,0 +64395,457256020,1540834234,0 +50070,457420810,597897427,0 +64402,457420810,1540834235,0 +64435,457421308,597897427,0 +64434,457421390,457421308,0 +92212,457421390,1540856203,1 +64408,457428510,599162160,0 +70239,457428510,745984394,1 +82058,462754120,598495534,0 +64710,462754120,1540834580,0 +81984,462754210,462754212,0 +81985,462754212,462754213,0 +98769,462754212,800448625,1 +81986,462754213,462754215,0 +98816,462754213,800448654,1 +81987,462754215,1540845755,0 +98752,462754219,800449039,1 +81988,462754219,1540845756,0 +81956,462754220,800448829,0 +108616,474383589,360003715,1 +65118,475012900,1540835005,0 +75466,475012900,1540840205,0 +65117,475012901,1540834996,0 +65119,475013802,1540835015,0 +73507,475013802,1540839671,0 +65122,475013808,1540835021,0 +65682,509726746,509731819,1 +65712,509726763,509784554,1 +65738,509726763,509788984,1 +65651,509726763,1540837206,1 +65741,509726766,509792008,1 +65649,509726766,509793998,1 +65644,509726773,509800752,1 +125001,509726773,558986344,1 +53927,509729310,363990269,0 +65684,509729310,509816891,1 +65691,509729317,509733341,1 +65686,509729317,509736324,1 +65688,509729325,509729330,1 +65699,509729325,509730692,1 +65797,509729330,363989206,0 +65803,509729330,509823006,1 +65689,509730033,509730047,1 +65745,509730033,509730697,1 +65690,509730047,509729317,1 +65707,509730047,509731413,1 +65700,509730692,509730697,1 +65705,509730692,509736334,1 +65701,509730697,509799513,1 +65780,509730697,509818658,1 +65746,509730697,509819404,1 +65754,509730716,509820568,1 +65777,509731413,509816891,1 +65708,509731413,509817608,1 +65711,509731423,509726763,1 +65714,509731423,509731819,0 +65683,509731819,509729310,1 +65715,509731819,1540837207,0 +65721,509732516,363989204,1 +65696,509732516,509734746,1 +65796,509733023,509729330,0 +65804,509733023,509733321,1 +65698,509733321,509729325,1 +65805,509733321,509733324,1 +65806,509733324,509733341,1 +65732,509733324,509736324,1 +65692,509733341,509734717,1 +65807,509733341,509816897,1 +53926,509733346,509729310,0 +65724,509734717,509734746,1 +65697,509734746,509733321,1 +65687,509736324,509729325,1 +65733,509736324,509736334,1 +65706,509736334,509730047,1 +65680,509762089,509786325,1 +65739,509775715,509788984,1 +125144,509775715,509797982,1 +75376,509781936,536580274,1 +125147,509781936,1540884019,1 +125149,509781962,250929229,1 +125143,509784103,509775715,1 +65713,509784554,509784103,1 +65681,509786325,509726746,1 +65737,509786325,509784554,1 +65740,509788984,509726766,1 +53930,509792008,509795863,0 +65742,509792008,509817729,1 +65748,509793998,363990271,1 +65650,509793998,509726763,1 +65648,509795647,509726766,1 +65749,509795647,509795863,1 +53931,509795863,363990272,0 +65647,509797751,509795647,1 +65750,509797751,509797982,1 +125145,509797982,558986344,1 +65751,509799083,363990272,1 +65646,509799083,509797751,1 +65702,509799513,509730716,1 +65645,509800752,509799083,1 +65753,509800752,1540837210,1 +65756,509801624,558986291,1 +65783,509801624,1540837215,1 +65800,509801624,1540837230,1 +65744,509816537,509730033,1 +65776,509816537,509731413,1 +65685,509816891,509729317,1 +65778,509816891,509816897,1 +65808,509816897,509733346,1 +65709,509817608,363990269,1 +65779,509817608,509817729,1 +65743,509817729,509816537,1 +65747,509819404,363989210,1 +124982,509819404,509819581,1 +65704,509819581,509730692,1 +124978,509820552,509820568,1 +124975,509820552,1540883957,1 +65755,509820568,509801624,1 +124981,509820568,1540883960,1 +65784,509822990,509829008,1 +65786,509823006,509823015,1 +65722,509823015,509733023,1 +65787,509823015,509823023,1 +65785,509829008,509823006,1 +75318,509829008,558969734,1 +69829,510957511,527804452,1 +65882,510958048,559494707,0 +75531,510958216,559547587,1 +65887,510958216,1540837250,1 +75484,510958263,559547586,1 +125070,510958334,510959026,1 +75537,510958690,559498295,1 +75539,510958707,559547591,1 +65914,510958841,510958855,1 +75512,510958841,1540840219,0 +65945,510958855,510958690,1 +69842,510960690,1540838596,1 +66256,512543904,512543905,1 +127559,512543904,512543936,0 +66273,512543905,512543931,1 +66259,512543906,512543907,1 +66296,512543907,512543927,1 +66263,512543911,512543906,1 +66262,512543911,512543912,1 +66294,512543912,512543922,1 +66267,512543914,512543915,1 +66291,512543914,512543959,1 +66279,512543915,512543916,1 +66268,512543916,512543918,1 +66280,512543916,1540837354,1 +66314,512543918,512543961,1 +66295,512543922,512543907,1 +66269,512543922,512543923,1 +66270,512543923,512543924,1 +66276,512543923,512543939,1 +66317,512543924,512543931,1 +66271,512543927,512543929,1 +66297,512543927,559554557,1 +66272,512543929,512543905,1 +66275,512543929,512543923,1 +66318,512543931,361217718,1 +66274,512543936,1540837353,1 +127560,512543936,1540885216,0 +66277,512543939,512543941,1 +75558,512543939,559554551,1 +66278,512543941,512543915,1 +66300,512543941,512543961,1 +66306,512543943,512543964,1 +66320,512543944,559554579,1 +66283,512543944,1540837355,1 +66309,512543946,1540837363,1 +66322,512543947,512543980,1 +66284,512543947,1540837356,1 +124986,512543951,512543980,1 +124995,512543954,512543956,1 +66286,512543954,559554573,1 +66313,512543956,512543918,1 +66305,512543957,512543943,1 +66290,512543957,1540837359,1 +66299,512543959,512543941,1 +66292,512543959,559554549,1 +127561,512543960,559554516,0 +66315,512543961,559554551,1 +66301,512543961,1540837360,1 +66312,512543964,512543956,1 +66307,512543964,1540837362,1 +66319,512543967,512543944,1 +66308,512543967,512543946,1 +66311,512543970,1540837366,1 +66310,512543971,1540837364,1 +65120,512543974,360015838,1 +124980,512543980,1113355734,1 +94548,523552911,737642136,1 +68966,523552911,1540838298,1 +94539,523552911,1540857161,1 +68967,523552914,523552926,1 +68981,523552914,737642097,1 +68970,523552916,523552922,1 +115143,523552917,737655447,1 +68972,523552917,1540838299,1 +68974,523552919,523552920,1 +94545,523552919,523552923,1 +68975,523552920,523552916,1 +68977,523552920,523552921,1 +115170,523552921,1540874355,1 +68971,523552922,523552917,1 +94546,523552923,737309562,1 +68979,523552923,737309696,1 +68968,523552926,737655829,1 +68985,523553316,247152817,0 +125352,523553316,797375755,1 +69780,527804357,527804358,1 +69788,527804357,527804374,1 +130236,527804358,352724693,0 +75441,527804358,559489055,1 +69781,527804359,527804361,1 +31340,527804359,559488972,0 +75440,527804359,559489037,1 +69783,527804361,1540838551,1 +2933,527804364,352723320,0 +69819,527804367,175702481,1 +69787,527804367,527804357,1 +69785,527804367,1540838553,1 +69786,527804372,527804373,1 +2940,527804372,1540773471,0 +89040,527804373,1540852117,1 +69789,527804374,527804375,1 +69795,527804374,559488989,1 +69790,527804375,527804376,1 +69794,527804375,559488968,1 +65847,527804376,352724694,0 +69791,527804376,560712446,1 +69793,527804377,527804375,1 +69800,527804383,527804384,1 +69846,527804383,1540838599,1 +69801,527804384,527804385,1 +69827,527804384,1540838582,1 +69802,527804385,527804386,1 +69808,527804385,1540838568,1 +69851,527804386,1540838603,1 +69815,527804387,527804377,1 +69817,527804387,527804413,1 +69803,527804387,1540838557,1 +69821,527804390,527804416,1 +69804,527804390,1540838559,1 +130257,527804393,510957511,1 +69805,527804393,1540838561,1 +69838,527804397,527804433,1 +69806,527804397,1540838564,1 +69833,527804400,527804439,1 +69807,527804400,1540838566,1 +75446,527804407,527804459,1 +75499,527804408,559498300,1 +69810,527804408,559498324,1 +69814,527804411,510958048,1 +69836,527804411,559494817,1 +69818,527804413,527804367,1 +69822,527804416,527804373,1 +69831,527804416,1540838591,1 +69820,527804418,527804390,1 +130254,527804418,1540886556,1 +69799,527804423,527804383,1 +130222,527804423,1540886535,1 +69798,527804424,527804423,1 +69811,527804424,1540838572,1 +75941,527804428,1540840463,1 +65846,527804432,527804376,0 +75940,527804432,527804428,1 +75443,527804432,527804715,1 +69825,527804433,1540838575,1 +69828,527804433,1540838586,1 +69834,527804439,527804461,1 +69826,527804439,1540838579,1 +69830,527804452,1540838589,1 +69816,527804459,527804387,1 +69850,527804459,1540838601,1 +130253,527804459,1540886554,1 +69832,527804460,527804400,1 +69852,527804460,1540838604,1 +69835,527804461,527804411,1 +69843,527804461,527804580,1 +69837,527804473,527804397,1 +69853,527804473,1540838605,1 +69844,527804580,527804687,1 +130219,527804580,1540886532,1 +130220,527804587,559494747,1 +130223,527804630,527804646,1 +75435,527804646,527804428,1 +130224,527804646,1540886537,1 +69848,527804647,527804715,1 +75477,527804687,559494747,1 +69845,527804687,1540838598,1 +69849,527804695,527804630,1 +69847,527804695,1540838600,1 +130256,527804703,527804393,1 +69792,527804715,527804377,1 +75444,527804715,575177978,1 +83878,528298545,600400245,1 +108610,528475264,474383589,1 +108622,528475264,961664611,1 +69854,528489602,528489604,1 +69884,528489602,528490635,1 +71632,528489602,536580034,1 +69855,528489604,528489606,1 +40935,528489604,528490498,1 +124969,528489606,795264058,1 +124945,528489606,1540883948,1 +69856,528489609,528489673,1 +71615,528489609,536579530,1 +124949,528489609,795264048,1 +124951,528489612,528489614,1 +124959,528489612,795264053,1 +69860,528489614,528489696,1 +124952,528489614,1540883949,1 +124937,528489623,1540883945,1 +124928,528489628,528489634,1 +97625,528489628,536579540,1 +124929,528489634,528489638,1 +69862,528489634,795264061,1 +124930,528489638,528489641,1 +124956,528489638,795264059,1 +124931,528489641,528489646,1 +69859,528489641,795264082,1 +97612,528489646,360015303,1 +124932,528489646,528489651,1 +69878,528489651,360015144,1 +69879,528489651,528490626,1 +69857,528489673,1540838606,1 +69858,528489683,528489641,1 +69861,528489696,1540838607,1 +40821,528489749,536600711,1 +69866,528489749,575190298,0 +69868,528489754,575190303,0 +69871,528489780,1540838616,0 +69872,528489785,528489791,0 +69873,528489791,528489796,0 +79949,528489791,1540841865,1 +69874,528489796,1540838618,0 +79952,528489796,1540841866,1 +71593,528489802,1540838946,0 +78924,528489802,1540841150,1 +78925,528489811,1540841151,1 +78927,528489815,966315215,1 +110208,528489815,1540871327,1 +78930,528489826,528489829,1 +78931,528489829,967241255,1 +78933,528489831,528489833,1 +109911,528489831,1540871155,1 +78934,528489833,528489836,1 +109990,528489833,1540871201,1 +78935,528489836,363986466,1 +109952,528489836,966314837,1 +97550,528490283,795263042,1 +104429,528490283,1540866209,1 +124960,528490283,1540883953,1 +124962,528490323,560935844,1 +69881,528490392,528490498,1 +124971,528490392,801484153,1 +40929,528490467,528490471,1 +40930,528490471,528490476,1 +97588,528490471,795263255,1 +40931,528490476,528490482,1 +40932,528490482,528490485,1 +96772,528490482,795263245,1 +40933,528490485,1540810205,1 +69882,528490498,528490632,1 +40936,528490498,801484164,1 +97619,528490503,528490516,1 +99516,528490516,360015125,1 +97620,528490516,1540860169,1 +69875,528490581,360015126,1 +97621,528490581,360015143,1 +69877,528490597,528489651,1 +97637,528490597,1540860174,1 +69880,528490626,528490392,1 +71617,528490626,795264064,1 +69883,528490632,528489602,1 +97624,528490632,1540860170,1 +69886,528505102,1540838619,1 +106592,528505102,1540868475,1 +69887,528505105,1540838621,1 +69888,528505111,528505112,1 +69889,528505112,528505113,1 +75745,528505112,559938637,1 +69890,528505113,528505114,1 +69891,528505114,528505120,1 +108623,528505114,956789196,1 +69892,528505120,559939191,1 +69893,528505120,559939194,1 +130252,528510373,560583695,0 +76045,528510373,560712656,1 +31327,528510376,560712656,0 +75924,528510376,1540840452,1 +81015,536578765,279591161,1 +71572,536578765,536578769,1 +99508,536578765,801480047,1 +71573,536578769,536578772,1 +99479,536578769,801480030,1 +71574,536578772,536578783,1 +99476,536578772,1540862144,1 +81014,536578783,360016250,1 +71575,536578783,583432483,1 +73518,536578787,536578890,1 +110084,536578787,1540871255,0 +73516,536578819,536578824,1 +71580,536578819,536578831,1 +71611,536578824,536578827,1 +73517,536578824,1540839683,1 +73522,536578827,1540839684,1 +73521,536578831,536578827,1 +105176,536578839,360010681,1 +73519,536578890,536578893,1 +105163,536578890,932361992,1 +105182,536578893,360008436,1 +73520,536578893,360014969,1 +110083,536578904,536578787,0 +71584,536578904,583432485,1 +71589,536578905,583432484,1 +110081,536578905,583432488,0 +110080,536578912,536578905,0 +71608,536578912,549785233,1 +71592,536578940,536578765,1 +81012,536578940,583432486,1 +71800,536579174,536600927,1 +71604,536579174,1540838954,0 +71827,536579193,575190303,1 +71600,536579193,1540838952,0 +71599,536579195,536579193,0 +71828,536579195,967331721,1 +71598,536579200,1540838949,0 +79948,536579202,528489785,1 +71597,536579202,536579200,0 +71594,536579208,575191572,0 +71789,536579208,1540839011,1 +71610,536579336,536578824,1 +105183,536579336,932361988,1 +40594,536579350,360010600,1 +105178,536579350,932361966,1 +105180,536579351,536579356,1 +105181,536579356,583433055,1 +124968,536579484,528489606,1 +71614,536579484,1540838962,1 +97642,536579487,528489614,1 +124966,536579487,795264078,1 +71613,536579491,528489623,1 +124964,536579491,795263245,1 +76153,536579491,1540840595,1 +76154,536579504,528490476,1 +97611,536579530,528489646,1 +71616,536579530,528490626,1 +97626,536579540,536579546,1 +97604,536579540,795264061,1 +97627,536579546,536579549,1 +97633,536579546,795264089,1 +40290,536579549,536601028,1 +97628,536579549,575189660,1 +97630,536579554,536579557,1 +40678,536579554,536600985,1 +71773,536579557,536600678,1 +97631,536579557,575190243,1 +71621,536579589,528490485,1 +71634,536579589,536580023,1 +71627,536579954,792049842,1 +96771,536579954,1540859777,1 +71626,536580021,536579954,1 +71625,536580023,536580021,1 +71624,536580024,536580023,1 +96769,536580024,1540859775,1 +71623,536580027,536580024,1 +96763,536580027,536580047,1 +40934,536580033,528489604,1 +71628,536580033,536580034,1 +71633,536580034,536579589,1 +71629,536580034,792049841,1 +71631,536580047,559556410,1 +71635,536580106,536580107,1 +124998,536580106,1540883973,1 +75380,536580107,558986043,1 +71636,536580107,558986191,1 +73506,536580108,1540839668,0 +75360,536580118,558986313,1 +71642,536580118,1540838967,1 +75368,536580126,558986317,1 +71643,536580126,1540838969,1 +75370,536580129,558986264,1 +71640,536580129,558986427,1 +71638,536580140,536580143,1 +65758,536580140,558986306,1 +71639,536580143,536580129,1 +75362,536580143,558986253,1 +71649,536580182,536580184,1 +75390,536580182,558998914,1 +75469,536580184,361407391,0 +71654,536580215,536580216,1 +71713,536580215,536580565,1 +75346,536580216,509823015,1 +71655,536580216,536580218,1 +71670,536580218,509823006,1 +71656,536580218,536580220,1 +75320,536580220,536580223,1 +75347,536580223,536580227,1 +75321,536580223,536580448,1 +75331,536580227,558969853,1 +71641,536580233,536580118,1 +65760,536580233,536580323,1 +75394,536580250,558985993,1 +124996,536580250,1540883972,1 +125000,536580258,509726773,1 +71658,536580258,536580274,1 +75377,536580274,536580276,1 +75378,536580276,536580279,1 +75409,536580276,1540840163,1 +75379,536580279,536580107,1 +75382,536580281,1540840139,1 +124989,536580281,1540883966,1 +41183,536580314,558972592,1 +71661,536580323,536580325,1 +65761,536580323,566676910,1 +71662,536580325,536580328,1 +75324,536580325,1540840131,1 +71663,536580328,536580335,1 +71667,536580328,536580356,1 +71664,536580335,536580338,1 +75343,536580335,536580368,1 +71716,536580338,536580568,1 +71721,536580350,536580362,1 +71665,536580350,558969921,1 +71684,536580356,536580445,1 +71668,536580356,558970157,1 +71722,536580362,558969704,1 +75341,536580362,558969914,1 +71683,536580368,536580356,1 +75344,536580368,536580380,1 +75345,536580380,536580216,1 +75191,536580380,558970157,1 +75348,536580417,361405859,1 +71676,536580417,558970199,1 +71726,536580430,558970277,1 +71715,536580441,536580338,1 +71682,536580441,536580368,1 +75323,536580445,536580325,1 +75322,536580448,536580445,1 +75193,536580448,558969885,1 +75336,536580466,360019201,1 +65763,536580466,558969635,1 +75366,536580480,363989215,1 +75398,536580480,558986277,1 +71711,536580557,509823023,1 +71712,536580557,536580215,1 +75190,536580565,536580380,1 +71714,536580565,536580441,1 +71717,536580568,558969906,1 +71724,536580569,361405791,1 +71719,536580569,558970476,1 +71727,536600430,528489785,1 +71731,536600430,536600453,1 +71728,536600444,528489780,1 +71730,536600444,536600430,1 +71729,536600449,536600444,1 +71769,536600449,575190250,1 +71732,536600453,536600456,1 +71733,536600456,1540838986,1 +110060,536600456,1540871247,1 +71734,536600462,536600463,1 +71735,536600463,536600465,1 +110010,536600463,1540871212,1 +71736,536600465,966314817,1 +109903,536600468,966314738,1 +71738,536600468,1540838988,1 +71739,536600470,536600472,1 +71740,536600472,536600473,1 +109928,536600472,1540871165,1 +71741,536600473,536600477,1 +110008,536600473,966314671,1 +71742,536600477,536600479,1 +71747,536600477,966314806,1 +71743,536600479,1540838989,1 +109969,536600479,1540871188,1 +71744,536600481,1540838990,1 +71745,536600484,536600486,1 +109985,536600484,966314842,1 +107841,536600486,940611001,1 +107853,536600488,536600489,1 +107844,536600488,940610994,1 +107854,536600489,536600490,1 +110025,536600489,966315160,1 +109984,536600490,536600484,1 +107855,536600490,536600492,1 +71746,536600492,536600477,1 +107856,536600492,1540869556,1 +71761,536600519,536600595,1 +71749,536600519,1540838993,1 +71750,536600528,1540838997,1 +110270,536600538,967331684,1 +71751,536600538,1540838999,1 +71752,536600549,536600554,1 +71764,536600549,536600613,1 +71753,536600554,967331715,1 +110301,536600557,967331692,1 +71755,536600557,1540839001,1 +111800,536600564,536600601,1 +71756,536600564,1540839002,1 +71757,536600569,536600572,1 +111769,536600569,536601283,1 +71786,536600572,360012485,1 +71758,536600572,536600575,1 +71759,536600575,972315277,1 +40842,536600579,972315512,1 +71762,536600595,536600554,1 +71763,536600595,536600601,1 +111801,536600601,972315303,1 +71765,536600613,536600616,1 +110296,536600613,967331684,1 +71766,536600616,536600619,1 +110303,536600616,967331620,1 +110256,536600619,967331695,1 +71767,536600619,1540839003,1 +71768,536600626,536600449,1 +110253,536600626,1540871360,1 +124934,536600652,1540883944,1 +78923,536600658,1540841148,0 +71772,536600671,536579557,1 +78921,536600671,1540841140,0 +71774,536600678,536600690,1 +71810,536600678,1540839016,1 +71826,536600690,536579193,1 +71775,536600690,967331721,1 +71777,536600711,536600714,1 +40822,536600711,967331646,1 +71778,536600714,972315498,1 +71783,536600718,972315164,1 +71785,536600730,536600572,1 +40833,536600730,1540810178,1 +71787,536600764,536600766,1 +79920,536600764,536601139,1 +110273,536600766,536600780,1 +71788,536600766,1540839007,1 +110274,536600780,536600786,1 +79936,536600780,1540841864,1 +110275,536600786,536600791,1 +71854,536600786,536601210,1 +110276,536600791,536600796,1 +71840,536600791,536601181,1 +110277,536600796,536600803,1 +71832,536600796,536601087,1 +110288,536600803,536600807,1 +40896,536600807,360013423,1 +71791,536600876,1540839015,1 +79947,536600879,536579202,1 +71792,536600879,967331658,1 +71794,536600884,536600889,1 +71842,536600889,536579200,1 +71795,536600889,967331623,1 +71797,536600894,536600905,1 +71830,536600894,536601084,1 +71825,536600905,536600690,1 +71798,536600905,536600908,1 +71811,536600908,360013425,1 +71799,536600908,536579554,1 +40734,536600927,360011302,1 +71801,536600927,536600942,1 +78920,536600942,1540841135,0 +71802,536600956,575189659,1 +78922,536600956,1540841143,0 +71804,536600985,360013428,1 +124939,536600985,1113233823,1 +71813,536601028,536601029,1 +97632,536601029,536579546,1 +71814,536601029,1540839019,1 +97602,536601038,795264060,1 +71815,536601038,1540839020,1 +71816,536601042,536601046,1 +71619,536601042,795264086,1 +71817,536601046,536601049,1 +97640,536601046,795264077,1 +71818,536601049,1540839021,1 +71861,536601049,1540839031,1 +71819,536601060,536601062,1 +71820,536601062,536601063,1 +71821,536601063,536601064,1 +79928,536601063,967331738,1 +71822,536601064,536601066,1 +71837,536601066,536601171,1 +71823,536601066,1540839022,1 +71831,536601084,536600796,1 +40895,536601084,536600807,1 +71833,536601087,1540839024,1 +71839,536601087,1540839025,1 +71834,536601102,536601105,1 +71835,536601102,536601167,1 +79930,536601105,536601113,1 +79931,536601113,575187160,1 +71853,536601113,1540839027,1 +79933,536601128,536601131,1 +79934,536601128,575187165,1 +79946,536601131,536601135,1 +79919,536601135,536600764,1 +79923,536601139,536601143,1 +79921,536601143,536601146,1 +79924,536601143,795263228,1 +79944,536601146,536601149,1 +79922,536601146,536601231,1 +79945,536601149,536601131,1 +79937,536601149,536601235,1 +71836,536601167,536601064,1 +110286,536601167,536601171,1 +110287,536601171,536600803,1 +71838,536601171,536601087,1 +71841,536601181,536600889,1 +40894,536601181,536601084,1 +71855,536601210,536600884,1 +40893,536601210,536601181,1 +71844,536601223,1540839026,1 +71845,536601228,536601229,1 +71856,536601228,536601251,1 +71846,536601229,536601230,1 +97600,536601229,795263224,1 +71847,536601230,795263229,1 +71850,536601231,967331627,1 +71852,536601235,536601113,1 +79938,536601235,795263244,1 +71857,536601251,536601252,1 +71858,536601252,536601254,1 +97574,536601252,795263224,1 +71859,536601254,536601256,1 +104431,536601254,795263242,1 +97572,536601256,795263256,1 +71860,536601256,1540839030,1 +110289,536601265,536600714,1 +40824,536601265,967331717,1 +40826,536601267,536601268,1 +40827,536601268,536601271,1 +40828,536601271,536601273,1 +111776,536601271,972315164,1 +40829,536601273,967331647,1 +111799,536601281,536600564,1 +40831,536601281,536601283,1 +40832,536601283,536600730,1 +73501,549556862,1540839647,0 +73503,549560806,1540839664,0 +419,549775624,1540770128,0 +118049,549775624,1540876384,1 +387,549775642,1540770079,0 +98699,549775654,800140482,0 +390,549775654,1540770089,0 +98709,549775669,800140476,0 +392,549775669,1540770095,0 +394,549775677,35839639,0 +98704,549775677,800140469,0 +75740,549775695,1540840326,0 +75758,549777920,1540840357,0 +73513,549778901,559938637,0 +40412,549785171,360007556,1 +149413,549785171,981693507,1 +149726,549785183,360006484,0 +71612,549785230,279591159,1 +40268,549785230,583432484,1 +71607,549785230,1540838959,1 +40455,549785233,360008268,0 +71609,549785233,1540838961,1 +22963,549785476,286367976,0 +40314,549785476,1540810007,0 +73543,549787375,549787387,1 +73528,549787375,972481824,1 +111879,549787380,972481635,1 +73530,549787380,1540839688,1 +73544,549787387,360189633,1 +64043,549787387,972481820,1 +53876,549787401,974030750,1 +53880,549787401,1540820533,1 +73546,549791264,549791266,1 +73539,549791264,549791366,1 +73547,549791266,549791267,1 +73551,549791266,549791273,1 +73548,549791267,549791269,1 +73549,549791269,549791270,1 +73550,549791270,549791271,1 +73554,549791270,549791277,1 +44883,549791271,549791275,1 +73553,549791273,549791269,1 +73552,549791273,549791275,1 +44884,549791275,360190665,1 +73607,549791277,360189873,1 +73555,549791279,549791281,1 +73561,549791279,549791302,1 +73576,549791279,1540839703,0 +73541,549791281,360190665,1 +73603,549791283,972481629,1 +73556,549791288,549791289,1 +73533,549791288,549791376,1 +73558,549791289,549791295,1 +73557,549791289,1540839690,1 +73559,549791295,549791297,1 +73560,549791295,549791299,1 +73537,549791299,549791381,1 +44886,549791302,972481872,1 +73573,549791310,549791344,1 +73562,549791310,1540839694,1 +73563,549791316,549791318,1 +73565,549791316,549791325,1 +73564,549791318,549791321,1 +73566,549791318,549791328,1 +73581,549791321,549791367,1 +73596,549791325,549791328,1 +73597,549791328,549791367,1 +73567,549791333,1540839695,1 +73599,549791333,1540839711,1 +73572,549791337,549791310,1 +73568,549791337,549791338,1 +73536,549791338,549791299,1 +73569,549791339,549791341,1 +73584,549791339,549791372,1 +73588,549791341,549791376,1 +73570,549791341,1540839696,1 +73571,549791343,549791337,1 +73590,549791343,549791379,1 +73591,549791344,549791381,1 +73574,549791344,1540839697,0 +73579,549791351,549791359,1 +73575,549791351,1540839701,0 +73580,549791359,549791321,1 +73577,549791359,1540839705,0 +73540,549791366,549791281,1 +73578,549791366,549791351,1 +73598,549791367,549791333,1 +73582,549791370,549791371,1 +73593,549791370,549791375,1 +73583,549791371,549791339,1 +73532,549791372,549791288,1 +73585,549791374,549791371,1 +104720,549791374,1540866376,1 +73587,549791375,549791341,1 +73594,549791375,549791378,1 +73534,549791376,549791379,1 +73595,549791378,549791325,1 +73589,549791378,549791343,1 +73535,549791379,549791338,1 +73538,549791381,1540839689,1 +73592,549791387,549791370,1 +111876,549791387,912014324,1 +111875,549791399,549791387,1 +112059,549791399,1540872734,1 +75356,558948630,558970199,1 +71653,558949277,536580215,1 +75326,558969627,558969662,1 +65764,558969635,153877090,1 +75314,558969635,558969639,1 +41181,558969639,1540810266,1 +75327,558969662,558969802,1 +75316,558969677,558969681,1 +75340,558969677,1540840135,1 +71723,558969704,536580569,1 +75319,558969734,536580220,1 +75329,558969734,558969853,1 +75325,558969794,558969627,1 +71720,558969802,536580350,1 +75328,558969802,558969811,1 +41178,558969811,1540810265,1 +75332,558969853,509822990,1 +75330,558969885,536580227,1 +75194,558969885,536580233,1 +71718,558969906,536580569,1 +75333,558969906,558969914,1 +75342,558969914,536580335,1 +75334,558969914,558969921,1 +71666,558969921,536580328,1 +75335,558969921,558969794,1 +75212,558969967,558970290,1 +71703,558969988,361405859,1 +75338,558969988,558969992,1 +75211,558970108,558969967,1 +71669,558970157,536580218,1 +75192,558970157,536580448,1 +71677,558970199,536580430,1 +75291,558970256,558948630,1 +75209,558970256,1540840100,1 +75210,558970277,1540840102,1 +41173,558970290,1540810260,1 +71700,558970405,361405794,1 +41174,558970405,558970476,1 +41175,558970476,360019192,1 +71660,558972562,536580314,1 +75357,558972562,1540840138,1 +75359,558972579,536580118,1 +75358,558972592,558972579,1 +124988,558985993,536580281,1 +75373,558985993,558985998,1 +75374,558985998,558986017,1 +124976,558986017,509820552,1 +124999,558986031,536580258,1 +75375,558986031,536580279,1 +75381,558986043,536580281,1 +125148,558986063,509781962,1 +75383,558986063,558986071,1 +75410,558986071,1540840164,1 +75386,558986107,1540840151,1 +75387,558986129,1540840154,1 +124997,558986179,536580106,1 +75393,558986179,1540840158,1 +71637,558986191,536580108,1 +124990,558986191,1540883969,1 +75395,558986247,558986253,1 +75363,558986253,558986263,1 +75396,558986262,558986263,1 +75397,558986263,558986264,1 +75364,558986263,558986298,1 +75371,558986264,558986277,1 +75372,558986277,363989221,1 +65757,558986291,536580140,1 +75399,558986291,558986298,1 +75365,558986298,536580480,1 +65759,558986306,536580233,1 +75400,558986306,1540840159,1 +75361,558986313,536580143,1 +75401,558986313,558986317,1 +75369,558986317,536580129,1 +125146,558986344,1540884018,1 +51541,558986366,1540816001,0 +75471,558986366,1540840209,0 +125004,558986385,1113355759,1 +73505,558986385,1540839666,0 +71644,558986427,558986620,1 +75367,558986593,536580126,1 +125003,558986620,558986385,1 +71645,558986620,1540838971,1 +124977,558986648,1540883958,1 +65782,558986653,558986017,1 +75389,558998565,536580182,1 +75402,558998565,558998570,1 +75403,558998570,558998573,1 +75421,558998570,558998855,1 +75405,558998704,558998710,1 +75429,558998704,558998914,1 +75414,558998710,558998799,1 +75406,558998719,558998721,1 +75417,558998719,558998806,1 +75426,558998727,558998877,1 +75407,558998727,1540840161,1 +71647,558998737,1540838975,1 +75408,558998737,1540840162,1 +75412,558998793,558998796,1 +75420,558998793,1540840168,1 +75413,558998796,558998710,1 +75415,558998799,558998801,1 +75392,558998799,1540840156,1 +75423,558998801,558998863,1 +75416,558998801,1540840167,1 +75425,558998806,558998727,1 +75428,558998818,558998704,1 +75419,558998818,558998793,1 +71648,558998855,536580182,1 +75422,558998855,558998801,1 +75424,558998863,1540840170,1 +71646,558998877,1540838972,1 +75427,558998877,1540840171,1 +75391,558998914,558998799,1 +75430,559481038,1540840174,1 +75434,559481038,1540840188,1 +75431,559481046,1540840178,1 +75432,559481046,1540840180,1 +75437,559488958,352724694,1 +31342,559488958,352724958,0 +69782,559488958,527804361,1 +75438,559488968,559488972,1 +130233,559488968,559489037,0 +31341,559488972,559488958,0 +130235,559488989,527804358,0 +75439,559488989,559488997,1 +31339,559488997,527804359,0 +130234,559489037,559488989,0 +31338,559489055,559488997,0 +127556,559494652,559494666,0 +75447,559494652,1540840196,0 +75449,559494656,559494659,0 +75465,559494659,1540840204,0 +75452,559494666,559494671,1 +127557,559494666,1540885215,0 +75516,559494671,559494711,0 +75453,559494671,1540840198,0 +75458,559494677,510959026,0 +75457,559494694,1540840199,0 +75464,559494702,1540840201,0 +75472,559494705,1540840211,0 +75473,559494707,559494708,0 +75492,559494707,559494817,1 +65883,559494707,1540837245,0 +75474,559494708,1540840212,0 +75497,559494708,1540840215,1 +75475,559494711,559494652,1 +75517,559494711,559498309,0 +130221,559494747,1540886533,1 +75478,559494761,1540840213,0 +75498,559494772,527804587,1 +69812,559494772,559498324,1 +75493,559494817,1540840214,1 +75479,559498281,559498282,1 +75496,559498281,559498302,1 +75515,559498283,559494671,0 +75480,559498283,559498285,1 +75481,559498285,559498286,1 +75491,559498285,559498297,1 +75482,559498286,559498287,1 +75488,559498286,559498294,1 +75483,559498287,510958263,1 +75486,559498287,559498291,1 +75456,559498291,559494677,0 +75487,559498292,559498286,1 +75533,559498292,559547588,1 +75455,559498294,559498291,0 +75538,559498295,510958707,1 +75489,559498295,559547588,1 +75454,559498297,559498294,0 +75494,559498300,559498301,1 +75495,559498301,559498281,1 +75519,559498302,1540840220,0 +75518,559498309,559498302,0 +75500,559498309,559498310,1 +69813,559498324,527804411,1 +75514,559547580,559498283,0 +75485,559547586,510958334,1 +75532,559547587,559498292,1 +75535,559547587,559547591,1 +75490,559547588,559498285,1 +75534,559547588,1540840243,1 +75540,559547591,510958717,1 +75550,559554515,559554516,1 +75565,559554515,559554557,1 +75564,559554518,559554515,1 +75556,559554528,559554529,1 +75569,559554528,559554577,1 +66288,559554529,559554632,1 +66293,559554549,512543912,1 +75557,559554549,512543939,1 +66316,559554551,512543924,1 +66298,559554557,512543960,1 +75451,559554564,559494666,0 +75566,559554564,559554565,1 +124974,559554572,1113355734,1 +66287,559554573,559554529,1 +75567,559554573,1540840246,1 +75568,559554576,559554528,1 +75570,559554576,559554579,1 +66282,559554577,512543944,1 +66321,559554579,512543947,1 +66289,559554632,512543952,1 +66281,559554632,559554577,1 +66261,559554849,512543911,1 +75571,559554849,559554858,1 +51638,559556410,792045763,1 +71622,559556449,536580027,1 +51640,559556449,1540816101,1 +75581,559564585,152942587,1 +80291,559564585,559564587,0 +80292,559564587,559564590,0 +75573,559564590,359997152,1 +80293,559564590,985946206,0 +75574,559564592,559564593,0 +80288,559564592,559564599,0 +75575,559564593,559564594,0 +75606,559564594,1540840262,1 +80280,559564597,1540843027,0 +75576,559564599,559564600,1 +80289,559564599,985946252,0 +2165,559564600,359998262,0 +75577,559564601,297562149,1 +80287,559564601,559564592,0 +75579,559564602,359998587,1 +75609,559564602,559564988,1 +75580,559564603,559564604,1 +80286,559564603,1540843032,0 +95785,559564605,365970562,0 +75592,559564605,559564606,1 +75593,559564606,559564607,1 +75594,559564606,1540840256,1 +75676,559564628,559590260,1 +80284,559564628,1540843030,0 +75604,559564650,559564930,1 +75595,559564650,1540840257,1 +95791,559564703,359998622,1 +75596,559564703,559564712,1 +75598,559564766,559564777,1 +75600,559564766,559564809,1 +75599,559564777,559564786,1 +75601,559564777,1540840258,1 +98716,559564901,359998262,0 +75602,559564901,1540840260,1 +75605,559564930,559564594,1 +75608,559564930,559564953,1 +40195,559565020,359998581,0 +95782,559565020,559591342,0 +40179,559565029,1540809933,1 +57886,559590145,365970666,1 +138641,559590155,365120351,1 +57855,559590175,365970408,1 +56150,559590175,365970433,0 +57850,559590178,365970425,0 +127575,559590207,559590213,1 +127574,559590213,559590219,1 +138646,559590219,559590569,1 +75616,559590250,559590252,1 +75678,559590250,559590364,1 +75617,559590260,559590262,1 +75677,559590260,1540840268,1 +75618,559590274,559590278,1 +75680,559590274,559590932,1 +75620,559590278,559590290,1 +75619,559590278,1540840265,1 +95788,559590281,365970561,0 +75654,559590281,365970607,0 +75626,559590290,559590364,1 +75652,559590298,150563575,0 +75621,559590298,559590299,1 +75622,559590307,559590309,1 +75661,559590307,559590547,0 +75623,559590317,559590320,1 +75668,559590317,1144177921,1 +75643,559590320,559590837,1 +75659,559590342,365970561,1 +75624,559590342,559590346,1 +75625,559590360,559590290,1 +75658,559590360,559590342,1 +75679,559590364,559590274,1 +75627,559590380,559590383,1 +75641,559590380,559590835,1 +75657,559590383,559590360,1 +75628,559590400,559590407,1 +127594,559590400,559590892,1 +75665,559590407,365970605,0 +125032,559590424,365970604,0 +75629,559590424,559590429,1 +75630,559590429,559590434,1 +134874,559590429,559590850,1 +98587,559590434,150563576,1 +75631,559590449,559590453,1 +134886,559590449,559590882,1 +134883,559590499,365970502,1 +75633,559590499,559590507,0 +75634,559590507,559590515,0 +75635,559590515,559590547,0 +75645,559590515,559590852,0 +75662,559590547,559590881,0 +138647,559590569,297562141,1 +75636,559590569,559590507,1 +56202,559590716,365970586,0 +138630,559590746,559590863,1 +75638,559590805,559590810,1 +127589,559590805,559590840,1 +127596,559590810,559590893,1 +75639,559590829,559590832,1 +94827,559590829,1493227274,1 +98581,559590832,559590840,1 +75640,559590834,559590380,1 +80282,559590834,559590876,0 +75642,559590835,559590320,1 +57861,559590835,559590888,0 +124993,559590837,365970561,0 +125028,559590838,559590892,0 +127590,559590840,559590841,1 +98582,559590840,559590893,1 +94826,559590841,559590829,1 +98586,559590848,559590434,1 +75649,559590850,559590848,0 +125031,559590851,559590424,0 +75648,559590851,559590850,0 +127584,559590852,365970502,0 +75646,559590852,365970559,0 +138649,559590853,559564597,1 +75644,559590853,559590515,0 +138631,559590863,1493227268,1 +98579,559590866,428468594,1 +125011,559590866,559590868,1 +64088,559590866,559590982,0 +125012,559590868,559590871,1 +125013,559590871,559590872,1 +75655,559590871,559590874,1 +94830,559590872,1540857349,1 +75684,559590874,559590991,1 +75656,559590876,559590383,1 +80283,559590876,1540843028,0 +125035,559590877,428468594,1 +125027,559590877,559590838,0 +94829,559590878,559590872,1 +75660,559590880,559590307,0 +80281,559590880,559590834,0 +75663,559590881,365970560,0 +127583,559590881,559590852,0 +152705,559590882,559590883,1 +94823,559590882,1540857345,1 +94824,559590883,1540857346,1 +75667,559590888,559590317,1 +57862,559590888,559590881,0 +127593,559590889,559590400,1 +127592,559590889,559590837,0 +125029,559590892,365970605,0 +127595,559590892,559590810,1 +98583,559590893,338485188,1 +127597,559590893,559590894,1 +94825,559590894,559590841,1 +75709,559590901,559590916,0 +75672,559590903,559590901,0 +75705,559590903,559590924,0 +75671,559590905,559590903,0 +125017,559590905,1540883974,0 +57882,559590910,365970608,1 +75670,559590910,559590905,0 +75673,559590916,559590917,1 +75710,559590916,559591142,0 +125016,559590921,559590905,0 +75674,559590921,559590924,1 +75675,559590924,559590925,1 +75706,559590924,559590991,0 +94832,559590925,1540857352,1 +75681,559590932,365970608,1 +95787,559590932,559590281,0 +125015,559590955,559590921,0 +125014,559590982,559590955,0 +75707,559590991,559590868,0 +75685,559590991,559590982,1 +75683,559590995,559590874,1 +94831,559590995,1540857351,1 +75686,559591005,559591007,1 +94836,559591005,1540857358,1 +75699,559591007,559591278,1 +75689,559591046,428468067,1 +75690,559591046,559591072,1 +75691,559591046,559591091,1 +75693,559591120,365970563,0 +57881,559591120,559590910,1 +75704,559591129,559590903,0 +95796,559591129,559591142,0 +95797,559591142,559591157,0 +75711,559591142,559591235,0 +95798,559591157,559591165,0 +94834,559591165,1540857355,1 +57880,559591192,559591120,1 +152366,559591192,559591199,1 +125021,559591199,428468059,0 +75703,559591228,559591129,0 +75694,559591228,559591235,1 +75712,559591235,428468061,0 +75695,559591235,559591242,1 +75697,559591242,559591157,1 +94835,559591271,559591005,1 +75698,559591271,559591007,1 +75700,559591299,559591303,1 +98589,559591299,559591383,1 +95790,559591303,559564703,1 +75701,559591314,559591317,0 +75719,559591314,559591411,1 +64083,559591317,428468061,1 +75702,559591317,559591228,0 +75708,559591326,1540840276,0 +94833,559591326,1540857353,1 +75725,559591331,428468067,1 +75713,559591331,559591336,1 +64087,559591336,1540833657,1 +95783,559591342,365970563,0 +75714,559591342,1540840277,1 +64079,559591347,365970610,1 +75715,559591353,559591360,1 +40109,559591353,1540809886,1 +75722,559591360,559591420,1 +75717,559591383,559591403,1 +75718,559591403,559591314,1 +75728,559591403,1540840278,1 +75720,559591411,559591416,1 +75729,559591411,559591470,1 +75721,559591416,559591360,1 +75726,559591416,559591439,1 +75723,559591420,153884112,1 +64082,559591441,559591317,1 +75727,559591441,559591403,1 +95793,559591449,1540858417,1 +2012,559591651,365970556,1 +40108,559591668,559591353,1 +75730,559591668,559591420,1 +75739,559597059,559597231,0 +75731,559597059,1013433859,0 +75732,559597072,1540840279,1 +75736,559597072,1540840288,0 +118036,559597231,1540876350,0 +118037,559597237,1540876355,0 +73515,559938589,1540839682,0 +75744,559938589,1540840333,1 +73514,559938637,559938589,0 +75746,559938648,1540840334,0 +119650,559938648,1540879265,0 +119653,559938648,1540879269,1 +75752,559938656,559938888,0 +75749,559938712,1540840336,1 +75750,559938830,559938712,0 +75751,559938860,1540840342,0 +75753,559938888,359999214,0 +118047,559938954,1540876378,0 +75755,559938981,1540840348,0 +137781,559938981,1540920278,0 +119660,559939005,1033229536,0 +75756,559939005,1540840351,0 +75757,559939021,1540840355,0 +75760,559939030,549775695,0 +75761,559939033,360003280,1 +94797,559939033,1540857334,1 +75763,559939040,559939041,1 +75764,559939041,559939042,1 +40183,559939042,559939080,1 +75765,559939044,559939045,1 +118029,559939044,1540876338,0 +75776,559939045,1540840368,0 +75766,559939046,559939047,1 +118030,559939046,1540876340,0 +75767,559939047,559939048,1 +75775,559939047,1540840367,0 +75768,559939055,559938860,0 +75769,559939059,559939060,1 +40213,559939059,1540809962,1 +75770,559939060,559939061,1 +75781,559939060,559939104,0 +75771,559939061,360003285,1 +75773,559939069,1540840364,0 +75772,559939070,559939069,0 +95751,559939070,1540858412,0 +40197,559939080,359998685,0 +40184,559939080,1540809936,1 +75774,559939080,1540840365,0 +75779,559939093,559939096,1 +75780,559939096,559939097,1 +94796,559939097,1540857333,1 +95752,559939104,360000951,0 +94792,559939104,559939096,1 +40248,559939113,360003285,0 +118040,559939113,1540876358,0 +118039,559939114,559939113,0 +75735,559939127,1540840281,1 +75782,559939127,1540840370,0 +95910,559939129,361433594,0 +95909,559939132,559939129,0 +95908,559939133,559939132,0 +95907,559939134,559939133,0 +95905,559939136,365970048,0 +75785,559939136,1113355836,1 +75784,559939137,559939136,1 +75788,559939137,559939150,1 +75783,559939138,559939137,1 +127576,559939139,361433594,1 +75786,559939139,559939140,1 +75615,559939147,365970048,0 +75787,559939147,1113355836,1 +124992,559939149,559940470,1 +94795,559939150,1540857332,1 +75789,559939153,559939134,1 +94788,559939153,559939155,1 +75790,559939155,559939133,1 +94789,559939155,559939158,1 +75791,559939158,559939160,1 +94790,559939158,559939169,1 +75792,559939164,559939167,1 +127582,559939164,1013433983,1 +75793,559939167,559939160,1 +127570,559939167,559939169,1 +127571,559939169,559939132,1 +94791,559939169,559939202,1 +119659,559939186,1540879270,0 +119654,559939191,559939194,1 +119655,559939194,961664455,1 +127579,559939202,365121036,1 +118025,559939216,1540876331,0 +118027,559939230,1540876336,0 +75614,559940322,559939147,0 +75795,559940322,559940323,1 +75613,559940324,559940322,0 +75796,559940324,559940325,1 +75797,559940326,559940327,1 +75804,559940326,559940462,1 +118031,559940333,1013433836,0 +75798,559940333,1540840378,0 +75747,559940357,360000523,0 +118034,559940379,1540876343,0 +118048,559940379,1540876382,0 +75799,559940439,559939149,0 +124985,559940439,1540883962,1 +75800,559940452,559940457,1 +124983,559940452,559940459,1 +75803,559940457,559940326,1 +75801,559940457,559940458,1 +124991,559940458,559939149,1 +124984,559940459,559940439,1 +75802,559940459,1540840387,1 +75612,559940462,559940324,0 +40181,559940463,1540809934,1 +94793,559940470,1540857327,1 +94794,559940470,1540857330,1 +2170,559940483,559564597,0 +75794,559940483,1540840374,1 +75893,560576458,560576460,1 +57789,560576458,560576537,1 +133740,560576458,1540896937,0 +75927,560576460,560583762,1 +40209,560576460,1540809958,0 +75894,560576461,560576462,0 +133741,560576461,560576463,0 +102741,560576462,560576544,1 +75895,560576463,560576464,0 +133742,560576463,560576674,0 +102744,560576464,560576550,1 +57825,560576474,365970188,1 +75896,560576474,560576475,1 +57784,560576475,365970044,0 +75897,560576475,560576476,1 +118012,560576476,365970303,0 +75898,560576476,560576477,1 +75899,560576477,365120903,1 +57799,560576477,365970042,1 +40242,560576479,365970047,0 +75900,560576479,560576480,1 +127540,560576480,365970046,1 +75901,560576481,560576482,1 +102772,560576481,560576656,0 +102776,560576482,365969993,0 +75902,560576482,560576483,1 +102763,560576483,365970012,1 +57823,560576484,365970306,1 +75903,560576484,560576485,1 +57782,560576485,365970305,0 +75904,560576485,560576486,1 +118014,560576486,365970012,0 +75905,560576486,560576487,1 +57797,560576487,365970302,1 +75906,560576487,560576488,1 +57809,560576488,365120907,0 +75907,560576491,560576498,0 +127509,560576491,1540885184,0 +75908,560576498,560576501,0 +57793,560576498,832461845,1 +118019,560576501,365970003,0 +102736,560576521,561406913,1 +102738,560576525,1540864435,1 +57790,560576537,365970379,1 +102739,560576537,560576540,1 +102740,560576540,560576462,1 +102769,560576544,360001348,0 +102742,560576544,560576548,1 +102743,560576548,560576464,1 +57842,560576550,365970353,1 +102745,560576550,560576554,1 +102746,560576554,560576557,1 +102747,560576557,560576565,1 +102748,560576565,560576569,1 +127546,560576565,560576674,1 +102749,560576569,560576572,1 +102750,560576572,559597231,1 +127521,560576613,365120913,1 +134947,560576613,561407060,0 +75912,560576625,560576628,1 +57837,560576628,365970309,1 +75913,560576628,560576632,1 +75914,560576632,560576636,1 +75915,560576632,560576646,1 +127534,560576636,365970047,1 +118018,560576656,560576501,0 +133743,560576674,559597059,0 +127523,560576807,1144045154,1 +75921,560582515,560582522,1 +75916,560582515,1540840447,1 +75919,560582517,560582519,1 +75917,560582517,1540840448,1 +2168,560582519,1540771641,0 +75922,560582522,560582523,1 +2169,560582522,1540771642,0 +80285,560582523,559564603,0 +40199,560582733,559939021,1 +40201,560582736,359998684,1 +94803,560582741,359998685,0 +75923,560582741,1540840451,1 +40210,560583695,1193473230,0 +75524,560583718,1540840241,0 +75928,560583762,560583803,1 +75925,560583762,560712557,1 +75929,560583803,560583804,1 +75930,560583804,560583806,1 +76020,560583804,1540840496,1 +75931,560583806,560583808,1 +75932,560583808,560712642,1 +75934,560583809,560583810,1 +75935,560583810,560712601,1 +76024,560583810,1540840499,1 +75937,560583812,560712604,1 +75939,560583813,560583815,1 +2984,560583813,560712646,1 +76007,560583815,1540840489,1 +130231,560712444,352724694,0 +75942,560712444,560712445,0 +75943,560712445,560712446,0 +76016,560712445,560712609,1 +75944,560712446,560712447,0 +130238,560712446,560712600,1 +75945,560712447,560712448,0 +76018,560712447,560712599,1 +75442,560712448,527804432,1 +75992,560712448,560712584,1 +75946,560712448,1540840466,0 +75947,560712450,527804432,0 +75948,560712450,1540840467,1 +76008,560712497,1540840492,1 +75522,560712538,1540840228,0 +75949,560712540,560712541,1 +76011,560712540,560712546,1 +75950,560712541,560712542,1 +75956,560712541,560712549,0 +75961,560712542,560712548,0 +75951,560712544,560712545,1 +75952,560712545,560712546,1 +75953,560712546,560712547,1 +75955,560712547,560712541,0 +75954,560712547,560712548,1 +75964,560712549,560712559,1 +75957,560712549,1540840471,0 +75958,560712552,1540840473,1 +75959,560712552,1540840477,0 +75926,560712557,1540840456,1 +75960,560712559,560712542,0 +75962,560712560,560712561,1 +75971,560712560,560712571,0 +76010,560712561,560712540,1 +75963,560712561,560712549,1 +75965,560712562,560712563,1 +75979,560712562,560712565,1 +75966,560712563,560712564,1 +75990,560712563,560712566,1 +75998,560712564,560712568,1 +75967,560712565,560712566,1 +75980,560712565,560712570,1 +75991,560712566,560712560,1 +75968,560712566,560712568,1 +75999,560712568,560712544,1 +75969,560712569,560712570,0 +130243,560712569,1540886541,1 +75970,560712570,560712560,0 +75981,560712570,1540840479,1 +75972,560712571,1540840478,0 +75973,560712574,560712575,1 +75994,560712574,560712595,1 +75974,560712575,560712576,1 +76004,560712575,560712595,1 +75975,560712576,560712577,1 +76002,560712576,560712596,1 +75976,560712577,560712578,1 +75988,560712577,560712592,1 +75977,560712578,560712579,1 +75978,560712579,560712562,1 +75989,560712579,1540840484,1 +75982,560712583,560712552,1 +76009,560712583,560712561,1 +75993,560712584,560712574,1 +75983,560712584,1540840482,1 +76003,560712586,560712575,1 +75984,560712586,560712587,1 +75985,560712587,560712588,1 +75986,560712588,560712589,1 +76001,560712589,560712576,1 +75987,560712589,1540840483,1 +76000,560712591,1540840486,1 +130241,560712591,1540886538,1 +75997,560712594,560712564,1 +75995,560712595,560712596,1 +75996,560712596,1540840485,1 +76019,560712599,560712587,1 +76005,560712599,560712600,1 +130239,560712600,560712611,1 +75936,560712601,560583812,1 +76006,560712601,1540840487,1 +75938,560712604,560583813,1 +76014,560712609,560712611,1 +76017,560712609,1540840493,1 +76015,560712611,560712588,1 +130240,560712611,560712591,1 +76062,560712616,560712671,1 +76021,560712625,1540840497,1 +76022,560712628,560583806,1 +76023,560712628,560712625,1 +76025,560712633,1540840503,1 +76026,560712633,1540840504,1 +76056,560712638,560583812,1 +76027,560712638,560712639,1 +76028,560712639,560712640,1 +76030,560712639,560712642,1 +76048,560712640,560583803,1 +76029,560712641,560712639,1 +76054,560712641,560712659,1 +75933,560712642,560583809,1 +2986,560712643,560712664,1 +76031,560712643,1540840507,1 +76033,560712645,560712648,1 +2985,560712646,1540773495,1 +76032,560712646,1540840508,1 +76051,560712648,1540840512,1 +2927,560712653,352712089,0 +76043,560712653,560712654,1 +76044,560712654,528510373,1 +76087,560712654,560712704,1 +31328,560712656,352724720,0 +2988,560712657,352724720,1 +76046,560712657,1540840511,1 +76047,560712659,560712640,1 +76068,560712660,560583815,1 +76049,560712660,560712661,1 +76050,560712661,560712648,1 +2987,560712664,560712657,1 +76052,560712664,560712665,1 +76055,560712665,560712638,1 +76053,560712665,1540840514,1 +76057,560712667,560712668,1 +76074,560712667,560712680,1 +76058,560712668,560712669,1 +76085,560712668,1540840524,1 +76094,560712669,1540840535,1 +76059,560712670,352724965,1 +76093,560712670,1540840534,1 +130242,560712671,560712569,1 +76092,560712672,560712670,1 +76063,560712672,560712673,1 +76064,560712673,560712674,1 +76086,560712673,1540840525,1 +76077,560712674,1540840520,1 +76065,560712675,352724970,1 +76091,560712675,1540840533,1 +76067,560712676,560712660,1 +31331,560712676,1540800796,0 +2930,560712677,560712682,0 +76069,560712677,1540840515,1 +76089,560712679,560712692,1 +76075,560712680,560712689,1 +76070,560712680,1540840516,0 +2931,560712682,175702471,0 +76099,560712682,1540840538,0 +31335,560712683,560712444,0 +76071,560712683,560712684,1 +76072,560712684,560712685,1 +130245,560712684,560712695,0 +76073,560712685,1540840517,1 +76076,560712689,560712674,1 +76078,560712692,352724972,1 +76090,560712692,560712675,1 +76096,560712693,352724958,1 +76081,560712693,560712685,1 +31334,560712694,560712683,0 +76082,560712694,560712695,1 +130246,560712695,352724959,0 +76083,560712695,560712696,1 +76084,560712696,1540840522,1 +2991,560712704,352712089,1 +76088,560712704,1540840529,1 +76100,560728572,560728574,1 +76114,560728572,560728578,1 +76137,560728574,560728580,1 +76101,560728578,560728580,1 +76115,560728578,560728630,1 +76138,560728580,560945025,1 +76102,560728586,1540840539,1 +76104,560728599,1540840543,1 +76221,560728599,1540840650,0 +76108,560728603,560944914,1 +76105,560728603,1540840545,1 +76239,560728609,560945160,0 +76106,560728609,1540840547,1 +76107,560728617,1540840550,1 +76192,560728624,1540840622,1 +76193,560728625,560944966,1 +76205,560728627,560944962,1 +76113,560728629,560728572,1 +76140,560728629,1540840573,1 +76116,560728630,560728586,1 +76117,560728631,560728632,1 +76141,560728631,1540840576,1 +76136,560728632,1540840572,1 +76118,560728633,1540840553,1 +76143,560728633,1540840582,1 +76122,560728637,1540840556,1 +76121,560728638,560728637,1 +76130,560728638,560728648,1 +76123,560728640,560728641,1 +76127,560728640,1540840559,1 +76124,560728641,1540840557,1 +76126,560728645,560728640,1 +76227,560728645,560945080,1 +76128,560728647,560728648,1 +76146,560728647,1540840588,1 +76129,560728648,560728649,1 +76131,560728648,560728650,1 +76142,560728649,1540840579,1 +76133,560728650,1540840562,1 +76132,560728651,1540840560,1 +76147,560728651,1540840589,1 +76135,560728654,560728632,1 +76149,560728681,560728682,1 +76151,560728682,560728686,1 +76150,560728682,1540840592,1 +119694,560728686,1036415445,1 +76152,560728686,1036415809,1 +124963,560935844,1540883954,1 +76111,560944905,560728624,1 +76155,560944905,560944906,1 +76156,560944906,560946013,1 +76184,560944906,1540840615,1 +76158,560944907,560944908,1 +76172,560944907,560944910,1 +76166,560944908,560944909,1 +76159,560944909,560944910,1 +76167,560944909,560944919,1 +76160,560944910,560944912,1 +76173,560944910,560944922,1 +76161,560944912,560944913,1 +76162,560944913,560944914,1 +76109,560944914,560944915,1 +76207,560944914,560944991,1 +76110,560944915,560944905,1 +76163,560944915,560944916,1 +76164,560944916,1540840596,1 +76185,560944916,1540840616,1 +76165,560944918,560944908,1 +76168,560944919,560944920,1 +76243,560944919,1540840664,0 +76245,560944920,560945044,0 +76171,560944921,560944907,1 +76174,560944922,560944923,1 +76241,560944922,560945039,0 +76247,560944923,1540840668,0 +119408,560944924,560944931,1 +76175,560944924,1540840601,1 +76176,560944929,560944930,1 +76214,560944930,560944934,1 +76210,560944930,1540840637,1 +76177,560944931,560944932,1 +119409,560944931,1540878893,1 +76178,560944932,560944929,1 +76179,560944932,1540840606,1 +76215,560944934,1540840643,1 +119406,560944935,560944971,1 +76180,560944935,560945998,1 +76182,560944936,560946001,1 +76186,560944955,560944936,1 +76197,560944955,1540840628,1 +76187,560944956,1540840617,1 +76211,560944956,1540840640,1 +76191,560944958,560944905,1 +76188,560944958,1540840620,1 +76189,560944961,560944962,1 +76206,560944962,560944990,1 +76190,560944963,560944958,1 +76212,560944963,1540840641,1 +76194,560944966,1540840624,1 +76195,560944969,1540840627,1 +76196,560944971,560944955,1 +119407,560944971,1540878892,1 +119405,560944982,560944935,1 +76170,560944982,1540840597,1 +76203,560944988,560944989,1 +76222,560944988,560945025,1 +76204,560944989,560728627,1 +76209,560944991,560944961,1 +76208,560944991,560944989,1 +76213,560944992,1540840642,1 +76235,560944997,278009617,1 +76216,560944997,560944998,1 +76230,560944998,560945008,1 +76229,560944999,560944998,1 +76217,560944999,560945000,1 +76234,560945000,560944997,1 +76218,560945000,1540840644,1 +76219,560945005,1540840648,1 +76238,560945005,1540840661,1 +76232,560945007,560945086,1 +76120,560945008,560728638,1 +76220,560945008,1540840649,1 +76145,560945014,1540840586,1 +76139,560945025,560728627,1 +76242,560945039,560944919,0 +76223,560945039,560945044,1 +76246,560945044,560944923,0 +76224,560945044,1540840651,1 +76225,560945077,560945079,1 +119404,560945077,1540878886,1 +76226,560945079,560728645,1 +76231,560945079,1540840656,1 +76244,560945079,1540840666,0 +76236,560945080,560945086,1 +76228,560945080,1540840654,1 +76237,560945086,560945005,1 +76233,560945086,1540840659,1 +76248,560945159,560728617,0 +76125,560945159,560945160,1 +76240,560945160,1540840663,0 +76103,560945167,1540840540,1 +76112,560945167,1540840552,0 +76181,560945998,560944936,1 +76251,560945998,560946039,1 +76249,560946001,560946039,1 +76183,560946001,1540840609,1 +76157,560946013,560944907,1 +76250,560946039,560944921,1 +76252,560946039,560946013,1 +76200,560946138,1030975289,1 +76202,560946140,560946143,1 +119402,560946143,1540878877,1 +119403,560946147,1540878878,1 +76411,561406781,1540840711,0 +57827,561406790,365970190,1 +76402,561406790,561406793,1 +57817,561406793,365970169,1 +76403,561406804,561406809,1 +57802,561406804,1540827678,0 +127520,561406809,560576613,1 +76419,561406809,561406952,0 +56113,561406845,365119239,0 +76404,561406845,561406849,0 +76423,561406849,561406958,0 +127481,561406856,365118910,0 +76405,561406856,561406865,1 +80982,561406865,365118825,0 +76406,561406894,561406896,1 +75911,561406894,1540840444,1 +102732,561406894,1540864433,0 +138655,561406896,1540923523,0 +102737,561406913,560576525,1 +76410,561406913,1540840710,0 +127507,561406920,1540885183,0 +76414,561406925,1540840713,0 +133739,561406933,1540896933,0 +102733,561406946,365118569,0 +76416,561406946,561406948,0 +76417,561406948,561406951,0 +56179,561406948,561407412,1 +76418,561406951,561406809,0 +56183,561406951,561407127,1 +56154,561406952,365119796,1 +76420,561406952,561406954,0 +56140,561406954,365119735,0 +76421,561406954,561406956,0 +56101,561406956,365119083,0 +76422,561406956,561406849,0 +134863,561406958,365119239,0 +102768,561406958,365119650,1 +76424,561406958,561406960,0 +56160,561406960,365119980,0 +76425,561406960,561406961,0 +56074,561406961,1540824337,0 +76426,561406961,1540840715,0 +134948,561407060,365121026,0 +56182,561407060,561406951,1 +80984,561407112,365119199,0 +80989,561407122,561407126,0 +57801,561407122,1540827675,0 +80990,561407126,561407127,0 +75909,561407127,561407412,1 +80991,561407127,1540844152,0 +127513,561407251,365119673,1 +102767,561407257,1540864439,1 +75910,561407412,561406894,1 +57788,561407865,365970040,1 +102773,561407905,1540864440,0 +127538,562865689,559590207,1 +76428,562865689,562865691,1 +76434,562865725,1540840717,0 +76436,562865739,1540840722,0 +76437,562865746,1540840725,0 +76438,562865751,1540840727,0 +76439,562865754,1540840728,0 +76440,562865767,365120079,0 +56148,562865767,562865879,0 +57820,562865789,365970171,1 +76441,562865789,562865792,0 +127516,562865792,365120855,1 +127514,562865792,365969989,0 +76442,562865792,562865739,0 +76452,562865799,365120855,0 +76443,562865799,1540840730,0 +76444,562865805,562865808,0 +76445,562865805,562865810,1 +40235,562865808,365970406,1 +56185,562865810,1540824351,0 +127477,562865819,365119620,0 +76450,562865819,1307600505,0 +127497,562865845,365120079,1 +76448,562865845,562865848,0 +56147,562865848,562865767,0 +40237,562865879,365970140,1 +56149,562865879,559590175,0 +65762,566676910,536580466,1 +71659,566676910,558972562,1 +78909,566678846,1540841131,0 +111707,566678875,972315792,1 +124884,566678875,1540883927,0 +40760,566679103,1540810165,1 +69863,566679103,1540838608,0 +71781,566679118,972315314,1 +69865,566679118,1540838614,0 +75467,566679830,1540840206,0 +2923,566803328,1540773461,0 +136329,566803328,1540909144,0 +136334,566803329,566803345,0 +56480,566803345,1540824871,0 +136335,566803345,1540909146,0 +30891,566803346,1131310896,1 +136336,566803346,1540909148,0 +136337,566803347,1540909149,0 +79036,567071079,366360713,1 +79060,568806865,568806867,1 +83856,568806865,600396750,1 +80034,568806867,1540841935,1 +80029,568806869,568806870,1 +80035,568806869,1540841936,1 +80030,568806870,360190668,1 +83855,568806870,1540846639,1 +22984,571449843,286541745,0 +95122,571449843,1540857409,1 +30828,574839084,360467599,0 +56483,574839084,574839086,0 +56484,574839086,365308986,0 +47817,574839086,706854248,0 +75445,575177978,527804407,1 +79932,575187160,536601128,1 +79917,575187160,1540841863,1 +79935,575187165,536600780,1 +79918,575187165,536601135,1 +97567,575187178,795263262,1 +79927,575187178,967240741,1 +110244,575187220,360019429,1 +40289,575189652,536579549,1 +40644,575189658,1113233829,1 +71605,575189658,1540838958,0 +71803,575189659,536600985,1 +40899,575189660,360013428,1 +97629,575189660,536579554,1 +71603,575190243,536579174,0 +71780,575190243,566679118,1 +71770,575190250,536579195,1 +69870,575190250,1540838615,0 +40820,575190261,528489749,1 +71602,575190261,1540838953,0 +71809,575190278,536600678,1 +71601,575190278,575190261,0 +69867,575190298,528489754,0 +71808,575190298,575190278,1 +69869,575190303,575190250,0 +79951,575191572,528489796,1 +71595,575191572,575191575,0 +79950,575191575,575191614,1 +71596,575191575,1540838948,0 +71790,575191614,1540839013,1 +80028,576508569,568806869,1 +111871,576508569,1540872314,1 +80033,576508579,1540841934,1 +53814,576508600,1540820500,1 +80295,577419344,678178652,0 +51698,577419344,1540816220,1 +80302,577419344,1540843035,0 +80304,577419381,1540843044,1 +80309,577419381,1540843052,0 +80303,577419388,1540843042,0 +80310,577419388,1540843053,0 +80308,577419395,1540843051,0 +125350,577419403,360476863,1 +80305,577419445,1540843045,1 +80323,577419445,1540843059,0 +80313,577419456,1540843056,1 +80327,577419475,936853817,0 +80307,577419475,1540843047,0 +80324,577419498,577419512,0 +80312,577419498,1540843055,1 +80326,577419501,1540843061,0 +80325,577419512,577419501,0 +80318,577419513,1540843057,0 +80317,577419524,577419513,0 +80337,577419525,577419498,0 +80319,577419525,1540843058,0 +1627,577419526,1540771165,0 +80335,577419526,1540843080,0 +80336,577419530,1540843087,0 +106594,577419530,1540868481,0 +80343,577419535,1540843104,0 +51710,577419536,360477598,1 +80342,577419537,1540843100,0 +80341,577419538,36244140,0 +2263,579786585,1540771779,0 +51706,579786585,1540816229,0 +80473,579786595,1540843208,0 +97321,579794567,793529671,1 +80474,579794567,1540843214,1 +80475,579794572,792071815,1 +96855,579794572,1540859804,1 +80548,579794578,361441560,0 +80478,579794578,579794583,1 +2837,579794583,1540773412,0 +97336,579794584,579794567,1 +97318,579794584,793529860,1 +97334,579794593,793529740,1 +97327,579794593,1540859923,0 +97344,579794606,1540859952,0 +127605,579794606,1540885226,0 +127604,579794612,579794606,0 +97332,579794612,1540859931,0 +97337,579794612,1540859939,0 +127603,579794613,579794612,0 +97250,579794613,793529743,1 +24008,579794630,1540793912,0 +82576,579794630,1540846375,0 +97331,579794630,1540859925,0 +80479,579794643,579794630,0 +97343,579794643,1540859951,1 +80551,579794831,1540843263,0 +80553,579794841,600205175,0 +96821,579799880,361198797,1 +80587,579805282,1540843277,0 +80544,579805328,361441554,0 +80481,579805328,1540843216,0 +80480,579805525,579805328,0 +2840,579805525,1540773414,0 +80589,579805587,1540843285,1 +80511,581260958,803745252,1 +126441,581260958,938502042,1 +80522,581260959,803745085,1 +80534,581260959,1141011963,1 +89974,581260960,803745041,1 +80538,581260960,1540843248,1 +80314,581267843,678168533,1 +80539,581286085,1540843250,0 +80541,581286086,1540843255,0 +80588,581286089,1540843283,0 +2899,581288189,1540773449,1 +51681,581288189,1540816162,0 +2898,581288199,1540773448,1 +80590,581288199,1540843289,0 +93180,581288213,704826158,0 +134835,581288213,704826185,1 +80591,581288214,1540843301,0 +51149,581290410,793772301,1 +80540,581290412,175678282,0 +80592,581290413,792069975,0 +80594,581290414,704826065,0 +134838,581290422,581288214,1 +80597,581291043,581291044,1 +80598,581291044,581291045,1 +80599,581291045,581291046,1 +80600,581291046,581291047,1 +80601,581291047,360476174,1 +80618,581291048,360476174,0 +80622,581291048,581291052,1 +80619,581291049,581291050,1 +134541,581291049,1540904930,1 +80621,581291050,581291048,1 +80620,581291050,581291051,1 +51310,581291051,581291060,0 +127405,581291052,581291047,1 +29604,581291060,1540798978,1 +51672,583222422,361434514,0 +93332,583222422,1540856484,1 +104437,583222432,361434479,0 +93331,583222432,583222422,1 +133408,583222432,705971099,0 +48156,583223031,705979278,0 +56476,583223031,705990576,1 +56038,583229697,365117752,1 +56045,583229697,365118106,1 +137796,583229699,1540920313,0 +137794,583229701,36645001,0 +56015,583229701,1305700915,1 +40272,583432483,360005634,1 +71576,583432483,536578787,1 +40269,583432484,360008505,1 +71590,583432484,932361983,1 +40271,583432485,583432483,1 +71585,583432485,932361991,1 +71587,583432486,536578769,1 +81013,583432486,536578783,1 +24103,583432487,279591155,0 +40457,583432487,360006263,0 +40475,583432488,360008506,1 +110082,583432488,536578904,0 +81017,583433054,767358945,0 +40709,583433054,1030300205,1 +24098,583433055,1540794245,0 +81021,583433275,972315343,1 +111631,583433275,972315547,1 +111739,583433275,972315890,1 +111737,583433275,972316189,1 +81029,583433288,360189631,1 +64040,583433288,360189875,1 +44853,583433293,418771205,1 +44880,583433293,1540811910,1 +44877,583433305,583433308,1 +111589,583433305,1540872106,1 +44878,583433308,360190380,1 +64018,583433337,418771174,1 +111818,583433365,1540872247,1 +64027,583433370,583433372,1 +111621,583433370,973983373,1 +112063,583433372,973983522,1 +64028,583433372,1540833571,1 +112070,583433376,973983056,1 +64030,583433376,1540833575,1 +112089,583433378,973983286,1 +64031,583433378,1540833577,1 +45804,583434225,360209795,1 +143869,583434225,1540937873,0 +45800,583434227,360209774,1 +143865,583434227,1540937868,0 +143870,583434227,1540937875,0 +143867,583434230,1345508956,0 +143872,583434230,1345509027,1 +45812,583434231,360209880,1 +143878,583434231,1540937883,0 +81040,583435260,583435305,1 +37563,583435260,966314786,1 +37565,583435261,363988499,1 +37568,583435264,583435265,1 +81038,583435264,1540844184,1 +37569,583435265,966314760,1 +37571,583435270,360189871,1 +81034,583435270,1540844167,1 +81037,583435297,583435265,1 +81035,583435297,966315487,1 +110037,583435303,966315152,1 +81039,583435303,1540844186,1 +81041,583435305,1540844188,1 +109823,583435305,1540871099,1 +64243,584358264,1540833926,0 +81164,584358264,1540844349,0 +87979,584358264,1540851141,1 +143020,584358284,584358285,0 +143004,584358285,445393446,0 +36856,584358285,1540805379,0 +2275,584361250,584361252,0 +81190,584361250,584361281,0 +17049,584361252,584361279,0 +81975,584361252,1540845751,0 +106891,584361252,1540868634,1 +81188,584361276,584361279,0 +81183,584361276,1540844386,0 +81189,584361279,584361250,0 +17050,584361279,1540787480,0 +81191,584361281,272562885,0 +17051,584361305,1540787481,0 +81223,585199945,662948268,0 +81239,585199950,585199945,0 +83884,585199960,1540846675,0 +83895,585199960,1540846721,0 +81260,585199965,585199966,0 +81259,585199966,585199950,0 +81253,585200692,1540844603,0 +91554,585200692,1540855777,0 +81225,585200697,1540844462,0 +81620,592380850,1540845045,0 +81625,592380930,1540845064,0 +5847,592380963,1540775954,0 +81626,592380963,1540845067,0 +81639,592381000,1540845137,0 +82007,592381002,1540845782,0 +82006,592381024,1540845776,0 +17070,592381081,1540787536,0 +82008,592381242,1540845795,0 +81640,592381248,1540845138,0 +81638,592381275,1540845131,0 +81654,592381652,1540845181,0 +81629,592383588,1540845080,0 +81630,592561536,1540845081,0 +81641,592561550,1540845142,0 +81636,592561605,1540845118,0 +81634,592561614,1540845116,0 +81637,592561637,1540845127,0 +81646,592561673,355929053,0 +17074,592561673,793252666,0 +53491,592567268,363860788,0 +81642,592567268,1540845147,0 +96880,592567268,1540859808,1 +81647,592567296,1540845170,0 +81648,592567313,1540845176,0 +5845,592567324,36243626,0 +33727,592567324,592567352,0 +81910,592567352,592567313,0 +31095,597688045,351948867,1 +31087,597688045,351953704,1 +81771,597692555,1540845682,0 +76415,597692580,1540840714,0 +81772,597692580,1540845684,0 +81773,597692598,1540845685,0 +137797,597692598,1540920315,0 +81775,597692611,597692693,0 +2944,597692611,597692699,0 +81777,597692623,1540845691,0 +81783,597692623,1540845697,0 +56035,597692637,583229699,0 +76407,597692637,1540840704,0 +76409,597692639,1540840706,0 +81779,597692642,1540845692,0 +81782,597692667,597692555,0 +68181,597692690,1141269257,0 +31267,597692690,1540800739,0 +127297,597692693,597692697,0 +76412,597692693,1141269255,0 +80992,597692693,1193464731,0 +2943,597692697,1540773474,0 +127298,597692697,1540885070,0 +2945,597692699,1540773475,0 +30942,597693485,347782338,0 +137793,597693485,1540920306,0 +137785,597693501,1540920290,0 +104435,597897194,361434477,0 +127319,597897194,597897195,0 +152365,597897195,360729189,1 +104440,597897195,1540866220,0 +50071,597897427,360716822,0 +50133,597897428,286535484,0 +133442,597897428,360720629,0 +64439,597897429,286541749,0 +92205,597897429,1540856197,1 +81954,598495494,598495496,0 +81955,598495496,1540845744,0 +81977,598495511,598495513,0 +82520,598495513,1540846311,0 +81979,598495520,745988379,0 +81981,598495524,1540845753,0 +81982,598495533,598495534,0 +17071,598495533,1540787547,0 +81983,598495534,462754210,0 +64362,598495534,598495892,0 +81207,598495540,1540844393,0 +81989,598495540,1540845757,0 +81990,598495542,793279535,0 +94973,598495542,793279545,1 +96899,598495544,793279445,1 +81993,598495544,793279622,0 +81995,598495546,598495547,0 +96901,598495546,793279468,1 +81996,598495547,598495548,0 +82009,598495547,1540845796,0 +81997,598495548,598495549,0 +64364,598495548,598495626,0 +24024,598495549,598495533,0 +81998,598495549,745990613,0 +95197,598495556,746691474,1 +82004,598495556,1540845763,0 +64365,598495626,294248195,0 +96944,598495626,793279468,1 +51282,598495891,361197057,1 +82001,598495891,746691473,0 +82010,598495892,598495533,0 +64363,598495892,598495548,0 +82018,598497217,1540845838,1 +82019,598497217,1540845860,1 +82031,598498283,1540845877,0 +99159,598498283,1540861903,1 +82032,598498285,598498286,0 +81961,598498285,1540845747,0 +81204,598498286,272567334,0 +82033,598498286,598498287,0 +97136,598498286,1540859869,1 +81960,598498287,598498285,0 +82034,598498287,1540845878,0 +82036,598498290,800448734,0 +50073,599162160,745984393,0 +82571,599162325,36244671,0 +82572,599162326,1540846373,0 +24005,599162400,1540793898,0 +82577,599162400,1540846379,0 +82573,599162401,294206988,0 +31703,599162412,353246385,0 +29692,599162412,678178638,1 +29696,599162413,338484712,1 +29599,599162413,360476280,1 +29700,599162414,338484715,1 +51305,599162414,361197598,0 +29645,599162436,353250796,0 +31728,599162437,353250872,1 +55688,599162437,599162436,1 +134536,599162771,683295954,1 +134534,599162771,683295958,1 +51701,599162772,338484590,1 +40470,599532941,360008436,1 +110085,599532941,360008495,0 +127634,600205087,361199410,1 +80564,600205087,938149108,0 +80572,600205102,938142813,0 +98049,600205102,1540861248,0 +127134,600205115,600205118,1 +2815,600205115,1540773402,0 +80578,600205118,938142955,0 +127135,600205118,938143056,1 +80586,600205127,600205146,0 +89075,600205127,1540852161,0 +2806,600205146,1540773395,0 +23897,600205146,1540793790,0 +80554,600205175,792071817,0 +80558,600205185,600205187,0 +51441,600205185,797394752,1 +80559,600205187,797375744,0 +80562,600205190,938149075,0 +107449,600205190,938149127,1 +80566,600205192,938149077,0 +107440,600205192,938149098,1 +80580,600205197,1540843270,0 +80584,600205200,938501953,0 +80031,600396272,600396283,1 +64046,600396272,972481956,1 +80032,600396283,1540841933,1 +73601,600396750,1540839712,1 +44889,600396751,360190668,1 +79059,600396751,1540841203,1 +111839,600396798,360195555,1 +152601,600396798,1540963212,0 +21489,600397449,360196432,1 +45238,600397449,360198954,1 +83868,600398870,360235706,1 +149317,600400026,600400028,1 +83880,600400028,600400044,1 +83875,600400044,1179195098,1 +87446,600400237,1179176144,1 +83881,600400238,1540846667,0 +121640,600400238,1540881855,0 +121641,600400244,360199663,0 +83879,600400245,600400237,1 +83885,600629014,1540846676,0 +111951,600629016,1540872467,0 +81257,600629036,1540844622,0 +83886,600629036,1540846680,0 +83897,600629071,973018539,0 +111982,600629166,973040049,0 +83896,600629166,1540846722,0 +111983,600629186,973040045,0 +2645,600629186,1540772360,0 +83900,600629186,1540846730,0 +83901,600629210,1540846737,0 +83903,600629210,1540846741,0 +45951,600629272,360195843,1 +83904,600629272,360215725,1 +3641,600915595,361198828,1 +134561,600915595,368356447,1 +3643,600915596,361198813,0 +134564,600915596,361198820,1 +127084,600915596,361198849,1 +48362,600915597,247151604,1 +83926,600917282,368362874,0 +83927,600917284,600917285,0 +83941,600917284,1540846782,0 +48347,600917285,653281863,0 +98136,600917285,797375880,0 +83928,600917286,600917287,0 +83933,600917286,1540846760,0 +48349,600917287,360476868,0 +83929,600917287,600917288,0 +48396,600917288,653281865,0 +83930,600917288,938502155,0 +3633,600917292,360476867,1 +83931,600917292,368362870,0 +48453,600918107,797375625,0 +23953,600918107,938502114,1 +126465,600918108,338485787,0 +126437,600918108,938502332,1 +23952,600918109,600918107,1 +99919,600918675,1540862326,1 +94531,600919181,600919194,1 +23888,600919181,737308389,1 +94559,600919183,737307292,1 +94537,600919183,737309576,1 +68963,600919183,1540838295,1 +68964,600919186,737309569,1 +94536,600919186,737309573,1 +94557,600919194,1540857169,1 +94442,600919204,737307365,1 +94565,600919204,737307554,1 +94168,600919210,1540856884,1 +94426,600919210,1540857058,1 +57779,600920086,294184359,1 +143334,600920086,1540936865,1 +2175,600924052,600924095,0 +83947,600924052,1540846786,1 +83945,600924095,152946871,1 +83944,600924095,152946877,0 +83967,600924095,1540846801,1 +59358,600924197,1540831982,0 +83948,600926419,1540846787,1 +83949,600926420,793810051,1 +83953,600926422,1540846788,1 +83965,600926427,152804436,1 +143965,600926427,1540937988,1 +83968,600926437,937216153,1 +83970,600926441,152804211,1 +106772,600926441,1540868568,1 +51443,600927575,1540815947,1 +83981,600927575,1540846808,0 +83982,600927578,600927579,0 +106716,600927578,1540868541,1 +83983,600927579,600927581,0 +83985,600927579,938140737,1 +83984,600927581,1540846810,0 +83988,600927584,1540846813,1 +106732,600927584,1540868545,1 +83989,600927586,1540846814,1 +107037,600927586,1540868907,1 +83991,600927588,600927589,1 +106608,600927588,1540868495,1 +83992,600927589,1540846815,1 +107398,600927591,938142799,1 +83995,600927591,938143084,1 +83998,600927592,938143092,1 +84000,600927594,1540846818,1 +84001,600927598,1540846820,1 +23965,600927600,294203217,1 +97503,600930452,793804774,1 +84008,600930452,1540846826,1 +84009,600930461,600930464,0 +84010,600930464,1540846828,0 +84014,600930492,1540846854,0 +2273,600936021,1540771788,0 +84012,600936021,1540846847,0 +84028,600999900,600999907,1 +84029,600999907,360007350,1 +84027,600999907,1540846863,1 +40348,601002970,360007207,1 +84038,601004557,360007211,1 +84034,601004557,1540846866,1 +40393,601013512,601013519,1 +84032,601013512,601013549,1 +84040,601017562,1540846873,1 +84039,601017585,1540846867,1 +84042,601025200,279590687,1 +40405,601025200,360007169,1 +40346,601025729,360007392,1 +84043,601025729,1540846876,1 +40372,601027558,360007063,1 +84044,601027558,603093036,1 +20299,601643782,278012066,1 +22941,601643782,1540792467,1 +40377,603093036,360007062,1 +84106,603748681,1540847160,0 +97501,603748681,1540859986,0 +84126,603748683,417279716,1 +97500,603748684,603748681,0 +84107,603748686,603748687,1 +84121,603748686,793799835,1 +84108,603748687,603748688,1 +84109,603748687,793781843,1 +94867,603748688,793799865,1 +97418,603748689,361199842,1 +94940,603748689,793781839,1 +84128,603748691,603748696,1 +84136,603748692,603748702,1 +81193,603748692,603753187,0 +84119,603748693,793781712,1 +97371,603748693,793781760,1 +84123,603748694,793799933,1 +63951,603748694,1540833527,0 +84140,603748695,603753221,1 +84129,603748696,603748697,1 +84181,603748696,603753180,1 +143953,603748697,603753181,1 +84130,603748697,1540847164,1 +81973,603748702,813097944,0 +100694,603748702,1540862821,1 +84139,603753179,603748695,1 +84150,603753179,1540847169,1 +84151,603753180,603753181,1 +84182,603753180,603753231,1 +84152,603753181,603753183,1 +143954,603753181,603753233,1 +84131,603753183,603753225,1 +84153,603753185,603753186,1 +84154,603753186,603753187,1 +84174,603753186,603753251,1 +81194,603753187,603753245,0 +84172,603753188,603753243,1 +84155,603753188,1540847171,1 +84168,603753191,603753243,1 +84156,603753202,603753203,1 +84176,603753202,603753258,1 +84189,603753203,603753278,1 +84157,603753206,603753207,1 +84134,603753206,1540847166,1 +84158,603753207,603753210,1 +143958,603753207,603753289,1 +84159,603753210,603753213,1 +84186,603753210,603753276,1 +84143,603753213,417279718,1 +84185,603753214,603753210,1 +84160,603753214,603753215,1 +143957,603753215,603753207,1 +84161,603753215,603753217,1 +84133,603753217,603753206,1 +84162,603753221,603753222,1 +84141,603753221,793800018,1 +84184,603753222,603753214,1 +84163,603753222,603753223,1 +143956,603753223,603753215,1 +84164,603753223,603753225,1 +84132,603753225,603753217,1 +84183,603753231,603753222,1 +84165,603753231,603753233,1 +84166,603753233,603753184,1 +143955,603753233,603753223,1 +84167,603753242,603753191,1 +84173,603753243,603753186,1 +84169,603753243,603753245,1 +81195,603753245,603753293,0 +84170,603753247,603753249,1 +84147,603753247,793799881,1 +84171,603753249,603753188,1 +143962,603753249,603753293,1 +84135,603753251,1540847167,1 +84175,603753257,603753202,1 +84146,603753257,603753247,1 +84177,603753258,603753261,1 +84180,603753258,603753271,1 +84178,603753261,603753264,1 +84179,603753261,603753270,1 +143961,603753264,603753249,1 +84191,603753270,603753283,1 +84188,603753273,603753203,1 +84145,603753273,603753257,1 +84187,603753276,603753278,1 +84195,603753276,603753289,1 +84190,603753278,603753270,1 +143960,603753283,603753264,1 +84196,603753289,603753242,1 +143959,603753289,603753283,1 +81196,603753293,1540844389,0 +51525,603753974,361200008,1 +84113,603753974,793781812,1 +84116,603753994,793781678,1 +97431,603753994,793781736,1 +91716,614379395,1540855949,1 +58355,614381224,662948245,1 +87448,615743482,1540850060,1 +86489,615743529,615849099,1 +86447,615743529,615868264,1 +132202,615743554,1540890726,1 +86449,615756564,615868077,1 +86451,615756566,615868286,1 +86456,615848997,615756564,1 +86457,615848997,615868256,1 +86488,615849000,615743529,1 +86490,615849099,1540848756,1 +86487,615868017,615849000,1 +86500,615868017,1540848757,1 +86446,615868020,615743482,1 +86501,615868024,616320096,1 +86669,615868024,616320140,1 +86522,615868026,615868061,1 +86505,615868026,616320116,1 +86508,615868028,615868030,1 +86518,615868028,616320134,1 +86509,615868030,1540848758,1 +86510,615868035,615868037,1 +86540,615868035,615868045,1 +86511,615868037,615868038,1 +86562,615868037,616320080,1 +86512,615868042,615868044,1 +86561,615868044,615868037,1 +86513,615868044,615868045,1 +86514,615868045,615868030,1 +86541,615868045,615868053,1 +86515,615868050,615868051,1 +86560,615868051,615868044,1 +86516,615868051,615868053,1 +86517,615868053,615868028,1 +86542,615868053,616320078,1 +86519,615868056,615868057,1 +86520,615868057,615868059,1 +86556,615868057,616320114,1 +86521,615868059,615868026,1 +86546,615868059,616320109,1 +86523,615868070,615868071,1 +86533,615868070,615868100,1 +86524,615868071,615868073,1 +86592,615868071,615868270,1 +86525,615868073,615868075,1 +86529,615868073,615868089,1 +86526,615868075,615868077,1 +86583,615868075,615868266,1 +86450,615868077,615756566,1 +86527,615868084,615868087,1 +86528,615868087,615868073,1 +86587,615868087,615868278,1 +86530,615868089,615868091,1 +86579,615868089,615868270,1 +86491,615868091,615868317,1 +86531,615868096,615868098,1 +86532,615868098,615868070,1 +86585,615868100,615868282,1 +86534,615868100,1540848760,1 +86535,615868149,616320018,1 +86668,615868166,615868024,1 +86550,615868181,615868187,1 +86551,615868187,615868149,1 +86667,615868199,615868166,1 +86552,615868199,616320094,1 +86458,615868256,615849000,1 +86576,615868256,615868264,1 +86448,615868264,615756564,1 +86577,615868264,615868266,1 +86584,615868266,615849099,1 +86578,615868266,615868089,1 +86580,615868270,615868098,1 +86593,615868270,615868317,1 +86581,615868277,615868278,1 +86582,615868278,615868075,1 +86588,615868278,615868286,1 +86591,615868282,615868071,1 +86586,615868282,615868087,1 +86452,615868286,615743554,1 +86589,615868286,615868295,1 +86633,615868295,616320020,1 +86590,615868311,615868282,1 +86492,615868317,615868096,1 +86608,615891140,1540848823,1 +86670,615891140,1540848976,1 +86610,615891203,1540848858,1 +152833,615891203,1540963580,1 +86630,616320016,616320017,1 +86566,616320017,615868187,1 +86631,616320017,616320018,1 +86536,616320018,1540848775,1 +86632,616320019,615868295,1 +86454,616320020,615756566,1 +86638,616320072,616320073,1 +86559,616320073,615868051,1 +86639,616320075,616320076,1 +86507,616320076,615868028,1 +86640,616320076,616320078,1 +86543,616320078,616320130,1 +86641,616320079,616320080,1 +86642,616320080,616320081,1 +86563,616320080,616320086,1 +86539,616320081,615868035,1 +86643,616320081,616320082,1 +86644,616320084,616320085,1 +86538,616320085,616320081,1 +86645,616320085,616320086,1 +86646,616320086,616320034,1 +86564,616320086,616320088,1 +86647,616320087,616320088,1 +86565,616320088,616320017,1 +86648,616320088,616320089,1 +86537,616320089,616320085,1 +86649,616320091,616320094,1 +86650,616320094,616320095,1 +86553,616320094,616320100,1 +86549,616320095,615868166,1 +86651,616320095,616320096,1 +86652,616320096,616320097,1 +86502,616320096,616320103,1 +86654,616320100,616320102,1 +86554,616320100,616320108,1 +86548,616320102,616320095,1 +86655,616320102,616320103,1 +86656,616320103,616320104,1 +86503,616320103,616320110,1 +86657,616320107,616320108,1 +86555,616320108,615868057,1 +86658,616320108,616320109,1 +86547,616320109,616320102,1 +86659,616320109,616320110,1 +86504,616320110,615868026,1 +86660,616320110,616320111,1 +86661,616320113,616320114,1 +86662,616320114,616320115,1 +86557,616320114,616320128,1 +86545,616320115,615868059,1 +86663,616320115,616320116,1 +86506,616320116,616320076,1 +86664,616320116,616320117,1 +86558,616320128,616320073,1 +86665,616320128,616320130,1 +86544,616320130,616320115,1 +86666,616320139,615868199,1 +86609,616326208,1540848843,1 +86653,616326208,1540848965,1 +86635,616326256,1540848941,1 +90628,620796409,1540855381,1 +91566,620796428,662948270,1 +86083,620844469,1540847704,1 +87445,620844469,1540850050,1 +98014,625903678,797190006,1 +87978,625903678,1540851139,1 +96507,625904125,788870560,1 +96581,625904125,788870670,1 +96476,625904128,788870491,1 +96583,625904128,788870563,1 +96534,625904128,788870658,1 +138454,625904132,1307367212,1 +96590,625904132,1307367348,1 +96594,625904139,1540859694,1 +138524,625904139,1540922809,1 +96595,625904164,1540859703,1 +96596,625904170,625904174,1 +88580,625904170,1540851562,1 +88577,625904174,1540851560,1 +96079,625904181,1540858983,1 +96626,625904181,1540859706,1 +96081,625904201,788870792,1 +96086,625904285,1540859011,1 +87992,625909073,1540851166,1 +88579,625909073,1540851561,1 +97514,625911762,1540859994,1 +87995,625911966,625911968,1 +138417,625911966,1540922732,1 +87996,625911968,625912013,1 +138337,625911968,1307367347,1 +138478,625912013,625912016,1 +88581,625912013,1540851564,1 +138479,625912016,1307367370,1 +138442,625912016,1307367450,1 +138482,625912020,1540922783,1 +138483,625912025,1307367424,1 +138394,625912025,1540922711,1 +138401,625912028,1540922721,1 +138486,625912028,1540922787,1 +138487,625912030,1307367460,1 +138437,625912030,1540922744,1 +138492,625912033,625912038,1 +96460,625912033,1307367286,1 +138493,625912038,1307367197,1 +138408,625912038,1307367282,1 +138521,625912041,1307367338,1 +138499,625912041,1540922789,1 +138508,625912058,1307367239,1 +138430,625912058,1307367289,1 +138457,625912059,1307367214,1 +138510,625912059,1540922800,1 +87993,625912804,1307367321,1 +87997,625912804,1540851170,1 +88582,625912824,625904164,1 +96075,625912837,1540858980,1 +88494,633036268,801479976,1 +88496,633036269,633036431,1 +99493,633036269,801480009,1 +88502,633036431,801467908,1 +88497,633036431,801479977,1 +88504,633036602,633036603,1 +88505,633036603,633036604,1 +88508,633036603,633036782,1 +88511,633036604,633036866,1 +88506,633036604,1540851539,1 +88507,633036606,1540851540,1 +41123,633036610,1540810248,1 +88510,633036782,633036604,1 +88509,633036782,1540851543,1 +99439,633036866,1540862113,1 +48410,653279465,797375685,1 +98052,653279465,797375755,0 +89908,653279477,653279465,1 +83925,653281176,600917282,0 +98120,653281176,1540861257,1 +83937,653281576,368362872,1 +48348,653281863,600917287,0 +89910,653281863,653281576,0 +89909,653281865,653281863,0 +48397,653281865,797375880,0 +89916,653315865,984726031,1 +89955,653315885,656189126,1 +89953,653315885,985285860,1 +89933,653315959,653315961,1 +89934,653315959,1540853759,1 +89920,653315961,984752553,1 +89935,653316027,653316029,1 +115481,653316027,984752574,1 +89918,653316029,984752897,1 +89942,653316107,985285991,1 +89923,653316108,984752568,1 +89931,653316109,985285979,1 +89945,653316109,1540853773,1 +89947,653316140,653316142,1 +115610,653316140,985286283,1 +89948,653316142,1540853774,1 +89949,653316148,1540853793,1 +89950,653316151,985417843,1 +89940,653316151,985417851,1 +125009,653316156,985285908,1 +135129,653316163,797375828,0 +48399,653316163,803749503,0 +89956,653316164,803745076,1 +135136,653316165,797375764,0 +98023,653316165,797375816,0 +80525,653316193,803745069,1 +127146,653316193,803745124,0 +89961,653316319,361198466,0 +99893,653316319,803745006,1 +127149,653316321,803745036,0 +98040,653316321,803745238,0 +98054,653316867,797375798,0 +135143,653316867,803745226,0 +99934,653316899,803745187,1 +89972,653316899,803745256,1 +89978,653316901,803745245,1 +125372,653316902,803745027,1 +89988,653316903,938502027,1 +127192,653316903,1540884992,1 +107599,653316912,938502333,0 +90004,653316912,938502385,1 +90006,653316913,653316914,1 +107533,653316913,938502191,0 +107584,653316914,938502303,1 +127185,653316919,294163207,1 +89996,653316919,938502280,1 +127200,653316922,1540885002,1 +127202,653316923,1540885005,1 +127198,653316927,938502287,1 +107608,653316929,1132701153,1 +23906,653316931,1540793800,0 +90002,653316935,1540853804,1 +90011,653316935,1540853807,1 +90012,653316942,1540853808,1 +107530,653316942,1540869028,1 +90020,653316945,1540853827,0 +127196,653316945,1540885001,0 +127197,653316946,653316947,0 +90010,653316946,1540853806,1 +107570,653316946,1540869051,0 +107578,653316947,938502400,0 +107582,653316954,653316947,0 +107581,653316955,653316954,0 +127207,653316956,1540885023,0 +127212,653316956,1540885035,1 +90017,653316957,1540853810,1 +127211,653316957,1540885034,1 +127203,653316958,653316927,1 +90016,653316958,653316957,1 +107610,653316959,653316979,1 +107617,653316959,1540869064,1 +127201,653316968,653316923,1 +90019,653316968,1540853826,1 +107611,653316979,938501948,1 +90021,653317014,653317015,0 +107477,653317014,1141084041,1 +107562,653317014,1540869043,1 +127186,653317015,1540884990,0 +127187,653317016,653317017,0 +127188,653317017,653317018,0 +90007,653317017,938502363,0 +127189,653317018,1540884991,0 +127190,653317019,653317015,0 +90022,653317019,653317095,1 +90023,653317095,653317097,1 +107531,653317097,653317557,0 +90024,653317097,938502201,1 +90029,653317099,1540853829,0 +107501,653317099,1540869009,1 +90015,653317286,938501997,1 +90031,653317286,1540853830,1 +107615,653317438,653316903,1 +90033,653317438,938502149,1 +107532,653317557,653316913,0 +90036,653317557,653317018,1 +126452,653317930,984772104,1 +115507,653317930,984772646,1 +90043,653318024,656190169,1 +90045,653318025,653318190,1 +90386,653318025,656190163,1 +90048,653318026,653318027,1 +90038,653318026,653318194,1 +90041,653318027,653318195,1 +90049,653318027,984771451,1 +90056,653318067,1540853850,1 +90070,653318072,653318190,1 +90060,653318072,1540853854,1 +90037,653318074,653318026,1 +115514,653318074,653318075,1 +90040,653318075,653318027,1 +90047,653318175,653318026,1 +90064,653318175,1540853858,1 +90046,653318190,653318175,1 +90071,653318190,653318191,1 +90073,653318191,653318193,1 +90072,653318192,653318191,1 +90078,653318192,656190111,1 +90063,653318193,653318175,1 +90074,653318193,653318194,1 +90075,653318194,653318195,1 +90039,653318194,984771986,1 +90076,653318195,984771554,1 +90042,653318195,984772104,1 +90077,653318202,1540853888,1 +115519,653318226,653317852,1 +115486,653318226,984772646,1 +89907,656189031,600917292,0 +3646,656189031,1540774166,0 +106598,656189124,984752865,1 +125008,656189126,653316156,1 +126448,656190111,1540884448,1 +90059,656190163,1540853853,1 +90044,656190169,653318025,1 +90387,656190169,1540854345,1 +90057,656190174,1540853851,1 +90065,656190187,984772205,1 +75521,660481539,1540840222,0 +107725,660490311,939593944,0 +91564,662948245,1540855823,0 +91848,662948248,973017990,0 +91556,662948248,1540855785,0 +91557,662948253,1540855788,0 +91563,662948264,620796428,1 +81254,662948267,1540844616,0 +81224,662948268,1540844450,0 +91558,662948268,1540855797,0 +91567,662948270,1540855827,1 +91568,662948270,1540855842,1 +91573,662948290,662948264,1 +91562,662948290,1540855815,1 +91555,662948310,662948248,0 +91565,662948310,1540855825,0 +91560,662948314,662948315,0 +81261,662948314,1540844624,0 +91849,662948315,973017463,0 +91561,662948315,1540855809,0 +91559,662948320,1540855807,0 +91569,662948321,662949717,1 +91571,662948321,1540855851,0 +91570,662949717,567071079,1 +91572,662949717,1540855853,1 +107523,667221929,365310981,1 +56488,667221929,1540824879,0 +90003,667221930,1540853805,1 +90013,667221930,1540853809,1 +92209,677410917,677411009,0 +92195,677410917,745984372,1 +92210,677411009,677411010,0 +95093,677411009,745984371,1 +92211,677411010,457421390,1 +96074,677948378,1540858975,1 +97941,677948411,788840615,1 +96071,677948411,1540858972,1 +92213,678158747,678158751,1 +2037,678158747,678168470,1 +92214,678158751,678158752,1 +92223,678158751,678158760,1 +127442,678158752,678158799,1 +92215,678158760,678158764,1 +92224,678158760,678158772,1 +2039,678158764,338485358,1 +92225,678158772,678158891,1 +92216,678158772,1540856204,1 +92217,678158799,1540856211,1 +92218,678158820,1540856217,1 +127440,678158834,360476002,1 +29653,678158857,338485256,1 +92219,678158857,1540856220,1 +100341,678158866,353250820,1 +80321,678158876,353250820,0 +92222,678158888,678158751,1 +92221,678158888,678158889,1 +127441,678158889,1540885161,1 +29649,678168452,353250804,0 +92226,678168452,678168453,1 +31724,678168453,353250869,1 +80605,678168457,338484637,0 +92227,678168457,678168464,1 +2038,678168470,678158764,1 +92228,678168470,678168471,1 +29644,678168471,599162436,0 +92239,678168522,353250844,0 +80315,678168533,577419344,1 +92231,678168533,678168522,0 +134524,678178637,353246385,0 +29693,678178638,678178640,1 +92232,678178639,1540856222,1 +29694,678178640,353246576,1 +92233,678178641,353246390,0 +31720,678178641,599162772,1 +92235,678178642,338485296,0 +92245,678178642,678178655,1 +51699,678178650,678178651,1 +51700,678178651,599162772,1 +80296,678178652,353246430,0 +92242,678178652,1540856225,1 +29675,678178653,338485330,0 +92243,678178653,678178654,1 +29674,678178654,678178650,0 +92244,678178654,678178655,1 +92246,678178655,678178651,1 +29679,678178656,338485328,0 +92247,678178656,678178657,1 +29635,683287842,246588552,0 +48303,683287842,360476008,1 +92926,683287850,360475285,1 +127448,683287852,246588553,0 +92929,683287852,683287854,1 +48306,683287855,360474546,1 +92930,683287855,683287850,1 +92229,683287907,246588478,1 +127420,683287907,1540885153,0 +127415,683290423,338484525,0 +127414,683290444,683290423,0 +31705,683290453,338484525,0 +29665,683290495,338485291,0 +29684,683290545,338485324,0 +127450,683290561,338484489,0 +134893,683290785,1142694910,1 +31709,683290785,1540802542,1 +80614,683295953,361197369,0 +92931,683295953,683295954,1 +134537,683295954,683295966,1 +134539,683295956,581291060,1 +134535,683295958,577419536,1 +92932,683295958,1540856340,0 +92933,683295964,599162771,1 +135111,683295964,683295958,1 +134538,683295966,683295956,1 +51703,683295969,1540816223,0 +92934,683295969,1540856341,0 +51678,683296017,1540816150,0 +51693,683296017,1540816215,0 +51308,683297616,360476177,0 +100336,683297616,683297763,1 +51319,683297730,361197588,1 +48322,683297730,683298011,1 +29699,683297760,599162414,1 +100337,683297763,360476193,1 +29598,683297768,599162413,1 +92935,683297768,683297772,1 +134529,683297772,338484712,1 +92936,683297772,683297775,1 +51298,683297775,338484713,1 +100335,683298011,683297616,1 +92937,683301091,683301102,1 +92944,683301091,683301707,1 +2854,683301102,683301320,1 +127406,683301242,1540885149,1 +2856,683301249,1540773425,1 +29593,683301255,360476139,1 +92938,683301255,1540856347,1 +2855,683301320,683301249,1 +134521,683301332,246588486,0 +92939,683301332,683301333,1 +127411,683301333,338484589,0 +92940,683301333,683301343,1 +48319,683301343,360476139,1 +127409,683301362,338484527,0 +92941,683301362,683301377,1 +29592,683301441,683301255,1 +92942,683301441,1540856348,1 +48316,683301577,360476137,1 +127425,683301577,1540885155,1 +127407,683301707,683301320,1 +135107,683301787,361197354,0 +92943,683301787,683301091,1 +51292,683301823,361197312,1 +127408,683301823,683301362,0 +134560,683916511,600915595,1 +48364,683916579,360476642,1 +51330,683916600,361198641,0 +92951,683916600,683916620,1 +92952,683916620,683916511,1 +92950,683916620,683916579,1 +48245,694737976,360474737,0 +92991,694737976,694738009,0 +50178,694738009,360473995,0 +56134,694738024,360474737,0 +92992,694738024,694738030,1 +127364,694738030,360473994,0 +56136,694738050,360474041,0 +92993,694738050,694738057,1 +56131,694738235,365119512,0 +127366,694738240,360473978,0 +92994,694738240,694738235,0 +56095,694738257,365119377,0 +48249,694738261,360474740,0 +50173,694738264,360474038,0 +56069,694738293,360474036,1 +48247,694738327,360474739,0 +92995,694738327,694738331,0 +50176,694738331,1540815074,0 +2843,694738742,360473964,0 +48251,694738742,1540813889,0 +2020,694758721,365122579,1 +96331,694758721,694758723,0 +96332,694758723,694758725,0 +48228,694758723,1540813887,0 +48232,694758725,360474623,0 +96333,694758725,360475069,0 +48204,694758812,1540813881,0 +92996,694758812,1540856392,0 +2016,694758816,1540771405,1 +93005,694769841,360474298,0 +134861,694769841,1540905147,0 +2870,694770163,1540773428,1 +127431,694770235,360474540,0 +134860,694770235,694769841,0 +93008,694789258,1260446574,1 +127470,694789258,1540885174,0 +127457,694789286,694789743,1 +48286,694789743,338485009,1 +2863,694789798,1540773426,1 +127452,694789798,1540885162,1 +127456,694789922,1540885164,1 +93009,694820199,694820201,1 +48309,694820199,694820377,1 +93010,694820205,694820206,1 +93011,694820206,694820208,1 +48311,694820208,1540813906,1 +93012,694820213,694820215,1 +48315,694820213,1540813908,0 +93013,694820215,1142694910,1 +29590,694820216,338484429,1 +48314,694820219,1540813907,0 +93029,694820272,694820362,1 +93028,694820283,694820272,1 +2861,694820287,360476071,1 +48308,694820297,694820199,1 +93018,694820297,694820300,1 +93019,694820343,694820345,1 +127445,694820345,246588552,0 +93020,694820345,1540856395,1 +127461,694820349,360476096,1 +93021,694820356,360475634,1 +93023,694820357,694820359,1 +127458,694820357,694820919,1 +93026,694820359,694820365,1 +93024,694820359,1236188112,1 +93030,694820362,694820377,1 +29626,694820365,694820786,1 +93027,694820375,694820283,1 +2860,694820375,694820287,1 +48310,694820377,694820208,1 +2858,694820526,175678289,1 +48307,694820526,694820297,1 +48280,694820744,338485123,0 +93031,694820744,694820751,1 +29638,694820751,338485158,0 +29625,694820780,694820365,1 +29627,694820786,1540798991,1 +127459,694820919,360476091,1 +29629,694820919,1540798994,1 +93032,694828951,360474653,0 +56189,694828951,365122328,0 +2028,694829012,150563683,1 +93035,694829012,1540856397,0 +127466,694829015,1540885168,0 +76408,695549703,597692639,0 +93038,695549703,695549704,1 +56042,695549704,365117789,1 +56048,695549705,365117918,1 +93039,695549705,695549706,1 +31625,695549708,353244322,0 +93040,695549708,695549709,1 +127220,695552903,1540885061,0 +134935,695552903,1540905175,1 +56030,695552912,353243221,1 +93041,695552912,695552915,1 +127237,695552915,353243805,1 +127235,695552921,365117279,1 +93043,695553009,695553011,1 +56017,695553009,695553017,1 +93044,695553011,365117660,1 +56018,695553017,365117568,1 +93045,695553017,1540856402,1 +31574,695556358,353243957,1 +127224,695556358,566803347,1 +31576,695556369,695556374,1 +55999,695556369,1540824321,0 +56010,695556374,1540824325,0 +2911,695556395,360468018,1 +125334,695578756,706854252,1 +136320,695578773,1285491814,0 +137787,695578773,1285491849,0 +93154,704804601,704804602,1 +93172,704804601,1540856449,1 +93161,704804602,704804629,1 +93155,704804602,1540856416,1 +93156,704804605,1540856417,1 +93159,704804605,1540856430,1 +93157,704804607,1540856419,1 +93158,704804607,1540856422,1 +148554,704804617,1540949839,1 +148552,704804622,1540949831,1 +148555,704804622,1540949852,1 +93162,704804629,1540856435,1 +93165,704804629,1540856436,1 +93166,704804634,1540856439,1 +93169,704804655,1540856442,1 +93171,704804655,1540856444,1 +148586,704804657,1540949928,1 +134837,704826042,581290422,1 +94805,704826046,360730767,1 +93173,704826046,704826042,0 +94804,704826046,704826051,1 +51220,704826063,581290414,0 +93175,704826063,1540856451,1 +80595,704826065,1540843302,0 +51216,704826069,361197210,0 +93176,704826069,1540856452,1 +51153,704826074,361197188,1 +93177,704826074,1540856453,1 +51256,704826082,705065835,0 +93179,704826082,705065839,1 +51258,704826156,704826210,0 +93227,704826156,1540856460,1 +94166,704826156,1540856882,0 +93229,704826158,704826159,1 +93181,704826158,704826182,0 +94807,704826159,704826046,0 +93184,704826159,704826187,0 +93182,704826182,704826183,0 +51218,704826182,704826187,0 +51151,704826183,361197240,1 +134836,704826185,704826042,1 +93183,704826185,704826159,0 +51219,704826187,704826063,0 +51290,704826210,361197244,0 +51204,704832125,361196176,1 +93185,704832125,704832128,0 +95750,704832128,361196106,0 +2895,704832132,246588491,1 +93186,704832132,1540856455,1 +134829,704832134,361196161,1 +2894,704832137,704832132,1 +93187,704832137,1540856456,1 +94809,704832150,361194388,0 +93189,704832150,705059091,1 +51125,704832185,361194523,0 +93192,704832185,704832186,1 +94812,704832186,361196143,0 +95748,704832187,704832199,0 +51196,704832188,361196109,1 +93195,704832188,704832187,0 +93194,704832190,704832188,0 +51202,704832190,704832197,1 +93193,704832192,704832190,0 +51113,704832192,705059075,0 +51203,704832197,704832125,1 +95749,704832199,704832128,0 +93196,704832199,704832197,0 +51194,704832204,360729203,1 +2897,704832204,1540773445,1 +93197,704877127,704877131,1 +51260,704877127,704877142,0 +51213,704877131,361196194,0 +93225,704877139,361196106,1 +93198,704877139,704877142,1 +51261,704877142,704877175,0 +94818,704877151,361196026,0 +93199,704877151,704877155,1 +93200,704877155,704877157,1 +51265,704877155,704877189,0 +51236,704877157,361196194,0 +51159,704877160,361196438,1 +93201,704877160,704877163,1 +51211,704877172,361196814,0 +93202,704877172,704877175,1 +51262,704877175,361196799,0 +51190,704877189,361196026,0 +51266,704877189,704877193,0 +51267,704877193,361196847,0 +51179,704877193,704877200,0 +51235,704877198,704877157,0 +51189,704877198,704877189,0 +51234,704877200,704877198,0 +93271,704877339,1540856467,1 +94821,704877339,1540857344,0 +93214,705059050,705059051,1 +93235,705059050,705059076,0 +93215,705059051,361194797,1 +93216,705059051,705059049,1 +93220,705059053,1540856459,1 +51118,705059070,361194407,0 +93230,705059070,705059071,1 +94783,705059071,1540857324,1 +51135,705059074,361194792,1 +93233,705059074,361194986,1 +51114,705059075,360730765,0 +93236,705059076,705059075,0 +93234,705059077,705059050,0 +51137,705059077,1540815925,1 +93237,705059078,361194307,1 +127399,705059078,705059083,1 +51101,705059079,1540815923,1 +51132,705059080,361194581,1 +93238,705059080,705059081,1 +51078,705059081,361194196,0 +51083,705059082,361194259,1 +93239,705059083,705059082,0 +127400,705059083,705059092,1 +51100,705059084,705059079,1 +93240,705059084,705059085,1 +51129,705059086,361194563,1 +93241,705059086,1540856463,1 +51121,705059089,361194497,0 +51193,705059090,361194500,1 +51103,705059091,361194319,1 +93190,705059091,705059092,1 +127401,705059092,361194285,1 +93242,705060325,705060326,1 +51055,705060326,705060375,1 +93243,705060327,705060328,1 +93251,705060327,705060377,1 +50267,705060328,360730698,1 +93244,705060329,705060330,1 +133425,705060330,361193397,1 +134813,705060331,360729193,1 +93245,705060331,705060332,1 +133424,705060332,705060330,1 +51052,705060346,1540815922,1 +93246,705060346,1540856465,1 +50270,705060352,361194348,1 +93247,705060352,705060354,1 +93345,705060354,360730761,1 +50266,705060360,705060328,1 +93248,705060360,705060362,1 +93340,705060362,705060370,1 +93249,705060368,705060370,1 +93341,705060370,361193892,1 +51056,705060375,360731334,1 +93250,705060375,705060327,1 +50229,705060377,360730698,1 +93252,705060396,705060397,1 +50224,705060397,360730697,1 +93253,705060397,705060398,1 +50226,705060400,361193220,1 +50261,705062330,360731332,1 +93255,705062330,705062331,1 +134808,705062333,360729191,1 +93256,705062333,705062334,1 +133417,705062334,360730892,1 +134807,705062335,705062333,1 +93257,705062335,705062336,1 +133416,705062336,705062334,1 +134806,705062338,705062335,1 +93258,705062338,705062339,1 +133415,705062339,705062336,1 +50249,705062341,1540815092,0 +135269,705062341,1540905616,0 +93259,705062353,705062354,1 +134810,705062353,705073986,1 +133421,705062354,360730895,1 +133420,705062355,705062354,1 +93260,705062355,705062356,1 +50245,705062356,705062359,0 +133419,705062357,705062355,1 +93261,705062357,705062358,1 +50247,705062358,360730987,0 +50246,705062359,705062358,0 +93262,705062359,705062360,1 +50263,705062360,360731319,1 +50252,705063792,360731157,0 +93265,705063792,705063793,0 +82531,705063793,360731137,0 +51070,705063794,361194058,0 +93266,705063794,705063795,1 +51089,705063795,705063798,1 +51069,705063796,705063794,0 +93267,705063796,705063797,1 +51091,705063797,360730761,1 +51090,705063798,705063797,1 +93268,705063798,705063799,1 +51169,705063799,361195482,1 +94816,705063967,361196178,0 +93269,705063967,705063968,1 +93210,705063968,705063987,1 +51209,705063969,361196178,0 +93270,705063969,705063970,0 +51192,705063970,361195985,0 +93206,705063972,361194990,1 +93209,705063986,705063968,1 +51208,705063986,705063969,0 +93211,705063987,361194988,1 +51205,705063990,361195915,0 +51168,705063990,705063799,1 +24013,705065784,705065826,0 +97015,705065786,793529861,0 +93272,705065791,705065793,1 +51223,705065791,705066619,0 +93273,705065799,705065801,1 +93274,705065799,705065806,1 +93276,705065799,705065809,1 +97013,705065799,1540859842,0 +24015,705065801,360731672,0 +93307,705065801,705066616,1 +51221,705065801,1540815930,0 +93275,705065806,793479435,1 +97244,705065806,793479445,1 +97234,705065809,793479445,1 +93277,705065809,793529702,1 +97255,705065811,793529673,1 +97290,705065811,793529733,1 +93279,705065815,705065816,1 +24011,705065815,705065824,0 +93280,705065816,705065818,1 +51228,705065818,705065843,0 +93281,705065818,705066627,1 +51278,705065819,705065821,0 +51232,705065820,361195400,0 +93286,705065820,705065819,0 +51279,705065821,361197158,0 +93287,705065821,705065822,0 +51231,705065822,705065820,0 +93288,705065822,705066595,0 +51227,705065823,705065818,0 +93289,705065823,705065824,1 +24012,705065824,705065784,0 +51225,705065825,360731515,0 +93290,705065825,705065826,1 +24014,705065826,705065801,0 +93291,705065829,705065831,1 +93293,705065831,705065833,1 +93292,705065831,1540856468,1 +93294,705065833,705065834,1 +93295,705065833,705065835,1 +93178,705065834,1540856454,1 +51257,705065835,361196558,0 +24010,705065837,705065815,0 +93296,705065837,705065839,1 +93297,705065839,705065841,1 +51281,705065841,705065816,0 +93298,705065841,705065843,1 +51229,705065843,361196555,0 +93299,705065843,705066623,1 +93301,705066594,705066595,1 +93284,705066594,705066603,0 +93302,705066595,705066596,1 +51252,705066596,705066621,0 +93283,705066597,705066594,0 +93303,705066597,705066598,1 +51251,705066598,705066596,0 +93304,705066599,705066600,1 +51246,705066599,705066628,1 +93306,705066600,705066603,1 +51157,705066602,361196847,1 +93305,705066602,705066600,1 +93285,705066603,705065820,0 +93308,705066616,361197034,1 +50307,705066616,746691570,1 +50306,705066617,705066616,1 +51224,705066619,705065825,0 +93310,705066619,705066620,1 +50305,705066620,1540815103,1 +51253,705066621,361196555,0 +93311,705066621,705066622,1 +93312,705066622,705066623,1 +93313,705066622,705066624,1 +93300,705066623,705066626,1 +50298,705066624,360731667,1 +50300,705066626,360731668,1 +50302,705066627,746691625,1 +51247,705066628,361196448,1 +93282,705066628,705066597,0 +51143,705066778,361195006,1 +50291,705066778,746691671,1 +93314,705073922,1540856469,1 +134820,705073924,1540905139,1 +93317,705073936,705073942,1 +127395,705073936,1540885137,1 +134816,705073941,360730673,1 +2889,705073942,705073943,1 +2890,705073943,705073948,1 +93318,705073943,1540856473,1 +134818,705073947,361194122,1 +2891,705073948,1540773443,1 +93319,705073948,1540856476,1 +127393,705073951,1540885134,1 +127375,705073952,360730300,0 +93323,705073952,705073953,1 +93324,705073953,705073954,1 +127391,705073954,360730594,1 +127373,705073954,705073955,1 +93325,705073956,1142507845,1 +127381,705073956,1540885131,0 +127388,705073957,1540885133,1 +127397,705073961,1540885143,1 +127403,705073961,1540885144,1 +2888,705073963,705073942,1 +50201,705073964,360730004,1 +127380,705073964,705073956,0 +93320,705073977,360730449,1 +93328,705073977,1540856479,1 +134811,705073986,360730912,1 +51079,705073998,361194300,1 +2892,705073998,705074001,1 +51115,705074001,361194472,1 +2893,705074001,1540773444,1 +31684,705970929,353245713,1 +93330,705970933,705970935,1 +134922,705970935,353245713,0 +50193,705971005,360728839,1 +93347,705971005,705971008,1 +93348,705971008,705971016,1 +93353,705971016,705971061,1 +50192,705971032,705971005,1 +127322,705971035,1093091225,1 +93350,705971053,705971056,1 +127316,705971056,360728840,1 +93351,705971056,1142282854,1 +82540,705971069,1540846328,0 +93354,705971069,1540856487,1 +93355,705971081,360728846,1 +127318,705971082,597897194,0 +50259,705971093,360730889,0 +50235,705971097,361434477,0 +93357,705971097,705971099,1 +133409,705971099,360730830,0 +93358,705971099,705971101,1 +64394,705971107,457256020,0 +93359,705971107,705971093,1 +50232,705971109,457256017,0 +93360,705971109,705971111,1 +133412,705971111,360730828,0 +134913,705979164,353245366,0 +134847,705979188,705990371,1 +93362,705979188,1540856491,0 +127368,705979263,353245109,0 +48157,705979278,353244829,0 +93365,705979278,353244894,1 +127346,705979280,353245365,0 +56479,705979282,353245365,1 +127353,705979282,705979164,1 +31636,705979298,353244985,0 +127341,705979302,705979304,1 +135089,705979302,1239786736,0 +127370,705979304,353245028,0 +31647,705979338,353244985,0 +2880,705979338,705979340,0 +2881,705979340,1540773435,0 +48154,705990364,353246116,0 +93368,705990364,1540856496,1 +48171,705990368,353246120,1 +93369,705990368,1540856497,1 +134848,705990371,353244899,1 +93376,705990388,705990399,1 +93374,705990388,1540856500,0 +48144,705990399,360472696,0 +93377,705990399,705990402,1 +48167,705990402,360473095,0 +134927,705990469,353246173,0 +93364,705990469,705979278,1 +31642,705990476,705990483,0 +2876,705990478,360473834,0 +31643,705990483,353244829,0 +93378,705990483,705990485,1 +93379,705990489,705990492,1 +48163,705990489,1540813872,0 +48147,705990492,360473550,0 +93380,705990492,360473766,1 +56477,705990576,353244895,1 +93402,706002664,360469872,1 +93393,706002664,706002667,1 +48015,706002667,360471788,1 +48123,706002675,360472070,1 +93394,706002675,706002678,1 +48019,706002678,360470138,1 +48121,706002702,360472261,1 +48188,706002877,706821452,1 +48191,706002880,353246257,1 +152347,706002907,360469562,1 +93404,706002907,360469859,1 +152339,706002916,360468049,1 +48137,706002941,1540813864,1 +93406,706002941,1540856514,1 +48131,706002947,360472363,1 +48140,706002954,360472122,0 +48139,706002989,706002954,0 +48116,706003065,360470979,0 +48138,706003065,706002989,0 +2917,706804573,353243658,1 +93408,706821410,360468289,1 +127283,706821410,360469347,1 +47877,706821434,360469320,1 +93431,706821447,360469616,1 +93415,706821447,706821452,1 +48189,706821452,353246260,1 +47889,706821618,706821630,1 +48176,706821622,706821633,0 +47890,706821630,706821645,1 +48177,706821633,1540813875,0 +47891,706821645,353246256,1 +93420,706821645,706821649,1 +93421,706821649,1540856519,1 +152363,706821660,353246253,1 +93422,706821674,706821649,1 +152362,706821674,706821660,1 +47875,706821681,360468053,1 +93423,706821681,360468133,1 +47860,706821907,360467905,1 +127299,706830627,706830630,1 +47855,706830630,1540813610,1 +135000,706836643,272554689,0 +16916,706836643,272560247,1 +16912,706836672,1540787233,1 +93434,706836672,1540856523,1 +30805,706854097,360467392,0 +93435,706854097,706854098,1 +30824,706854098,360467410,0 +30807,706854101,347502370,0 +93436,706854101,706854103,0 +30821,706854103,360467380,0 +93437,706854175,365308986,1 +136361,706854175,706854258,0 +93439,706854184,706854186,0 +136363,706854184,1540909156,0 +136328,706854186,1540909143,0 +93440,706854248,706854250,0 +47818,706854248,706854258,0 +30827,706854250,574839084,0 +93441,706854250,1540856526,0 +2925,706854252,1540773463,1 +136358,706854255,1285491845,0 +30802,706854256,360467621,0 +136360,706854256,706854175,0 +136362,706854258,706854184,0 +2924,706854261,1540773462,0 +30801,706854268,706854256,0 +136326,706854268,1540909142,0 +30693,706854285,1540800286,0 +142548,716879736,365388304,1 +93444,716888422,716888423,1 +119092,716888422,1030329188,1 +119121,716888422,1540878314,0 +93445,716888423,716888426,1 +93483,716888423,716888905,1 +93446,716888426,716888429,1 +93495,716888426,716888966,1 +93447,716888429,1030328543,1 +93450,716888435,716888438,1 +118986,716888435,1540878077,0 +93455,716888438,1540856532,1 +93452,716888455,1540856530,1 +119084,716888478,1030329116,1 +93453,716888478,1540856531,1 +93454,716888493,716888438,1 +45649,716888550,360205939,1 +93457,716888550,1540856533,1 +93462,716888599,1540856535,1 +93463,716888615,974066538,1 +112154,716888663,974030878,1 +93466,716888663,974031216,1 +93474,716888709,360205302,1 +93470,716888709,1540856543,1 +93471,716888733,974066353,1 +112226,716888733,974066435,1 +93476,716888818,1540856544,0 +135247,716888861,716888865,0 +45565,716888865,278009652,1 +135248,716888865,1540905610,0 +135249,716888879,1540905612,0 +93482,716888902,716888423,1 +119047,716888902,1030328458,1 +93509,716888905,716888966,1 +93484,716888905,1030323848,1 +112152,716888908,716889049,1 +93508,716888937,716888905,1 +93494,716888937,1540856554,1 +118867,716888947,1540878002,0 +93510,716888966,716888429,1 +93496,716888966,1030323743,1 +93502,716889049,716889055,1 +142501,716889055,279589619,1 +93507,716889097,716888937,1 +93511,716889345,279589624,1 +21419,716889345,1540790971,0 +93971,736532215,736532819,1 +93969,736532336,736533283,1 +93910,736532361,736532372,1 +93976,736532361,1540856792,1 +93911,736532372,736532380,1 +93914,736532372,1540856753,1 +93912,736532380,736532385,1 +93918,736532380,736532547,1 +93916,736532385,736532468,1 +93913,736532385,1540856747,1 +93917,736532468,736532528,1 +93915,736532518,736532385,1 +93919,736532574,736532581,1 +93920,736532581,736532590,1 +93974,736532581,1540856788,1 +93921,736532590,736532596,1 +93922,736532596,1540856754,1 +93960,736532596,1540856784,1 +93923,736532620,736532630,1 +93955,736532620,736533084,1 +93924,736532630,736532642,1 +93943,736532630,736532935,1 +93925,736532642,736532651,1 +93953,736532642,736532729,1 +93984,736532651,736532712,1 +93926,736532651,1540856756,1 +93985,736532712,736533361,1 +93935,736532712,1540856773,1 +93936,736532729,736532740,1 +93954,736532729,736533042,1 +93942,736532740,736532630,1 +93937,736532761,1540856774,1 +93938,736532784,1540856777,1 +93975,736532784,1540856790,1 +93939,736532791,1540856778,1 +93940,736532791,1540856779,1 +93959,736532807,1540856783,1 +94017,736532819,736533220,1 +93972,736532819,736533277,1 +93968,736532872,736532336,1 +93941,736532932,736532740,1 +93958,736532932,1540856781,1 +93944,736532935,736532965,1 +93945,736532965,736532968,1 +93964,736532965,736533084,1 +93946,736532968,736532970,1 +94020,736532968,736533026,1 +93999,736532970,736533604,1 +93983,736532992,736532651,1 +93947,736532992,736532997,1 +93952,736532997,736532642,1 +93948,736532997,736532935,1 +93949,736533019,736533026,1 +93997,736533019,736604568,1 +93950,736533026,736533034,1 +94021,736533026,736533790,1 +93963,736533034,736532965,1 +93951,736533034,736532997,1 +93957,736533042,736532932,1 +93977,736533042,736533346,1 +93956,736533084,736533100,1 +93965,736533084,1540856787,1 +94019,736533100,736532968,1 +93966,736533195,736533277,1 +93961,736533195,1540856786,1 +94018,736533220,736533100,1 +94016,736533220,736533604,1 +93982,736533257,736532992,1 +93962,736533257,736533034,1 +93973,736533277,736532581,1 +93967,736533277,736532872,1 +93970,736533300,736532215,1 +94002,736533300,737260660,1 +94378,736533300,1540857043,1 +93978,736533346,736533351,1 +93979,736533351,736533361,1 +93986,736533361,737308037,1 +93980,736533361,1540856795,1 +93927,736533381,1540856767,1 +93996,736533498,736533019,1 +93981,736533498,736533257,1 +94491,736533506,1540857105,1 +94049,736533550,736546157,1 +93991,736533550,736546170,1 +94109,736533576,736604928,1 +93995,736533576,1540856798,1 +94000,736533604,1540856800,1 +94006,736533625,737260664,1 +94388,736533625,737299091,1 +94011,736533638,736533647,1 +94339,736533638,737300246,1 +94012,736533647,736533652,1 +94376,736533647,1540857039,1 +94013,736533652,737260697,1 +94385,736533652,1540857045,1 +93928,736537339,737307762,1 +94488,736537339,737307787,1 +94022,736545162,736545169,1 +93993,736545162,736545295,1 +94023,736545169,736545174,1 +94031,736545169,736545253,1 +94024,736545174,736545181,1 +94026,736545174,736545205,1 +94064,736545181,736545302,1 +94025,736545199,736545174,1 +94055,736545199,736546172,1 +94027,736545205,736545215,1 +94042,736545205,736545302,1 +94047,736545215,736545329,1 +94028,736545215,736605138,1 +94030,736545248,736545169,1 +94053,736545248,736546171,1 +94041,736545253,736545205,1 +94032,736545253,736545257,1 +94046,736545257,736545215,1 +94033,736545257,736545262,1 +94034,736545262,736545269,1 +94122,736545262,736605138,1 +94035,736545269,736545278,1 +94143,736545269,736605212,1 +94128,736545278,736605163,1 +94036,736545278,1540856803,1 +94099,736545295,736604928,1 +94039,736545295,736605054,1 +93994,736545295,1540856796,1 +94065,736545302,736545329,1 +94043,736545302,1540856810,1 +94076,736545306,736545333,1 +94048,736545329,736545333,1 +94066,736545329,736605139,1 +94077,736545333,737635741,1 +94050,736546157,736546161,1 +94061,736546157,736546171,1 +94051,736546161,736546163,1 +94074,736546163,736546181,1 +93992,736546170,736545162,1 +94052,736546170,736545248,1 +94054,736546171,736545199,1 +94062,736546172,736546161,1 +94056,736546172,736546178,1 +94063,736546178,736545181,1 +94057,736546178,1540856811,1 +94075,736546181,736545306,1 +94058,736546181,1540856812,1 +94125,736546187,736546848,1 +94068,736546187,1540856820,1 +94624,736546846,737307460,1 +94072,736546846,1540856827,1 +94079,736546848,736546851,1 +94080,736546851,1540856828,1 +94087,736546851,1540856836,1 +94094,736546855,736607240,1 +94287,736546855,1540856976,1 +93998,736604568,736532970,1 +94081,736604568,736604579,1 +94102,736604579,736604948,1 +94070,736604617,736605285,1 +94082,736604617,1540856831,1 +94084,736604701,736604714,1 +94149,736604701,1540856870,1 +94085,736604714,736604722,1 +94086,736604722,736604731,1 +152408,736604731,736607229,1 +94089,736604772,736604782,1 +94134,736604772,736605193,1 +94090,736604782,736607202,1 +94162,736604782,736607278,1 +94137,736604883,736607236,1 +94096,736604883,1540856839,1 +152411,736604902,1540962920,1 +94100,736604928,736604936,1 +94044,736604928,736605061,1 +94101,736604936,736604579,1 +94141,736604936,736605070,1 +94126,736604948,736605088,1 +94103,736604948,1540856840,1 +94104,736604989,736604997,1 +94105,736604997,736607245,1 +94120,736604997,737260673,1 +94040,736605054,736545253,1 +94110,736605054,736605061,1 +94045,736605061,736545257,1 +94111,736605061,736605070,1 +94142,736605070,736545269,1 +94112,736605070,1540856845,1 +94127,736605088,736545278,1 +94113,736605088,1540856846,1 +94119,736605096,736604989,1 +94114,736605096,1540856847,1 +94117,736605116,736605123,1 +94147,736605116,1540856867,1 +94118,736605123,736605096,1 +94037,736605123,1540856805,1 +94001,736605128,736533300,1 +94123,736605138,736605139,1 +94029,736605138,736605167,1 +94067,736605139,736546187,1 +94124,736605159,736546187,1 +94132,736605159,1540856855,1 +94129,736605163,736605165,1 +94146,736605163,1540856865,1 +94130,736605165,1540856851,1 +94131,736605167,1540856852,1 +94069,736605186,736604617,1 +94133,736605186,1540856862,1 +94135,736605193,736607270,1 +94158,736605193,1540856878,1 +94145,736605212,736605163,1 +94144,736605212,736605165,1 +94151,736605285,736607202,1 +94071,736605285,1540856825,1 +94150,736607169,736607175,1 +94093,736607169,1540856837,1 +94161,736607175,736607229,1 +94091,736607202,736607297,1 +152409,736607229,737248943,1 +94219,736607234,736968946,1 +94297,736607234,737258663,1 +152412,736607234,1540962921,1 +94138,736607236,737258710,1 +152414,736607236,1540962922,1 +94095,736607240,736604883,1 +94152,736607242,736607245,1 +94115,736607242,1540856848,1 +94106,736607245,1540856841,1 +94153,736607245,1540856876,1 +94155,736607249,736607251,1 +94116,736607249,1540856849,1 +94156,736607251,736607253,1 +94038,736607251,1540856807,1 +94148,736607253,1540856868,1 +94097,736607257,736607259,1 +94098,736607259,736604902,1 +94088,736607265,736604772,1 +94157,736607265,1540856877,1 +94136,736607270,1540856863,1 +94163,736607278,736607257,1 +94159,736607278,1540856880,1 +94165,736607280,736607259,1 +94160,736607280,1540856881,1 +94092,736607297,736607169,1 +94164,736607297,736607280,1 +94107,736607456,737248999,1 +94083,736607549,1540856832,1 +51184,736618839,361195750,0 +51207,736618839,705063986,0 +94169,736968721,1540856885,1 +94173,736968722,736533506,1 +130419,736968931,1540886609,1 +152394,736968931,1540962911,1 +94336,736968933,737260636,1 +152395,736968933,1540962912,1 +152398,736968935,736968936,1 +94342,736968935,737260629,1 +152399,736968936,737260647,1 +152401,736968937,1540962913,1 +152406,736968944,737249000,1 +94358,736968944,737260655,1 +94220,736968946,736968950,1 +94174,736968946,737248944,1 +94216,736968948,736968952,1 +94176,736968948,1540856888,1 +94221,736968950,736968959,1 +94180,736968950,737248945,1 +94182,736968952,1540856894,1 +94217,736968952,1540856924,1 +94252,736968954,737253178,1 +94183,736968954,1540856895,1 +94218,736968956,737248959,1 +94190,736968956,1540856900,1 +94222,736968959,737255204,1 +94192,737248913,1540856902,1 +94250,737248915,737252823,1 +94194,737248915,1540856903,1 +94195,737248920,1540856904,1 +94249,737248920,1540856951,1 +94196,737248931,1540856908,1 +94205,737248931,1540856915,1 +94324,737248936,737260617,1 +94197,737248936,1540856909,1 +152410,737248943,736604902,1 +94199,737248943,737248944,1 +94200,737248944,737248945,1 +94175,737248944,1540856886,1 +94201,737248945,737248946,1 +94181,737248945,1540856893,1 +94191,737248946,736968959,1 +94202,737248946,737248947,1 +94203,737248946,1540856911,1 +94209,737248947,1540856920,1 +94204,737248950,1540856913,1 +94225,737248953,737255148,1 +94206,737248958,737253139,1 +94208,737248959,1540856919,1 +94213,737248963,737248950,1 +94210,737248963,1540856921,1 +94108,737248999,736604722,1 +94214,737248999,737249000,1 +94215,737249000,736968948,1 +152407,737249000,1540962919,1 +94227,737252794,1540856925,1 +94228,737252801,1540856926,1 +94229,737252805,1540856927,1 +94236,737252812,737255258,1 +94230,737252812,737255280,1 +94232,737252814,737258768,1 +94260,737252814,1540856957,1 +94251,737252823,737252801,1 +94234,737252823,1540856930,1 +94237,737252838,737252840,1 +94212,737252838,1540856923,1 +94243,737252840,1540856935,1 +94211,737252846,737252838,1 +94238,737252846,737252848,1 +94242,737252848,1540856934,1 +94248,737252852,737248920,1 +94244,737252852,1540856937,1 +94247,737252868,1540856947,1 +94239,737252881,737252884,1 +94186,737252881,737253290,1 +94187,737252884,737252896,1 +94240,737252884,1540856933,1 +94198,737252891,1540856910,1 +94188,737252896,737253283,1 +94245,737252899,1540856944,1 +94241,737252904,737252848,1 +94246,737252933,1540856945,1 +94193,737253124,737248915,1 +94207,737253139,737248959,1 +94257,737253139,737252933,1 +94253,737253178,737253199,1 +94177,737253178,1540856889,1 +152405,737253199,1540962918,1 +94352,737253235,737260659,1 +94254,737253235,1540856956,1 +152403,737253235,1540962915,1 +94185,737253252,1540856896,1 +94184,737253280,737253252,1 +94255,737253280,737253283,1 +94256,737253283,737253139,1 +94189,737253283,1540856898,1 +152402,737253290,1540962914,1 +94226,737255148,737248913,1 +94258,737255148,737255511,1 +94275,737255157,737255258,1 +94224,737255163,737248953,1 +94261,737255163,737258768,1 +94274,737255171,737255157,1 +94264,737255171,1540856961,1 +94223,737255204,737255163,1 +94265,737255204,737258709,1 +94314,737255206,737258751,1 +94270,737255206,1540856966,1 +94273,737255211,737255171,1 +94271,737255211,1540856967,1 +117026,737255236,737255249,1 +94272,737255236,737258773,1 +94312,737255249,1540857004,1 +94231,737255280,737252814,1 +94276,737255280,1540856973,1 +94235,737255488,1540856932,1 +94280,737255488,1540856974,1 +94277,737255497,737248913,1 +94279,737255497,737255488,1 +94259,737255511,737252814,1 +94278,737255511,737255497,1 +94281,737258654,737258656,1 +94303,737258654,737258705,1 +94282,737258656,737258657,1 +94283,737258656,737258659,1 +94291,737258657,1540856989,1 +94318,737258659,1540857013,1 +94284,737258662,737258663,1 +94296,737258662,737258698,1 +94285,737258663,1540856975,1 +94298,737258663,1540856990,1 +94286,737258667,737258668,1 +94307,737258667,737258706,1 +94268,737258668,737258702,1 +94289,737258690,737258691,1 +94317,737258690,1540857012,1 +94290,737258691,737258657,1 +94292,737258693,737258694,1 +94293,737258694,737258696,1 +94294,737258694,737258697,1 +94300,737258696,737258702,1 +94295,737258697,737258662,1 +94305,737258697,737258700,1 +152413,737258698,736607236,1 +94306,737258700,737258667,1 +94299,737258700,1540856991,1 +94269,737258702,737255206,1 +94301,737258702,737258703,1 +94263,737258703,1540856959,1 +94302,737258704,737258654,1 +94319,737258704,737258712,1 +94140,737258705,737258693,1 +94304,737258705,737258697,1 +94179,737258706,736968950,1 +94308,737258706,1540856992,1 +94266,737258709,737258765,1 +94139,737258710,737258705,1 +94309,737258710,1540856994,1 +94320,737258712,1540857014,1 +94310,737258713,1540856995,1 +94311,737258722,1540857001,1 +94313,737258746,1540857007,1 +94316,737258746,1540857010,1 +94315,737258751,737258691,1 +94267,737258765,737258668,1 +94178,737258765,737258706,1 +94262,737258768,737258703,1 +94233,737258768,737258765,1 +94321,737260612,737260613,1 +94341,737260612,1540857025,1 +94322,737260613,737299117,1 +94377,737260613,1540857041,1 +94367,737260615,1540857036,1 +94325,737260617,737260618,1 +94329,737260617,737260629,1 +94326,737260618,1540857015,1 +94332,737260618,1540857018,1 +94327,737260624,1540857016,1 +94330,737260629,737300242,1 +152397,737260630,736968935,1 +94400,737260632,737260624,1 +94333,737260632,1540857019,1 +94335,737260636,1540857022,1 +94392,737260640,1540857049,1 +94337,737260641,737260642,1 +94009,737260641,1540856801,1 +94338,737260643,737260644,1 +94348,737260643,1540857026,1 +152404,737260644,1540962917,1 +152400,737260647,736968937,1 +94343,737260651,737299114,1 +94375,737260651,1540857038,1 +94406,737260652,737300221,1 +94346,737260655,737260656,1 +94359,737260655,737260685,1 +94357,737260656,737253199,1 +94347,737260656,737260643,1 +94353,737260659,737260666,1 +94349,737260660,737260661,1 +94003,737260660,737299122,1 +94355,737260661,1540857029,1 +94005,737260662,736533625,1 +94350,737260662,737260663,1 +94351,737260664,737260665,1 +94007,737260664,737299088,1 +94010,737260666,1540856802,1 +94121,737260673,736605128,1 +94354,737260673,1540857028,1 +94154,737260685,737260686,1 +94360,737260685,737260695,1 +94356,737260686,1540857031,1 +94014,737260697,737260698,1 +94366,737260697,1540857034,1 +94015,737260698,736968931,1 +94396,737260698,1540857050,1 +94368,737299067,737299073,1 +94361,737299072,737299073,1 +94369,737299073,737299086,1 +94362,737299073,737300263,1 +94345,737299074,737260652,1 +94364,737299074,1540857032,1 +94370,737299086,737299087,1 +94382,737299086,737300253,1 +94371,737299087,737299088,1 +94373,737299087,737300268,1 +94008,737299088,737260641,1 +94372,737299091,737299087,1 +94389,737299091,741424113,1 +94379,737299108,737299110,1 +94380,737299110,741424113,1 +94384,737299114,736533652,1 +94344,737299114,737299074,1 +94323,737299117,737260615,1 +94386,737299117,1540857046,1 +94004,737299122,737260662,1 +94387,737299122,737299110,1 +94391,737300221,1540857048,1 +94407,737300221,1540857053,1 +94395,737300226,737260698,1 +94393,737300226,737300227,1 +94394,737300227,737300229,1 +94365,737300229,737260697,1 +152396,737300234,737260630,1 +94397,737300234,737300237,1 +94398,737300237,737300238,1 +94334,737300237,1540857021,1 +94328,737300238,737260627,1 +94331,737300242,737260630,1 +94399,737300242,737260632,1 +94340,737300246,737260612,1 +94401,737300246,1540857051,1 +94383,737300253,737299114,1 +94403,737300253,737300263,1 +94363,737300263,737299074,1 +94404,737300263,737300273,1 +94402,737300268,737300253,1 +94374,737300268,1540857037,1 +94405,737300273,737260652,1 +94429,737307258,737307331,1 +94572,737307258,984639848,1 +94408,737307258,1540857054,1 +94411,737307262,984634551,1 +115381,737307262,1540874507,1 +94413,737307266,1540857056,1 +94414,737307269,1540857057,1 +115337,737307273,984364120,1 +94416,737307273,984364391,1 +94418,737307275,737307277,1 +23941,737307275,984364803,0 +23935,737307277,1540793842,0 +94419,737307282,737307285,1 +94464,737307282,1540857086,1 +94561,737307285,737307549,1 +94420,737307287,737307292,1 +94465,737307287,737307295,1 +94560,737307292,737307285,1 +94422,737307295,737308362,1 +94425,737307305,737307306,1 +94467,737307305,737307582,1 +94461,737307305,1540857083,1 +94466,737307305,1540857087,1 +94436,737307306,737307258,1 +94428,737307325,737307258,1 +94430,737307331,737307336,1 +94431,737307336,737307337,1 +94432,737307337,1540857059,1 +94580,737307337,1540857181,1 +94433,737307341,984639871,1 +115358,737307341,1540874492,1 +115417,737307344,737307345,1 +149681,737307344,1411198272,1 +115418,737307345,737307347,1 +115311,737307345,1540874480,1 +94439,737307350,737307354,1 +94435,737307350,1540857063,1 +94440,737307354,737307355,1 +94463,737307354,1540857085,1 +94563,737307355,1540857171,1 +94441,737307358,737307360,1 +94462,737307358,1540857084,1 +94564,737307360,600919204,1 +94443,737307365,737307366,1 +94444,737307366,1540857066,1 +94459,737307366,1540857081,1 +94446,737307369,1540857067,1 +94540,737307381,737309648,1 +94447,737307381,1540857070,1 +94448,737307384,737307387,1 +94613,737307387,737635340,1 +94449,737307387,1540857071,1 +94452,737307401,737634941,1 +94455,737307433,737307444,1 +94625,737307433,1540857229,1 +94456,737307444,737307460,1 +94457,737307460,1540857080,1 +94458,737307548,737307366,1 +93934,737307548,1540856771,1 +94562,737307549,737307355,1 +94566,737307554,984639812,1 +94460,737307554,1540857082,1 +94468,737307582,737307583,1 +94568,737307582,1540857176,1 +94469,737307583,737307586,1 +94477,737307583,1540857093,1 +94476,737307586,736968721,1 +94470,737307586,737307588,1 +94471,737307588,737307591,1 +94475,737307588,1540857090,1 +94472,737307591,737307592,1 +94480,737307591,737307695,1 +94473,737307592,737307594,1 +94483,737307592,1540857098,1 +94474,737307594,737307596,1 +94486,737307594,1540857099,1 +94517,737307614,1540857136,1 +94478,737307638,1540857096,1 +94518,737307638,1540857137,1 +93933,737307653,1540856770,1 +94479,737307686,737307591,1 +94170,737307686,737307726,1 +94516,737307695,737307614,1 +94481,737307695,737307707,1 +93932,737307707,737307653,1 +94482,737307726,737307592,1 +94171,737307726,737307745,1 +94484,737307733,737307735,1 +94515,737307733,1540857134,1 +93930,737307735,737307820,1 +94172,737307745,736968722,1 +94485,737307745,737307594,1 +94487,737307753,1540857100,1 +94514,737307753,1540857133,1 +93929,737307762,737307735,1 +94513,737307787,737307753,1 +94489,737307787,1540857101,1 +93989,737307801,737307927,1 +94490,737307817,737307820,1 +93931,737307820,737307707,1 +94519,737307836,737307924,1 +94492,737307836,1540857106,1 +94501,737307859,737307871,1 +94493,737307859,737998390,1 +94502,737307871,737307911,1 +94497,737307871,1540857117,1 +94500,737307892,737307911,1 +94498,737307892,1540857120,1 +94503,737307924,737307927,1 +94520,737307924,737307939,1 +93990,737307927,736533506,1 +93988,737307936,737307801,1 +94504,737307936,737307939,1 +94505,737307939,1540857123,1 +94521,737307939,1540857139,1 +94522,737307949,737307970,1 +94506,737307949,1540857124,1 +94523,737307955,1540857141,1 +94507,737307967,737307970,1 +94508,737307970,1540857125,1 +94509,737307990,1540857130,1 +94510,737308026,736533351,1 +94511,737308026,737308037,1 +94512,737308037,737307787,1 +93987,737308037,737307936,1 +94421,737308361,737307295,1 +23878,737308361,737308374,1 +94423,737308362,737308363,1 +94524,737308362,737308366,1 +94424,737308363,600919183,1 +23886,737308363,737308376,1 +94528,737308366,737308376,1 +94525,737308366,1540857150,1 +94530,737308368,600919181,1 +94526,737308368,1540857152,1 +23884,737308371,294114430,1 +94527,737308374,737308366,1 +23879,737308374,984634450,1 +23887,737308376,600919181,1 +94529,737308376,1540857157,1 +94558,737308382,600919183,1 +23889,737308389,294114600,1 +94532,737308389,737308391,1 +94556,737308391,1540857168,1 +94569,737308391,1540857178,1 +23877,737308404,737308361,1 +94547,737309562,523552911,1 +94533,737309562,737309564,1 +94571,737309564,737309569,1 +68965,737309569,1540838296,1 +94534,737309569,1540857160,1 +94535,737309573,737309576,1 +94538,737309576,737309586,1 +94445,737309586,737307369,1 +94590,737309648,737634823,1 +94541,737309648,1540857162,1 +94544,737309668,523552919,1 +94552,737309668,737309676,1 +94632,737309670,737307384,1 +94550,737309670,737642004,1 +94555,737309676,1540857167,1 +94554,737309682,737309676,1 +23882,737309682,1540793768,1 +94570,737309694,737309564,1 +68978,737309694,1540838303,1 +68976,737309696,523552920,1 +68980,737309696,1540838305,1 +83942,737309706,294138005,1 +94542,737309706,984332222,1 +23918,737309706,1540793816,0 +115718,737311448,737311461,1 +94575,737311448,985968886,1 +94579,737311449,737311453,1 +94692,737311449,1540857306,1 +152173,737311453,985968669,1 +115689,737311453,985968878,1 +115685,737311454,985968838,1 +152175,737311454,985968917,1 +152190,737311455,737998385,1 +152188,737311455,1540961385,1 +94582,737311459,984639863,1 +115422,737311459,985968685,1 +94584,737311461,737311463,1 +94585,737311463,985968674,1 +104466,737311463,985968829,1 +115687,737311464,985968659,1 +152180,737311464,1540961379,1 +152181,737311465,1540961380,1 +152178,737311467,985968849,1 +152184,737311467,1540961383,1 +115720,737311475,1540874853,1 +152185,737311475,1540961384,1 +115677,737311477,985968701,1 +152186,737311477,1482899198,1 +94588,737634737,737634755,1 +94608,737634737,737635483,1 +94589,737634755,1540857182,1 +94591,737634823,1540857185,1 +94592,737634858,1540857186,1 +94593,737634941,737635001,1 +94453,737634941,737635013,1 +94594,737635001,737635013,1 +94454,737635013,1540857076,1 +94595,737635125,1540857192,1 +94615,737635125,1540857215,1 +94596,737635177,737635180,1 +94451,737635177,1540857075,1 +94597,737635180,737635185,1 +94606,737635180,1540857209,1 +94598,737635185,737634858,1 +94607,737635185,1540857210,1 +94618,737635220,737635859,1 +94599,737635220,1540857195,1 +94603,737635288,737635340,1 +94635,737635288,737642026,1 +94600,737635288,1540857200,1 +94614,737635340,737635125,1 +94604,737635340,1540857205,1 +94450,737635373,1540857073,1 +94605,737635373,1540857207,1 +94609,737635513,737635530,1 +94616,737635513,737635849,1 +94610,737635530,1540857211,1 +94621,737635530,1540857225,1 +94611,737635624,737635641,1 +94612,737635641,1540857213,1 +94626,737635641,1540857231,1 +94078,737635741,736546848,1 +94617,737635849,737635220,1 +94620,737635849,1540857222,1 +94619,737635859,1540857217,1 +94622,737635859,1540857228,1 +94623,737636146,736546846,1 +94627,737636146,1540857233,1 +94629,737636260,737635918,1 +94073,737636296,736546163,1 +94628,737636296,737636260,1 +94059,737636351,1540856813,1 +94630,737636351,1540857235,1 +94060,737636363,1540856819,1 +94631,737636363,1540857236,1 +94551,737642004,737307387,1 +94633,737642004,1540857237,1 +94634,737642023,737642026,1 +94601,737642023,1540857203,1 +94636,737642026,737642087,1 +94637,737642087,737642097,1 +94638,737642097,737655914,1 +68982,737642097,737656060,1 +94549,737642136,737309670,1 +94641,737642136,1540857238,1 +94602,737642149,1540857204,1 +94642,737642149,1540857239,1 +94643,737642212,737656655,1 +68984,737642212,1540838306,1 +94644,737655385,1540857240,1 +115145,737655385,1540874308,1 +94645,737655406,737655417,1 +94655,737655406,1540857259,1 +115144,737655447,737655385,1 +94656,737655474,737655527,1 +94646,737655527,1540857242,1 +94657,737655527,1540857260,1 +94658,737655673,737656124,1 +94647,737655673,1540857244,1 +68969,737655829,523552916,1 +94648,737655829,737655849,1 +94640,737655849,523552922,1 +94639,737655914,737655849,1 +94649,737655914,1540857258,1 +94650,737655929,737655940,1 +94652,737655929,737656070,1 +68983,737656060,737642212,1 +94651,737656060,737655929,1 +94653,737656070,737656080,1 +94660,737656070,737656214,1 +94654,737656080,737655406,1 +94662,737656080,737656310,1 +89053,737656124,1540852126,0 +94659,737656208,737656070,1 +94661,737656282,737656080,1 +115148,737656882,1540874323,0 +115169,737656882,1540874354,1 +94663,737998246,737998248,1 +94678,737998246,737998352,1 +94675,737998248,1540857273,1 +94664,737998257,737998261,1 +94672,737998257,737998265,1 +94665,737998265,737998267,1 +94673,737998265,1540857272,1 +94666,737998271,279590314,1 +143886,737998278,279590314,1 +94668,737998278,737998279,1 +94669,737998281,279590321,1 +94690,737998281,737998414,1 +152194,737998282,1540961403,1 +152193,737998283,737998282,1 +135176,737998288,1540905570,1 +94671,737998290,1540857266,1 +143888,737998290,1540937891,1 +94674,737998298,737998248,1 +94681,737998298,1540857302,1 +94676,737998334,1540857292,1 +94677,737998351,737998246,1 +94679,737998357,1540857295,1 +94680,737998367,1540857298,1 +152197,737998367,1540961414,1 +152189,737998371,1540961392,1 +152191,737998385,1540961399,1 +94494,737998390,1540857114,1 +152192,737998390,1540961401,1 +152196,737998414,1540961408,1 +94682,737998430,737998444,1 +94683,737998444,279590317,1 +94687,737998444,737998462,1 +94685,737998455,737998456,1 +94686,737998456,737998457,1 +94496,737998462,737998456,1 +94688,737998462,737998464,1 +94689,737998464,737998281,1 +94691,737998464,737998288,1 +94495,737998498,737998462,1 +135175,737998498,1540905569,1 +94694,737998501,737998504,1 +94499,737998501,985968631,1 +94695,737998504,736968722,1 +94697,737998504,737998512,1 +94390,741424113,737299072,1 +94381,741424113,737299086,1 +94866,745090194,603748688,1 +94842,745090194,745090195,1 +94843,745090195,745090199,1 +94964,745090199,745090816,1 +94844,745090216,745090195,1 +94945,745090216,745090789,1 +94847,745090228,745090229,1 +94925,745090228,745090681,1 +94848,745090229,745090230,1 +94951,745090229,745090664,1 +94849,745090230,745090232,1 +97490,745090230,745090421,0 +63945,745090232,1540833523,0 +94851,745090254,745090257,1 +94853,745090254,793781822,1 +94924,745090257,745090228,1 +94852,745090257,1540857369,1 +94949,745090261,793799842,1 +94959,745090272,793781728,1 +51498,745090272,793781764,1 +94855,745090287,745090290,1 +97493,745090287,745090450,0 +94856,745090290,745090292,1 +63943,745090290,745090423,0 +94857,745090292,745090295,1 +94893,745090292,745090427,1 +83959,745090295,745090457,1 +94858,745090295,1540857370,1 +94860,745090317,1345658067,1 +94859,745090317,1540857372,1 +97509,745090323,1540859992,1 +94863,745090372,745090374,1 +97497,745090372,793810069,0 +94864,745090374,745090377,1 +63939,745090374,745090818,0 +83962,745090377,745090746,1 +94865,745090385,745090194,1 +94942,745090385,793781762,1 +94869,745090387,745090390,1 +97499,745090387,1540859985,0 +63937,745090390,793810044,0 +94870,745090402,745090404,1 +95025,745090402,1540857382,1 +94873,745090404,745090415,1 +94871,745090409,745090412,1 +97486,745090409,745090617,0 +94872,745090412,745090404,1 +63948,745090412,745090596,0 +94874,745090421,745090423,1 +97491,745090421,793799885,0 +63944,745090423,745090232,0 +94875,745090423,745090425,1 +94876,745090425,745090427,1 +94886,745090425,745090494,1 +94894,745090427,745090519,1 +94877,745090441,745090443,1 +97495,745090441,745090816,0 +94878,745090443,745090445,1 +63941,745090443,745090452,0 +94891,745090445,745090455,1 +97494,745090450,745090441,0 +94879,745090450,745090452,1 +63942,745090452,745090290,0 +94880,745090452,745090455,1 +94892,745090455,745090292,1 +94881,745090455,745090457,1 +83960,745090457,745090509,1 +94905,745090471,745090496,1 +94882,745090471,793810040,1 +94884,745090474,600926419,1 +94885,745090474,1540857373,1 +94887,745090494,745090496,1 +95026,745090494,745090519,1 +94906,745090496,745090524,1 +94888,745090496,1540857374,1 +94890,745090509,745090445,1 +83961,745090509,1540846790,1 +94895,745090519,745090524,1 +95027,745090519,745090554,1 +94907,745090524,745090557,1 +94896,745090524,793810036,1 +94897,745090554,745090557,1 +95028,745090554,745090738,1 +94898,745090557,600926422,1 +94908,745090557,745090597,1 +94899,745090584,745090587,1 +94929,745090584,745090686,1 +94900,745090587,745090589,1 +94912,745090587,745090609,1 +94901,745090589,745090591,1 +94902,745090591,745090595,1 +94917,745090591,745090614,1 +97485,745090595,745090409,0 +94903,745090595,745090596,1 +94904,745090596,745090471,1 +63949,745090596,1540833524,0 +83954,745090597,793810054,1 +94972,745090599,417279549,1 +94909,745090599,745090601,1 +94910,745090601,745090589,1 +94911,745090607,745090587,1 +94939,745090607,745090601,1 +94913,745090609,745090612,1 +97438,745090609,793799938,1 +94914,745090612,745090614,1 +94920,745090612,793799929,1 +94915,745090614,745090617,1 +94918,745090614,793799993,1 +94916,745090617,745090621,1 +97487,745090617,793799951,0 +63947,745090621,745090412,0 +95022,745090645,745090891,1 +95021,745090664,745090645,1 +94961,745090678,745090789,1 +94922,745090678,793781802,1 +94926,745090681,793781710,1 +95019,745090681,793799981,1 +94928,745090683,745090584,1 +94935,745090683,793799938,1 +94930,745090686,745090688,1 +94938,745090688,745090607,1 +94931,745090688,745090690,1 +94932,745090690,745090699,1 +94971,745090699,1540857380,1 +51489,745090706,793781692,1 +94933,745090706,793781817,1 +94936,745090713,745090686,1 +51487,745090713,793781814,1 +94937,745090717,745090690,1 +51485,745090717,793781654,1 +83958,745090738,745090295,1 +83963,745090746,1540846791,1 +94946,745090789,793799857,1 +94962,745090789,1540857378,1 +94952,745090796,1540857375,1 +94953,745090800,793385647,1 +97042,745090803,793385719,1 +94956,745090803,793385785,1 +51520,745090805,793781789,1 +94958,745090805,1540857376,1 +97496,745090816,745090372,0 +94965,745090816,745090818,1 +63940,745090818,745090443,0 +94966,745090818,745090509,1 +95024,745090852,745090402,1 +63946,745090852,745090621,0 +97489,745090891,745090230,0 +95023,745090891,745090852,1 +95047,745090918,745091092,1 +94978,745090918,793279619,1 +94980,745090919,793279480,1 +94982,745090920,793279552,1 +96967,745090920,793279648,1 +94984,745090921,793385762,1 +97029,745090921,1540859845,1 +94987,745090922,745090923,1 +97073,745090922,1540859860,1 +94988,745090923,793428348,1 +97100,745090923,793428474,1 +94990,745090925,745090926,1 +95009,745090925,793428519,1 +94991,745090926,745090928,1 +94992,745090928,745090930,1 +94993,745090928,793428382,1 +97124,745090930,793428500,1 +94995,745090937,793428352,1 +94997,745090939,745090941,1 +97131,745090941,793428434,1 +94998,745090941,793428479,1 +24000,745090943,1540793890,1 +95003,745090951,793428477,1 +23996,745090951,1540793886,1 +95078,745090953,793428459,1 +95005,745090953,1540857381,1 +95014,745090958,745090960,1 +51513,745090958,793781837,1 +95064,745090960,793781775,1 +95015,745090960,793781827,1 +97084,745090984,745090986,1 +95031,745090986,745091002,1 +97085,745090986,793279518,1 +97087,745090989,745090991,1 +95058,745090989,793279486,1 +97088,745090991,793279459,1 +96999,745090991,793279532,1 +95030,745091000,745090986,1 +95040,745091000,793279616,1 +96991,745091002,793279605,1 +95032,745091002,793279625,1 +95062,745091004,793428491,1 +95034,745091004,1540857383,1 +64367,745091042,1540834217,0 +95038,745091042,1540857388,1 +96943,745091066,745090984,1 +95039,745091066,745091000,1 +95057,745091071,745090989,1 +95042,745091071,1540857389,1 +95043,745091077,745091082,1 +96997,745091077,793279526,1 +95044,745091082,745091086,1 +95045,745091086,793279521,1 +96924,745091086,793279650,1 +95048,745091092,1540857391,1 +96910,745091099,793279587,1 +95049,745091099,793385680,1 +96890,745091126,793279549,1 +95060,745091126,1540857392,1 +95061,745091139,745091004,1 +97046,745091139,1540859849,1 +94967,745092364,793781724,1 +51508,745092364,793781752,1 +95083,745092374,745092394,1 +95001,745092374,793428510,1 +94969,745092378,361199832,1 +95072,745092378,793781759,1 +97410,745092385,793781799,1 +95074,745092392,793428507,1 +95084,745092394,745092397,1 +97119,745092394,793428447,1 +97148,745092397,793428456,1 +95085,745984371,745984372,0 +92196,745984372,1235838543,1 +95086,745984373,745984374,1 +50144,745984373,1540815057,0 +95087,745984374,745984375,1 +95088,745984374,745984376,1 +92199,745984375,360720402,1 +133433,745984376,745984378,0 +95089,745984377,745984378,1 +133434,745984378,360720401,0 +17705,745984391,286538932,1 +95090,745984393,286537120,0 +50074,745984393,360718926,0 +70240,745984394,286537120,1 +95091,745984394,745984395,1 +70243,745984396,360719401,1 +95092,745984396,745984397,1 +50146,745984400,360720758,0 +133437,745984400,1540894450,0 +95094,745985491,286537122,0 +100780,745985491,360720097,1 +95095,745985492,745985493,1 +64391,745985492,745985494,1 +100778,745985493,745985518,1 +64392,745985494,286537128,1 +95096,745985494,745985495,1 +95097,745985495,745985496,1 +95098,745985495,745985497,1 +100777,745985496,745985493,1 +22976,745985497,286541739,0 +50086,745985506,360719268,0 +95099,745985506,745985507,1 +50084,745985508,745985514,0 +50078,745985513,745985516,0 +95100,745985513,1540857394,0 +50085,745985514,745985506,0 +95101,745985514,745985515,1 +50079,745985516,360718927,0 +95102,745985516,745985517,1 +133445,745985518,286537125,0 +100779,745985518,745985491,1 +22965,745985519,286535484,1 +133444,745985519,745985518,0 +24040,745986934,360719794,0 +50095,745986935,360720093,0 +95104,745986935,745986936,1 +133478,745986936,294251017,1 +95105,745986937,745986938,1 +22978,745986937,745986939,0 +22979,745986939,286535486,0 +95106,745986939,745986940,1 +95108,745988367,286541745,0 +95110,745988367,745988370,1 +95107,745988368,745988367,0 +92206,745988368,1540856198,1 +64438,745988369,597897429,0 +95109,745988369,745988367,1 +95111,745988370,745988371,1 +95127,745988370,745988398,1 +95112,745988371,1540857398,1 +95113,745988373,745988374,1 +95139,745988373,745988430,1 +95114,745988374,1540857399,1 +100788,745988376,598495520,1 +95115,745988377,745988371,1 +95129,745988377,745988402,1 +95116,745988378,745988379,1 +24037,745988378,1540793929,1 +81980,745988379,598495524,0 +24038,745988380,598495524,1 +95117,745988380,1540857400,0 +50136,745988382,360720578,1 +95119,745988382,745988383,1 +95120,745988383,1540857408,1 +95136,745988383,1540857421,1 +24034,745988385,745988386,1 +24035,745988386,294250113,1 +95121,745988386,745988374,1 +95125,745988388,745988396,1 +95123,745988389,1540857410,1 +50135,745988394,745988382,1 +95124,745988394,745988388,1 +95126,745988396,745988370,1 +95128,745988396,745988377,1 +92207,745988398,38840263,1 +95137,745988402,745988429,1 +81635,745988413,745988414,0 +81644,745988413,1540845155,0 +81631,745988414,745988431,0 +33731,745988414,1540803288,0 +95130,745988415,745988416,1 +95134,745988415,1540857417,1 +95131,745988416,360720578,1 +95135,745988416,1540857420,1 +100786,745988421,294250113,1 +95138,745988429,745988373,1 +24033,745988429,1540793928,1 +81643,745988431,745988413,0 +81632,745988431,1540845084,0 +50139,745988435,360720623,1 +64437,745988435,745988369,0 +50124,745988707,360720401,0 +95140,745988707,745988708,1 +95141,745988709,745988710,1 +133440,745988709,745988711,0 +50129,745988710,360720465,0 +133441,745988711,597897428,0 +95142,745988711,745988712,1 +50131,745988713,360720525,0 +95143,745988713,745988714,1 +50128,745988757,745988710,0 +95144,745988757,745988758,1 +92202,745988758,745988760,1 +92203,745988760,360720516,1 +95145,745988760,745988761,1 +95146,745990344,745990349,1 +95171,745990344,745990591,1 +95147,745990349,745990352,1 +95179,745990349,1540857427,1 +95148,745990352,745990355,1 +95152,745990352,745990380,1 +95149,745990355,745990359,1 +24020,745990355,1540793913,0 +97008,745990359,793479407,0 +95150,745990359,1540857422,1 +95175,745990380,294244956,1 +95153,745990388,745990392,1 +95177,745990388,745990535,1 +24018,745990392,745990552,0 +51272,745990402,361197038,1 +95154,745990402,745990405,1 +95155,745990405,746691616,1 +51275,745990405,1540815934,1 +95194,745990407,746691471,1 +95157,745990407,1540857424,1 +95158,745990528,745990531,1 +95189,745990528,1540857434,1 +95170,745990531,745990344,1 +95159,745990531,745990535,1 +95178,745990535,745990349,1 +95160,745990535,745990552,1 +24019,745990552,745990355,0 +24017,745990564,745990392,0 +95161,745990564,745990568,1 +95176,745990568,745990388,1 +95162,745990568,745990571,1 +95169,745990571,745990531,1 +95163,745990571,745990575,1 +95164,745990575,745990579,1 +95188,745990579,745990528,1 +95165,745990579,745990583,1 +95166,745990583,746691472,1 +95168,745990586,361197057,1 +95182,745990586,745990600,1 +95173,745990591,745990595,1 +95172,745990591,1540857425,1 +95174,745990595,745990380,1 +95180,745990599,745990600,1 +51284,745990599,745990601,1 +95183,745990600,745990602,1 +95181,745990601,745990602,1 +51285,745990601,1540815936,1 +95184,745990602,1540857430,1 +95185,745990605,745990606,1 +95187,745990605,1540857432,1 +95186,745990606,745990594,1 +95190,745990613,745990614,1 +81999,745990613,745990615,0 +51288,745990614,745990625,1 +95191,745990615,745990616,1 +82000,745990615,1540845758,0 +51287,745990616,745990614,1 +95192,745990617,745990606,1 +51286,745990617,745990616,1 +97005,745990622,1540859841,0 +24023,745990625,1540793920,0 +50284,746691469,746691602,1 +95193,746691469,1540857436,1 +95195,746691471,746691472,1 +95196,746691471,746691473,1 +95167,746691472,745990586,1 +82002,746691473,746691722,0 +95199,746691490,746691495,1 +95208,746691490,746691558,1 +95200,746691495,746691498,1 +51269,746691498,746691556,1 +82522,746691510,286541749,0 +95201,746691510,746691518,1 +50281,746691518,1540815101,0 +51270,746691556,361197034,1 +95202,746691556,746691558,1 +95209,746691558,746691616,1 +50308,746691570,360731671,1 +51244,746691586,1540815932,1 +95218,746691594,746691688,1 +95205,746691594,1540857437,1 +50285,746691602,360731510,1 +95206,746691610,360731510,1 +95156,746691616,745990407,1 +50303,746691625,360731513,1 +95210,746691625,1540857438,1 +50288,746691630,360731512,1 +95211,746691638,746691495,1 +50287,746691638,746691630,1 +95213,746691654,360720516,0 +82524,746691654,746691667,0 +95212,746691656,746691654,0 +133575,746691656,746691658,1 +50280,746691656,1540815100,0 +133576,746691658,746691661,1 +95216,746691658,746691686,1 +133577,746691661,361194993,1 +82525,746691667,1540846318,0 +95214,746691667,1540857439,1 +50292,746691671,360731402,1 +50279,746691680,746691656,0 +95215,746691680,1540857440,1 +95217,746691686,746691594,1 +95220,746691686,1540857441,1 +95219,746691688,360731665,1 +51243,746691688,746691586,1 +82003,746691722,598495556,0 +48465,746981320,797375727,0 +95541,746981321,360477363,0 +134578,746981321,797375873,0 +118850,761371857,1540877991,1 +81018,767358945,360012359,0 +95780,767358945,761371857,1 +96039,774084982,774084983,1 +96098,774084982,774085196,1 +96120,774084982,1540859090,1 +96040,774084983,1540858890,1 +96228,774084983,1540859343,1 +96042,774084994,774084995,1 +96043,774084995,1540858898,1 +96051,774084995,1540858920,1 +96044,774084999,775868204,1 +96417,774084999,1540859627,1 +96047,774085003,1540858904,1 +96227,774085003,1540859340,1 +96049,774085012,1540858912,1 +96050,774085021,1540858773,1 +96408,774085021,1540859609,1 +96052,774085040,788841545,1 +96449,774085040,1540859659,1 +96054,774085046,774085047,1 +96055,774085047,774085048,1 +96056,774085048,1540858926,1 +96444,774085048,1540859653,1 +96446,774085052,1540859658,1 +97952,774085052,1540861153,1 +96092,774085053,775863130,1 +96057,774085053,1540858929,1 +96234,774085055,775868274,1 +96058,774085055,1540858930,1 +96059,774085058,1540858932,1 +96060,774085061,1540858934,1 +96061,774085067,774085068,1 +96094,774085067,775868273,1 +96149,774085068,775863131,1 +96062,774085068,1540858936,1 +96140,774085072,775863100,1 +96063,774085072,1540858939,1 +96064,774085074,1540858940,1 +96065,774085081,774085082,1 +96108,774085081,1540859035,1 +96131,774085082,1540859120,1 +96344,774085085,1540859458,1 +97944,774085085,1540861122,1 +96383,774085110,1540859557,1 +97947,774085110,1540861146,1 +97949,774085115,774085116,1 +96412,774085116,788840964,1 +97950,774085116,1540861150,1 +96445,774085118,788841416,1 +97951,774085118,1540861151,1 +96088,774085136,775863128,1 +96066,774085136,1540858946,1 +96067,774085162,774085163,1 +96240,774085162,775868281,1 +96068,774085163,775863059,1 +96250,774085163,775868316,1 +96070,774085164,1540858971,1 +149794,774085166,1540953340,1 +140871,774085168,1540928610,1 +149795,774085168,1540953341,1 +149798,774085173,774085174,1 +140836,774085173,1333799046,1 +149799,774085174,1333810085,1 +141236,774085175,1333810123,1 +141240,774085175,1540929754,1 +96096,774085188,1540859021,1 +96119,774085188,1540859083,1 +96097,774085193,1540859025,1 +96099,774085196,1540859027,1 +96159,774085199,775866091,1 +96185,774085199,775866146,1 +96102,775862950,1540859029,1 +96114,775862950,1540859047,1 +96118,775862950,1540859063,1 +96103,775862953,774085193,1 +96104,775862954,774085074,1 +96116,775862954,1540859048,1 +96105,775862959,775862960,1 +96121,775862959,1540859091,1 +96106,775862960,1540859031,1 +96107,775862960,1540859033,1 +96113,775862965,775862950,1 +96109,775862970,775862971,1 +96110,775862971,1540859039,1 +96111,775862971,1540859041,1 +96135,775862974,1540859129,1 +96142,775862980,775863081,1 +96112,775862981,1540859046,1 +96122,775862981,1540859095,1 +96115,775862984,775862954,1 +96117,775862997,1540859060,1 +96170,775862997,1540859227,1 +96123,775863001,1540859104,1 +96124,775863046,1540859107,1 +96130,775863046,1540859117,1 +96125,775863048,1540859108,1 +96126,775863057,775868328,1 +96132,775863057,775868329,1 +96129,775863058,1540859116,1 +96069,775863059,774085164,1 +96128,775863059,775863058,1 +96134,775863072,1540859128,1 +96143,775863081,775863107,1 +96136,775863082,1540859135,1 +96154,775863082,1540859179,1 +96090,775863093,775863129,1 +96153,775863094,775863082,1 +96137,775863094,1540859145,1 +96138,775863098,1540859148,1 +96144,775863098,1540859155,1 +96139,775863100,1540859149,1 +96141,775863100,1540859154,1 +96147,775863107,1540859162,1 +96146,775863111,1540859161,1 +96145,775863112,1540859158,1 +96155,775863112,1540859186,1 +96148,775863127,775863058,1 +96089,775863128,775863093,1 +96091,775863129,1540859014,1 +96093,775863130,1540859015,1 +96152,775863131,775863094,1 +96150,775863131,1540859172,1 +96151,775863131,1540859178,1 +96156,775866069,1540859195,1 +96209,775866069,1540859290,1 +96203,775866076,1540859275,1 +96157,775866077,1540859201,1 +96207,775866077,1540859281,1 +96202,775866080,1540859267,1 +96201,775866081,775866080,1 +96158,775866081,1540859203,1 +96160,775866091,1540859212,1 +96166,775866091,1540859225,1 +96161,775866094,1540859214,1 +96216,775866094,1540859300,1 +96162,775866099,1540859218,1 +96212,775866099,1540859296,1 +96163,775866103,775866104,1 +96219,775866103,1540859316,1 +96223,775866104,775868249,1 +96164,775866104,1540859221,1 +96222,775866109,1540859326,1 +96262,775866112,1345209590,1 +96168,775866113,774085168,1 +96182,775866113,775866143,1 +96169,775866114,775866115,1 +96181,775866115,1540859239,1 +96171,775866119,775866120,1 +96172,775866119,775866121,1 +96173,775866122,1540859230,1 +96208,775866122,1540859286,1 +96190,775866126,1540859250,1 +96197,775866127,775866130,1 +96174,775866127,1540859233,1 +96211,775866127,1540859294,1 +96194,775866129,1540859260,1 +96175,775866130,775866131,1 +96198,775866130,1540859265,1 +96177,775866131,775866134,1 +96176,775866131,1540859234,1 +96195,775866133,1540859261,1 +96178,775866134,1540859235,1 +96205,775866136,1540859277,1 +96179,775866137,775866134,1 +96199,775866137,775866178,1 +96180,775866138,1540859236,1 +141242,775866138,1540929758,1 +96183,775866143,774085166,1 +96254,775866143,775868328,1 +96184,775866144,775866145,1 +96191,775866144,1540859255,1 +96210,775866145,1540859291,1 +96186,775866146,1540859240,1 +96187,775866146,1540859242,1 +96189,775866149,1540859248,1 +96188,775866154,1540859246,1 +96192,775866166,775866167,1 +96193,775866167,1540859257,1 +96196,775866173,1540859262,1 +96204,775866178,1540859276,1 +96100,775866179,1540859028,1 +96200,775866179,1540859266,1 +96101,775866180,774085199,1 +96206,775866180,775866077,1 +96235,775866180,1540859355,1 +96237,775868198,775868207,1 +96213,775868199,1540859298,1 +96239,775868199,1540859356,1 +96214,775868202,775868203,1 +96215,775868202,775868204,1 +96046,775868203,1540858902,1 +96045,775868204,1540858901,1 +96236,775868206,775868198,1 +96238,775868207,775868199,1 +96217,775868207,1540859301,1 +96218,775868214,1540859307,1 +96256,775868214,1540859396,1 +96220,775868225,775868226,1 +96226,775868225,1540859339,1 +96221,775868226,1540859317,1 +96396,775868248,1540859594,1 +96224,775868249,775868226,1 +96225,775868249,1540859338,1 +96231,775868261,774085193,1 +96229,775868261,1540859347,1 +96233,775868265,1540859351,1 +96230,775868266,1540859350,1 +96252,775868266,1540859395,1 +96253,775868268,774085058,1 +96232,775868268,775868265,1 +96095,775868273,1540859017,1 +97954,775868274,1540861164,1 +96243,775868288,1540859366,1 +96245,775868288,1540859383,1 +96244,775868290,1540859367,1 +97953,775868307,1540861161,1 +96246,775868313,1333810083,1 +149796,775868313,1540953342,1 +96249,775868316,1540859390,1 +96041,775868324,1540858892,1 +96251,775868324,1540859393,1 +96127,775868328,775863058,1 +96133,775868329,775863072,1 +96255,775868329,775863127,1 +96257,775868526,1345218166,1 +96259,775868535,1345218450,1 +96266,775868535,1540859418,1 +47843,778677122,360468406,0 +96268,778677122,778677123,1 +127253,778677123,347502444,1 +47842,778677125,778677122,0 +96269,778677125,778677126,1 +127252,778677126,778677123,1 +30764,778677132,360468507,1 +96341,788839502,1540859453,1 +96368,788839502,1540859533,1 +96342,788839513,1540859455,1 +96343,788839543,788839545,1 +96356,788839543,788839777,1 +96350,788839545,788839658,1 +96345,788839572,788839578,1 +96347,788839572,788839597,1 +96346,788839578,788839582,1 +96348,788839578,1540859464,1 +96359,788839582,788839513,1 +96349,788839597,1540859467,1 +96351,788839658,1540859480,1 +96352,788839658,1540859481,1 +96399,788839676,788839746,1 +96355,788839720,1540859490,1 +96353,788839736,788839739,1 +96370,788839736,1540859536,1 +96354,788839746,1540859488,1 +96364,788839746,1540859520,1 +96363,788839768,1540859513,1 +96371,788839777,788840041,1 +96357,788839784,1540859494,1 +96366,788839784,1540859528,1 +96360,788839787,788839837,1 +96358,788839787,1540859495,1 +96367,788839837,1540859529,1 +96361,788839851,1540859504,1 +96380,788839851,1540859549,1 +96362,788839873,1540859509,1 +96369,788839938,788839736,1 +96365,788839979,1540859526,1 +97943,788839979,1540861116,1 +96372,788840060,788840063,1 +96384,788840060,1540859558,1 +96388,788840063,1540859567,1 +96373,788840071,788840077,1 +96385,788840071,1540859562,1 +96389,788840077,788840114,1 +96374,788840110,788840114,1 +96381,788840110,1540859556,1 +96390,788840114,1540859569,1 +96376,788840127,788840131,1 +149803,788840131,1540953345,1 +149801,788840159,1411219064,1 +149793,788840159,1540953334,1 +96377,788840246,1540859537,1 +96398,788840246,1540859598,1 +96379,788840274,1540859546,1 +96378,788840290,1540859543,1 +97946,788840290,1540861144,1 +97948,788840459,774085115,1 +96386,788840459,1540859564,1 +96387,788840486,788840063,1 +96391,788840589,788840486,1 +96392,788840615,1540859571,1 +96393,788840615,1540859573,1 +97942,788840615,1540861110,1 +96394,788840631,1540859588,1 +96409,788840735,1540859611,1 +96410,788840735,1540859613,1 +96404,788840822,1540859604,1 +96395,788840838,775868248,1 +96072,788840838,1540858973,1 +96165,788840856,1540859223,1 +96397,788840872,788840246,1 +97945,788840872,1540861133,1 +96400,788840901,788840905,1 +96401,788840905,788840910,1 +96434,788840905,1540859645,1 +96402,788840910,788840926,1 +96422,788840910,1540859634,1 +96403,788840926,788840930,1 +96428,788840926,1540859641,1 +96415,788840930,1540859622,1 +96405,788840951,1540859607,1 +96424,788840960,774085115,1 +96406,788840960,788840964,1 +96413,788840964,788841086,1 +96407,788840979,788840951,1 +96435,788840979,1540859646,1 +96420,788841045,788841159,1 +96411,788841082,774085116,1 +96448,788841082,788841436,1 +96414,788841086,1540859620,1 +96429,788841111,788841206,1 +96416,788841111,1540859625,1 +96418,788841120,1540859630,1 +96419,788841141,1540859631,1 +96426,788841141,1540859638,1 +96431,788841159,788841245,1 +96421,788841159,1540859633,1 +96423,788841177,788840960,1 +96436,788841177,1540859648,1 +96048,788841193,1540858906,1 +96425,788841193,1540859637,1 +96430,788841206,788841159,1 +96427,788841206,1540859639,1 +96437,788841229,788841086,1 +96433,788841245,788840905,1 +96432,788841245,1540859644,1 +96438,788841327,788841355,1 +96454,788841327,788841545,1 +96439,788841355,1540859649,1 +96441,788841372,788841381,1 +96452,788841378,774085061,1 +96440,788841378,788841372,1 +96443,788841381,774085046,1 +96442,788841381,774085047,1 +96447,788841416,788841082,1 +96450,788841518,788841520,1 +96453,788841518,1540859665,1 +96451,788841520,1540859664,1 +96455,788841520,1540859670,1 +96053,788841545,1540858921,1 +96456,788851314,788851372,1 +96073,788851314,1540858974,1 +96457,788851372,788851375,1 +96459,788851372,1540859676,1 +96458,788851384,1540859675,1 +138335,788870476,1540922676,1 +96497,788870479,788870551,1 +96512,788870480,788870485,1 +96463,788870480,1540859678,1 +96466,788870482,788870485,1 +96464,788870482,1307354579,1 +138212,788870484,1307354359,1 +96513,788870485,788870604,1 +96511,788870486,788870480,1 +96467,788870486,788870487,1 +138298,788870487,1307354549,1 +96468,788870487,1540859680,1 +96474,788870488,788870490,1 +96473,788870489,788870488,1 +96475,788870490,1307354377,1 +138203,788870490,1540922566,1 +96477,788870492,788870493,1 +96539,788870492,788870502,1 +96478,788870493,788870494,1 +96587,788870493,788870519,1 +96479,788870502,788870505,1 +96540,788870502,788870553,1 +96586,788870505,788870493,1 +96480,788870505,788870507,1 +96484,788870515,1540859683,1 +138328,788870515,1540922674,1 +96538,788870517,788870492,1 +96485,788870517,788870519,1 +138460,788870517,1540922765,1 +96588,788870519,788870529,1 +96486,788870519,1540859684,1 +96589,788870529,625904132,1 +96491,788870529,1307367458,1 +96493,788870539,788870541,1 +96528,788870539,788870613,1 +96531,788870541,788870628,1 +96506,788870546,625904125,1 +96495,788870546,788870549,1 +96496,788870549,788870479,1 +96501,788870549,788870560,1 +96498,788870551,788870553,1 +96509,788870551,788870569,1 +96499,788870553,788870554,1 +96541,788870553,788870562,1 +96585,788870554,788870505,1 +96500,788870554,788870556,1 +96508,788870560,788870551,1 +96502,788870560,788870562,1 +96503,788870562,788870563,1 +96542,788870562,788870670,1 +96584,788870563,788870554,1 +96504,788870563,788870565,1 +96505,788870567,788870546,1 +96510,788870602,788870486,1 +96553,788870602,1307354549,1 +96550,788870604,788870686,1 +96514,788870604,1307354540,1 +96517,788870606,1307354638,1 +96522,788870606,1540859688,1 +96523,788870607,788870622,1 +138104,788870607,1307354355,1 +96519,788870613,788870615,1 +96529,788870613,788870633,1 +96520,788870615,788870617,1 +96572,788870615,788870624,1 +96521,788870617,788870606,1 +96608,788870617,788870622,1 +138196,788870619,1307354429,1 +96524,788870622,788870624,1 +96609,788870622,788870762,1 +96525,788870624,788870626,1 +96527,788870626,788870539,1 +96526,788870626,788870628,1 +96530,788870636,788870541,1 +96533,788870656,788870658,1 +96544,788870656,788870672,1 +96535,788870658,788870664,1 +96536,788870664,788870666,1 +96537,788870666,788870636,1 +96616,788870666,788870774,1 +96582,788870670,625904128,1 +96543,788870670,788870656,1 +96633,788870672,788870664,1 +96545,788870672,788870674,1 +96615,788870674,788870666,1 +96546,788870678,788870680,1 +96547,788870680,788870682,1 +96571,788870682,788870615,1 +96548,788870682,788870684,1 +96549,788870684,788870604,1 +96607,788870684,788870617,1 +96551,788870686,1540859689,1 +96552,788870691,788870602,1 +96605,788870691,788870711,1 +96558,788870698,788870700,1 +96601,788870698,788870718,1 +96559,788870700,788870702,1 +96575,788870700,788870726,1 +96560,788870702,788870680,1 +96565,788870702,788870710,1 +96632,788870705,788870672,1 +96562,788870705,788870707,1 +96614,788870707,788870674,1 +96563,788870707,788870709,1 +96620,788870709,788870678,1 +96564,788870709,788870702,1 +96570,788870710,788870682,1 +96566,788870710,788870711,1 +96567,788870711,788870480,1 +96606,788870711,788870684,1 +96568,788870718,788870720,1 +96602,788870718,788870753,1 +96574,788870720,788870700,1 +96569,788870720,788870710,1 +96604,788870724,788870691,1 +96573,788870724,788870720,1 +96619,788870726,788870709,1 +96576,788870726,788870728,1 +96613,788870728,788870707,1 +96577,788870728,788870729,1 +96578,788870729,355920392,1 +96631,788870729,788870705,1 +96611,788870745,355920392,1 +96597,788870745,788870746,1 +96630,788870746,788870729,1 +96598,788870746,788870748,1 +96612,788870748,788870728,1 +96599,788870748,788870750,1 +96600,788870750,788870698,1 +96618,788870750,788870726,1 +96603,788870753,788870724,1 +96610,788870762,1540859705,1 +96617,788870779,788870750,1 +96621,788870783,788870784,1 +96078,788870783,1540858982,1 +96076,788870786,1343088169,1 +96622,788870786,1343089345,1 +96624,788870792,788870794,1 +96082,788870792,1540858987,1 +96625,788870794,788870796,1 +96628,788870794,1540859711,1 +96627,788870796,1540859709,1 +96629,788870808,788870746,1 +96634,789215831,789215833,1 +96675,789215831,1540859736,1 +96653,789215833,789215972,1 +148686,789215837,1540950139,1 +148687,789215839,1540950140,1 +148672,789215843,1371125437,1 +148688,789215843,1540950142,1 +148689,789215847,789215849,1 +133565,789215847,1540895602,1 +148657,789215849,1371125593,1 +148690,789215849,1540950143,1 +96637,789215853,789215885,1 +148691,789215853,1540950144,1 +148649,789215866,1540950104,1 +148693,789215866,1540950151,1 +148523,789215874,1371043825,1 +100582,789215874,1540862738,1 +96636,789215878,789215853,1 +100583,789215878,1540862739,1 +96638,789215885,789215894,1 +148584,789215885,1540949922,1 +148575,789215894,1371125640,1 +96639,789215912,789215914,1 +96684,789215912,1184259745,1 +96672,789215914,1184260710,1 +96681,789215918,789215929,1 +96640,789215918,1540859713,1 +96642,789215922,789215929,1 +96641,789215922,1540859714,1 +148384,789215924,1371044061,1 +96668,789215924,1371044077,1 +96682,789215929,789216009,1 +96643,789215929,1540859715,1 +96658,789215940,789216003,1 +96644,789215940,1540859719,1 +96699,789215944,789215988,1 +96647,789215947,1540859725,1 +96649,789215957,1371043908,1 +148359,789215957,1371043909,1 +100572,789215962,810716445,1 +96652,789215967,1540859733,1 +96674,789215967,1540859735,1 +96654,789215986,1371477967,1 +96656,789215988,789215990,1 +96700,789215988,789216075,1 +96660,789215990,789216005,1 +96657,789215995,789215940,1 +96693,789215995,789216037,1 +96659,789216003,789215990,1 +96661,789216003,789216009,1 +96683,789216009,789215912,1 +96662,789216009,789216011,1 +96670,789216011,1371044078,1 +96663,789216016,789216018,1 +120094,789216016,1540879923,0 +96664,789216018,1371044074,1 +148445,789216018,1540949749,1 +96695,789216020,1371044048,1 +96666,789216020,1371044076,1 +96677,789216033,1371044100,1 +120095,789216033,1540879925,0 +96679,789216035,1540859737,1 +148527,789216035,1540949799,1 +96680,789216037,789215918,1 +96694,789216037,789216020,1 +120073,789216061,1038225074,1 +96686,789216061,1038225229,1 +96691,789216065,1540859743,1 +96701,789216065,1540859745,1 +96698,789216069,789215944,1 +96692,789216069,789215995,1 +51661,792045729,1540816136,1 +51637,792045741,1540816096,1 +96757,792045741,1540859770,1 +97618,792045745,528490503,1 +51636,792045745,1540816094,1 +51641,792045759,361409654,1 +96767,792045759,792049848,1 +51639,792045763,559556449,1 +96764,792045763,792049843,1 +96759,792048334,360015812,1 +96760,792048334,1540859772,1 +71630,792049841,1540838965,1 +96766,792049842,528490476,1 +96761,792049844,792049848,1 +96762,792049848,536580027,1 +51679,792051090,1540816153,0 +51680,792051103,1540816154,0 +80469,792051103,1540843191,0 +96776,792054023,792054054,1 +127103,792054025,792054029,1 +96773,792054025,797394866,1 +96778,792054029,361198104,1 +51709,792054042,577419536,1 +96779,792054042,792054023,1 +96777,792054054,792054029,1 +51338,792054055,577419536,0 +96775,792054055,792054023,1 +127102,792054059,792054025,1 +51708,792054063,792054042,1 +96780,792054063,1540859778,1 +96794,792054066,1540859780,1 +96814,792056419,792056455,1 +127095,792056419,792056477,1 +96783,792056420,792056447,1 +127079,792056420,1540884965,1 +51380,792056422,792056468,1 +127073,792056424,792056428,1 +51382,792056426,792056449,1 +127074,792056428,792056441,1 +96785,792056428,792056454,1 +51362,792056430,792056434,1 +96812,792056430,797375836,1 +51386,792056433,792056446,1 +96782,792056433,1540859779,1 +96835,792056434,797375865,1 +51363,792056434,797394821,1 +51390,792056436,361198772,1 +96800,792056437,792056461,1 +96804,792056437,792056478,1 +96792,792056439,361198819,1 +51389,792056439,792056436,1 +127075,792056441,792056445,1 +96830,792056442,361198224,1 +51392,792056442,1540815943,1 +127684,792056444,792056473,1 +127076,792056445,792056457,1 +51387,792056446,361198796,1 +96836,792056446,1540859791,1 +96784,792056447,792056449,1 +96787,792056447,792056479,1 +96816,792056448,361198799,1 +51413,792056448,361198844,1 +51383,792056449,797394847,1 +96832,792056452,361198710,1 +96789,792056452,792056471,1 +51378,792056454,792056466,1 +98222,792056455,152803460,1 +96815,792056455,792056448,1 +96803,792056456,1540859784,1 +127077,792056457,361198217,1 +96791,792056457,792056422,1 +127094,792056460,1540884966,1 +98048,792056461,797375864,1 +96801,792056461,1540859783,1 +51376,792056464,361198710,1 +96798,792056464,792056472,1 +51379,792056466,792056422,1 +96811,792056466,792056430,1 +51381,792056468,792056426,1 +96834,792056468,792056434,1 +135118,792056469,1540905565,1 +51395,792056470,579799880,1 +96833,792056470,792056436,1 +96790,792056471,792056456,1 +96795,792056471,792056472,1 +96799,792056472,792056437,1 +96796,792056472,792056474,1 +135117,792056473,792056469,1 +51367,792056474,797375631,1 +80472,792056475,1540843206,0 +96817,792056475,1540859785,0 +127096,792056477,152803459,1 +96805,792056478,797375598,1 +51369,792056478,797375735,1 +96825,792056479,361198711,1 +96788,792056479,792056452,1 +80593,792069975,581290414,0 +96837,792069975,1540859792,1 +96838,792069982,890361700,1 +80556,792071787,792071813,0 +96864,792071788,792071805,1 +96843,792071788,792071813,1 +96872,792071790,792071795,1 +80547,792071790,1540843262,0 +80477,792071791,579794578,1 +96860,792071791,792071834,1 +127607,792071792,792071835,1 +96873,792071795,792071807,1 +96849,792071795,792071815,1 +96851,792071797,792071824,1 +96844,792071797,792071834,1 +96870,792071798,792071806,1 +96876,792071798,792071835,1 +2833,792071803,797375864,0 +96878,792071804,792071825,1 +96853,792071804,792071830,1 +98163,792071805,792071833,1 +96871,792071806,792071819,1 +96863,792071806,792071830,1 +96841,792071810,792071811,1 +96842,792071811,792071788,1 +96866,792071811,792071833,1 +127606,792071812,792071792,1 +80557,792071813,600205185,0 +96850,792071815,792071797,1 +80476,792071815,1540843215,1 +96869,792071816,792071798,1 +96862,792071816,1540859807,1 +96859,792071817,792071810,1 +80555,792071817,1540843264,0 +96865,792071818,579794831,1 +96875,792071818,792071798,1 +80552,792071819,579794841,0 +96846,792071821,792071836,1 +96857,792071821,1540859806,1 +2831,792071823,338485978,0 +96868,792071824,792071816,1 +96848,792071825,1540859803,1 +80550,792071826,579794831,0 +96874,792071826,792071818,1 +96867,792071829,792071824,1 +96856,792071829,1540859805,1 +96854,792071830,579794841,1 +98164,792071833,797394815,1 +96845,792071834,361441560,1 +96861,792071834,792071816,1 +96877,792071835,792071804,1 +96852,792071836,792071812,1 +96847,792071836,792071825,1 +17075,793252666,801062930,0 +81645,793252679,592561673,0 +96883,793252679,1540859823,0 +17072,793252682,355929051,0 +96884,793252682,1540859825,0 +96882,793252719,592567268,0 +96885,793252719,1540859826,0 +97083,793279436,745090984,1 +96990,793279436,1540859840,1 +96932,793279440,793279482,1 +96987,793279440,793279521,1 +96947,793279445,793279543,1 +96982,793279448,793279473,1 +96942,793279448,793279497,1 +96908,793279452,793279534,1 +96961,793279452,793385748,1 +96956,793279456,793279591,1 +97089,793279459,745090919,1 +96926,793279459,793279494,1 +96935,793279462,793279534,1 +94976,793279465,793279482,1 +96940,793279465,793279637,1 +96945,793279468,793279492,1 +96902,793279468,793279512,1 +81992,793279470,598495544,0 +96920,793279470,793279601,1 +96983,793279473,793279587,1 +96936,793279473,793279645,1 +94975,793279477,793279465,1 +96958,793279477,793279609,1 +96893,793279479,793279552,1 +97077,793279479,793385767,1 +94981,793279480,745090920,1 +94977,793279482,745090918,1 +96933,793279482,793279484,1 +96918,793279484,745091092,1 +96934,793279484,793279462,1 +95059,793279486,745091126,1 +96993,793279486,793279532,1 +96974,793279490,793279545,1 +96900,793279490,793279591,1 +96946,793279492,793279445,1 +96989,793279492,793279633,1 +96995,793279494,793279480,1 +96927,793279494,793279507,1 +96969,793279497,793279613,1 +96955,793279502,793279456,1 +96985,793279502,793279515,1 +96960,793279504,793279452,1 +96919,793279504,793279462,1 +96928,793279507,793279629,1 +96965,793279507,793385612,1 +96905,793279510,745091071,1 +96950,793279510,793279633,1 +96903,793279512,745091000,1 +96949,793279512,793279510,1 +96986,793279515,793279440,1 +96939,793279515,793279465,1 +97086,793279518,745090989,1 +95046,793279521,1540857390,1 +96981,793279523,793279448,1 +96904,793279523,793279648,1 +96998,793279526,745090991,1 +96978,793279526,793279650,1 +96996,793279528,745091077,1 +96952,793279528,793279653,1 +96994,793279532,793279494,1 +97000,793279532,793279656,1 +96909,793279534,745091099,1 +81991,793279535,793279470,0 +96886,793279535,793279663,1 +96922,793279543,793279547,1 +94974,793279545,793279477,1 +96954,793279547,793279502,1 +96923,793279547,1540859837,1 +96891,793279549,793279629,1 +94983,793279552,745090921,1 +96894,793279552,1540859836,1 +96912,793279583,793279660,1 +96976,793279583,793385756,1 +96911,793279587,793279583,1 +96984,793279587,793385711,1 +96957,793279591,793279477,1 +81206,793279595,598495540,0 +96906,793279595,793385698,1 +97035,793279599,294244999,1 +97067,793279599,1540859858,0 +97082,793279599,1540859863,1 +96921,793279601,793279543,1 +96972,793279601,793279663,1 +96992,793279605,793279486,1 +97021,793279605,793385697,1 +96959,793279609,793279504,1 +96916,793279609,793279637,1 +96970,793279613,793279660,1 +95041,793279616,745091071,1 +96931,793279616,793279518,1 +94979,793279619,745090919,1 +96980,793279619,793279523,1 +81994,793279622,598495546,0 +96988,793279622,793279492,1 +95033,793279625,745091004,1 +96888,793279625,793385697,1 +96892,793279629,793279479,1 +96929,793279629,793385682,1 +96951,793279633,793279528,1 +96917,793279637,793279484,1 +96941,793279637,793279540,1 +96975,793279645,793279583,1 +96937,793279645,793279613,1 +96968,793279648,793279497,1 +96925,793279650,793279459,1 +96979,793279650,793279619,1 +96938,793279653,745091082,1 +96953,793279653,793279547,1 +96964,793279656,793279507,1 +97001,793279656,793279549,1 +96913,793279660,793385629,1 +96971,793279660,793385660,1 +96973,793279663,793279490,1 +96887,793279663,1540859835,1 +96966,793385612,745090920,1 +97076,793385612,1540859861,1 +97058,793385614,793385655,1 +95053,793385614,793385691,1 +96915,793385616,745090800,1 +97062,793385618,793385692,1 +97165,793385618,793428499,1 +97049,793385620,793385709,1 +96896,793385622,793385733,1 +97056,793385627,793385773,1 +96914,793385629,793385616,1 +96895,793385629,793385622,1 +97024,793385630,793385727,1 +97060,793385630,793385744,1 +97090,793385634,793385682,1 +97033,793385635,793385654,1 +95035,793385639,1540857384,1 +97055,793385641,793385627,1 +97028,793385643,745090921,1 +97079,793385643,793385654,1 +97051,793385645,793385731,1 +97102,793385645,793385741,1 +97048,793385647,793385620,1 +94954,793385647,793385754,1 +97034,793385654,793385762,1 +97080,793385654,793385771,1 +97059,793385655,793385725,1 +97026,793385655,793385786,1 +97066,793385660,793385622,1 +23990,793385663,793479431,1 +97054,793385664,793385641,1 +97098,793385674,793428399,1 +97071,793385675,793428431,1 +97175,793385678,793428496,1 +95050,793385680,793385692,1 +97091,793385682,793385767,1 +96930,793385682,1540859838,1 +94986,793385687,745090922,1 +97032,793385687,793385620,1 +95054,793385691,793385746,1 +97037,793385691,1540859846,1 +95051,793385692,793428481,1 +97063,793385692,1540859856,1 +96889,793385697,745091126,1 +96907,793385698,793279452,1 +97023,793385698,793385630,1 +24028,793385707,294244999,0 +97052,793385707,1540859854,1 +97050,793385709,793385645,1 +97074,793385709,793385719,1 +97064,793385711,793385756,1 +97070,793385715,793385675,1 +97022,793385715,1540859843,1 +97075,793385719,793385778,1 +97043,793385719,1540859847,1 +96898,793385721,793385641,1 +97040,793385721,793385729,1 +97002,793385723,294244346,0 +97045,793385723,793279599,1 +97038,793385725,793385739,1 +97025,793385727,793385678,1 +97041,793385729,745090803,1 +97068,793385729,793385664,1 +95011,793385731,793428484,1 +96897,793385733,793385721,1 +97047,793385733,1540859853,1 +97020,793385739,793385627,1 +97039,793385739,793385721,1 +97103,793385741,793428460,1 +97044,793385741,1540859848,1 +96963,793385744,793385610,1 +97061,793385744,793385618,1 +95055,793385746,793428414,1 +97092,793385748,793385680,1 +96962,793385748,793385744,1 +97177,793385750,793428391,1 +97030,793385752,793385771,1 +94955,793385754,745090803,1 +96977,793385756,793385725,1 +97065,793385756,1540859857,1 +94985,793385762,793385687,1 +97078,793385767,793385643,1 +97081,793385771,793385675,1 +97031,793385771,793385687,1 +97057,793385773,1540859855,1 +97199,793385778,793428460,1 +97069,793385781,793385715,1 +94957,793385785,745090805,1 +97053,793385785,793385664,1 +97198,793385785,793385778,1 +97036,793385786,793385691,1 +97027,793385786,793385773,1 +97133,793428336,793428398,1 +97121,793428336,1540859867,1 +97150,793428338,1540859877,1 +97407,793428338,1540859966,1 +97122,793428340,793428380,1 +95077,793428343,745090953,1 +97191,793428343,793428412,1 +97113,793428344,793428450,1 +97180,793428344,1540859887,1 +94989,793428348,745090925,1 +97130,793428351,745090941,1 +97155,793428351,793428465,1 +94996,793428352,745090939,1 +97169,793428352,793428490,1 +97194,793428353,1540859897,1 +95006,793428358,793428494,1 +97128,793428358,793428509,1 +97139,793428364,793428468,1 +97138,793428365,793428364,1 +97179,793428365,1540859885,1 +97109,793428370,793428425,1 +97141,793428375,793428491,1 +97126,793428377,793428412,1 +97096,793428377,793428451,1 +97160,793428378,793428517,1 +97123,793428380,745090930,1 +94994,793428382,745090937,1 +97196,793428382,1540859898,1 +97167,793428389,793428450,1 +97135,793428389,793428513,1 +95082,793428396,745092374,1 +97171,793428396,793428427,1 +97134,793428398,793428353,1 +97187,793428398,793428464,1 +97099,793428399,745090923,1 +97158,793428401,745090926,1 +97094,793428401,745090937,1 +95000,793428404,745092374,1 +97189,793428404,793428447,1 +97144,793428405,793428448,1 +23992,793428405,793479450,1 +97127,793428412,793428358,1 +95056,793428414,603753974,1 +97106,793428414,1540859865,1 +95076,793428415,793428343,1 +97095,793428415,793428377,1 +63921,793428417,417278829,1 +63919,793428420,417278010,1 +97118,793428423,745092394,1 +97110,793428425,793428420,1 +97162,793428427,793428479,1 +97137,793428428,793428365,1 +97104,793428428,793428512,1 +97115,793428429,361200011,1 +97108,793428429,793428370,1 +97072,793428431,745090922,1 +97146,793428431,1540859872,1 +97202,793428432,793428511,1 +97116,793428434,793428490,1 +97132,793428434,1540859868,1 +95008,793428439,745090925,1 +97142,793428439,793428515,1 +97193,793428440,793428353,1 +97120,793428447,793428336,1 +97190,793428447,793428440,1 +97145,793428448,745092392,1 +95036,793428448,793428477,1 +97114,793428450,793428429,1 +97168,793428450,1540859880,1 +97183,793428451,793428453,1 +97097,793428451,1540859864,1 +97184,793428453,793428494,1 +97197,793428453,793428515,1 +97157,793428454,793428401,1 +97192,793428456,793428440,1 +97149,793428456,1540859874,1 +97172,793428459,793428472,1 +95079,793428459,793428511,1 +97200,793428460,793428493,1 +97163,793428462,793428510,1 +97152,793428462,793428520,1 +97195,793428464,745090930,1 +97181,793428465,745090939,1 +97156,793428465,793428454,1 +97166,793428468,793428389,1 +97140,793428468,1540859870,1 +97159,793428472,793428378,1 +97173,793428472,793428509,1 +97101,793428474,793385645,1 +97178,793428474,793428519,1 +95004,793428477,745090953,1 +95037,793428477,1540857386,1 +94999,793428479,793428404,1 +95052,793428481,793385614,1 +97125,793428481,793428339,1 +97186,793428482,793428454,1 +95012,793428484,793428493,1 +97170,793428490,793428340,1 +95063,793428491,793385663,1 +95013,793428493,745090958,1 +97201,793428493,793428361,1 +95007,793428494,793428439,1 +97185,793428494,793428482,1 +97188,793428496,793428364,1 +97176,793428496,1540859881,1 +51507,793428500,745092364,1 +97368,793428500,1540859961,1 +95075,793428507,793428415,1 +97182,793428507,1540859888,1 +97129,793428509,793428351,1 +97174,793428509,793428482,1 +95002,793428510,745090943,1 +97164,793428510,793428423,1 +97203,793428511,793428378,1 +95080,793428511,793428520,1 +97112,793428512,793428344,1 +97105,793428512,793428417,1 +97107,793428513,1540859866,1 +97143,793428515,1540859871,1 +97154,793428517,793428351,1 +97161,793428517,793428427,1 +95010,793428519,793385731,1 +95081,793428520,793428396,1 +97153,793428520,1540859879,1 +23994,793479395,294203947,1 +97225,793479398,793479443,1 +97224,793479401,1540859901,1 +97232,793479403,793479404,1 +97218,793479403,1540859900,1 +97233,793479404,294203947,1 +97223,793479404,793479425,1 +97007,793479405,745990359,0 +97210,793479405,1540859899,1 +97009,793479407,294243379,0 +97219,793479407,793479440,1 +97207,793479409,793479431,1 +97206,793479414,793479409,1 +97215,793479414,793479443,1 +97237,793479416,793479440,1 +97209,793479416,793479449,1 +97227,793479419,793479450,1 +97221,793479419,793479462,1 +97241,793479421,793479457,1 +97212,793479421,793479459,1 +133587,793479425,793529738,1 +97012,793479429,705065799,0 +97243,793479429,1540859903,1 +23991,793479431,1540793885,1 +133579,793479435,360731675,1 +97238,793479440,793479448,1 +97226,793479443,793479419,1 +97216,793479443,793479459,1 +97235,793479445,360731675,1 +97245,793479445,793529786,1 +97239,793479448,793479401,1 +97240,793479448,793479421,1 +97229,793479449,793529754,1 +23993,793479450,793479395,1 +97231,793479457,793479403,1 +97242,793479457,793529697,1 +97217,793479459,793479403,1 +97213,793479459,793479462,1 +97214,793479462,793479395,1 +97222,793479462,793479404,1 +97204,793479464,799917471,1 +95151,793479464,1540857423,1 +125349,793479467,360731679,1 +97248,793479467,793529728,1 +125327,793529568,793529658,1 +97280,793529568,793529693,1 +133591,793529631,793529727,1 +97294,793529634,793529728,1 +97293,793529634,793529791,1 +125329,793529637,1540884065,1 +97265,793529641,793529788,1 +97263,793529641,793529793,1 +125343,793529652,793529841,1 +133590,793529656,793529631,1 +97279,793529656,793529719,1 +97275,793529658,793529804,1 +125328,793529658,1540884064,1 +97289,793529662,793529750,1 +97273,793529662,1540859905,1 +97312,793529663,793529835,1 +97260,793529664,793529791,1 +97299,793529669,793529730,1 +125338,793529669,793529883,1 +97322,793529671,793529725,1 +97256,793529673,360731678,1 +97247,793529673,793479467,1 +97014,793529678,705065786,0 +97300,793529678,1540859919,1 +125340,793529686,793529723,1 +97310,793529688,793529878,1 +125347,793529688,1540884071,1 +97281,793529692,793529844,1 +127601,793529693,793529768,1 +133585,793529697,793529865,1 +125342,793529699,1540884069,1 +125336,793529700,793529699,1 +97326,793529700,793529730,1 +93278,793529702,705065811,1 +97309,793529702,793529786,1 +23999,793529719,1540793888,1 +125341,793529723,793529775,1 +97257,793529723,793529781,1 +97272,793529725,793529662,1 +97323,793529725,793529838,1 +133592,793529727,793529785,1 +97249,793529728,793529856,1 +125337,793529730,1540884068,1 +97284,793529731,793529735,1 +97259,793529731,793529809,1 +97325,793529732,792071822,1 +97253,793529732,793529763,1 +97291,793529733,793529759,1 +125348,793529733,1540884072,1 +97285,793529735,793529836,1 +23998,793529738,793529719,1 +97335,793529740,579794584,1 +97277,793529740,793529800,1 +97251,793529743,1540859904,1 +97288,793529743,1540859906,1 +97315,793529747,1540859921,1 +97303,793529750,793529838,1 +125335,793529750,1540884067,1 +97307,793529751,793529770,1 +97296,793529751,793529796,1 +97230,793529754,793479457,1 +97311,793529754,793529663,1 +97292,793529759,793529634,1 +97254,793529763,793529852,1 +127602,793529768,792071822,1 +97308,793529770,793529702,1 +97268,793529770,793529819,1 +125325,793529775,793529830,1 +97283,793529785,793529731,1 +133593,793529785,793529851,1 +97246,793529786,793529673,1 +125330,793529788,793529727,1 +97266,793529788,793529852,1 +97017,793529789,793529826,0 +97258,793529789,793529841,1 +97261,793529791,793529856,1 +97264,793529793,793529631,1 +97286,793529796,793529819,1 +97297,793529796,793529833,1 +97278,793529800,793529743,1 +97301,793529800,793529860,1 +125346,793529803,793529688,1 +97252,793529804,793529732,1 +97276,793529804,793529768,1 +97305,793529809,793529844,1 +97287,793529819,705065811,1 +97269,793529819,793529803,1 +97270,793529826,793529652,1 +97018,793529826,793529880,0 +125326,793529830,793529568,1 +97324,793529830,793529761,1 +125345,793529833,1540884070,1 +133589,793529835,793529656,1 +133584,793529835,793529697,1 +97316,793529836,809943343,1 +127600,793529838,1540885225,1 +97304,793529840,793529809,1 +133595,793529840,1540895697,1 +125344,793529841,793529833,1 +97306,793529844,793529747,1 +97274,793529846,793529800,1 +97320,793529846,793529883,1 +97271,793529848,793529759,1 +133594,793529851,793529840,1 +97298,793529851,1540859914,1 +97267,793529852,809943343,1 +133582,793529855,360731679,1 +97282,793529855,793529663,1 +97262,793529856,793529641,1 +97302,793529860,793529671,1 +97319,793529860,793529846,1 +97016,793529861,793529789,0 +97295,793529861,1540859913,1 +133586,793529865,793479425,1 +97019,793529880,579794613,0 +97313,793529880,793529699,1 +125339,793529883,793529686,1 +97333,793771274,1540859934,0 +97328,793771278,793774351,0 +97339,793771282,793771307,0 +97342,793771299,1540859947,0 +97341,793771302,793771299,0 +97330,793771307,1540859924,0 +97340,793771307,1540859942,0 +97338,793771331,793771282,0 +97347,793771331,1540859955,0 +51150,793772301,704826183,1 +97345,793772301,1540859953,0 +97329,793774351,793771282,0 +97346,793774351,793771331,0 +84118,793781646,603748693,1 +51503,793781648,361199842,1 +97393,793781650,793781646,1 +97378,793781650,793781666,1 +97373,793781652,793781686,1 +51486,793781654,745090713,1 +94846,793781656,745090228,1 +51502,793781658,793781648,1 +97411,793781658,1540859969,1 +97423,793781659,793781724,1 +97362,793781659,793781804,1 +97415,793781664,793781767,1 +51516,793781664,793781832,1 +51505,793781666,1540815965,1 +51511,793781668,793781680,1 +97391,793781668,793781689,1 +97428,793781677,793781738,1 +97360,793781677,1540859959,1 +84117,793781678,793781646,1 +97377,793781678,1540859962,1 +51512,793781680,745090958,1 +97419,793781680,793781784,1 +97462,793781682,793799848,1 +94944,793781684,745090216,1 +97374,793781686,793781797,1 +97422,793781687,793781659,1 +97355,793781687,793781699,1 +95068,793781689,793781699,1 +51490,793781692,361199833,1 +97435,793781692,793781810,1 +97364,793781696,793781790,1 +97399,793781696,937365633,1 +95069,793781699,793781747,1 +97408,793781701,793781825,1 +51524,793781706,603753974,1 +97382,793781706,793781782,1 +97416,793781708,793781748,1 +97397,793781708,793781779,1 +94927,793781710,745090683,1 +97437,793781710,793800001,1 +84120,793781712,603748686,1 +51518,793781714,793781757,1 +97358,793781714,793781785,1 +97425,793781717,793781759,1 +97369,793781717,793781825,1 +95067,793781722,793781689,1 +97414,793781722,793781800,1 +94968,793781724,745092378,1 +97424,793781724,793781717,1 +94960,793781728,745090678,1 +97392,793781730,793781812,1 +97385,793781730,1540859963,1 +51506,793781731,603748693,1 +94948,793781735,745090261,1 +97404,793781736,793781652,1 +97432,793781736,793781794,1 +97401,793781738,793781712,1 +97367,793781740,793781648,1 +97406,793781740,793781795,1 +95018,793781741,745090681,1 +97381,793781741,793781656,1 +97421,793781745,793781814,1 +95070,793781747,793781804,1 +97426,793781747,793781835,1 +97417,793781748,793781827,1 +100585,793781748,793781837,1 +84115,793781750,603753994,1 +97361,793781752,793781659,1 +51509,793781752,793781777,1 +84111,793781755,603748689,1 +97359,793781755,793781677,1 +97356,793781757,361199840,1 +51519,793781757,745090805,1 +95073,793781759,745092385,1 +97372,793781760,793781652,1 +97429,793781760,793799956,1 +94943,793781762,793781684,1 +51499,793781764,361199841,1 +97398,793781764,793781684,1 +97461,793781765,793781682,1 +97351,793781765,793799882,1 +51494,793781767,1540815963,1 +97434,793781775,793781692,1 +95065,793781775,793781784,1 +51510,793781777,793781668,1 +97354,793781777,793781687,1 +51492,793781779,361199837,1 +51523,793781780,793781706,1 +97366,793781780,793781740,1 +97383,793781782,793781795,1 +97348,793781782,1540859956,1 +95066,793781784,793781722,1 +97420,793781784,793781745,1 +51496,793781785,361199840,1 +97376,793781787,361200013,1 +97412,793781789,361199841,1 +51521,793781789,793781829,1 +97365,793781790,1540859960,1 +97433,793781794,361200011,1 +97386,793781794,793781686,1 +97384,793781795,793781730,1 +97375,793781797,793781787,1 +97349,793781797,1540859957,1 +51482,793781799,793804771,1 +97390,793781800,793781745,1 +94923,793781802,745090257,1 +97388,793781802,793781735,1 +95071,793781804,745092378,1 +51515,793781805,793781664,1 +97396,793781805,793781708,1 +51501,793781807,793781658,1 +84021,793781809,937365376,1 +106840,793781809,937365502,1 +97436,793781810,793781710,1 +97380,793781810,793781741,1 +84114,793781812,793781750,1 +51488,793781814,745090706,1 +51528,793781815,361200013,1 +97357,793781815,1540859958,1 +94934,793781817,745090683,1 +97379,793781817,793781810,1 +94854,793781822,793781728,1 +97387,793781822,793781802,1 +97409,793781825,745092385,1 +97370,793781825,793781790,1 +95016,793781827,361199833,1 +51522,793781829,793781780,1 +97394,793781829,793781834,1 +51517,793781832,793781714,1 +97402,793781832,1540859965,1 +97405,793781834,793781740,1 +97395,793781834,1540859964,1 +97427,793781835,793781654,1 +97389,793781835,793781800,1 +51514,793781837,793781805,1 +94941,793781839,745090385,1 +97400,793781843,793781738,1 +84110,793781843,793781755,1 +84122,793799835,603748694,1 +94950,793799842,745090229,1 +97446,793799842,1540859976,1 +97448,793799844,417276968,1 +97460,793799844,793781765,1 +97450,793799848,793799983,1 +97463,793799848,1540859979,1 +94947,793799857,793781735,1 +97474,793799857,793799991,1 +94868,793799865,745090387,1 +97470,793799865,1540859980,1 +97469,793799869,793799933,1 +97452,793799869,793800018,1 +97442,793799872,793799888,1 +94963,793799874,745090199,1 +84148,793799881,417279720,1 +63916,793799882,793799919,1 +97352,793799882,793799922,1 +97492,793799885,745090287,0 +97456,793799888,793799959,1 +97443,793799888,1540859971,1 +97455,793799897,603753257,1 +97444,793799897,1540859973,1 +63917,793799919,793799983,1 +97353,793799922,603753273,1 +97467,793799922,793799999,1 +94921,793799929,745090664,1 +97472,793799929,793799993,1 +84124,793799933,603748695,1 +97439,793799938,793800001,1 +97488,793799951,745090891,0 +97430,793799956,793781682,1 +97454,793799956,793799835,1 +97457,793799959,361200016,1 +97476,793799959,793799881,1 +97441,793799968,1540859970,1 +95020,793799981,745090664,1 +97451,793799983,793799869,1 +97466,793799984,793799922,1 +97445,793799984,1540859975,1 +97350,793799988,793781765,1 +97453,793799988,793799956,1 +97447,793799991,793799874,1 +97475,793799991,1540859981,1 +94919,793799993,745090645,1 +97473,793799993,793799951,1 +97468,793799999,793799869,1 +97465,793799999,793799919,1 +97440,793800001,793799981,1 +84142,793800018,603753213,1 +51483,793804771,361199832,1 +97480,793804771,793804783,1 +97502,793804774,793804785,1 +97504,793804774,793804789,1 +97483,793804785,417279549,0 +97505,793804789,745090599,1 +97481,793804789,793804782,1 +83952,793810036,600926422,1 +94883,793810040,745090474,1 +97518,793810040,793810060,1 +63938,793810044,745090374,0 +97516,793810044,793810073,1 +83950,793810051,152804209,1 +83955,793810054,1540846789,1 +97506,793810054,1540859987,1 +83956,793810058,793810072,1 +94889,793810060,793810051,1 +97498,793810069,745090387,0 +97515,793810069,793810044,1 +83957,793810072,745090738,1 +97517,793810076,1540859995,1 +73865,795262985,361406204,1 +73869,795263003,1540839733,1 +97541,795263009,795263019,1 +97555,795263009,795263044,1 +73871,795263012,1540839736,1 +73873,795263015,795262985,1 +97542,795263015,1540860161,1 +73870,795263019,1540839734,1 +97545,795263038,528490283,1 +97561,795263039,795263038,1 +97557,795263039,795263042,1 +97559,795263041,361406198,1 +97554,795263041,795263009,1 +97551,795263042,795263249,1 +97547,795263044,361406207,1 +97556,795263044,795263039,1 +97553,795263044,1540860163,1 +97575,795263224,795263260,1 +97596,795263226,528490323,1 +97578,795263226,795263255,1 +97585,795263227,795263256,1 +97589,795263227,967331729,1 +79925,795263228,795263248,1 +97563,795263228,795263258,1 +97582,795263229,795263260,1 +71848,795263229,967331619,1 +97577,795263231,795263250,1 +104430,795263231,1540866210,1 +97569,795263233,536601228,1 +79941,795263233,795263254,1 +97571,795263235,795263240,1 +97562,795263236,795263228,1 +97549,795263237,536601251,1 +97576,795263237,795263231,1 +97595,795263240,795263226,1 +97584,795263242,795263227,1 +79939,795263244,536601062,1 +124965,795263245,536579487,1 +97573,795263247,528490467,1 +97593,795263247,795263251,1 +79926,795263248,575187178,1 +97598,795263248,795263254,1 +97552,795263249,361409663,1 +97570,795263249,1540860166,1 +97581,795263250,1540860167,1 +97594,795263251,795263240,1 +124961,795263252,528490323,1 +97580,795263252,795263250,1 +97599,795263254,536601229,1 +79942,795263254,795263258,1 +97579,795263255,536579504,1 +97586,795263256,536601060,1 +79943,795263258,536601146,1 +97564,795263258,536601230,1 +97583,795263260,795263242,1 +97568,795263262,795263233,1 +124950,795264048,528489612,1 +97608,795264050,360015282,1 +97638,795264050,795264076,1 +124955,795264051,528489638,1 +97623,795264056,528489673,1 +124958,795264056,1540883952,1 +124970,795264058,528490392,1 +97610,795264058,536579530,1 +97613,795264059,528489683,1 +124957,795264059,795264056,1 +97603,795264060,536579540,1 +97605,795264061,795264066,1 +71618,795264064,360015125,1 +97636,795264064,528490597,1 +124954,795264066,795264051,1 +97606,795264066,795264079,1 +41024,795264076,360015253,1 +97639,795264076,795264088,1 +97641,795264077,528489696,1 +124938,795264077,1540883946,1 +124967,795264078,536579484,1 +97617,795264078,795264048,1 +97607,795264079,795264050,1 +97616,795264079,795264082,1 +124916,795264082,795264051,1 +97635,795264083,1540860172,1 +124953,795264083,1540883951,1 +71620,795264086,528489628,1 +97609,795264086,795264060,1 +40287,795264088,1113233820,1 +97601,795264089,575189652,1 +97634,795264089,1540860171,1 +97955,796727361,1540861168,1 +97957,796727361,1540861175,1 +97958,796743692,796743694,1 +97963,796743692,1540861182,1 +97959,796743694,796743696,1 +97960,796743696,1540861176,1 +97965,796743696,1540861183,1 +97961,796743705,1540861179,1 +97956,796743717,1540861171,1 +97966,796743724,1540861184,1 +97967,796743724,1540861185,1 +96087,796746781,796727361,1 +97968,796746781,1540861186,1 +57764,797159527,1540827650,1 +97970,797159527,1540861187,1 +97971,797159533,1540861188,1 +97973,797159542,797159578,1 +97972,797159542,1540861190,1 +57767,797159560,1540827654,1 +97975,797159578,797159593,1 +97974,797159578,1540861192,1 +97962,797159587,796743694,1 +97979,797159593,1540861088,1 +97976,797159593,1540861195,1 +97980,797159601,797159637,1 +97977,797159601,1540861196,1 +97978,797159608,797159533,1 +97964,797159637,796743717,1 +97981,797175353,797175356,1 +98005,797175353,797175436,1 +97982,797175356,797175358,1 +97986,797175356,1540861201,1 +97988,797175358,797175375,1 +97983,797175358,1343000073,1 +98001,797175363,797175412,1 +97984,797175363,1540861198,1 +97985,797175370,797175356,1 +97991,797175375,797175370,1 +97989,797175375,797175376,1 +97994,797175376,797175412,1 +98639,797175387,365311012,1 +97992,797175387,1540861205,0 +97993,797175407,1540861207,1 +98010,797175407,1540861218,1 +98002,797175412,365925632,1 +97995,797175412,797175414,1 +97996,797175414,797175416,1 +98000,797175414,1540861209,1 +97997,797175416,365311009,1 +97998,797175416,797175419,1 +97999,797175419,365311008,1 +98003,797175419,797175428,1 +98004,797175428,1540861210,1 +98006,797175436,1540861213,1 +143178,797175451,1540936580,1 +57766,797175462,797159560,1 +98009,797175462,797175407,1 +98013,797175507,1540861231,1 +115482,797175507,1540874579,1 +98015,797190006,1540861235,1 +98018,797190040,797190062,1 +98017,797190040,1540861241,1 +98019,797190062,365378192,1 +57762,797196065,1540827636,1 +51696,797347625,1540816217,0 +98020,797347625,1540861242,0 +134540,797347631,1540904929,1 +29605,797347639,1540798982,1 +48382,797375555,797375593,1 +98135,797375555,797375793,1 +98112,797375560,797375702,1 +51361,797375563,792056430,1 +98150,797375563,797375830,1 +51452,797375568,797375613,1 +98083,797375568,797375882,1 +98077,797375572,797375695,1 +98027,797375572,797375818,1 +98102,797375573,797375659,1 +51350,797375573,797375702,1 +48471,797375576,360477360,0 +98133,797375576,797375837,0 +51358,797375578,361198639,0 +98050,797375578,797375839,1 +134590,797375584,338485829,0 +48377,797375586,360476804,1 +98039,797375588,1540861245,0 +125354,797375588,1540884073,1 +98151,797375590,797375659,1 +29712,797375590,797375830,1 +48383,797375593,360476809,1 +98024,797375593,797375855,0 +51454,797375595,361199444,1 +98075,797375595,797375603,1 +96806,797375598,797375800,1 +98078,797375598,797375810,1 +98076,797375603,797375572,1 +134584,797375606,797375821,0 +29718,797375607,797375733,1 +98114,797375610,797375842,1 +98154,797375610,1540861275,1 +51453,797375613,797375595,1 +98081,797375613,797375845,1 +98073,797375615,1145577411,1 +51404,797375623,361198828,0 +98030,797375623,797375879,1 +48454,797375625,797375825,0 +51451,797375626,797375568,1 +98097,797375626,797375852,1 +98042,797375628,803745080,0 +29716,797375630,797375695,1 +51372,797375630,797375762,1 +51368,797375631,792056478,1 +98111,797375631,1540861255,1 +135140,797375633,797375709,0 +98094,797375634,797375767,0 +48473,797375634,1540813922,0 +98149,797375636,792071823,1 +134581,797375638,797375671,0 +48484,797375638,797375779,0 +98122,797375658,1540861263,1 +98103,797375659,361198929,1 +98152,797375659,797375673,1 +48469,797375662,360477365,0 +51325,797375662,361198612,0 +135135,797375664,653316165,0 +80561,797375667,600205190,0 +98202,797375667,797394819,1 +51374,797375669,361198697,1 +134582,797375671,360476800,0 +98105,797375671,797375775,0 +98153,797375673,797375610,1 +98080,797375673,797375877,1 +98093,797375676,797375634,0 +125362,797375676,797375773,0 +95537,797375681,338485830,0 +48375,797375681,797375796,1 +96808,797375682,797375607,1 +98148,797375682,797375636,1 +98123,797375685,1540861267,1 +51324,797375687,797375662,0 +134576,797375687,797375782,0 +135120,797375690,360476809,0 +135125,797375690,797375855,0 +135133,797375692,338485737,0 +29717,797375695,797375607,1 +98036,797375698,360476616,1 +48385,797375698,797375767,0 +51351,797375702,247151320,1 +48461,797375704,360477342,0 +98110,797375704,797375606,1 +98025,797375707,1540861244,1 +98121,797375707,1540861260,1 +98128,797375709,797375729,0 +135141,797375709,797375771,0 +48384,797375711,797375698,0 +51342,797375711,938502219,1 +134589,797375713,797375584,0 +135122,797375713,797375731,0 +127083,797375721,361198642,0 +51346,797375721,797375833,1 +98138,797375721,1540861271,1 +135145,797375722,338485738,0 +98088,797375722,1139744362,0 +48466,797375727,360477363,0 +89968,797375729,797375804,0 +98129,797375729,803745060,0 +135123,797375731,653281865,0 +48456,797375731,938502202,0 +29719,797375733,338485976,1 +98026,797375733,797375818,1 +98047,797375735,792056461,1 +51370,797375735,1540815942,1 +51406,797375736,600915597,0 +98022,797375736,1250044733,1 +51417,797375738,361198875,1 +98108,797375738,797375669,1 +89971,797375740,797375851,0 +80560,797375744,797375667,0 +98206,797375744,797394854,1 +98085,797375746,803745074,0 +89963,797375746,803745173,0 +48380,797375748,360476828,1 +51323,797375753,797375687,0 +98100,797375753,797375801,1 +125353,797375755,797375588,1 +98045,797375758,653316164,0 +98144,797375758,797375828,0 +127166,797375758,803745088,0 +51349,797375759,797375573,1 +98021,797375759,797375736,1 +51373,797375762,797375669,1 +98147,797375762,797375682,1 +95539,797375764,360476807,0 +135137,797375764,797375815,0 +48386,797375767,797375854,0 +135142,797375771,653316867,0 +51322,797375771,797375753,0 +98142,797375773,360477360,0 +134574,797375773,797375837,0 +48463,797375775,797375779,0 +98140,797375778,938149141,1 +48485,797375779,360477396,0 +48464,797375779,746981320,0 +134577,797375782,746981321,0 +98126,797375782,797375801,0 +48374,797375784,797375681,1 +98146,797375784,1540861274,0 +80533,797375787,600918675,1 +98056,797375787,803745030,0 +135128,797375793,653316163,0 +48376,797375796,797375586,1 +98109,797375796,797375692,1 +89965,797375798,803745243,0 +98055,797375798,1540861249,0 +96807,797375800,797375682,1 +98127,797375801,797375709,0 +98101,797375801,797375870,1 +51450,797375803,797375626,1 +98115,797375804,797375860,0 +89969,797375804,803745002,0 +98125,797375806,797375861,1 +89967,797375807,797375729,0 +51321,797375807,797375771,0 +80521,797375809,581260959,1 +127143,797375809,803745053,0 +98046,797375810,797375735,1 +98079,797375810,1540861253,1 +135138,797375815,797375860,0 +98095,797375815,803745111,1 +48373,797375816,797375784,1 +98028,797375818,797375858,1 +134585,797375821,360476827,0 +98134,797375821,797375748,1 +98053,797375824,653316867,0 +98099,797375824,797375753,1 +98143,797375825,797375584,0 +48455,797375825,797375731,0 +2827,797375827,338485974,0 +135130,797375828,360476794,0 +29713,797375830,338486506,1 +51347,797375833,361198459,1 +98113,797375833,797375610,1 +96813,797375836,338486506,1 +98106,797375836,797375865,1 +134575,797375837,797375687,0 +48359,797375839,360476616,0 +98051,797375839,797375854,1 +2829,797375840,338485976,0 +51422,797375842,1540815946,1 +98092,797375843,797375676,0 +98098,797375843,797375824,1 +98124,797375845,797375806,1 +98082,797375845,797375871,1 +98033,797375848,797375586,0 +135132,797375848,797375692,0 +127160,797375848,797375863,0 +127148,797375851,653316321,0 +98035,797375852,797375827,1 +48387,797375854,360476820,0 +135126,797375855,803745151,0 +98031,797375858,797375803,1 +98029,797375858,797375840,1 +135139,797375860,797375633,0 +2826,797375861,797375827,0 +98044,797375863,797375758,0 +2834,797375864,272565046,0 +98107,797375865,797375738,1 +98119,797375867,1540861256,1 +127138,797375870,797375633,1 +107456,797375871,797375615,1 +134579,797375873,338485830,0 +98145,797375873,797375784,0 +48379,797375874,797375748,1 +98032,797375874,803749501,1 +51421,797375877,797375842,1 +51353,797375879,247151814,1 +48398,797375880,600918109,0 +98137,797375880,797375625,0 +98084,797375882,797375806,1 +98034,797375882,797375852,1 +98215,797394751,938143093,1 +107182,797394751,1540868933,1 +98162,797394752,792071805,1 +51442,797394752,797394808,1 +98197,797394753,797394851,1 +98172,797394755,797394762,1 +127637,797394755,797394777,1 +98195,797394761,797394789,1 +106758,797394761,938149078,1 +98213,797394762,797394837,1 +98173,797394762,797394858,1 +98209,797394764,797394776,1 +98204,797394769,797394869,1 +127615,797394769,1540885229,1 +127636,797394771,797394755,1 +98187,797394771,797394876,1 +98211,797394774,797394785,1 +98167,797394774,797394856,1 +98210,797394776,797394774,1 +127617,797394776,797394859,1 +98200,797394777,797394837,1 +127638,797394777,797394862,1 +127612,797394785,797394876,1 +98159,797394787,938149140,1 +98174,797394787,938149162,1 +98176,797394789,938142815,1 +98196,797394789,1540861286,1 +127616,797394792,797394776,1 +98218,797394792,797394856,1 +98185,797394794,1540861281,1 +127619,797394794,1540885230,1 +127618,797394798,797394794,1 +98157,797394798,797394819,1 +98203,797394800,797394769,1 +98171,797394807,797394755,1 +127622,797394807,797394834,1 +98156,797394808,797394798,1 +127620,797394808,1540885231,1 +98166,797394811,797394769,1 +98169,797394811,797394839,1 +127611,797394813,797394785,1 +98165,797394815,797394811,1 +98208,797394815,797394844,1 +127609,797394819,797394753,1 +98158,797394819,797394787,1 +51364,797394821,361198864,1 +98217,797394832,797394792,1 +98199,797394834,797394777,1 +127623,797394834,1540885233,1 +98214,797394837,797394751,1 +98201,797394837,797394849,1 +127610,797394839,797394813,1 +127635,797394844,797394771,1 +98155,797394844,797394808,1 +51384,797394847,361198734,1 +98220,797394847,797394821,1 +98198,797394851,797394834,1 +98161,797394854,797394752,1 +98207,797394854,797394798,1 +98219,797394856,797394813,1 +98168,797394856,797394869,1 +98190,797394859,1540861283,1 +107181,797394862,797394751,1 +127639,797394862,938142963,1 +96774,797394866,792054066,1 +98170,797394866,1540861276,1 +98205,797394869,797394839,1 +98212,797394873,797394762,1 +98189,797394873,797394859,1 +98188,797394876,797394873,1 +97211,799917471,793479398,1 +97205,799917471,793479414,1 +98722,800140462,152801591,1 +51656,800140462,1540816125,1 +98720,800140465,800140505,1 +98696,800140465,801467983,1 +98702,800140466,800140469,0 +401,800140466,800140495,0 +98703,800140469,549775642,0 +98705,800140469,800140495,0 +73512,800140476,800140483,0 +98710,800140476,1540861533,0 +98713,800140482,36231496,0 +75741,800140482,295775157,0 +98700,800140482,1540861517,0 +393,800140483,1540770096,0 +98706,800140495,360016036,0 +98701,800140495,1540861524,0 +100519,800140499,35839643,0 +98708,800140499,1540861527,0 +98718,800140503,1540861545,0 +98724,800140503,1540861555,1 +98721,800140505,800140462,1 +41122,800140505,1540810247,1 +98694,800140515,801468003,1 +98727,800150206,1540861556,1 +98740,800150206,1540861586,1 +98739,800150217,1540861583,1 +98735,800150235,1540861576,1 +98728,800150242,1540861559,1 +98734,800150244,1540861571,1 +98746,800150244,1540861600,0 +98725,800150275,800150278,1 +98733,800150278,1540861570,1 +98744,800150303,800150524,0 +98743,800150369,800150303,0 +99458,800150395,1540862130,1 +98741,800150442,800150545,1 +98736,800150442,1540861577,1 +98730,800150480,1540861560,0 +98723,800150524,1540861553,1 +98745,800150524,1540861599,0 +98729,800150545,800150480,1 +98726,800150609,800150244,1 +98731,800150609,1540861563,0 +98798,800448603,800448608,1 +98799,800448608,800448770,1 +98759,800448609,1540861607,1 +98783,800448610,1540861613,1 +98838,800448612,800449059,1 +98804,800448613,800448704,1 +99046,800448613,1540861707,1 +98866,800448618,800448898,1 +98773,800448618,1540861610,1 +98749,800448619,800448700,1 +98824,800448619,800449055,1 +98831,800448622,800448707,1 +98871,800448622,1540861655,1 +98835,800448625,800448654,1 +98770,800448625,800448762,1 +98822,800448630,800448988,1 +82038,800448632,800465977,0 +98850,800448635,800448765,1 +98776,800448635,800448955,1 +98767,800448638,800448735,1 +98815,800448638,800448917,1 +98761,800448641,800448925,1 +98819,800448641,1540861631,1 +98780,800448652,800448752,1 +98857,800448652,800448822,1 +98755,800448653,800448711,1 +98792,800448653,800448915,1 +98836,800448654,800448732,1 +98813,800448655,1540861627,1 +98876,800448656,800448662,1 +82052,800448656,1540845896,0 +98812,800448658,800448655,1 +98852,800448662,800466091,1 +98827,800448662,1540861639,1 +98806,800448664,1540861624,1 +98811,800448664,1540861626,1 +98751,800448681,598498290,1 +98750,800448700,800448681,1 +98843,800448700,800448763,1 +98785,800448704,800448608,1 +99017,800448704,800465734,1 +98805,800448704,1540861623,1 +98847,800448707,1540861652,1 +98781,800448711,800448806,1 +98756,800448711,800449014,1 +82055,800448713,800448874,0 +98846,800448713,1540861651,1 +98808,800448717,800448632,1 +98834,800448717,1540861645,1 +98775,800448727,800448635,1 +98777,800448732,800448970,1 +98837,800448732,1540861648,1 +82037,800448734,1540845880,0 +98760,800448752,800448641,1 +81959,800448757,598498287,0 +98825,800448757,800448775,1 +98830,800448762,1540861642,1 +98832,800448763,800448917,1 +98844,800448763,800448949,1 +98851,800448765,1540861654,1 +98800,800448770,800448655,1 +98747,800448770,800448658,1 +98826,800448775,800448681,1 +98870,800448775,800448890,1 +98864,800448776,462754215,1 +98865,800448776,800448618,1 +98820,800448780,1540861632,1 +98947,800448780,1540861682,1 +98797,800448782,800448603,1 +98814,800448782,800448638,1 +98784,800448788,1540861618,1 +98856,800448803,800448652,1 +98828,800448803,800448925,1 +98861,800448805,800448975,1 +98782,800448806,800448610,1 +98789,800448808,800448867,1 +98774,800448808,1540861611,1 +98872,800448809,800448805,1 +98786,800448809,800448944,1 +98858,800448822,800448859,1 +98765,800448822,800448955,1 +98821,800448829,800448630,1 +81957,800448829,800448942,0 +98803,800448832,800448613,1 +98924,800448832,800466323,1 +98842,800448851,800448700,1 +98869,800448851,800448775,1 +98754,800448853,800448653,1 +98771,800448853,800448885,1 +98859,800448859,800448926,1 +98849,800448859,1540861653,1 +98790,800448867,800448946,1 +98817,800448867,800448982,1 +82056,800448874,355929053,0 +98829,800448874,800448762,1 +98758,800448883,1540861605,1 +98801,800448883,1540861620,1 +98873,800448885,800448915,1 +98772,800448885,800448988,1 +82035,800448890,1540845879,0 +98840,800448898,800448946,1 +98867,800448898,800449039,1 +98874,800448915,800448806,1 +98793,800448915,800448958,1 +98833,800448917,1540861643,1 +98802,800448924,800448832,1 +98762,800448925,800448962,1 +98779,800448926,800448727,1 +98860,800448926,800448805,1 +81958,800448942,800448757,0 +98841,800448942,1540861649,1 +98787,800448944,800448849,1 +98848,800448944,800448859,1 +98791,800448946,1540861619,1 +98796,800448949,800448782,1 +98845,800448949,1540861650,1 +98766,800448955,800448609,1 +98810,800448958,800448610,1 +98794,800448958,800449055,1 +98763,800448962,1540861608,1 +98877,800448970,800448612,1 +98778,800448970,1540861612,1 +98788,800448975,800448808,1 +98862,800448975,800449012,1 +98809,800448982,800448711,1 +98818,800448982,800448765,1 +98855,800448984,800448803,1 +98748,800448984,1540861602,1 +98823,800448988,800448619,1 +98863,800449012,800448776,1 +98757,800449014,1540861604,1 +98868,800449039,800448630,1 +98753,800449039,800448853,1 +98795,800449055,800448949,1 +98839,800449059,800449012,1 +98959,800465734,800465835,1 +98957,800465791,800466035,1 +98926,800465791,1540861676,1 +98941,800465800,800466375,1 +98960,800465835,800466161,1 +98983,800465835,800466302,1 +82040,800465892,1540845882,0 +98807,800465918,800448717,1 +99041,800465918,800466161,1 +82039,800465977,800465892,0 +98958,800466035,800465734,1 +99047,800466035,800466249,1 +98853,800466091,800448999,1 +98961,800466161,800466096,1 +98879,800466169,1540861656,1 +98974,800466169,1540861699,1 +98882,800466245,1540861658,1 +98975,800466245,1540861700,1 +98880,800466249,800466363,1 +98984,800466302,800466363,1 +99042,800466302,800466438,1 +98925,800466323,1540861675,1 +98956,800466353,800465791,1 +98881,800466363,800466169,1 +98992,800466375,800466323,1 +98942,800466375,800466353,1 +98973,800466438,800466169,1 +99043,800466438,1540861706,1 +99264,801062649,801062933,1 +99199,801062650,801451827,1 +99249,801062650,801451920,1 +99277,801062652,801062839,1 +99172,801062658,801062735,1 +99248,801062691,801062650,1 +99168,801062691,1540861906,1 +99260,801062696,801062847,1 +99298,801062696,1540861950,1 +99265,801062711,801063027,1 +81965,801062735,272562941,0 +99247,801062745,801062691,1 +82030,801062755,1540845872,0 +99242,801062755,1540861926,1 +99284,801062778,801062903,1 +99299,801062778,1540861955,1 +99282,801062783,801063058,1 +99170,801062804,801062847,1 +99246,801062810,801062745,1 +99259,801062839,801062696,1 +99278,801062839,801063153,1 +99171,801062847,801062658,1 +99261,801062847,801063027,1 +99296,801062864,272562941,1 +99263,801062864,801062649,1 +81962,801062884,130197703,0 +81967,801062905,801451885,0 +17076,801062930,1540787548,0 +99280,801062930,1540861930,1 +99255,801062933,801062905,1 +99198,801062933,1540861910,1 +99287,801062946,801063058,1 +99245,801062979,801062810,1 +99216,801062979,801063238,1 +99262,801063027,801062864,1 +99244,801063132,801062979,1 +99279,801063153,130197703,1 +99160,801063153,801063193,1 +99161,801063193,801062658,1 +99297,801063193,801062696,1 +17077,801063202,272567910,0 +99213,801063202,801062721,1 +99243,801063215,801063132,1 +99370,801451827,801451923,1 +81968,801451885,417276274,0 +99367,801451885,1540862098,1 +99250,801451920,801451952,1 +99408,801451920,801451980,1 +99407,801451949,1540862108,1 +100710,801451957,1540862854,1 +99409,801451980,801451923,1 +88503,801467908,633036602,1 +99456,801467908,1540862128,1 +99453,801467911,633036606,1 +99438,801467911,633036866,1 +41124,801467918,360016242,1 +99436,801467921,801467946,1 +99463,801467921,1540862133,1 +99435,801467922,801467921,1 +99446,801467922,801468004,1 +99434,801467924,801467918,1 +99462,801467926,801467921,1 +99471,801467926,801467928,1 +98691,801467928,801468010,1 +99455,801467928,1540862126,1 +99451,801467943,360016242,1 +99443,801467943,801467924,1 +98693,801467944,800140515,1 +99450,801467944,801467943,1 +99437,801467946,801467984,1 +99467,801467946,801468014,1 +99466,801467948,1540862136,1 +41127,801467949,360016244,1 +51660,801467951,801468029,0 +99461,801467951,1540862132,1 +99442,801467952,1540862118,1 +99465,801467952,1540862135,1 +88499,801467959,801479962,1 +99432,801467970,801468004,1 +99464,801467970,1540862134,1 +98690,801467971,801467928,1 +137776,801467980,294113203,0 +98697,801467983,360015847,1 +99445,801467985,801467922,1 +99470,801467985,801467926,1 +98689,801467987,801467971,1 +88492,801467987,801468012,1 +99469,801467995,801468029,0 +99489,801467995,1540862145,1 +98695,801468003,800140465,1 +99433,801468003,801467924,1 +99447,801468004,1540862121,1 +99454,801468010,360016243,1 +98692,801468010,801467944,1 +41130,801468012,360016247,1 +88493,801468012,633036268,1 +88491,801468016,801467987,1 +51659,801468016,1540816134,0 +99468,801468016,1540862140,0 +99509,801468016,1540862157,1 +99441,801468027,1540862117,1 +99444,801468029,1540862119,1 +99431,801468031,801467971,1 +99459,801468034,801467959,1 +99457,801468034,1540862129,1 +24110,801479955,801480019,0 +99481,801479958,801479977,1 +99506,801479958,801480035,1 +88500,801479962,1540851536,1 +40315,801479968,1540810011,0 +115658,801479968,1540874795,1 +88495,801479976,633036269,1 +88498,801479977,801467959,1 +99487,801480000,801480035,1 +99502,801480000,1540862151,1 +98688,801480001,801467987,1 +99486,801480001,801480037,1 +99475,801480004,536578772,1 +99477,801480004,801480053,1 +99505,801480009,801479958,1 +99494,801480009,801480050,1 +41132,801480013,360016249,1 +99497,801480013,801480053,1 +24111,801480019,1540794032,0 +99495,801480021,801480056,1 +99491,801480021,1540862149,1 +99472,801480026,801480051,1 +99492,801480026,1540862150,1 +99484,801480028,360016247,1 +99482,801480028,801479976,1 +99504,801480028,801480009,1 +99480,801480030,801479958,1 +99500,801480030,801480047,1 +99488,801480035,801479962,1 +99507,801480035,1540862156,1 +99490,801480037,801480021,1 +99501,801480047,801480000,1 +99499,801480050,801480030,1 +99473,801480051,360016249,1 +98686,801480051,801480056,1 +99478,801480053,801480028,1 +99498,801480053,801480050,1 +88501,801480054,801479968,1 +24112,801480054,1540794258,0 +98687,801480056,801480001,1 +99496,801480056,801480013,1 +99515,801484153,801484164,1 +124972,801484153,1540883956,1 +40937,801484164,528490503,1 +99526,801484168,1540862161,1 +89970,803745002,797375740,0 +99894,803745002,803745231,1 +127152,803745006,1540884979,1 +99888,803745016,803745022,1 +107551,803745017,938501955,1 +23914,803745017,1540793805,0 +99912,803745018,653316164,0 +80517,803745021,803745210,1 +127140,803745022,361198466,0 +99950,803745023,803745104,0 +99907,803745023,803745251,1 +99875,803745024,803745107,0 +127154,803745025,1540884980,1 +98057,803745030,803745140,0 +99957,803745030,803745186,1 +127070,803745031,803745136,0 +127176,803745031,1141011970,1 +89980,803745032,803745104,1 +99925,803745032,803745189,0 +127150,803745036,803745137,0 +80532,803745039,797375787,1 +99926,803745039,803745162,0 +89975,803745041,803745148,1 +125373,803745047,1540884077,0 +98087,803745050,797375722,0 +99887,803745050,803745016,1 +99965,803745052,803745024,1 +98131,803745052,1540861269,0 +127144,803745053,797375863,0 +99967,803745053,803745215,1 +99889,803745054,803745025,1 +125369,803745054,803745047,0 +99962,803745058,803745110,1 +99983,803745058,1141011983,1 +99979,803745059,1141011981,0 +80529,803745060,803745204,1 +99914,803745061,803745099,1 +99946,803745061,803745115,0 +98060,803745065,803745079,0 +125371,803745066,1540884075,1 +98118,803745068,797375628,1 +99971,803745068,803745036,1 +80526,803745069,803745231,1 +99973,803745069,1141011977,0 +99981,803745072,803745041,0 +99939,803745073,1141011979,1 +98086,803745074,803745050,0 +99895,803745074,1540862325,1 +89957,803745076,653316163,1 +99972,803745076,1540862336,1 +98061,803745079,803745091,0 +89984,803745079,1141034627,1 +98043,803745080,797375863,0 +89069,803745081,294163564,0 +99949,803745081,803745023,0 +80523,803745085,803745241,1 +99977,803745085,1141011965,0 +89068,803745087,1540852149,0 +80519,803745088,803745153,1 +98059,803745090,803745065,0 +127182,803745090,803745161,0 +99913,803745091,803745066,1 +98062,803745091,803745229,0 +99922,803745092,803745221,1 +80516,803745093,803745021,1 +99960,803745093,803745106,0 +89067,803745094,803745087,0 +99880,803745094,1540862321,0 +99915,803745099,803745180,1 +99933,803745100,653316899,1 +99902,803745100,803745175,0 +99918,803745102,600918675,1 +127168,803745102,803745177,0 +89981,803745104,803745209,1 +125370,803745105,803745066,1 +99924,803745105,1540862327,1 +99899,803745106,803745250,0 +80515,803745107,803745093,1 +99945,803745108,803745061,0 +125374,803745108,1540884080,0 +99988,803745110,803745182,1 +98096,803745111,797375740,1 +99920,803745115,803745255,1 +99908,803745116,803745201,0 +126439,803745116,938501991,1 +98064,803745117,294163564,0 +127147,803745124,797375851,0 +127158,803745125,803745213,0 +99986,803745125,803745218,1 +80536,803745126,803745244,1 +99911,803745128,803745018,0 +127167,803745129,803745102,0 +99904,803745130,803745126,0 +99874,803745133,803745024,0 +99910,803745133,803745128,0 +89071,803745135,1540852150,0 +99961,803745136,803745058,1 +127071,803745136,803745060,0 +127151,803745137,653316165,0 +99876,803745137,803745111,1 +23903,803745138,803745160,0 +98058,803745140,803745090,0 +89976,803745148,803745174,1 +99881,803745148,1540862322,0 +127178,803745149,1540884989,1 +99938,803745150,803745073,1 +135127,803745151,797375793,0 +99879,803745151,803745128,0 +80520,803745153,797375809,1 +99966,803745153,803745130,1 +98130,803745154,803745052,0 +80513,803745154,803745196,1 +89986,803745155,653316902,1 +99948,803745155,1540862332,1 +99956,803745157,803745180,1 +23904,803745160,1540793798,0 +127183,803745161,803745092,0 +99944,803745162,803745140,1 +89983,803745163,803745079,1 +99969,803745163,803745251,1 +99964,803745164,294163207,0 +89066,803745164,1540852148,0 +99898,803745167,803745106,0 +99982,803745167,803745196,0 +99917,803745171,803745150,1 +99873,803745171,1540862320,1 +127129,803745172,361198943,1 +89964,803745173,797375798,0 +99976,803745173,803745129,1 +89977,803745174,653316901,1 +89958,803745174,803745199,1 +127162,803745175,803745088,0 +99903,803745175,803745130,0 +99891,803745177,1140945513,1 +127169,803745177,1540884988,0 +127170,803745180,803745092,1 +125376,803745180,1540884081,1 +99942,803745182,803745233,1 +99897,803745184,803745167,0 +23905,803745185,1540793799,0 +89987,803745185,1540853800,1 +99905,803745186,803745161,1 +99958,803745186,803745255,1 +89064,803745187,1540852145,0 +99941,803745189,803745182,1 +99901,803745193,803745100,0 +80514,803745196,803745107,1 +99935,803745199,803745230,1 +89959,803745199,1141011954,1 +99909,803745201,803745133,0 +98132,803745201,1540861270,0 +99987,803745204,803745110,1 +80530,803745204,803745219,1 +99952,803745207,803745221,1 +125377,803745207,1540884083,1 +99963,803745208,1540862334,0 +89982,803745209,803745163,1 +80518,803745210,803745088,1 +99872,803745210,803745193,0 +127159,803745213,803745054,0 +99968,803745215,803745124,1 +99937,803745216,803745150,1 +127155,803745218,1540884983,1 +80531,803745219,803745039,1 +99923,803745221,653316902,1 +127171,803745221,1141034610,0 +99951,803745223,803745249,0 +135144,803745226,797375722,0 +99932,803745226,803745206,1 +98063,803745229,803745117,0 +99927,803745229,803745149,1 +99953,803745230,653316901,0 +99936,803745230,803745216,1 +80527,803745231,803745249,1 +99943,803745233,803745162,1 +99878,803745233,803745209,0 +98041,803745238,797375628,0 +99947,803745238,803745215,1 +99916,803745239,803745171,1 +99975,803745239,803745216,0 +80524,803745241,653316193,1 +99896,803745242,803745184,0 +126443,803745242,1540884443,1 +89966,803745243,797375807,0 +99886,803745243,803745219,1 +80537,803745244,581260960,1 +127180,803745244,803745072,1 +89979,803745245,803745032,1 +127181,803745245,803745087,0 +99928,803745245,1540862329,0 +80528,803745249,803745060,1 +99906,803745250,803745021,0 +99900,803745250,803745193,0 +99970,803745251,1540862335,1 +80512,803745252,803745154,1 +99890,803745252,1540862323,0 +99921,803745255,803745092,1 +99959,803745255,803745099,1 +89973,803745256,581260960,1 +127173,803745256,1141011966,1 +89063,803747942,803745187,0 +48343,803749499,360476794,0 +99989,803749499,803749501,0 +99990,803749501,803749503,0 +48400,803749503,360476828,0 +97317,809943343,792071822,1 +100517,809948956,549778901,0 +93160,810713373,1371125057,1 +93163,810713373,1371125074,1 +20250,810713382,1540790318,1 +93168,810713382,1540856441,1 +100577,810716444,1540862735,1 +148330,810716444,1540949555,1 +100573,810716445,1371043816,1 +100575,810716447,810716449,1 +100576,810716449,810716444,1 +148424,810716449,1540949701,1 +100579,810716450,810716452,1 +100580,810716452,1371043836,1 +148624,810716452,1540950051,1 +100578,810716453,1540862736,1 +100686,813097784,1540862794,1 +100722,813097808,813097939,1 +100718,813097808,813097984,1 +100695,813097816,813097962,1 +100691,813097816,813097997,1 +100719,813097843,813097847,1 +100684,813097843,1540862791,1 +100720,813097847,813097957,1 +100690,813097905,1540862814,1 +100687,813097914,1540862795,1 +100696,813097914,1540862822,1 +100685,813097939,1540862793,1 +100703,813097944,813097957,1 +81974,813097944,1540845750,0 +100689,813097946,1540862811,1 +100721,813097946,1540862861,1 +100704,813097957,1540862830,1 +100700,813097975,813097905,1 +100699,813098010,1540862827,1 +100711,813098010,1540862855,1 +118017,832461836,560576656,0 +102784,832461836,1540864441,1 +57794,832461845,365970093,1 +104432,889471538,1540866211,0 +104434,889471538,1540866216,0 +96839,890361700,1540859793,1 +104433,890361700,1540866215,0 +104453,891523944,279591152,1 +105174,891523944,1540867388,1 +105173,891523951,891523944,1 +104455,891523951,1540866224,1 +21434,891523958,279590089,1 +104459,891523958,1540866229,1 +104460,891523971,1540866233,1 +149651,891523976,1540952670,1 +149650,891523982,1540952668,1 +104469,891523995,1540866237,1 +115694,891523995,1540874829,1 +115703,891523995,1540874836,1 +104470,891524000,891524001,1 +135146,891524000,985968918,0 +104471,891524001,1540866238,1 +104473,891524045,891524046,1 +104456,891524045,1540866225,1 +104452,891524046,891523944,1 +104474,891524046,932361980,1 +149066,911998377,360215100,0 +104700,911998377,1540866363,0 +104713,912014321,1019990398,1 +118470,912014321,1540877110,1 +111877,912014324,418771213,1 +104710,912014324,1540866367,1 +104717,912014327,1540866373,1 +118451,912014327,1540877023,1 +104712,912014335,1540866369,1 +104718,912014337,1540866375,1 +118455,912014337,1540877062,1 +45916,913523106,1540812237,1 +2745,913575786,1540773208,1 +104739,913575786,1540866379,1 +45186,913575820,1540811967,1 +45304,918272749,360197260,1 +104734,918272749,360199520,1 +45942,920589763,1540812257,1 +2735,920605600,1540773177,0 +2736,920605603,1540773178,0 +40472,932361964,360008437,1 +105164,932361964,360011588,1 +105179,932361966,536579351,1 +24099,932361967,279591152,0 +104454,932361967,891523951,1 +104457,932361968,932361966,1 +24102,932361970,583432487,0 +104458,932361970,932361990,1 +40599,932361972,360010645,1 +105175,932361972,1540867389,1 +105172,932361975,891523951,1 +104475,932361980,536578827,1 +71588,932361981,536578905,1 +40454,932361981,549785233,0 +73523,932361982,536578839,1 +105170,932361982,932361986,1 +71591,932361983,536578940,1 +105162,932361983,932361991,1 +40451,932361985,360008265,0 +105171,932361986,932361968,1 +105184,932361986,932361980,1 +71579,932361990,536578819,1 +71586,932361991,583432486,1 +71583,932361992,536578904,1 +71577,932361993,360008268,1 +110079,932361993,536578912,0 +105826,935854427,935855246,1 +152879,935854528,935855089,1 +105824,935854552,1345647041,1 +138288,935854559,1307354780,1 +105831,935854559,1540867964,1 +152877,935854584,935855262,1 +105904,935854584,1540868150,1 +143007,935854642,935854427,1 +105853,935854642,935855038,1 +105840,935854664,935855006,1 +105848,935854664,935855555,1 +105768,935854691,935855343,1 +105838,935854739,935854880,1 +105701,935854739,1540867807,1 +105737,935854740,935855576,1 +138240,935854740,1540922610,1 +105686,935854834,935855038,1 +105706,935854834,1540867814,1 +105850,935854875,935855787,1 +105692,935854875,1540867764,1 +105839,935854880,1540868021,1 +105879,935854880,1540868102,1 +152875,935854884,935855116,1 +105883,935854884,935855372,1 +105752,935854918,935855827,1 +105841,935855006,935855372,1 +105830,935855029,1540867961,1 +105687,935855038,935854552,1 +152878,935855089,935855453,1 +105877,935855114,935854528,1 +152876,935855116,935854584,1 +105902,935855227,1540868124,1 +105697,935855245,935855575,1 +81166,935855245,1540844353,0 +105827,935855246,935855576,1 +105668,935855246,1345643909,1 +105888,935855262,935855343,1 +143008,935855262,1342497364,1 +105832,935855283,935855621,1 +138142,935855283,1307354639,1 +105699,935855403,1345651509,1 +105878,935855403,1540868101,1 +105691,935855427,1540867756,1 +105695,935855427,1540867798,0 +105663,935855453,935855729,1 +152873,935855453,935855761,1 +105880,935855555,935855729,1 +105849,935855555,935855851,1 +36838,935855575,1540805355,0 +105698,935855575,1540867800,1 +105828,935855576,1345642983,1 +143916,935855576,1540937938,1 +143006,935855599,935854642,1 +105707,935855599,1540867815,1 +105833,935855621,1540867965,1 +105903,935855677,1540868147,1 +105930,935855686,935855761,1 +105858,935855686,1540868029,1 +105709,935855700,935855116,1 +105859,935855700,1540868031,1 +105664,935855729,935854921,1 +105708,935855738,935854740,1 +105667,935855738,935855246,1 +152874,935855761,935854884,1 +105931,935855761,935855006,1 +105857,935855787,1540868027,1 +105856,935855827,935855787,1 +105753,935855827,1540867865,1 +105696,935855851,935855089,0 +396,936804097,1540770101,0 +23872,936804192,1540793758,0 +73510,936804227,1540839676,0 +118050,936804293,35841643,1 +80345,936804372,1540843136,0 +137778,936804451,35840454,0 +48346,936853681,600917285,0 +80334,936853681,1540843077,0 +80330,936853720,1139646180,0 +80333,936853776,1540843075,0 +80311,936853817,360476528,0 +80328,936853817,1540843062,0 +80320,936853855,678158876,0 +125355,936853887,1119354126,1 +80329,936853887,1540843066,0 +106711,937215998,361199478,1 +106678,937215998,937216452,1 +106683,937216001,937216099,1 +106807,937216001,937216422,1 +106615,937216007,937216207,1 +106677,937216007,1540868525,1 +106652,937216010,1540868523,1 +106733,937216010,1540868546,1 +83974,937216014,1540846804,1 +106692,937216016,937216336,1 +106629,937216018,937216161,1 +106688,937216018,1540868529,1 +106668,937216035,937216301,1 +106623,937216035,937216530,1 +106800,937216037,937216531,1 +106729,937216039,937216492,1 +106617,937216047,1540868498,1 +106703,937216049,937216396,1 +107067,937216049,938140754,1 +106689,937216051,937216259,1 +106663,937216051,937216542,1 +106691,937216053,937216016,1 +106806,937216053,1540868576,1 +106633,937216063,937216283,1 +106721,937216063,937216554,1 +106701,937216065,938140779,1 +107051,937216065,1540868911,1 +106798,937216067,937216281,1 +106739,937216067,1540868552,1 +106666,937216075,937216281,1 +106730,937216075,937216549,1 +106614,937216081,937216007,1 +106743,937216081,937216579,1 +106646,937216091,937216582,1 +106774,937216095,152803615,1 +106684,937216099,937216557,1 +106710,937216110,937215998,1 +106636,937216123,1540868506,1 +106651,937216128,937216010,1 +106719,937216128,937216173,1 +106650,937216138,152804211,1 +106696,937216144,937216422,1 +106723,937216144,937216570,1 +84019,937216151,152803615,1 +106640,937216151,937216355,1 +83969,937216153,600926441,1 +106713,937216153,1540868539,1 +106715,937216157,937216039,1 +83979,937216157,937216413,1 +106769,937216159,937216248,1 +106776,937216160,937216047,1 +106670,937216160,937216570,1 +106661,937216161,937216216,1 +106619,937216167,1540868501,1 +106720,937216173,937216063,1 +106734,937216173,937216470,1 +106698,937216175,361199479,1 +106632,937216176,937216063,1 +106654,937216176,937216470,1 +106667,937216183,937216035,1 +106660,937216183,1540868524,1 +106693,937216193,937216378,1 +106675,937216193,937216379,1 +106768,937216200,937216159,1 +106802,937216207,937216612,1 +106682,937216212,937216001,1 +106653,937216212,937216176,1 +107042,937216214,938140771,1 +106705,937216214,1540868537,1 +106662,937216216,937216051,1 +106657,937216216,937216487,1 +106659,937216220,937216183,1 +106714,937216220,937216530,1 +106626,937216225,1540868503,1 +106697,937216236,1540868534,1 +106738,937216236,1540868549,1 +106736,937216244,937216020,1 +106625,937216244,937216225,1 +106639,937216246,1540868515,1 +106737,937216246,1540868548,1 +106770,937216248,937216482,1 +106649,937216248,1540868522,1 +83975,937216256,1540846805,1 +106766,937216256,1540868567,1 +106690,937216259,937216014,1 +106687,937216259,1540868528,1 +106656,937216261,937216442,1 +106643,937216261,1540868520,1 +106621,937216270,937216487,1 +106637,937216277,1540868509,1 +106799,937216281,937216037,1 +143449,937216283,937216414,1 +106635,937216286,937216421,1 +106695,937216288,937216144,1 +143451,937216288,1540937103,1 +106669,937216310,937216160,1 +106810,937216328,937216167,1 +106673,937216329,294203205,1 +83978,937216333,1540846806,1 +106728,937216333,1540868544,1 +106718,937216336,937216128,1 +143446,937216351,1343074677,1 +143452,937216351,1343076830,1 +106642,937216354,937216261,1 +106631,937216355,937216091,1 +106641,937216355,1540868518,1 +106613,937216375,937216081,1 +51445,937216375,938140757,1 +106712,937216378,937216598,1 +106694,937216378,1540868533,1 +106676,937216379,937216200,1 +106761,937216379,937216582,1 +106664,937216389,937216095,1 +106644,937216395,937216328,1 +106725,937216395,937216436,1 +106704,937216396,937216214,1 +106645,937216397,937216091,1 +84018,937216397,937216151,1 +83980,937216413,1540846807,1 +143450,937216414,937216288,1 +106680,937216414,937216554,1 +106620,937216421,937216270,1 +106808,937216422,937216479,1 +106638,937216425,1540868512,1 +106746,937216425,1540868555,1 +106618,937216436,1540868499,1 +51479,937216440,937216581,1 +106648,937216442,1540868521,1 +106665,937216452,937216075,1 +106679,937216452,937216175,1 +106627,937216455,1540868504,1 +106686,937216455,1540868527,1 +83976,937216460,152803983,1 +106727,937216460,1540868543,1 +106760,937216467,937216159,1 +106804,937216467,1540868575,1 +106655,937216470,937216016,1 +106672,937216479,937216286,1 +106809,937216479,937216328,1 +106771,937216482,361199750,1 +106622,937216487,1540868502,1 +106717,937216492,937216336,1 +106674,937216498,937216193,1 +84017,937216498,1540846862,1 +106630,937216507,937216355,1 +106741,937216507,937365584,1 +106726,937216520,937216138,1 +23988,937216528,294203205,1 +106624,937216530,937216244,1 +106709,937216531,937216110,1 +106801,937216531,1540868574,1 +106616,937216538,937216047,1 +106628,937216542,1540868505,1 +106775,937216549,937216037,1 +106731,937216549,937216110,1 +106722,937216554,937216144,1 +106681,937216554,937216212,1 +106634,937216557,937216286,1 +106685,937216557,1540868526,1 +106745,937216564,1540868554,1 +106724,937216570,937216395,1 +106671,937216570,937216479,1 +106744,937216579,1540868553,1 +51480,937216581,1540815960,1 +107072,937216581,1540868913,1 +106762,937216582,937216354,1 +106647,937216582,937216442,1 +106748,937216587,1540868559,1 +106767,937216598,937216200,1 +106658,937216599,937216220,1 +106773,937216599,937216225,1 +83972,937216608,1540846802,1 +106803,937216612,937216467,1 +106853,937365376,937365481,1 +84022,937365376,937365597,1 +106821,937365377,937365535,1 +106865,937365377,937365577,1 +106778,937365378,937365498,1 +106779,937365378,937365589,1 +106873,937365382,937365602,1 +106859,937365388,361199485,1 +106875,937365388,937365600,1 +106816,937365390,937365404,1 +106863,937365390,937365604,1 +106842,937365396,937365473,1 +106763,937365396,1540868562,1 +106796,937365404,937365462,1 +106844,937365411,937365634,1 +106812,937365420,937216236,1 +106813,937365420,1540868579,1 +106781,937365428,937365473,1 +106795,937365430,937365404,1 +106817,937365430,937365534,1 +106820,937365435,937365377,1 +106792,937365435,937365620,1 +106765,937365437,1540868564,1 +106794,937365446,937365430,1 +106827,937365446,937365604,1 +106846,937365448,937216587,1 +106872,937365448,937365382,1 +106849,937365449,937365563,1 +106787,937365449,937365620,1 +106784,937365450,937365548,1 +23983,937365460,361199274,1 +106834,937365460,1540868588,1 +23986,937365462,938143061,1 +106870,937365463,937365520,1 +106832,937365463,1540868587,1 +106843,937365473,937365411,1 +106782,937365473,937365437,1 +106830,937365476,1540868585,1 +106836,937365476,1540868591,1 +106881,937365480,937365502,1 +106855,937365480,937365563,1 +106854,937365481,937365480,1 +106851,937365498,937365619,1 +106841,937365502,937365396,1 +106777,937365506,937365378,1 +106869,937365506,937365463,1 +106829,937365514,937365476,1 +106848,937365514,937365535,1 +84025,937365516,937216528,1 +106871,937365520,937365411,1 +106823,937365529,361199486,1 +106818,937365534,937365516,1 +106837,937365534,937365565,1 +106822,937365535,937365529,1 +106835,937365547,937365476,1 +106860,937365547,1540868594,1 +106880,937365548,937365480,1 +106785,937365548,937365579,1 +106819,937365553,937365630,1 +106815,937365553,1540868582,1 +106839,937365561,793781809,1 +106850,937365563,937365498,1 +106856,937365563,1540868592,1 +106838,937365565,937365579,1 +106826,937365565,1540868584,1 +106791,937365567,937365435,1 +106867,937365568,937365628,1 +106858,937365568,1540868593,1 +106879,937365577,937365567,1 +106866,937365577,937365568,1 +106786,937365579,937365449,1 +106742,937365584,152803615,1 +106797,937365584,1540868571,1 +84024,937365587,937365516,1 +106825,937365587,937365565,1 +106780,937365589,937365428,1 +106847,937365589,937365520,1 +106783,937365597,937365450,1 +84023,937365597,937365587,1 +106876,937365600,937365529,1 +106878,937365600,937365577,1 +106874,937365602,937365388,1 +106814,937365602,937365553,1 +106864,937365604,937365377,1 +106828,937365604,937365514,1 +106764,937365605,1540868563,1 +106877,937365605,1540868595,1 +106852,937365619,937365396,1 +106788,937365619,937365428,1 +106793,937365620,1540868570,1 +106868,937365628,937365506,1 +106833,937365630,937365382,1 +106789,937365633,937365561,1 +106811,937365634,937365420,1 +106845,937365634,937365448,1 +106790,937365639,937365567,1 +106857,937365639,937365568,1 +106906,937378131,152805030,1 +106892,937378209,1540868640,1 +106886,937378278,355921354,1 +106909,937378278,1540868675,1 +2178,937378304,152805029,1 +107058,938140734,938140786,1 +51469,938140736,1540815958,1 +107053,938140737,938140818,1 +83986,938140737,938140822,1 +107027,938140738,938140808,1 +107064,938140741,1540868912,1 +23976,938140742,938140808,1 +107057,938140743,938140734,1 +51474,938140744,938140771,1 +107077,938140744,1540868917,1 +107060,938140745,938140824,1 +106700,938140746,937216065,1 +107073,938140746,1540868915,1 +51471,938140748,938140752,1 +107094,938140748,938140785,1 +51472,938140752,938140759,1 +107098,938140752,938140776,1 +107066,938140753,938140745,1 +106610,938140753,938140818,1 +107068,938140754,938140774,1 +107088,938140754,938140790,1 +51446,938140757,361199478,1 +107055,938140757,938140791,1 +51476,938140758,361199745,1 +107036,938140758,937216396,1 +51473,938140759,938140744,1 +106706,938140760,938140795,1 +107078,938140760,938140829,1 +107048,938140761,938140806,1 +107090,938140761,938140816,1 +51463,938140765,361199499,1 +107100,938140765,938140802,1 +107087,938140766,937216440,1 +107063,938140766,938140789,1 +107030,938140767,938140770,1 +107039,938140767,938140820,1 +107009,938140768,938140828,1 +107026,938140769,938140738,1 +51459,938140769,938140800,1 +107081,938140770,600927589,1 +51475,938140771,938140758,1 +107047,938140772,361199497,1 +107093,938140772,938140813,1 +107005,938140773,938140783,1 +23980,938140773,1540793879,1 +107069,938140774,938140824,1 +107099,938140776,938140765,1 +107033,938140776,938140827,1 +107035,938140777,938140758,1 +107092,938140777,938140772,1 +107080,938140778,938140770,1 +106702,938140779,937216049,1 +107045,938140779,1540868908,1 +106749,938140780,361199485,1 +107075,938140781,600927581,1 +106612,938140781,1540868497,1 +107006,938140783,938140787,1 +106708,938140785,938140736,1 +107095,938140785,938140810,1 +107059,938140786,938140745,1 +107043,938140786,938140793,1 +107089,938140787,938140761,1 +106747,938140789,937216587,1 +107041,938140790,937216214,1 +107056,938140791,938140743,1 +107074,938140791,1540868916,1 +83990,938140792,600927588,1 +143454,938140792,1540937106,1 +107071,938140793,938140774,1 +107044,938140793,938140779,1 +107076,938140795,938140759,1 +106707,938140795,1540868538,1 +23979,938140797,938140773,1 +107082,938140797,938140806,1 +51460,938140800,361199498,1 +107097,938140800,1540868918,1 +23973,938140802,1540793877,1 +83993,938140803,361199623,1 +107049,938140806,938140738,1 +107083,938140806,938140809,1 +23977,938140808,938142923,1 +107084,938140809,938140819,1 +51457,938140809,1540815952,1 +107096,938140810,938140803,1 +106609,938140812,938140753,1 +107038,938140812,938140767,1 +107086,938140813,938140766,1 +51462,938140815,938140765,1 +107028,938140815,938140827,1 +51456,938140816,938140809,1 +107054,938140818,938140734,1 +106611,938140818,1540868496,1 +107052,938140819,938140780,1 +107085,938140819,938140813,1 +107062,938140820,938140778,1 +107040,938140820,938140790,1 +83987,938140822,600927584,1 +107065,938140822,938140753,1 +107061,938140824,938140820,1 +107032,938140826,938140776,1 +51467,938140826,1540815956,1 +107034,938140827,938140768,1 +107029,938140827,1540868906,1 +107010,938140828,938140771,1 +107091,938140828,938140777,1 +107079,938140829,938140778,1 +107070,938140829,938140810,1 +107361,938142799,938140736,1 +107399,938142799,938143046,1 +107244,938142801,938142997,1 +107259,938142801,938143154,1 +107176,938142803,938143059,1 +107238,938142803,938143118,1 +107306,938142805,938143026,1 +107390,938142807,938143016,1 +107371,938142809,1540868971,1 +107329,938142811,938143008,1 +107104,938142813,938142854,1 +80573,938142813,938142908,0 +107376,938142814,600927598,1 +98177,938142815,938143135,1 +107303,938142816,938142882,1 +107112,938142816,938143014,1 +84006,938142829,600927600,1 +107334,938142829,938143133,1 +107378,938142830,938143047,1 +107302,938142832,938142816,1 +107392,938142832,938142970,1 +107406,938142833,294203215,1 +107266,938142833,938143140,1 +107357,938142836,1193517423,1 +107566,938142836,1540869046,1 +98192,938142839,1540861284,1 +107229,938142841,938143051,1 +23962,938142843,294184526,1 +107236,938142843,938142900,1 +127665,938142848,600205197,1 +107131,938142849,938142943,1 +107209,938142850,600927592,1 +107359,938142850,938143033,1 +107031,938142852,938140826,1 +107217,938142852,938142917,1 +107105,938142854,938142981,1 +107293,938142854,938143036,1 +107370,938142856,1540868970,1 +107327,938142858,938143039,1 +107156,938142858,938143153,1 +107198,938142860,600927600,1 +107400,938142860,938143053,1 +107374,938142867,938142987,1 +107323,938142869,938142968,1 +107316,938142870,938142961,1 +107355,938142879,938143062,1 +107188,938142879,1540868934,1 +107304,938142882,938143156,1 +107270,938142885,938142892,1 +107139,938142885,938143057,1 +107350,938142886,938143016,1 +107383,938142886,938143029,1 +127664,938142888,938142848,1 +107199,938142888,938142958,1 +107275,938142890,600927594,1 +107185,938142890,938143126,1 +107309,938142892,938143098,1 +23971,938142896,361199504,1 +107252,938142896,1540868953,1 +107272,938142898,938143063,1 +107336,938142898,938143066,1 +107308,938142899,938142892,1 +107163,938142899,938143067,1 +107377,938142900,938142830,1 +107237,938142900,1540868949,1 +107380,938142901,938142979,1 +127656,938142901,938143030,1 +107339,938142903,938143035,1 +127651,938142904,938143086,1 +107115,938142904,938143139,1 +51433,938142905,361199004,1 +107149,938142905,938143070,1 +107106,938142906,938143082,1 +107012,938142906,938143101,1 +51466,938142907,1540815955,1 +80574,938142908,938142922,0 +107248,938142909,938143073,1 +107368,938142910,938143006,1 +107205,938142912,1540868937,1 +127681,938142912,1540885254,1 +107174,938142913,938142841,1 +107150,938142913,1540868923,1 +107193,938142915,938143078,1 +127650,938142916,600205200,1 +107164,938142916,1540868932,1 +107233,938142917,938143037,1 +107292,938142918,938142854,1 +107190,938142918,938143019,1 +107114,938142919,938142904,1 +127660,938142919,938143088,1 +127662,938142920,938143089,1 +107280,938142920,938143094,1 +107315,938142922,938142870,1 +80575,938142922,938143120,0 +23978,938142923,938140797,1 +107389,938142923,938142807,1 +107183,938142924,938143023,1 +84002,938142924,1540846822,1 +98194,938142925,797394761,1 +107168,938142925,938143138,1 +107143,938142926,938143089,1 +107103,938142926,938143094,1 +98184,938142929,1540861280,1 +107379,938142931,938142901,1 +107147,938142931,938143100,1 +127654,938142932,361199004,1 +107312,938142932,938143070,1 +51437,938142933,938142940,1 +107296,938142933,1540868956,1 +107260,938142934,938143045,1 +107326,938142934,1540868963,1 +107283,938142935,938143003,1 +107172,938142935,938143140,1 +107246,938142936,938143107,1 +107221,938142936,938143124,1 +80569,938142939,938143136,0 +107353,938142940,938142978,1 +51438,938142940,938143049,1 +106861,938142941,294203207,1 +107321,938142941,938143111,1 +107358,938142943,938142850,1 +107132,938142943,938143092,1 +107178,938142944,938142860,1 +107362,938142944,938143047,1 +107247,938142945,938142909,1 +107191,938142945,938143107,1 +107265,938142946,938143050,1 +107215,938142947,938142915,1 +107220,938142947,938142936,1 +107195,938142948,938143034,1 +107290,938142948,1540868955,1 +127632,938142954,938149120,1 +80579,938142955,600205197,0 +107101,938142955,938143131,1 +107397,938142956,938143133,1 +107346,938142956,938143143,1 +107332,938142957,938142989,1 +107341,938142957,938143053,1 +107250,938142958,938143068,1 +107200,938142958,938143072,1 +98181,938142959,938143044,1 +107289,938142959,938143108,1 +107126,938142961,938143086,1 +107317,938142961,938143139,1 +107373,938142962,1540868974,1 +107320,938142963,938142941,1 +127640,938142963,938143002,1 +107299,938142964,938143059,1 +107403,938142965,361199006,1 +107145,938142965,938143142,1 +107166,938142966,938143068,1 +107343,938142966,938143072,1 +107351,938142968,938142997,1 +107324,938142968,938143146,1 +107277,938142969,938143119,1 +98191,938142970,938142839,1 +107393,938142970,938143149,1 +107282,938142972,938142935,1 +107382,938142972,938142993,1 +107122,938142973,938149176,1 +107264,938142973,1540868954,1 +107141,938142974,1540868922,1 +107224,938142974,1540868946,1 +107331,938142976,938142957,1 +107279,938142976,938143085,1 +107396,938142977,938142956,1 +107226,938142977,938143121,1 +107175,938142978,938143122,1 +107354,938142978,938143156,1 +107381,938142979,938142972,1 +107255,938142979,938143012,1 +127614,938142981,938142805,1 +107118,938142981,938143019,1 +107372,938142984,1540868973,1 +89076,938142985,294163842,0 +107231,938142986,938143104,1 +107375,938142987,938142814,1 +107285,938142987,938143132,1 +107333,938142989,938143034,1 +98179,938142990,938143096,1 +107262,938142990,938143105,1 +107268,938142993,938143150,1 +107142,938142994,938142969,1 +127659,938142994,1540885239,1 +107245,938142997,1540868952,1 +107153,938142998,938143112,1 +107298,938142998,1540868957,1 +107165,938143004,938142966,1 +107158,938143004,938143079,1 +107369,938143006,938142856,1 +107109,938143006,938143008,1 +107483,938143007,938143110,1 +107330,938143008,1540868966,1 +107256,938143012,938143057,1 +51435,938143012,938143150,1 +107366,938143013,938143153,1 +127608,938143014,938143136,1 +107120,938143014,938143149,1 +107124,938143015,938143138,1 +107391,938143016,1540868976,1 +107405,938143017,938142833,1 +107253,938143017,938143077,1 +127629,938143019,938142882,1 +107119,938143019,938143014,1 +107301,938143022,938140773,1 +107349,938143022,938142886,1 +107184,938143023,938142890,1 +107395,938143023,938142977,1 +107288,938143024,938142869,1 +107307,938143026,938142899,1 +107295,938143026,938142933,1 +98193,938143027,938142925,1 +107206,938143027,1540868939,1 +107394,938143029,938142832,1 +107384,938143029,938142839,1 +127657,938143030,361199006,1 +107170,938143030,938143077,1 +107014,938143032,361199624,1 +107243,938143032,938142801,1 +107360,938143033,938142799,1 +107388,938143033,938143084,1 +107196,938143034,938143040,1 +107216,938143035,938142852,1 +107340,938143035,938142907,1 +107294,938143036,938142870,1 +127631,938143036,938142908,1 +107387,938143037,938143033,1 +107234,938143037,938143046,1 +107180,938143038,797394862,1 +127624,938143038,938143074,1 +107328,938143039,938142811,1 +107284,938143039,938142910,1 +107197,938143040,938142860,1 +107187,938143040,938142879,1 +107338,938143042,938142903,1 +107173,938143042,938142913,1 +107263,938143044,361199273,1 +98182,938143044,938143069,1 +107261,938143045,938143013,1 +107235,938143046,361199622,1 +107363,938143047,294184526,1 +51439,938143049,361199010,1 +107110,938143049,938143122,1 +80568,938143050,938142939,0 +107130,938143051,938142849,1 +107230,938143051,938142986,1 +107401,938143053,938143119,1 +127136,938143056,361199003,1 +107129,938143056,938143131,1 +107257,938143057,938143123,1 +127628,938143058,361199274,1 +107291,938143058,938142929,1 +107300,938143059,938142830,1 +107177,938143059,938142944,1 +23987,938143061,937216528,1 +107356,938143062,938142836,1 +107152,938143062,938142998,1 +107345,938143063,938142956,1 +107273,938143063,938143121,1 +80577,938143065,1540843269,0 +107162,938143066,938143091,1 +107337,938143066,1540868967,1 +107117,938143067,938142981,1 +127630,938143067,938143036,1 +107167,938143068,938142848,1 +107251,938143068,938143134,1 +98183,938143069,938142929,1 +107347,938143069,938143147,1 +107313,938143070,938143124,1 +107201,938143072,938143079,1 +107344,938143072,1193517426,1 +107249,938143073,938142958,1 +127625,938143074,938143111,1 +107171,938143077,938142935,1 +107254,938143077,938142979,1 +107194,938143078,938142948,1 +107151,938143078,938143062,1 +107159,938143079,938502012,1 +107202,938143079,1144399715,1 +107018,938143080,1540868892,1 +143441,938143080,1540937095,1 +107352,938143081,938142940,1 +107212,938143081,1540868941,1 +107287,938143082,938143024,1 +107107,938143082,938143071,1 +83996,938143084,938143113,1 +107214,938143085,938142947,1 +107127,938143086,938143088,1 +127652,938143086,938143120,1 +107225,938143087,938142977,1 +84003,938143087,1343049092,1 +107128,938143088,938143056,1 +127661,938143088,938143065,1 +127663,938143089,938142888,1 +107144,938143089,938143073,1 +23968,938143091,361198981,1 +83999,938143092,1540846817,1 +107319,938143093,938142963,1 +98216,938143093,1540861287,1 +107281,938143094,361199003,1 +98180,938143096,938142959,1 +107219,938143096,938143074,1 +107386,938143098,938142904,1 +107310,938143098,938143123,1 +107318,938143099,938143093,1 +107148,938143100,938142905,1 +107213,938143100,938143085,1 +107013,938143101,938143032,1 +107322,938143101,1540868959,1 +107342,938143102,938142966,1 +80582,938143102,938143144,0 +107208,938143104,938142850,1 +107232,938143104,938142917,1 +106756,938143105,938143125,1 +107192,938143107,938142915,1 +106755,938143108,938143105,1 +107297,938143110,938142998,1 +107484,938143110,938502099,1 +127626,938143111,361199273,1 +107240,938143112,1343037582,1 +83997,938143113,600927592,1 +107385,938143113,938143071,1 +107140,938143115,938142974,1 +107155,938143115,1540868926,1 +107239,938143118,1540868951,1 +107402,938143119,938142965,1 +107278,938143119,938142976,1 +80576,938143120,938143065,0 +107274,938143121,938142890,1 +107227,938143121,1540868947,1 +107111,938143122,938142816,1 +107258,938143123,938142919,1 +107311,938143123,938142932,1 +107222,938143124,938142920,1 +107314,938143124,1540868958,1 +107207,938143125,938142815,1 +106757,938143125,1540868561,1 +107186,938143126,938142849,1 +107160,938143126,1540868928,1 +107189,938143130,938142918,1 +80571,938143130,1540843268,0 +107102,938143131,938142926,1 +107286,938143132,938142927,1 +107154,938143132,1540868924,1 +107335,938143133,938142898,1 +80581,938143134,938143102,0 +127646,938143134,938502120,1 +98178,938143135,938142990,1 +107179,938143135,938143038,1 +80570,938143136,938143130,0 +107125,938143138,938142954,1 +127641,938143138,938149178,1 +107116,938143139,938143067,1 +107267,938143140,938142993,1 +107146,938143142,938142931,1 +107169,938143142,938143030,1 +84005,938143143,938142829,1 +80583,938143144,600205200,0 +107157,938143144,938143004,1 +107325,938143146,938142934,1 +107218,938143146,1540868942,1 +107348,938143147,938143022,1 +106754,938143147,938143108,1 +127613,938143149,938142939,1 +107121,938143149,938142973,1 +107269,938143150,938142885,1 +51436,938143150,938142933,1 +107367,938143153,938142910,1 +107365,938143154,1540868968,1 +107161,938143155,1540868929,1 +107228,938143155,1540868948,1 +107305,938143156,938142805,1 +107443,938149074,938149123,1 +80563,938149075,1540843267,0 +51424,938149076,361198932,1 +80567,938149077,938143050,0 +106759,938149078,938142954,1 +107438,938149078,938149162,1 +107134,938149080,938149090,1 +107421,938149086,938149180,1 +107413,938149086,938149185,1 +98066,938149090,938149139,1 +107135,938149090,938502170,1 +98070,938149094,938149121,1 +107430,938149094,938149174,1 +107458,938149096,938149125,1 +107460,938149096,938149188,1 +107441,938149098,938143015,1 +107419,938149098,938149148,1 +107455,938149102,797375871,1 +107431,938149102,938149074,1 +80565,938149108,600205192,0 +107453,938149110,938149121,1 +107433,938149110,938149157,1 +107417,938149111,938149075,1 +107446,938149113,938149076,1 +107459,938149113,1540868981,1 +107439,938149120,938149178,1 +127633,938149120,1540885234,1 +98071,938149121,938149186,1 +51427,938149122,361198936,1 +107457,938149122,938149096,1 +107432,938149123,938149110,1 +107444,938149123,1540868979,1 +98068,938149125,938149187,1 +107450,938149127,797394787,1 +107427,938149127,938149111,1 +107435,938149131,938149080,1 +107426,938149131,938149142,1 +98067,938149139,938149125,1 +107425,938149139,938149131,1 +98160,938149140,938142954,1 +107416,938149140,938149111,1 +98141,938149141,1540861273,1 +2821,938149142,1540773404,0 +107420,938149148,938142946,1 +107437,938149148,1540868977,1 +107505,938149149,1540869012,1 +107418,938149151,938149098,1 +127643,938149151,1540885235,1 +2822,938149155,338485834,0 +107452,938149155,938149110,1 +107412,938149156,938149086,1 +107423,938149156,1145611279,1 +107434,938149157,938149131,1 +107454,938149158,938149102,1 +2824,938149158,1540773406,0 +107448,938149160,938149082,1 +98175,938149162,797394789,1 +51426,938149168,938149122,1 +107407,938149168,938149189,1 +107123,938149176,938143015,1 +107436,938149176,938149148,1 +127642,938149178,938149151,1 +107422,938149180,938149082,1 +107409,938149180,938149149,1 +107411,938149184,938149156,1 +107428,938149184,938149189,1 +107414,938149185,938502132,1 +127688,938149185,1145611271,1 +98072,938149186,797375615,1 +107445,938149186,1540868980,1 +98069,938149187,938149094,1 +107451,938149187,938149157,1 +107137,938149188,338485831,1 +107429,938149189,938149160,1 +107408,938149189,938149180,1 +125364,938501936,361198448,1 +127156,938501936,1540884984,0 +107607,938501939,938502376,1 +127645,938501939,1540885237,1 +107511,938501942,938502149,1 +89991,938501942,938502230,1 +107490,938501947,938502072,1 +107591,938501947,1144399675,1 +107612,938501948,938502237,1 +127107,938501950,938502299,1 +127119,938501950,1540884976,0 +107510,938501951,938502238,1 +107485,938501953,1145611281,1 +80585,938501953,1540843272,0 +89998,938501955,938502333,1 +127104,938501957,938502207,0 +107560,938501957,1540869042,1 +89078,938501961,1540852165,0 +107621,938501962,938502063,1 +107569,938501962,938502170,1 +107603,938501966,938502227,1 +127133,938501975,600205115,1 +107577,938501979,938502182,1 +107594,938501979,938502261,1 +107580,938501987,653316955,0 +127213,938501987,653316979,1 +126440,938501991,581260958,1 +126445,938501993,938502083,1 +127164,938501993,938502102,1 +107571,938501996,653317095,0 +107563,938501996,938502399,1 +127194,938501997,1540884999,0 +99931,938502011,938501936,1 +107475,938502011,938502321,1 +107472,938502022,938502054,1 +107573,938502022,938502342,1 +89989,938502027,938502258,1 +89081,938502036,1540852170,0 +23959,938502038,1540793872,0 +23910,938502040,938502157,0 +107489,938502041,938501950,0 +127122,938502041,938502414,0 +126442,938502042,803745242,1 +107494,938502042,1540868993,1 +107598,938502048,653316912,0 +107539,938502048,1540869030,0 +2808,938502049,365309670,0 +107572,938502050,938502022,1 +107537,938502050,938502376,1 +107549,938502063,938502161,1 +2811,938502072,938502120,0 +107593,938502076,938501979,1 +107474,938502080,938502049,1 +107587,938502080,938502359,1 +126446,938502083,1540884444,1 +2819,938502084,338485833,0 +107204,938502098,1540868936,1 +107487,938502098,1540868991,1 +127165,938502102,938502207,1 +90000,938502105,938502259,1 +23908,938502108,938502173,0 +107535,938502108,938502258,1 +23954,938502114,365310391,1 +107488,938502114,938502041,0 +127647,938502120,938502076,1 +2812,938502120,1540773400,0 +107473,938502123,1540868986,1 +107529,938502124,938501991,1 +107495,938502124,1540868997,1 +134588,938502130,797375713,0 +99929,938502132,938502284,1 +107415,938502132,1145611285,1 +107553,938502134,938502285,1 +107567,938502134,1540869048,1 +107496,938502135,1540868998,1 +107516,938502135,1540869016,1 +107471,938502136,938502022,1 +107493,938502136,938502178,1 +107470,938502146,938502136,1 +107541,938502146,938502209,1 +107512,938502149,938502201,1 +90034,938502149,938502303,1 +2814,938502152,600205115,0 +107518,938502152,938502405,1 +48458,938502155,938502410,0 +23911,938502157,294163207,0 +107508,938502157,938502240,1 +107550,938502161,938149090,1 +107619,938502161,938502084,1 +107479,938502165,1540868990,0 +107136,938502170,938149188,1 +23909,938502173,938502040,0 +107616,938502176,938502102,1 +107521,938502178,938502342,1 +107517,938502181,938502083,1 +107499,938502181,938502332,1 +107606,938502182,938501939,1 +23916,938502187,294145226,0 +107534,938502187,1540869029,0 +127179,938502191,938502040,1 +89994,938502191,938502240,1 +126444,938502196,938501993,1 +107548,938502197,938502063,1 +90025,938502201,938502324,1 +107513,938502201,938502370,1 +107503,938502202,938502130,1 +48457,938502202,938502155,0 +107590,938502206,938501947,1 +127115,938502207,938502414,0 +107542,938502209,361199000,1 +107520,938502209,938502178,1 +107482,938502212,938143007,1 +89079,938502212,1540852168,0 +127121,938502215,938502041,0 +106596,938502215,938502387,1 +134587,938502218,938502130,0 +107515,938502218,938502410,1 +51343,938502219,1145611285,1 +107557,938502222,1540869038,1 +127214,938502222,1540885037,1 +23901,938502224,294163568,0 +107600,938502224,938502252,1 +107559,938502227,938502206,1 +107604,938502227,1144399667,1 +107545,938502228,938502272,1 +107507,938502230,938502173,1 +89992,938502230,938502349,1 +107613,938502237,1540869063,1 +107544,938502238,938502228,1 +89995,938502240,653316919,1 +127131,938502250,361199000,1 +107575,938502250,938501963,1 +89072,938502252,1540852153,0 +107601,938502252,1540869060,1 +89990,938502258,938501942,1 +90001,938502259,1540853803,1 +107595,938502261,1540869058,1 +107546,938502272,1145611251,1 +107491,938502272,1540868992,1 +107555,938502278,365309669,1 +107596,938502278,938502405,1 +89997,938502280,938501955,1 +107506,938502284,938502219,1 +99930,938502284,1540862331,1 +127199,938502287,653316929,1 +127210,938502287,653316957,1 +107476,938502297,938502027,1 +23907,938502297,1540793801,0 +107514,938502299,938502031,1 +127108,938502299,938502348,1 +127693,938502300,361198943,1 +107576,938502300,938502228,1 +90035,938502303,653317557,1 +89080,938502304,1540852169,0 +107574,938502304,1540869052,1 +115329,938502307,984634572,1 +2817,938502312,938502368,0 +2810,938502319,938502072,0 +107618,938502319,938502345,1 +51340,938502321,1540815939,1 +107614,938502324,653317438,1 +90026,938502324,938502404,1 +127193,938502331,1540884998,1 +126438,938502332,803745116,1 +89999,938502333,938502105,1 +23896,938502337,1540793788,0 +107522,938502342,1144399672,1 +107498,938502343,1540869006,1 +107552,938502343,1540869031,1 +107589,938502345,938502206,1 +107525,938502346,1540869020,1 +107568,938502346,1540869050,0 +107583,938502349,653316914,1 +89993,938502349,938502191,1 +90014,938502353,653317286,1 +107588,938502359,938502345,1 +107538,938502363,938502048,0 +90008,938502363,938502385,0 +2818,938502368,938502084,0 +107504,938502368,1540869010,1 +107565,938502370,1540869045,1 +107540,938502376,938502146,1 +107554,938502376,1540869032,1 +90005,938502385,653316913,1 +90009,938502385,653316919,0 +107526,938502386,1540869021,1 +107556,938502386,1540869033,1 +127120,938502387,360477147,0 +106597,938502387,656189124,1 +107509,938502392,938501951,1 +2816,938502392,938502312,0 +107497,938502398,1540869001,1 +115362,938502398,1540874493,1 +90030,938502399,653317097,0 +107564,938502399,938502370,1 +90028,938502400,653317099,0 +107579,938502400,938501987,0 +107536,938502401,938501951,1 +107492,938502401,938502312,1 +90027,938502404,1540853828,1 +143203,938502404,1540936646,1 +107597,938502405,938501975,1 +107519,938502405,1540869019,1 +48459,938502410,360476870,0 +127123,938502414,938502083,0 +127116,938502414,1540884975,0 +75384,939551644,250929231,1 +65123,939569799,1540835030,0 +75448,939570206,559494656,0 +107733,939593933,1540869418,0 +107739,939593933,1540869439,0 +107731,939593944,1540869416,0 +107732,939593956,1540869417,0 +107736,939593956,1540869425,0 +107740,939593999,1540869441,0 +107743,939593999,1540869448,0 +98682,939594027,1540861506,0 +107737,939594027,1540869432,1 +107734,939594028,939594136,0 +107742,939594028,1540869447,0 +118131,939594062,1540876500,0 +107730,939594136,360015820,0 +107735,939594136,1540869419,0 +107845,940610994,940611031,1 +109978,940610994,966314687,1 +107852,940610999,940611038,1 +107829,940610999,940611048,1 +107842,940611001,940611022,1 +110024,940611001,1540871221,1 +107836,940611003,940611044,1 +109930,940611003,1540871167,1 +107848,940611005,940611024,1 +107832,940611007,940611046,1 +109922,940611007,1540871161,1 +107828,940611011,940610999,1 +107847,940611011,1540869552,1 +110021,940611017,966315508,1 +107835,940611019,940611003,1 +110007,940611019,1540871210,1 +107843,940611022,536600488,1 +107849,940611024,1540869554,1 +110044,940611024,1540871244,1 +107846,940611031,940611011,1 +107851,940611031,1540869555,1 +110046,940611038,966314782,1 +107850,940611040,940611031,1 +109936,940611040,1540871169,1 +107837,940611044,940611017,1 +107833,940611046,966314731,1 +110026,940611046,1540871223,1 +107830,940611048,966314755,1 +81044,940611048,1540844198,1 +107983,952160960,1540869747,0 +107980,952161029,952161374,0 +107997,952161076,1540869759,0 +119217,952161076,1540878537,1 +107932,952161109,1540869653,1 +107963,952161109,1540869707,0 +107941,952161121,278009624,1 +107948,952161121,1540869658,1 +107995,952161163,952161785,0 +119265,952161163,1540878602,1 +107984,952161183,1030688867,0 +119185,952161183,1030689651,0 +107947,952161209,952161121,1 +107930,952161231,952161299,1 +107970,952161231,952161411,1 +107987,952161259,952161551,1 +107966,952161259,1540869712,0 +107954,952161298,1540869669,0 +107982,952161299,1540869746,0 +107933,952161319,952161029,1 +107981,952161374,1540869742,0 +107991,952161380,952161411,1 +107934,952161380,952161551,1 +107931,952161384,952161850,1 +142570,952161384,1540934767,1 +107971,952161411,952161842,1 +107950,952161425,278009627,1 +107965,952161425,1540869710,0 +142577,952161496,278009630,1 +107988,952161551,952161635,1 +107935,952161551,1540869654,1 +107967,952161554,278009621,1 +107993,952161554,1540869755,0 +107946,952161559,952161209,1 +107964,952161559,1540869708,0 +107973,952161584,952161374,1 +107962,952161584,1540869706,0 +107990,952161635,952161380,1 +107989,952161635,952161496,1 +107929,952161690,1540869651,1 +107961,952161690,1540869704,0 +107994,952161739,1540869756,0 +107979,952161779,952161029,0 +107939,952161779,1030688937,1 +107996,952161785,1540869757,0 +119763,952161806,1036415701,1 +107992,952161806,1540869753,0 +107972,952161842,952160960,1 +107938,952161846,952161779,1 +107955,952161846,1540869674,0 +107949,952161850,1540869660,1 +142575,952161852,1030975549,1 +107937,952161857,952161846,1 +119184,952161861,952161183,0 +107953,952161861,1540869664,0 +108627,956787101,961664602,1 +40187,956787101,1540809939,1 +108650,956787111,961664432,1 +108189,956787111,1540869842,1 +108649,956789170,360016395,1 +108624,956789196,956789199,1 +108625,956789199,956789202,1 +108626,956789202,1540870093,1 +108425,959695087,360468284,1 +47859,959695087,706821907,1 +108639,961664417,961664432,1 +108648,961664417,1540870103,1 +108645,961664425,961664649,1 +108660,961664425,1540870109,1 +108656,961664431,1540870105,1 +108667,961664431,1540870116,1 +108651,961664432,961664617,1 +108640,961664432,1540870097,1 +108615,961664434,474383589,1 +108671,961664434,1540870118,1 +108621,961664439,961664414,1 +108668,961664439,961664716,1 +108190,961664455,956789196,1 +119656,961664455,961664746,1 +108620,961664464,961664749,1 +108654,961664491,961664559,1 +108187,961664543,528505102,1 +108657,961664543,1540870108,1 +108628,961664550,1540870094,1 +108613,961664559,961664678,1 +108631,961664583,528505111,1 +108659,961664583,961664425,1 +2267,961664584,1540771785,1 +108619,961664602,961664713,1 +108635,961664603,961664699,1 +108609,961664603,1540870087,1 +108618,961664608,1540870091,1 +108630,961664610,961664583,1 +108641,961664610,961664690,1 +108638,961664611,961664417,1 +108634,961664617,961664550,1 +108646,961664649,528505112,1 +108652,961664649,961664738,1 +108633,961664653,956789199,1 +108614,961664678,961664434,1 +108637,961664678,961664611,1 +108642,961664690,1540870102,1 +40191,961664697,528505105,1 +108658,961664697,961664583,1 +108636,961664699,961664439,1 +108643,961664710,956789202,1 +108612,961664710,961664653,1 +108647,961664713,961664417,1 +108669,961664716,961664608,1 +108644,961664716,961664699,1 +108653,961664738,956789196,1 +119657,961664746,359998407,1 +108632,961664746,961664653,1 +2265,961664749,360015510,1 +46131,963987465,1540812388,0 +46162,963987470,1540812428,0 +149059,963987470,1540950742,0 +149060,963987494,1540950750,0 +109061,965013869,1540870363,1 +109062,965013872,1333878542,1 +109071,965013909,1196620816,1 +141143,965013909,1540929430,1 +141114,965013913,1333877820,1 +109101,965140463,965140641,1 +109197,965140463,1540870560,1 +109103,965140596,965140899,1 +109102,965140641,965140596,1 +109104,965140899,965140833,1 +109231,965140899,1540870625,1 +109462,965323843,1540870813,1 +109464,965324220,1540870821,1 +109461,965324248,965323843,1 +109554,965324248,1540870898,1 +109696,965332005,966154132,1 +109579,965332081,1540870920,1 +109727,965332081,1540871029,1 +109881,965332085,966153823,1 +109718,966153694,966153747,1 +109723,966153694,966154090,1 +109694,966153747,966153947,1 +109719,966153747,1540871027,1 +109726,966153751,965332081,1 +109463,966153823,1540870816,1 +37558,966153833,1540806329,1 +109720,966153833,1540871028,1 +109816,966153870,1540871092,1 +109692,966153913,966154113,1 +37559,966153913,1540806330,1 +109698,966153921,966153823,1 +109707,966153921,966154161,1 +109695,966153947,1540871015,1 +109739,966153947,1540871036,1 +109725,966153997,966153751,1 +109738,966153997,966153947,1 +109766,966153998,966154162,1 +109714,966153998,1540871024,1 +109712,966154033,966154044,1 +109740,966154033,966154103,1 +109713,966154044,1540871022,1 +109737,966154073,965332005,1 +109756,966154073,966154161,1 +109764,966154079,966154113,1 +109721,966154079,966154134,1 +109817,966154088,363986467,1 +109999,966154088,966314837,1 +109724,966154090,966153997,1 +109762,966154090,1540871057,1 +109755,966154103,966154073,1 +109741,966154103,1540871037,1 +109693,966154113,966153747,1 +109765,966154113,1540871058,1 +37560,966154120,1540806331,1 +109665,966154132,966153661,1 +109697,966154132,966153921,1 +109722,966154134,966153694,1 +109757,966154161,965324220,1 +109708,966154161,966153870,1 +41214,966278600,966279126,1 +109789,966278600,966279197,1 +41219,966278722,360019603,1 +41205,966278873,360020008,1 +109795,966278873,966278722,1 +41202,966279082,360020007,1 +41215,966279126,360020043,1 +109788,966279126,966279082,1 +110229,966279430,1540871345,1 +41218,966279528,966278722,1 +41212,966279531,360019602,1 +109790,966279531,967199541,1 +41204,966279592,966278873,1 +109775,966279592,966279528,1 +109883,966294201,363986460,1 +109814,966294252,363986466,1 +109900,966294252,966294204,1 +109878,966294311,966294412,1 +109813,966294340,1540871088,1 +109877,966294352,966294311,1 +109880,966294375,965332085,1 +109867,966294375,966294218,1 +109879,966294412,966294375,1 +109824,966303886,363986997,1 +37562,966303920,583435260,1 +109902,966303920,1540871138,1 +109822,966303953,583435305,1 +110055,966314660,966315093,1 +110013,966314669,966314954,1 +109996,966314669,1540871204,1 +109970,966314671,1540871190,1 +110015,966314674,1540871216,1 +110034,966314674,1540871230,1 +109916,966314675,966315123,1 +109942,966314675,1540871173,1 +109964,966314681,966314901,1 +109987,966314681,966315504,1 +109954,966314683,966314894,1 +109735,966314683,1540871035,1 +109979,966314687,966314956,1 +109975,966314687,966315310,1 +110057,966314689,966315424,1 +109988,966314691,966315140,1 +110040,966314697,1540871239,1 +111718,966314697,1540872187,1 +110019,966314702,1540871217,1 +110020,966314710,940611017,1 +109907,966314710,940611044,1 +107834,966314731,940611019,1 +109920,966314731,966314936,1 +110032,966314733,1540871229,1 +109927,966314738,536600472,1 +109904,966314738,1540871146,1 +109938,966314744,966315072,1 +109906,966314744,1540871148,1 +109918,966314749,966314763,1 +110005,966314749,966315275,1 +107831,966314755,1540869545,1 +109982,966314755,1540871194,1 +109974,966314758,528489831,1 +109733,966314758,1540871033,1 +37570,966314760,1540806335,1 +109919,966314763,1540871159,1 +110011,966314763,1540871214,1 +110045,966314776,940611038,1 +110059,966314776,966303886,1 +110012,966314778,966314669,1 +110018,966314778,966314702,1 +81042,966314782,1540844193,1 +110047,966314782,1540871246,1 +37564,966314786,1540806332,1 +109960,966314788,966315097,1 +109962,966314797,1540871182,1 +110000,966314797,1540871208,1 +109957,966314811,966315271,1 +109951,966314811,1540871180,1 +110117,966314812,967199365,1 +71737,966314817,1540838987,1 +110029,966314820,972316194,1 +109921,966314822,940611007,1 +110049,966314822,966315156,1 +109931,966314827,1540871168,1 +109953,966314837,966314683,1 +107839,966314842,966315207,1 +109993,966314846,966315217,1 +109946,966314846,966315482,1 +110048,966314850,966314822,1 +109968,966314850,1540871186,1 +37567,966314856,583435264,1 +110042,966314859,966315418,1 +110036,966314859,1540871235,1 +109991,966314861,966315162,1 +109929,966314861,1540871166,1 +109914,966314878,1540871158,1 +111613,966314878,1540872110,1 +109959,966314880,966314788,1 +109915,966314889,966314675,1 +109949,966314892,966315160,1 +109955,966314894,966314862,1 +109743,966314894,966315015,1 +109934,966314901,966314956,1 +109965,966314901,966315310,1 +109924,966314911,966315167,1 +110014,966314954,966314733,1 +110031,966314954,1540871228,1 +109935,966314956,940611040,1 +109980,966314956,966315066,1 +109972,966314986,966315214,1 +110002,966315015,966314708,1 +109933,966315029,966314901,1 +111721,966315029,1540872188,1 +110041,966315059,1540871242,1 +109995,966315062,966314669,1 +109977,966315062,966315129,1 +109986,966315066,966314681,1 +109981,966315066,966315152,1 +109945,966315072,966314846,1 +109939,966315072,1540871170,1 +109908,966315087,1540871150,1 +109963,966315090,1540871183,1 +110056,966315093,966314689,1 +110003,966315093,966315316,1 +109937,966315096,966314744,1 +109961,966315097,966314797,1 +109971,966315097,966314986,1 +110039,966315100,966314697,1 +109913,966315100,1540871157,1 +109917,966315123,966314749,1 +110023,966315123,1540871220,1 +110017,966315124,966314778,1 +109997,966315124,966315181,1 +109983,966315125,1540871197,1 +110016,966315129,966315124,1 +109909,966315140,1540871154,1 +109989,966315140,1540871198,1 +110038,966315152,1540871238,1 +110050,966315156,966315381,1 +109948,966315156,1540871178,1 +109950,966315160,966314811,1 +109992,966315162,966314846,1 +109905,966315162,1540871147,1 +109925,966315167,966315482,1 +110035,966315167,1540871232,1 +109923,966315181,966314911,1 +109998,966315181,1540871207,1 +107840,966315207,1540869550,1 +110009,966315214,966314689,1 +109973,966315214,966314758,1 +78928,966315215,1540841154,1 +110033,966315217,966314674,1 +109994,966315217,966315062,1 +81045,966315271,966315189,1 +109944,966315275,1540871176,1 +109966,966315310,940611022,1 +109976,966315310,1540871192,1 +109940,966315316,966315424,1 +110004,966315316,1540871209,1 +110001,966315323,966315015,1 +109734,966315323,1540871034,1 +109956,966315332,966315342,1 +81043,966315332,1540844195,1 +110051,966315381,966315511,1 +109821,966315404,1540871096,1 +110058,966315418,940611005,1 +110043,966315418,1540871243,1 +109941,966315424,966314675,1 +110006,966315440,940611019,1 +110053,966315440,966315447,1 +78929,966315443,1540841160,1 +110054,966315447,966314660,1 +111683,966315458,972315255,1 +109926,966315482,966314738,1 +109947,966315482,966314817,1 +109910,966315487,966314856,1 +81036,966315487,1540844183,1 +111720,966315504,966315029,1 +109943,966315508,1540871174,1 +110022,966315508,1540871218,1 +109932,966315509,966315029,1 +110028,966315509,1540871225,1 +110052,966315511,966315440,1 +109967,966315511,1540871185,1 +110062,966639633,966639753,1 +64020,966639633,1540833567,1 +64021,966639659,418771201,1 +110066,966639659,966640088,1 +110075,966639674,360012824,1 +111754,966639674,418771199,1 +110064,966639718,1540871252,1 +111711,966639718,1540872179,1 +111752,966639753,966640088,1 +110063,966639753,1540871251,1 +124892,966639798,972315541,1 +124873,966639960,972315890,1 +124900,966639960,1540883933,1 +110065,966639979,966639798,1 +124902,966639979,1540883935,1 +111753,966640088,966639674,1 +110067,966640088,966639798,1 +110071,966653507,360010675,1 +40598,966653507,1540810127,1 +110069,966653508,966653591,1 +124872,966653508,1540883925,1 +110073,966653522,966653587,1 +64023,966653522,1540833568,1 +111623,966653553,360010948,1 +110077,966653553,360012718,1 +40597,966653557,1540810126,1 +111696,966653561,972315562,1 +110074,966653587,1030300207,1 +111756,966653587,1540872199,1 +124906,966653591,360012822,1 +124868,966653591,1540883921,1 +118855,966653599,1540877997,1 +40692,966666250,360011680,1 +40978,966666250,360014627,1 +110095,966666258,360005635,1 +110087,966666258,966666266,0 +110090,966666266,360011586,1 +78940,966666270,360011645,1 +40604,966666274,360011680,1 +40276,966666289,360015394,1 +110089,966666289,1540871257,1 +110133,967199338,1540871283,1 +110166,967199339,1540871296,1 +110113,967199341,967199630,1 +110170,967199341,967199704,1 +110098,967199357,967199460,1 +110118,967199365,1540871276,1 +109856,967199382,967240629,1 +110136,967199382,1540871285,1 +110123,967199403,967199543,1 +73614,967199406,363984897,1 +110147,967199406,967199765,1 +110135,967199416,967199729,1 +110154,967199416,1540871294,1 +110153,967199419,967199416,1 +110162,967199431,967199561,1 +110151,967199431,967241032,1 +41198,967199443,1540810282,1 +110107,967199449,1540871270,1 +110184,967199449,1540871308,1 +109858,967199457,1540871113,1 +110099,967199460,967199748,1 +110122,967199469,967199403,1 +110157,967199469,967199661,1 +110138,967199482,967199503,1 +110102,967199482,1540871267,1 +110130,967199486,967199556,1 +110209,967199486,967240673,1 +110112,967199503,967199341,1 +71697,967199509,360019460,1 +109859,967199511,967199419,1 +110158,967199511,967199635,1 +109791,967199541,966279430,1 +110160,967199541,967199443,1 +110111,967199543,1540871275,1 +73618,967199544,363984901,1 +110106,967199551,967199449,1 +110129,967199553,967199338,1 +110140,967199553,967199576,1 +110131,967199556,1540871282,1 +110223,967199556,1540871339,1 +110163,967199561,967199457,1 +110115,967199561,967199757,1 +110110,967199571,967199543,1 +110155,967199571,967199653,1 +110169,967199576,967199341,1 +110141,967199576,967199471,1 +110144,967199582,967199753,1 +109854,967199582,967241193,1 +110119,967199588,1540871281,1 +110150,967199595,967199431,1 +110132,967199619,967199338,1 +110168,967199619,1540871299,1 +110164,967199624,967241128,1 +110227,967199624,967241210,1 +110128,967199630,967199553,1 +110134,967199635,967199416,1 +110159,967199635,1540871295,1 +110121,967199636,967199469,1 +110105,967199636,967199551,1 +41217,967199650,966279528,1 +110156,967199653,967199357,1 +73617,967199661,1540839716,1 +110125,967199670,967240548,1 +110241,967199670,1540871349,1 +110101,967199704,967199482,1 +73620,967199712,363984903,1 +110109,967199712,967199571,1 +110143,967199724,967199597,1 +110120,967199724,967199636,1 +41188,967199729,967240791,1 +110127,967199748,967199630,1 +110100,967199748,1540871266,1 +110145,967199753,967199544,1 +110142,967199753,967199650,1 +110116,967199757,967199595,1 +110108,967199765,967199739,1 +110148,967199765,1540871293,1 +110194,967240505,967240600,1 +110200,967240505,967240794,1 +110177,967240511,361406126,0 +110222,967240511,1540871336,0 +110187,967240535,967240729,1 +110231,967240544,967331650,1 +110207,967240544,1540871326,0 +110126,967240548,361406195,1 +51628,967240549,361406126,0 +110205,967240549,1540871324,0 +41186,967240558,967241207,1 +110239,967240585,795263262,1 +110195,967240585,1540871317,1 +41245,967240594,360019841,1 +110217,967240594,967241370,1 +73629,967240600,967240999,1 +51630,967240601,152941274,0 +110219,967240604,528489826,1 +110211,967240604,1540871332,1 +109857,967240629,967199457,1 +110228,967240629,1540871344,1 +78926,967240633,528489815,1 +110237,967240637,967241414,1 +110240,967240637,1540871348,1 +110190,967240642,967241285,0 +110238,967240642,1540871346,1 +110185,967240645,1540871309,0 +110215,967240645,1540871334,0 +73626,967240665,360019968,1 +110210,967240673,967240604,1 +51535,967240676,361406227,0 +110204,967240676,967240549,0 +110214,967240681,1540871333,0 +110192,967240741,967331611,0 +110236,967240769,967240637,1 +110220,967240769,967241342,1 +41189,967240791,360019461,1 +110201,967240794,1540871319,1 +41243,967240833,360019822,1 +110198,967240833,967241258,1 +73630,967240999,967241121,1 +110251,967240999,1382818844,1 +110235,967241022,967240769,1 +97597,967241022,1540860168,1 +110152,967241032,967199419,1 +110234,967241052,967241022,1 +110197,967241058,967241128,1 +110213,967241058,967241378,1 +73628,967241101,967240600,1 +110172,967241101,1540871300,1 +73631,967241121,361406194,1 +110230,967241121,967240794,1 +110165,967241128,967199339,1 +110226,967241171,967199624,1 +110212,967241171,967241058,1 +109855,967241193,1540871112,1 +110188,967241205,1540871312,0 +110206,967241207,967240544,0 +78932,967241255,528489831,1 +110196,967241255,967241058,1 +110199,967241258,967240505,1 +110171,967241258,967241101,1 +110191,967241285,967240741,0 +110189,967241292,1540871315,0 +110203,967241292,1540871321,0 +97565,967241329,360019414,1 +110233,967241329,967241052,1 +110225,967241333,967240548,1 +110221,967241342,967240504,1 +110173,967241342,1540871301,1 +110186,967241370,967240535,1 +110218,967241370,1540871335,1 +109912,967241378,1540871156,1 +110181,967241392,361407943,0 +110193,967331611,1540871316,0 +71691,967331615,360019722,1 +110297,967331617,967331628,1 +110262,967331617,967331695,1 +73624,967331618,360019721,1 +110294,967331618,967331723,1 +71849,967331619,536601231,1 +110300,967331619,967331729,1 +110261,967331620,967331617,1 +110304,967331620,967331647,1 +71796,967331623,536600894,1 +71851,967331627,536601235,1 +110298,967331628,536601273,1 +110266,967331632,967331731,1 +110283,967331634,967331616,1 +41238,967331635,1540810293,1 +110279,967331638,967331666,1 +110258,967331639,536601268,1 +110268,967331639,967331628,1 +40823,967331646,536601265,1 +40830,967331647,536601281,1 +110232,967331650,967241329,1 +110284,967331650,967331667,1 +97591,967331654,795263244,1 +110269,967331654,967331627,1 +71793,967331658,536600884,1 +110282,967331663,1540871373,1 +110293,967331663,1540871377,1 +110280,967331666,967331620,1 +110271,967331684,967331742,1 +110259,967331692,967331638,1 +110302,967331692,1540871385,1 +41185,967331693,1540810268,1 +110260,967331693,1540871364,1 +110257,967331695,967331639,1 +110263,967331695,967331731,1 +71754,967331715,536600557,1 +110278,967331715,967331638,1 +40825,967331717,536601267,1 +71829,967331721,536600894,1 +71776,967331721,1540839006,1 +110295,967331723,967331635,1 +110272,967331723,1540871370,1 +110255,967331726,1540871362,1 +110305,967331728,528489754,1 +110254,967331728,967331646,1 +97590,967331729,967331654,1 +110267,967331731,536601267,1 +110264,967331731,967331740,1 +110291,967331736,967331740,1 +79929,967331738,536601105,1 +110285,967331738,536601167,1 +110265,967331740,967331660,1 +110292,967331740,967331717,1 +110442,968962544,363971710,1 +110464,968962544,1540871458,1 +110437,968962546,968962571,1 +110456,968962546,968962586,1 +110449,968962553,363971719,1 +110462,968962553,968962574,1 +110436,968962554,363971715,1 +110460,968962554,968962578,1 +110466,968962557,968962560,1 +53870,968962557,968962571,1 +53839,968962559,968962592,1 +110470,968962559,974031171,1 +110451,968962560,974031211,1 +110441,968962566,968962544,1 +53865,968962566,968962590,1 +53837,968962568,363971772,1 +110438,968962568,968962574,1 +53871,968962571,363972544,1 +110439,968962574,968962584,1 +110463,968962574,1540871457,1 +110448,968962577,968962553,1 +110467,968962577,1540871459,1 +53873,968962578,363971317,1 +110461,968962578,968962553,1 +110468,968962584,1540871460,1 +110465,968962586,968962557,1 +110457,968962586,1540871456,1 +110469,968962587,968962559,1 +112179,968962587,1540872840,1 +110458,968962590,363971998,1 +53866,968962590,363972228,1 +53840,968962592,1343906174,1 +110445,968962594,1540871450,1 +110453,968962594,1540871452,1 +110459,968962598,968962554,1 +110444,968962598,1540871449,1 +71784,972315164,536600730,1 +111584,972315168,1540872099,1 +111700,972315173,972315606,1 +124875,972315173,972315724,1 +111680,972315178,972316028,1 +111653,972315178,1540872168,1 +111661,972315179,972315184,1 +111602,972315179,972315707,1 +111662,972315184,972315325,1 +111667,972315184,972315396,1 +124910,972315191,1540883937,1 +111762,972315193,972315421,1 +111654,972315193,972315606,1 +111759,972315196,536600528,1 +107838,972315196,1540869546,1 +111782,972315205,972315543,1 +111787,972315205,972315608,1 +111651,972315209,972315355,1 +111709,972315209,972316052,1 +111713,972315221,972315492,1 +111673,972315221,1540872171,1 +111804,972315231,972316082,1 +111694,972315234,972315383,1 +111604,972315234,972316090,1 +111684,972315255,360190111,1 +111861,972315255,972481963,1 +111580,972315269,966653561,1 +111743,972315269,972315354,1 +111722,972315272,972315699,1 +71760,972315277,536600579,1 +111579,972315287,972315269,1 +111703,972315287,972315358,1 +111760,972315301,972315724,1 +111775,972315301,1540872200,1 +111802,972315303,360012487,1 +111614,972315303,972315786,1 +111595,972315304,972315342,1 +110027,972315306,1540871224,1 +110068,972315307,966653508,1 +124914,972315307,972315541,1 +124871,972315311,1540883924,1 +71782,972315314,536600718,1 +111663,972315325,972315361,1 +111806,972315325,972316231,1 +111583,972315337,1540872098,1 +111657,972315338,966639798,1 +124913,972315338,966639960,1 +111731,972315340,972316176,1 +111619,972315340,1540872118,1 +111783,972315342,972315709,1 +111596,972315342,972316127,1 +81022,972315343,972316179,1 +111648,972315346,1540872166,1 +111656,972315352,972315338,1 +111741,972315352,972315672,1 +111791,972315354,972315383,1 +111744,972315354,972316090,1 +111652,972315355,418771202,1 +124897,972315355,972315734,1 +111790,972315358,972315354,1 +111704,972315358,972316196,1 +111664,972315361,972315771,1 +111576,972315361,972316231,1 +111796,972315364,1540872209,1 +112118,972315364,1540872787,1 +111695,972315383,966653561,1 +111792,972315383,972315311,1 +111575,972315390,972315361,1 +111675,972315390,972315709,1 +111668,972315396,972315421,1 +111780,972315396,972316134,1 +111669,972315421,972315682,1 +111763,972315421,972315814,1 +111617,972315425,360012483,1 +111747,972315425,536600575,1 +111736,972315449,972315277,1 +40834,972315449,1540810179,1 +111735,972315457,1540872194,1 +111677,972315461,536600519,1 +111724,972315461,972315231,1 +111646,972315472,1540872163,1 +111714,972315492,972315193,1 +111779,972315492,972315396,1 +71779,972315498,536600718,1 +111581,972315498,972315314,1 +111725,972315503,972315537,1 +111767,972315503,972315786,1 +124904,972315512,1540883936,1 +111706,972315537,360012485,1 +111726,972315537,972315674,1 +124893,972315541,360012824,1 +111794,972315543,972316082,1 +111699,972315547,1540872178,1 +124886,972315562,972315307,1 +124912,972315562,972315338,1 +111585,972315566,1540872100,1 +78911,972315570,360012650,0 +111611,972315570,1030300192,1 +111678,972315602,972316145,1 +111749,972315602,1540872195,1 +44875,972315604,360190247,1 +111601,972315604,1540872107,1 +111655,972315606,972315352,1 +111701,972315606,972315615,1 +111788,972315608,972315705,1 +111765,972315608,972316099,1 +111650,972315613,972315209,1 +111702,972315615,972315287,1 +111671,972315615,972315672,1 +111608,972315642,972315874,1 +111729,972315642,1540872192,1 +111594,972315650,972315304,1 +111574,972315650,972315390,1 +111600,972315664,972315604,1 +111742,972315672,972315269,1 +111672,972315672,972315562,1 +111746,972315674,972315425,1 +111727,972315674,972316169,1 +111607,972315677,972315642,1 +111679,972315677,1540872172,1 +111670,972315682,972315615,1 +111723,972315699,972315461,1 +111789,972315705,972315358,1 +111577,972315705,1540872096,1 +111591,972315707,972316039,1 +111676,972315709,972315461,1 +111784,972315709,972315771,1 +111761,972315724,972315193,1 +124876,972315724,972315472,1 +111730,972315731,972315340,1 +111586,972315731,1540872101,1 +124898,972315734,972315912,1 +111771,972315734,972316052,1 +111660,972315736,972315179,1 +111712,972315736,972315221,1 +111778,972315738,972315492,1 +111645,972315738,1540872162,1 +111666,972315751,972315184,1 +111674,972315751,972315390,1 +124911,972315753,972315311,1 +111603,972315753,1540872108,1 +111644,972315764,1540872160,1 +112048,972315768,973983208,1 +111785,972315771,972315801,1 +111615,972315786,360012485,1 +111768,972315786,536600569,1 +111708,972315792,972316218,1 +124869,972315792,1030300192,1 +111786,972315801,972315205,1 +111764,972315814,972315608,1 +111630,972315846,1540872136,1 +64036,972315864,1540833581,1 +111593,972315874,972315650,1 +111716,972315878,972481679,1 +111690,972315878,1540872175,1 +111618,972315882,972315516,1 +111588,972315882,1540872105,1 +111599,972315887,972315664,1 +111682,972315887,972315846,1 +124874,972315890,972315173,1 +111740,972315890,972315352,1 +81024,972315912,418771182,1 +124899,972315912,1540883931,1 +111578,972315919,972315287,1 +111636,972315919,972315682,1 +111774,972315931,972315301,1 +111698,972315931,972315547,1 +124905,972315974,360012663,1 +111620,972315987,583433370,1 +111734,972316026,972315457,1 +111757,972316026,972316220,1 +111658,972316033,972316131,1 +111643,972316033,1540872158,1 +111665,972316039,972315751,1 +111592,972316039,972315874,1 +111710,972316052,972315343,1 +111772,972316052,972316189,1 +111805,972316082,972315771,1 +111745,972316090,972315674,1 +111605,972316090,972316196,1 +111691,972316095,1540872177,1 +111850,972316095,1540872287,1 +111766,972316099,972315503,1 +111793,972316099,972315543,1 +111597,972316127,972315457,1 +111637,972316127,1540872146,1 +111659,972316131,972315736,1 +111632,972316131,1540872137,1 +111781,972316134,972315205,1 +111688,972316134,972315814,1 +64016,972316145,418771179,1 +111697,972316151,972315931,1 +111649,972316151,1540872167,1 +111719,972316154,966315504,1 +111641,972316154,1540872150,1 +111634,972316162,1540872142,1 +111642,972316162,1540872155,1 +111693,972316169,972315234,1 +111728,972316169,1540872190,1 +111687,972316171,360190247,1 +111640,972316171,972315664,1 +111635,972316176,972315853,1 +111732,972316176,1015275655,1 +81023,972316179,972315912,1 +111738,972316189,972315613,1 +111773,972316189,972315931,1 +111647,972316190,1540872164,1 +111606,972316194,972315677,1 +110030,972316194,1540871227,1 +111705,972316196,972315537,1 +111681,972316198,972315887,1 +111686,972316198,1540872174,1 +111590,972316210,972315707,1 +111633,972316210,1540872139,1 +124901,972316218,972315974,1 +111758,972316220,972315196,1 +111582,972316220,1540872097,1 +111807,972316231,1540872213,1 +111639,972316243,972315987,1 +44948,972481553,360191240,1 +111884,972481575,972481752,1 +44864,972481575,1540811898,1 +111886,972481579,972481913,1 +80036,972481579,1540841937,1 +44971,972481605,360191385,1 +111831,972481605,972481669,0 +44924,972481607,360191386,1 +111855,972481609,972481712,1 +44968,972481613,972481834,1 +111898,972481613,1540872339,1 +73610,972481624,360189875,1 +111858,972481624,972481602,1 +73604,972481629,360189872,1 +143850,972481633,972481738,0 +64045,972481635,600396272,1 +111883,972481641,972481575,1 +53809,972481641,972481653,1 +45072,972481642,972481938,1 +80037,972481647,972481866,1 +111869,972481647,1540872310,1 +53810,972481653,972481932,1 +111820,972481653,1540872250,1 +111822,972481665,1540872256,1 +149361,972481665,1540951413,0 +44939,972481669,360191411,1 +111832,972481669,972481726,0 +53805,972481671,1540820481,1 +111867,972481671,1540872303,1 +111717,972481679,972315355,1 +111881,972481687,972481768,1 +149362,972481687,1540951414,0 +53806,972481699,1540820486,1 +53807,972481704,972481800,1 +45594,972481704,972481966,1 +111856,972481712,1540872299,1 +149339,972481712,1540951393,0 +44947,972481717,972481553,1 +44937,972481720,279591664,1 +111827,972481720,972481834,1 +44923,972481725,972481607,1 +111835,972481725,1540872274,0 +44946,972481726,972481717,1 +111833,972481726,972481858,0 +135210,972481730,972481878,0 +135209,972481730,972481975,0 +46114,972481734,972481821,0 +111836,972481734,1540872275,0 +135207,972481738,972481609,0 +135208,972481738,972481730,0 +44870,972481750,360190108,1 +111817,972481750,1540872241,1 +111885,972481752,972481579,1 +111870,972481752,1540872313,1 +111838,972481759,360224583,0 +21520,972481759,1540791057,0 +135212,972481760,972481768,0 +111821,972481760,1540872253,1 +111882,972481768,972481641,1 +111859,972481768,972481807,0 +73527,972481776,549787375,1 +111899,972481776,1540872340,1 +44861,972481783,360189633,1 +64042,972481797,549787387,1 +111900,972481797,972481783,1 +111809,972481800,972481807,1 +53808,972481800,1540820493,1 +45604,972481801,360191384,1 +111830,972481801,1540872272,0 +111866,972481803,972481716,1 +73526,972481803,972481776,1 +111888,972481804,360190669,1 +83854,972481804,568806870,1 +111810,972481807,1540872215,1 +111860,972481807,1540872301,0 +135213,972481813,1540905586,0 +53817,972481814,363970709,1 +111816,972481814,972481738,0 +64044,972481820,972481635,1 +152326,972481821,1540962695,1 +152337,972481821,1540962698,0 +73529,972481824,549787380,1 +111813,972481824,1540872225,1 +44901,972481830,360190711,1 +111852,972481830,1540872294,1 +44969,972481834,279591663,1 +111837,972481839,1540872276,0 +45071,972481858,972481642,1 +111834,972481858,1540872273,0 +45596,972481861,360194250,1 +111849,972481861,1540872285,1 +44865,972481866,1540811901,1 +44887,972481872,360190667,1 +111878,972481872,1540872332,1 +135211,972481878,972481760,0 +111854,972481878,1540872296,1 +111826,972481905,1540872266,1 +111868,972481905,1540872308,1 +53804,972481906,1540820480,1 +111814,972481906,1540872233,1 +111887,972481913,972481804,1 +111851,972481913,1540872291,1 +44936,972481914,972481720,1 +53811,972481932,972481998,1 +45073,972481938,360191196,1 +149363,972481953,972481813,0 +111864,972481956,360189635,1 +64047,972481956,583433365,1 +135214,972481961,360194250,0 +111812,972481961,1540872220,0 +111862,972481963,972481812,1 +45595,972481966,972481861,1 +53813,972481975,1540820499,1 +44918,972481981,360194177,1 +21519,972481982,972481759,0 +111890,972481982,1540872333,0 +111829,972481984,1540872271,0 +111715,972481992,1540872181,1 +111853,972481998,972481878,1 +53812,972481998,1540820498,1 +44868,972482009,360190107,1 +111819,972482009,1540872249,1 +81255,973016840,600629210,0 +111939,973016840,1540872455,0 +46139,973017196,360227483,1 +111952,973017226,1540872476,0 +111972,973017297,662948310,0 +2646,973017307,1540772361,0 +83892,973017307,1540846708,1 +83891,973017371,1540846705,0 +111906,973017463,973017297,0 +2644,973017470,1540772359,0 +111971,973017470,1540872577,0 +111970,973017990,973018160,0 +111940,973018160,662948314,0 +83898,973018539,1540846723,0 +111959,973018539,1540872509,0 +83887,973018627,1540846687,0 +111981,973018627,1540872595,0 +2074,973037227,1540771482,0 +111977,973037227,1540872587,0 +83889,973037242,1540846695,0 +111979,973037250,360215600,0 +111978,973037254,155587359,0 +83890,973037254,1540846697,0 +81258,973040045,585199960,0 +111984,973040045,600629014,0 +83902,973040049,1540846740,0 +111995,973053968,973054040,1 +46118,973053975,360216670,1 +46012,973053975,973054054,1 +46120,973053979,973054040,1 +46116,973053981,1540812364,1 +111996,973054001,973054037,1 +46124,973054001,973054073,1 +83914,973054037,973053981,1 +46121,973054040,1540812366,1 +46013,973054054,360216677,1 +111993,973054054,973054073,1 +45979,973054068,360216194,1 +111994,973054068,1540872601,1 +46125,973054073,360216481,1 +114726,973777017,982077199,0 +40711,973982977,360011675,1 +111627,973982977,1540872132,1 +53884,973982981,1540820539,1 +112065,973983016,973983080,1 +112075,973983016,1540872747,1 +112115,973983017,973983571,1 +112106,973983017,1540872779,1 +112088,973983024,360189342,1 +111797,973983024,1540872211,1 +112057,973983041,973983136,1 +112068,973983043,360010951,1 +112043,973983056,973983286,1 +112071,973983056,973983445,1 +112112,973983080,360190669,1 +112066,973983080,973983247,1 +112098,973983087,1540872768,1 +112114,973983087,1540872782,1 +64034,973983094,418771196,1 +112083,973983094,973983439,1 +79056,973983107,1540841202,1 +112087,973983113,1540872767,1 +53908,973983115,1540820556,1 +112080,973983116,1540872751,1 +112103,973983116,1540872775,1 +112058,973983136,1540872731,1 +112085,973983136,1540872766,1 +112104,973983161,1540872776,1 +112046,973983170,973983439,1 +112062,973983170,973983634,1 +112086,973983208,973983113,1 +112091,973983222,973983161,1 +112097,973983222,973983507,1 +53886,973983241,1540820541,1 +112122,973983265,973983115,1 +112100,973983265,1540872770,1 +79058,973983269,600396751,1 +112111,973983269,973983332,1 +112090,973983286,973983222,1 +112044,973983286,973983436,1 +118852,973983301,991240614,1 +112105,973983334,1540872778,1 +24090,973983340,1540794234,0 +112121,973983340,1540872788,1 +111622,973983373,966653553,1 +112093,973983373,973983522,1 +44895,973983396,360190887,1 +112110,973983399,973983043,1 +112049,973983399,973983694,1 +44892,973983407,360190738,1 +112108,973983414,1540872780,1 +111874,973983429,1540872323,1 +112113,973983429,1540872781,1 +112045,973983436,973983170,1 +112077,973983436,973983735,1 +112084,973983439,973983041,1 +112047,973983439,1540872724,1 +79057,973983444,973983269,1 +112073,973983444,973983476,1 +112096,973983445,973983222,1 +112072,973983445,973983334,1 +112107,973983479,973983414,1 +112074,973983485,973983016,1 +112099,973983485,973983685,1 +112079,973983507,1540872749,1 +112064,973983522,973983479,1 +112094,973983522,973983571,1 +112095,973983571,973983445,1 +112116,973983571,973983691,1 +24095,973983605,279591136,0 +73586,973983616,1540839709,1 +112056,973983634,973983041,1 +112092,973983639,279591124,0 +112060,973983685,1540872743,1 +112042,973983691,973983056,1 +112117,973983691,1540872786,1 +40616,973983694,360010766,1 +112050,973983694,973983605,1 +53823,973983698,1540820510,1 +53907,973983698,1540820555,1 +112055,973983735,973983634,1 +112078,973983735,1540872748,1 +64033,973983737,973983094,1 +112061,973983737,973983170,1 +29727,974030358,360209532,1 +149355,974030382,338487310,0 +45673,974030382,360206040,1 +112149,974030436,279589687,1 +21450,974030468,363973406,0 +112163,974030487,974030673,1 +112167,974030487,974031162,1 +112144,974030491,974030802,1 +112174,974030491,974031166,1 +21442,974030505,360209399,0 +29729,974030505,363975108,1 +53854,974030515,338487127,1 +110454,974030515,363975106,1 +112178,974030524,974031117,1 +135188,974030526,363972022,0 +53850,974030540,363971995,1 +112160,974030540,974031007,1 +112186,974030549,974031211,1 +149352,974030555,338487319,1 +21456,974030571,279591398,1 +112162,974030571,974030487,1 +53857,974030572,1540820524,1 +112123,974030572,1540872793,1 +143845,974030576,338487126,0 +112170,974030576,1540872820,0 +135160,974030610,360207423,1 +112053,974030615,1540872726,0 +143844,974030619,974030576,0 +112171,974030619,1540872825,0 +112182,974030638,363971998,1 +135201,974030673,363975777,0 +112164,974030673,974030358,1 +79043,974030708,279589614,0 +53856,974030726,974030572,1 +112133,974030726,974030844,1 +135205,974030729,360206842,0 +112155,974030729,1540872811,1 +112135,974030747,974030436,1 +142505,974030747,1030294078,1 +53877,974030750,363972551,1 +112165,974030750,363973123,1 +112156,974030750,974030429,1 +53847,974030784,1540820518,1 +112143,974030784,1540872809,1 +112137,974030790,974030878,1 +93460,974030790,974067491,1 +149349,974030797,360206360,1 +111824,974030797,1540872258,1 +112173,974030802,1540872831,1 +112134,974030844,974030549,1 +112140,974030844,974031014,1 +142504,974030859,974030747,1 +112184,974030870,363971818,1 +112128,974030870,974030610,1 +112290,974030875,360205940,1 +112139,974030875,974030555,1 +112138,974030878,974031216,1 +112159,974030884,974030556,1 +112142,974030884,1540872807,1 +53843,974030906,363971818,1 +29724,974030923,363975095,1 +112177,974030923,1540872839,1 +133831,974030929,1540898086,1 +112126,974030958,1540872803,1 +112158,974030958,1540872816,1 +112127,974030962,974030870,1 +112132,974030962,974030906,1 +112161,974031007,363975098,1 +112145,974031007,974030638,1 +112141,974031014,360207423,1 +53845,974031014,363971821,1 +149344,974031018,279591424,1 +112148,974031041,974030436,1 +112125,974031041,1540872802,1 +110446,974031058,363971319,1 +135190,974031084,360207423,0 +112175,974031110,360209695,1 +112169,974031110,1540872818,0 +53849,974031112,974030540,1 +29723,974031112,1540799015,1 +53848,974031117,1540820521,1 +112168,974031162,279591057,1 +53819,974031162,363970711,1 +112130,974031171,1540872805,1 +112180,974031202,363975104,1 +149319,974031208,360206038,0 +110452,974031211,968962594,1 +93467,974031216,974066231,1 +45746,974066138,360210340,1 +112282,974066138,974067222,1 +112270,974066190,1540872983,1 +112266,974066193,1540872965,1 +112280,974066193,1540873006,1 +112249,974066229,974066730,1 +112271,974066229,1540872985,1 +93468,974066231,360205417,1 +112230,974066231,1540872892,1 +112241,974066233,1540872919,1 +112267,974066233,1540872970,1 +112235,974066255,1540872903,1 +112207,974066280,974066589,1 +112284,974066280,1540873028,1 +112253,974066281,974067567,1 +149338,974066281,1540951392,1 +142517,974066289,360207182,1 +112236,974066289,1540872906,1 +112285,974066323,1540873029,1 +112292,974066323,1540873030,1 +112203,974066348,974066564,1 +112246,974066348,974067025,1 +93472,974066353,974067491,1 +143898,974066369,360206854,1 +112188,974066386,974066626,0 +112223,974066401,974066432,1 +45685,974066401,1540812132,1 +112269,974066403,974066190,1 +112293,974066403,1540873033,1 +112279,974066415,1540872999,1 +149336,974066415,1540951388,1 +112275,974066432,360207868,1 +112224,974066432,974067410,1 +119108,974066435,716888599,1 +112227,974066435,1540872886,1 +112215,974066472,974067170,1 +112259,974066472,1540872952,1 +112274,974066523,974066386,0 +112194,974066523,1540872849,0 +93464,974066538,974066730,1 +112277,974066538,974067316,1 +112195,974066558,1540872850,1 +112255,974066558,1540872944,1 +112245,974066564,716888599,1 +112204,974066564,1540872869,1 +112187,974066566,1540872841,0 +45664,974066587,360206034,1 +112208,974066589,974066289,1 +136475,974066589,1291956620,1 +112238,974066611,974067361,1 +112248,974066611,1540872938,1 +112234,974066614,974066255,1 +112189,974066626,974066673,0 +112190,974066673,1540872842,0 +112237,974066673,1540872907,1 +149334,974066704,974066940,1 +112251,974066712,974066944,1 +112250,974066730,1540872941,1 +112232,974066733,360206872,1 +112263,974066747,974066369,1 +112211,974066747,1540872875,1 +112209,974066783,974066899,1 +45768,974066783,1540812168,1 +112202,974066787,1540872867,1 +112258,974066787,1540872948,0 +112198,974066791,360210340,1 +142516,974066794,974066289,1 +112192,974066797,1540872848,0 +112197,974066820,974066791,1 +112242,974066820,1540872930,1 +112221,974066899,360207196,1 +112210,974066899,1540872874,1 +112199,974066906,974066397,1 +45663,974066906,1540812127,1 +149335,974066940,974066415,1 +112201,974066940,1540872860,1 +112252,974066944,1540872942,1 +112262,974066961,974066747,1 +45744,974066961,974066963,1 +45745,974066963,974066138,1 +112260,974066963,974067378,1 +112264,974066998,1540872953,1 +112247,974067025,716888615,1 +112219,974067025,1540872883,1 +149318,974067028,1540951380,1 +112214,974067107,1540872877,1 +112205,974067117,1540872871,1 +45680,974067154,360207196,1 +142515,974067154,1540934707,1 +142513,974067160,974067506,1 +45684,974067160,1540812130,1 +112216,974067170,1540872878,1 +112231,974067170,1540872899,1 +112268,974067171,1540872980,1 +149337,974067171,1540951389,1 +112243,974067199,974067268,1 +112240,974067199,1540872916,1 +112213,974067222,1540872876,1 +112283,974067222,1540873023,1 +112244,974067268,1540872935,1 +112265,974067268,1540872964,1 +142509,974067296,1540934704,1 +112256,974067304,974067502,0 +112276,974067304,1540872993,1 +112229,974067316,1540872891,1 +112278,974067316,1540872995,1 +112239,974067361,1540872911,1 +112261,974067378,974066791,1 +45749,974067410,1540812166,1 +112228,974067413,974067316,1 +93461,974067491,716888599,1 +93473,974067491,974067117,1 +112257,974067502,1540872945,0 +112212,974067506,974067222,1 +142514,974067506,1540934706,1 +112191,974067523,1540872845,0 +119087,974067523,1540878220,0 +112294,974067567,974066611,1 +112254,974067567,1540872943,1 +112206,974067575,1540872872,1 +142512,974067575,1540934705,1 +114709,981693501,981693511,1 +149414,981693507,1540951572,1 +114710,981693511,981693557,1 +114702,981693511,1540873938,1 +149689,981693512,1411198252,1 +40435,981693513,981693545,1 +114716,981693513,981693557,1 +114707,981693524,981693528,1 +114713,981693524,1411198203,1 +23950,981693526,981693541,1 +40418,981693526,1540810064,1 +149676,981693528,1411198187,1 +40437,981693529,360007810,1 +114718,981693529,981693501,1 +40423,981693532,360007723,1 +114705,981693532,1540873939,1 +149678,981693535,1540953158,1 +115429,981693541,1540874553,1 +114712,981693542,981693524,1 +114704,981693542,981693535,1 +149680,981693544,360007813,1 +114701,981693545,981693511,1 +40436,981693545,981693529,1 +23949,981693546,1540793864,1 +149679,981693556,981693544,1 +114711,981693557,981693542,1 +114717,981693557,981693556,1 +114715,981693560,981693512,1 +149693,981693560,1411198213,1 +40434,981693572,981693513,1 +114703,981693572,981693542,1 +114753,982077189,1540873950,1 +114727,982077199,302045960,0 +114750,982077199,982077243,1 +24602,982077203,302897535,1 +114749,982077211,982077199,1 +114730,982077211,982077273,1 +24949,982077213,982077221,0 +114746,982077213,1540873945,1 +24950,982077221,303698831,0 +111999,982077221,1540872603,1 +114748,982077222,982077211,1 +114724,982077224,302552972,0 +24278,982077226,302656919,1 +89045,982077226,360713082,0 +114754,982077240,982077203,1 +24277,982077240,1540795530,1 +114751,982077243,1540873948,1 +24547,982077259,302661528,0 +114752,982077259,982077189,1 +114745,982077261,982077213,1 +114747,982077268,982077222,1 +115152,984332185,984332543,1 +115137,984332185,1540874292,1 +29708,984332186,984332498,1 +143578,984332186,1540937324,1 +115130,984332189,1540874257,1 +115156,984332189,1540874334,1 +29704,984332219,984332412,1 +115139,984332219,1540874295,1 +89059,984332222,294138005,0 +94543,984332222,1540857163,1 +115167,984332240,1540874351,1 +115171,984332240,1540874356,1 +115150,984332247,1540874324,1 +115173,984332247,1540874362,1 +29706,984332297,1540799009,1 +143577,984332306,984332186,1 +115155,984332306,1540874332,1 +115163,984332317,1540874341,1 +115132,984332318,1540874275,1 +115168,984332318,1540874353,1 +115158,984332361,984332543,1 +115149,984332363,984332317,1 +143579,984332363,1540937327,1 +115164,984332386,1540874344,1 +115289,984332386,1540874454,1 +29705,984332412,1540799005,1 +115147,984332412,1540874320,1 +115129,984332428,984332189,1 +115160,984332428,1540874338,1 +23920,984332451,984634322,0 +115157,984332451,1540874337,1 +89052,984332456,1540852124,0 +23922,984332482,1540793827,0 +29703,984332482,1540799003,1 +115151,984332496,984332185,1 +29709,984332498,938502307,1 +115162,984332498,1540874340,1 +115140,984332503,1540874299,1 +115154,984332503,1540874329,1 +89058,984332534,1540852133,0 +115166,984332536,984332240,1 +115159,984332543,984332428,1 +115153,984332543,1540874328,1 +29707,984332545,984332186,1 +115146,984332545,1540874311,1 +23874,984332560,1540793766,1 +115131,984332560,1540874266,1 +29702,984332586,984332482,1 +89054,984332586,984634444,0 +115165,984332590,984332536,1 +115174,984332626,984332200,1 +115172,984332626,1540874357,1 +23919,984332645,1540793822,0 +115138,984332648,984332219,1 +115133,984332648,984332361,1 +115136,984332675,1540874284,1 +115135,984332687,1540874281,1 +115186,984364111,984364340,1 +115215,984364111,984364895,1 +23936,984364113,294144525,0 +115180,984364113,984364590,1 +115338,984364120,984364475,1 +115194,984364130,984364309,1 +115198,984364130,1540874383,1 +115229,984364155,984364328,1 +115193,984364155,1540874381,1 +23934,984364168,737307277,0 +115240,984364168,1540874411,1 +115220,984364175,984364337,1 +115211,984364175,984364355,1 +115217,984364197,984364337,1 +115200,984364197,984364369,1 +23876,984364205,294114238,1 +115226,984364205,1540874397,0 +115185,984364208,984364375,1 +115224,984364230,1540874394,1 +115223,984364248,984364230,1 +115190,984364248,1540874375,1 +115209,984364257,984364846,1 +115196,984364257,1540874382,1 +114758,984364272,984364475,1 +115227,984364272,1540874399,0 +115188,984364277,1540874373,1 +115203,984364277,1540874388,1 +115176,984364293,984364567,1 +115219,984364309,984364175,1 +115197,984364320,984364130,1 +115207,984364320,1540874391,1 +115216,984364322,984364197,1 +115225,984364322,1540874396,1 +115237,984364325,1540874408,1 +115221,984364337,984364469,1 +115187,984364340,984364230,1 +115202,984364340,1540874385,1 +115214,984364355,984364111,1 +115212,984364355,984364369,1 +115201,984364369,984364340,1 +125005,984364375,984364320,1 +125037,984364375,984415664,1 +94417,984364391,737307275,1 +115181,984364428,984364605,1 +23940,984364428,1540793853,0 +115218,984364460,984364309,1 +115205,984364460,984364639,1 +115234,984364469,1540874406,1 +115339,984364475,984634491,1 +115238,984364513,984364723,1 +115233,984364531,984364469,1 +23932,984364552,984364900,0 +115183,984364552,1540874371,1 +115189,984364556,984364248,1 +115179,984364556,1540874369,1 +115177,984364567,984364814,1 +115231,984364590,1540874401,1 +115199,984364594,984364197,1 +115235,984364594,984606766,1 +115182,984364605,984364120,1 +115228,984364605,984364391,0 +40540,984364617,1129262188,1 +115191,984364617,1540874379,1 +115213,984364639,984364830,1 +115206,984364639,1540874390,1 +115232,984364670,984364531,1 +115195,984364720,984364257,1 +125025,984364723,985286045,1 +125041,984364769,1540883975,1 +115239,984364803,984364168,1 +23942,984364803,1540793855,0 +115192,984364814,984364155,1 +115178,984364814,1540874366,1 +125039,984364830,984415684,1 +115210,984364846,984364175,1 +115184,984364855,1540874372,1 +115222,984364876,984364855,1 +115208,984364876,1540874393,1 +114757,984364890,984364272,1 +23939,984364890,1540793850,0 +115204,984364895,984364460,1 +23933,984364900,1540793840,0 +115175,984364900,1540874363,1 +115292,984415638,1540874466,1 +115254,984415645,984364208,1 +115247,984415648,984415673,1 +115274,984415650,984606779,1 +115250,984415650,1540874413,1 +115273,984415652,984415648,1 +115261,984415652,984415665,1 +115241,984415654,984415658,1 +23930,984415654,1540793837,0 +115263,984415655,984415667,1 +115243,984415655,984415681,1 +115253,984415658,984415645,1 +115242,984415658,984415655,1 +125038,984415664,984364830,1 +115296,984415665,984415673,1 +115264,984415667,984606748,1 +115259,984415667,984607108,1 +115248,984415673,984415683,1 +115262,984415673,984415684,1 +115350,984415674,984634498,1 +23943,984415674,1540793856,0 +115251,984415681,984364375,1 +115244,984415681,984606732,1 +115255,984415682,984415645,1 +23931,984415682,1540793838,0 +115256,984415683,984364769,1 +115249,984415683,984415650,1 +125040,984415684,984364769,1 +115246,984415685,984415648,1 +115252,984415685,984415664,1 +115275,984606559,984606596,1 +115278,984606564,984606691,1 +115293,984606564,1540874467,1 +115258,984606596,984415667,1 +115276,984606596,984606610,1 +115407,984606649,1113561531,1 +23928,984606649,1540793833,0 +115271,984606655,1540874442,1 +115294,984606655,1540874472,1 +115285,984606691,984606748,1 +115279,984606691,984607108,1 +23946,984606704,1540793863,0 +125052,984606704,1540883979,1 +115245,984606732,1540874412,1 +115265,984606748,984415638,1 +115236,984606766,984364325,1 +115287,984606856,1540874451,1 +115272,984606880,984415652,1 +115284,984606880,984606691,1 +115295,984606939,984415665,1 +115283,984606939,984606880,1 +115290,984607072,360006879,1 +115282,984607072,1540874447,1 +115288,984607094,1540874452,1 +115260,984607108,984415652,1 +115280,984607108,984606732,1 +136465,984633877,984634288,1 +115348,984633877,984634498,1 +115378,984633916,984634563,1 +115374,984633916,1540874506,1 +115402,984633920,984634411,1 +115326,984633920,1540874486,1 +115399,984633939,984634299,1 +115341,984633939,984634649,1 +115345,984633979,984634306,1 +115310,984633979,984634411,1 +115380,984634005,984634597,1 +149668,984634005,1540953154,1 +115328,984634033,984634066,1 +115305,984634033,984634602,0 +115370,984634066,1540874499,0 +23948,984634084,294114688,0 +115308,984634084,984634628,0 +125055,984634086,1540883982,1 +115333,984634109,984634388,1 +115343,984634114,737307269,1 +115386,984634114,984634332,1 +115382,984634118,984634224,1 +115301,984634118,984634652,1 +115317,984634145,1540874483,1 +115389,984634145,1540874515,1 +115391,984634169,984634539,1 +115397,984634169,984634675,1 +115354,984634172,984634496,1 +115313,984634172,984634675,1 +23947,984634174,984634084,0 +115367,984634174,1540874498,0 +115336,984634195,737307273,1 +115385,984634224,984634114,1 +115383,984634224,984634609,1 +115332,984634226,984634109,1 +115300,984634226,984634118,1 +115356,984634241,984634248,1 +115325,984634241,1540874484,1 +115360,984634247,737307347,1 +149663,984634247,1411198190,1 +115318,984634248,984634667,1 +115357,984634248,1540874491,1 +115359,984634261,984634247,1 +125056,984634261,1540883985,1 +115369,984634272,984634066,0 +115377,984634277,984633916,1 +115352,984634277,984634412,1 +115411,984634285,1540874526,0 +115335,984634288,984634195,1 +115322,984634296,984634109,1 +115347,984634296,984634447,1 +115299,984634299,984634652,1 +115400,984634299,984634654,1 +115346,984634306,984634296,1 +94409,984634320,984634622,1 +23921,984634322,984332482,0 +115304,984634330,1540874478,0 +115316,984634332,737307266,1 +115387,984634332,984634644,1 +125058,984634383,984634285,1 +115384,984634388,984634224,1 +115334,984634388,984634288,1 +125053,984634389,984634659,1 +115344,984634389,1540874489,1 +115324,984634400,984634241,1 +115353,984634412,984634629,1 +115307,984634412,1540874479,0 +115427,984634435,294113934,1 +115376,984634435,984634277,1 +68973,984634444,984634322,1 +89055,984634444,1540852127,0 +136464,984634447,984633877,1 +23880,984634450,294114443,1 +115315,984634461,984634332,1 +94438,984634470,737307350,1 +115320,984634483,984634320,1 +115298,984634483,1540874477,1 +115340,984634491,294114237,1 +115388,984634491,984634145,1 +115390,984634496,984634169,1 +115355,984634496,984634241,1 +115349,984634498,984364391,1 +115351,984634498,984634195,1 +125057,984634525,984634383,1 +115312,984634525,1540874482,1 +115331,984634526,984634226,1 +115321,984634526,984634306,1 +115396,984634539,984634400,1 +115392,984634539,984634660,1 +94412,984634551,1540857055,1 +115379,984634563,984634005,1 +115327,984634563,984634033,1 +115361,984634572,938502398,1 +115323,984634576,984634400,1 +115364,984634576,984634667,1 +149665,984634597,1540953136,1 +115375,984634602,984634272,1 +115306,984634602,984634412,0 +94415,984634609,737307273,1 +94410,984634622,737307262,1 +94437,984634622,984634470,1 +115366,984634628,984634174,0 +23927,984634628,1540793832,0 +115368,984634629,984634272,0 +115394,984634644,984634680,1 +115342,984634649,984634114,1 +115303,984634649,984634461,1 +115302,984634652,984634649,1 +115401,984634654,984633920,1 +115330,984634654,984634526,1 +115371,984634659,1540874501,1 +125054,984634659,1540883980,1 +115363,984634660,984634576,1 +115393,984634660,984634644,1 +115319,984634667,984634483,1 +115365,984634667,1540874496,1 +115398,984634675,984633939,1 +115314,984634675,984634461,1 +115297,984634680,984634483,1 +115395,984634680,984634551,1 +115424,984639754,984639910,1 +94581,984639809,737311459,1 +115408,984639809,1540874520,1 +94567,984639812,1540857173,1 +94574,984639818,737311448,1 +115405,984639834,1540874519,0 +115416,984639838,737307344,1 +115410,984639838,1540874523,0 +94573,984639848,984639818,1 +115404,984639854,1540874517,0 +115412,984639854,1540874528,0 +94583,984639863,737311461,1 +115415,984639863,984639818,1 +125047,984639867,1411198293,1 +115419,984639867,1540874533,1 +125046,984639869,984639867,1 +115406,984639869,984639888,0 +94434,984639871,1540857061,1 +115414,984639871,1540874531,1 +115409,984639888,1540874522,0 +115420,984639912,1540874539,1 +115461,984725718,984725738,1 +115445,984725718,1540874564,1 +75591,984725721,984725789,1 +115462,984725738,984725948,1 +89914,984725759,984725923,1 +40095,984725789,152802868,1 +115451,984725789,984725793,1 +115441,984725791,984726031,1 +115469,984725791,984752822,1 +115433,984725793,984725798,1 +115452,984725793,1540874567,1 +115454,984725796,984726073,1 +75589,984725796,1540840254,1 +115434,984725798,984725993,1 +89913,984725839,1540853757,1 +89915,984725923,1540853758,1 +115459,984725923,1540874571,1 +115463,984725948,984726109,1 +115430,984725948,1540874554,1 +115438,984725963,152802872,1 +115466,984725963,984726006,1 +75590,984725976,984725721,1 +115436,984725976,1540874558,1 +115442,984725982,984725993,1 +115449,984725982,984726006,1 +115460,984725984,984725718,1 +115465,984725984,984726119,1 +89912,984725991,1540853756,1 +115443,984725993,984726016,1 +115435,984725993,1540874557,1 +115450,984726006,984726051,1 +40102,984726008,359995958,1 +115453,984726016,984725671,1 +115444,984726016,1540874563,1 +115437,984726029,984725963,1 +115457,984726029,984726051,1 +89917,984726031,653316029,1 +115458,984726051,984725716,1 +40098,984726062,1540809884,1 +40140,984726066,359996114,1 +115431,984726066,984725738,1 +115432,984726073,984725756,1 +115455,984726073,1540874570,1 +115467,984726086,984725798,1 +115448,984726086,984725982,1 +40105,984726104,1540809885,1 +115464,984726109,152802874,1 +115456,984726109,984726029,1 +115446,984726119,984725759,1 +48439,984752502,360477223,0 +115475,984752502,984752518,1 +127100,984752524,360476537,0 +115479,984752524,984752691,1 +89921,984752553,984752687,1 +115478,984752553,984752792,1 +115476,984752568,984752513,1 +89924,984752568,985285539,1 +48413,984752586,360476926,1 +80332,984752586,1540843072,0 +127101,984752628,1540884968,1 +115477,984752661,360476336,1 +48344,984752667,360477261,1 +89922,984752687,653316108,1 +115468,984752687,984752938,1 +115472,984752770,1540874575,1 +115598,984752781,653316107,1 +89937,984752822,1540853765,1 +115470,984752822,1540874572,1 +106599,984752865,1113454648,1 +115474,984752865,1540874578,1 +115471,984752875,984752770,1 +48445,984752875,1540813918,0 +48422,984752878,360477014,0 +115480,984752878,984752577,1 +48415,984752891,360476930,1 +115473,984752891,360477014,1 +89919,984752897,653315961,1 +115597,984752897,984752781,1 +48417,984752920,360476934,1 +48435,984752920,360477016,0 +89938,984752930,984752897,1 +143151,984771377,1540936459,1 +143176,984771377,1540936575,1 +115505,984771387,984772128,1 +115557,984771387,1540874728,1 +115512,984771399,984771632,1 +115538,984771399,1540874687,1 +115558,984771405,1540874737,1 +143174,984771405,1540936571,1 +115535,984771420,1540874684,1 +143149,984771437,1342999507,1 +143172,984771437,1540936556,1 +142634,984771446,1540934961,1 +115525,984771451,984771554,1 +90050,984771451,1540853831,1 +126454,984771473,984771569,1 +115540,984771473,984772144,1 +115496,984771489,984772169,1 +115503,984771489,984772412,1 +143182,984771495,1540936596,1 +115524,984771549,1540874662,1 +115526,984771554,984771946,1 +115532,984771562,984772503,1 +115521,984771562,984772747,1 +126455,984771569,984771946,1 +143148,984771572,1540936457,1 +143152,984771572,1540936462,1 +115517,984771596,1540874652,1 +115555,984771596,1540874726,1 +115549,984771632,1540874704,1 +90055,984771697,1540853848,1 +115530,984771747,984771697,1 +115501,984771827,984771420,1 +115550,984771827,1540874707,1 +98011,984771834,1540861227,1 +115495,984771834,1540874597,1 +115491,984771845,984771747,1 +115493,984771845,1540874595,1 +126456,984771946,984772020,1 +115552,984771985,1540874715,1 +126460,984771985,1540884457,1 +126451,984771986,653317930,1 +115502,984772020,984771489,1 +126457,984772020,984772423,1 +90053,984772024,1540853834,1 +115490,984772024,1540874593,1 +115553,984772024,1540874716,1 +115539,984772066,1540874689,1 +115544,984772073,984771569,1 +115489,984772073,984772412,1 +115522,984772103,984772138,1 +115534,984772103,1540874678,1 +126453,984772104,984771473,1 +115536,984772128,984772410,1 +115523,984772138,984771549,1 +115488,984772144,984772073,1 +115541,984772144,984772522,1 +115542,984772169,984772302,1 +115497,984772169,984772546,1 +115511,984772169,1540874626,1 +115506,984772175,984772066,1 +115548,984772175,1540874702,1 +115513,984772205,653318074,1 +90066,984772205,1540853861,1 +115494,984772262,984772336,1 +115527,984772262,984772380,1 +90069,984772269,1540853882,1 +115546,984772269,1540874700,1 +115529,984772276,1540874673,1 +143184,984772276,1540936611,1 +115485,984772291,653318226,1 +94288,984772291,1540856987,1 +115554,984772336,1540874721,1 +90052,984772377,1540853833,1 +115528,984772380,1540874669,1 +90054,984772403,1540853844,1 +115492,984772403,1540874594,1 +115537,984772410,1540874685,1 +115504,984772412,984771423,1 +115499,984772415,984772579,1 +90067,984772415,984772598,1 +126458,984772423,365310997,1 +115510,984772423,984772169,1 +98012,984772461,1540861230,1 +115547,984772469,984772175,1 +115515,984772469,1540874630,1 +115484,984772488,1540874581,1 +90051,984772503,1540853832,1 +115533,984772503,1540874674,1 +115520,984772546,984771751,1 +115498,984772546,1540874613,1 +115500,984772579,984771827,1 +115516,984772579,1540874636,1 +90068,984772598,1540853874,1 +115508,984772646,653317961,1 +115487,984772646,984772144,1 +115483,984772683,984772488,1 +115509,984772683,1540874615,1 +115556,984772719,1540874727,1 +115545,984772780,1540874697,1 +115551,984772780,1540874713,1 +115543,984772839,984772073,1 +115585,985285539,985285769,1 +89925,985285539,985286246,1 +115601,985285550,985285723,1 +115589,985285550,1540874751,1 +115607,985285557,985285952,1 +115614,985285590,1540874763,1 +89927,985285596,985285852,1 +115590,985285596,985286082,1 +115600,985285633,985285550,1 +115618,985285633,985286118,1 +115619,985285639,985285590,1 +115595,985285639,985286122,1 +115579,985285642,1540874748,1 +115580,985285723,985285557,1 +115602,985285723,985286289,1 +125007,985285846,656189126,1 +89944,985285846,1540853768,1 +89928,985285852,985285941,1 +89954,985285860,653316156,1 +115617,985285871,985285633,1 +115609,985285871,1540874760,1 +115599,985285897,985285633,1 +89930,985285903,653316109,1 +125010,985285908,1030294722,1 +115620,985285908,1540874766,1 +115604,985285911,985286289,1 +115581,985285935,1030294722,1 +115606,985285935,1540874758,1 +89946,985285937,653316140,1 +115615,985285937,1540874765,1 +89929,985285941,985285903,1 +115592,985285941,1540874753,1 +115588,985285952,985285550,1 +115608,985285952,985285871,1 +89932,985285979,653315885,1 +115582,985285979,985286049,1 +115586,985285991,985286122,1 +89943,985285991,1540853767,1 +115616,985286049,985285642,1 +115583,985286049,985285766,1 +115584,985286052,985285994,1 +115593,985286052,1540874754,1 +115587,985286122,1540874750,1 +115591,985286167,653316142,1 +115613,985286167,1540874762,1 +125024,985286241,984364723,1 +89926,985286246,985285596,1 +115594,985286246,1540874756,1 +115611,985286283,985285852,1 +115612,985286283,985286167,1 +115603,985286289,985285860,1 +115605,985286289,985285935,1 +115623,985417806,653316148,1 +89951,985417843,985417858,1 +115624,985417843,985417914,1 +89941,985417851,653316107,1 +115622,985417851,985417806,1 +89952,985417858,653316153,1 +115621,985417858,985417806,1 +40168,985921385,359997378,1 +115631,985921397,985921402,1 +40174,985921397,1540809931,1 +115632,985921402,985921385,1 +115634,985921402,985921498,1 +115633,985921411,985921436,1 +40121,985921425,359997133,1 +40119,985921436,152942457,1 +40114,985921486,359997138,1 +115635,985921486,1540874768,1 +115628,985921498,985921500,1 +115636,985921499,985921386,1 +40164,985921499,1540809924,1 +115629,985921500,359997066,1 +40173,985921500,985921397,1 +115660,985945859,359997705,1 +115646,985945859,1540874782,1 +40172,985945867,985946167,1 +115667,985945867,985946420,1 +2164,985945871,559564600,0 +115642,985945881,295776873,0 +115669,985945923,985946244,1 +40150,985945923,1540809918,1 +115641,985945940,985946253,1 +40116,985945940,985946416,1 +40171,985945971,985945867,1 +115653,985945971,985946046,1 +80290,985945999,559564585,0 +115666,985946025,985946390,1 +22961,985946029,985946154,0 +115654,985946046,359997135,1 +115648,985946098,985946382,1 +115671,985946098,985946401,1 +115672,985946126,1540874809,0 +40154,985946150,1540809919,1 +115650,985946150,1540874784,0 +115659,985946154,985945859,1 +22962,985946154,1540792804,0 +22949,985946167,1025767714,1 +115643,985946198,1540874769,1 +115647,985946206,985946098,1 +80294,985946206,1540843034,0 +115651,985946214,295865936,1 +40155,985946214,359997195,1 +115668,985946252,1540874801,0 +40091,985946279,359997152,0 +40147,985946280,985946313,1 +40148,985946313,559564587,1 +115670,985946313,1540874803,1 +40123,985946343,359997134,1 +40093,985946374,152802117,0 +24133,985946374,295865928,1 +115649,985946382,985946025,1 +115656,985946382,1540874788,1 +115657,985946390,985946275,1 +22944,985946401,1305716360,1 +115664,985946412,985946279,1 +40117,985946416,359997153,1 +115655,985946416,1540874786,1 +115640,985946420,985946046,1 +24131,985946472,359997196,1 +115674,985968627,985968638,1 +94577,985968630,985968647,1 +115699,985968630,1540874832,1 +115710,985968634,985968827,0 +115724,985968634,1411198431,1 +115712,985968635,985968895,0 +115675,985968638,985968725,1 +94578,985968647,737311449,1 +115688,985968659,737311453,1 +115719,985968659,985968849,1 +115728,985968664,985968698,1 +115716,985968664,985968746,1 +115709,985968666,985968634,0 +115693,985968667,279590064,1 +115715,985968667,985968875,0 +115678,985968668,985968882,1 +115733,985968668,1540874867,1 +152174,985968669,737311454,1 +115698,985968674,985968630,1 +94586,985968674,985968906,1 +115686,985968677,1540874815,1 +115423,985968685,984639754,1 +115673,985968685,985968798,1 +94427,985968690,737307325,1 +115721,985968690,1540874856,1 +115729,985968698,985968823,1 +104464,985968698,985968886,1 +115679,985968709,985968759,1 +135148,985968709,985968827,0 +115702,985968746,737307325,1 +115717,985968746,737311448,1 +104468,985968748,1540866236,1 +115734,985968751,279590065,1 +135150,985968751,1540905567,1 +115696,985968759,985968635,1 +115680,985968759,1540874810,1 +115695,985968800,985968759,1 +115690,985968800,985968918,1 +94693,985968802,737998501,1 +115706,985968818,1540874844,1 +115714,985968818,1540874852,0 +115700,985968823,1540874834,1 +115730,985968823,1540874860,1 +115711,985968827,1540874849,0 +104467,985968829,1540866235,1 +115732,985968829,1540874866,1 +152179,985968849,1540961375,1 +115723,985968852,985968904,1 +135149,985968875,985968751,1 +115692,985968879,1540874818,1 +115707,985968879,1540874846,1 +115722,985968883,985968852,1 +115726,985968883,985968914,1 +115683,985968885,985968907,1 +104465,985968886,737311463,1 +94576,985968886,985968630,1 +115682,985968889,985968650,1 +152183,985968889,1540961381,1 +115713,985968895,985968818,0 +115681,985968895,985968900,1 +152177,985968898,1540961374,1 +21438,985968900,279590090,1 +115676,985968903,985968669,1 +94696,985968904,1540857308,1 +115701,985968904,1540874835,1 +94587,985968906,737311464,1 +115691,985968906,985968647,1 +115684,985968907,1540874813,1 +115704,985968907,1540874842,1 +115731,985968910,985968790,1 +152182,985968910,985968889,1 +115727,985968914,985968664,1 +115697,985968914,1540874830,1 +152176,985968917,737311455,1 +135147,985968918,985968709,0 +118853,991240614,360012743,1 +111998,1013381818,982077221,1 +40208,1013433823,1540809954,0 +118023,1013433831,360000003,0 +127551,1013433831,360002721,0 +118026,1013433836,1540876332,0 +118032,1013433836,1540876341,0 +118045,1013433836,1540876373,0 +118043,1013433856,1540876368,0 +137790,1013433856,1540920297,0 +118046,1013433859,559597072,0 +118038,1013433863,1540876357,0 +137774,1013433863,1540920271,0 +127572,1013433900,1540885219,0 +127550,1013433945,1013433831,0 +127581,1013433973,559939164,1 +51532,1013433983,1540815969,0 +119652,1013434005,1540879267,0 +118028,1013434025,559939114,0 +75734,1013434025,1540840280,1 +75759,1013465133,559939030,0 +107744,1015274267,1540869450,0 +107727,1015274270,1540869404,1 +118132,1015274279,1540876503,0 +53826,1015275358,1540820511,1 +111638,1015275655,1540872148,1 +111733,1015275655,1540872193,1 +118459,1019989387,1540877091,1 +118468,1019989387,1540877095,1 +118460,1019989420,1019989631,1 +118452,1019989420,1540877026,1 +118465,1019989426,1019990344,1 +104716,1019989595,912014327,1 +118461,1019989631,1019990136,1 +118469,1019989631,1540877108,1 +118453,1019989686,1019989863,1 +118464,1019989821,1019989426,1 +118458,1019989821,1540877087,1 +118454,1019989863,1540877044,1 +118462,1019990136,1019990398,1 +118463,1019990136,1540877092,1 +118467,1019990225,1019989387,1 +118456,1019990225,1019990327,1 +17597,1019990282,418771215,1 +104715,1019990290,1019989595,1 +118457,1019990327,1540877064,1 +118466,1019990344,1540877094,1 +104714,1019990398,1019990290,1 +40564,1025767698,360009658,1 +118610,1025767702,360009853,1 +40509,1025767707,1540810086,1 +118627,1025767708,1025767710,1 +118624,1025767708,1025767735,1 +118618,1025767710,1025767703,1 +118617,1025767712,359996729,1 +118619,1025767714,1025767709,1 +22950,1025767714,1540792793,1 +40510,1025767715,360009658,1 +118612,1025767715,1540877514,1 +118615,1025767720,359996726,1 +118611,1025767720,359997064,1 +40572,1025767724,360009853,1 +118613,1025767724,1025767738,1 +118622,1025767735,1540877522,1 +118628,1025767737,1025767700,1 +40144,1025767737,1540809914,1 +40508,1025767738,1025767707,1 +118625,1025767739,1025767698,1 +40568,1025767739,1025767707,1 +40142,1025767741,359996726,1 +118620,1025767741,1025767701,1 +45651,1030294074,360205940,1 +142507,1030294076,974031018,1 +112124,1030294076,1540872799,1 +142506,1030294078,1030294076,1 +29736,1030294080,338487310,1 +118848,1030294080,1030294074,1 +125042,1030294722,653283481,1 +125023,1030294722,985286241,1 +124870,1030300192,360012661,1 +111612,1030300192,972316218,1 +118858,1030300198,360012742,1 +40857,1030300198,360012746,1 +118851,1030300201,1540877994,1 +40817,1030300202,360012539,1 +40765,1030300203,360012185,1 +40740,1030300203,1030300209,1 +40710,1030300205,973982977,1 +118849,1030300205,1540877989,1 +124883,1030300207,360012824,1 +78916,1030300209,360012537,0 +78914,1030300217,360012651,0 +118857,1030300217,1030300198,1 +118893,1030313077,1030313208,1 +118877,1030313077,1030313233,1 +21461,1030313078,279591653,1 +21417,1030313078,1540790966,0 +118863,1030313082,1030313183,1 +93503,1030313082,1030313192,1 +118921,1030313087,1030313138,1 +118981,1030313087,1030323803,1 +119006,1030313089,1030323711,1 +118934,1030313089,1030323718,1 +93506,1030313096,716889097,1 +118870,1030313096,1540878013,0 +118932,1030313102,1030313220,1 +118928,1030313102,1540878043,0 +118918,1030313106,360204997,1 +118892,1030313106,1030313077,1 +45567,1030313108,1030313117,1 +118936,1030313108,1030313154,1 +45568,1030313117,360204997,1 +118916,1030313117,1030313278,1 +118871,1030313118,1540878014,0 +118922,1030313138,1540878032,1 +142537,1030313138,1540934719,1 +118891,1030313142,1030313259,1 +118901,1030313142,1540878021,1 +118924,1030313144,1540878033,0 +118873,1030313148,1030313163,1 +118927,1030313148,1540878041,0 +45624,1030313151,1030313252,0 +118884,1030313153,278009648,1 +118931,1030313153,1540878053,0 +118879,1030313154,278009651,1 +118937,1030313154,1030313192,1 +118874,1030313163,1030323784,1 +118866,1030313163,1540878001,1 +118926,1030313166,1540878037,0 +142534,1030313169,278009645,1 +118923,1030313169,1030313259,1 +118919,1030313181,1540878031,1 +135246,1030313183,1030313214,1 +118864,1030313183,1030313220,1 +93504,1030313192,278009650,1 +118938,1030313192,1030313245,1 +118890,1030313199,1540878019,1 +142536,1030313199,1540934717,1 +118904,1030313208,1030323815,0 +135245,1030313208,1540905607,1 +118895,1030313211,360193189,1 +45575,1030313211,360204928,1 +118929,1030313214,1540878046,0 +45591,1030313215,360205112,1 +118887,1030313215,1030313257,1 +118920,1030313219,1030313087,1 +118925,1030313219,1540878034,0 +118933,1030313220,1030313089,1 +118865,1030313220,1540877999,1 +118889,1030313231,1030313151,1 +118882,1030313231,1030313285,1 +118862,1030313233,1030313082,1 +118878,1030313233,1030313154,1 +118930,1030313245,1540878048,0 +45625,1030313252,1540812102,0 +118886,1030313253,1030313182,1 +118869,1030313253,1540878011,0 +45579,1030313257,360205016,1 +118888,1030313257,1030313231,1 +118903,1030313258,1030313189,1 +118868,1030313258,1540878007,0 +135267,1030313259,1030328829,1 +135268,1030313259,1540905615,1 +119008,1030313263,1030323827,1 +93478,1030313266,1540856546,0 +118902,1030313271,1030313258,1 +149348,1030313274,278009537,1 +21418,1030313274,1540790967,0 +118917,1030313278,1030313106,1 +118861,1030313278,1030313233,1 +118883,1030313285,360204997,1 +45582,1030313285,360205016,1 +118950,1030313287,1030323707,1 +118915,1030323707,1030313166,1 +45448,1030323708,360203555,1 +118948,1030323708,1030323808,1 +119007,1030323711,1030313263,1 +118991,1030323711,1030323852,1 +93493,1030323712,716888937,1 +118989,1030323712,1540878082,0 +45529,1030323715,1030323856,1 +118935,1030323718,1030323802,1 +118945,1030323718,1030323852,1 +121636,1030323719,1030323821,1 +118955,1030323720,1540878058,1 +118952,1030323723,1030323736,1 +118994,1030323723,1030323753,1 +118956,1030323724,1030323759,1 +118960,1030323724,1540878060,1 +118947,1030323728,1030323822,1 +119001,1030323728,1030323827,1 +45535,1030323733,1540812061,1 +118984,1030323735,1030323776,1 +45549,1030323735,1030323823,1 +118953,1030323736,1030323715,1 +118999,1030323736,1030323813,1 +135239,1030323737,360191911,0 +118963,1030323741,1030323862,1 +93497,1030323743,429286584,1 +118987,1030323743,1540878079,0 +45532,1030323745,1030323859,1 +118973,1030323753,1030323761,1 +118995,1030323753,1030323862,1 +44987,1030323757,360191911,1 +119010,1030323757,1030323791,1 +119014,1030323759,1030323800,1 +118998,1030323761,1030323736,1 +118974,1030323761,1030323795,1 +45444,1030323768,360202580,1 +118980,1030323769,1030323733,1 +118967,1030323769,1030323778,1 +45519,1030323771,360204362,1 +118996,1030323771,1030323783,1 +135241,1030323776,360204350,0 +45534,1030323778,1030323733,1 +118910,1030323779,360193320,0 +118951,1030323779,1540878056,1 +118962,1030323783,1030323741,1 +118997,1030323783,1030323761,1 +118875,1030323784,1030313263,1 +118939,1030323784,1540878055,1 +118912,1030323786,360204943,0 +118972,1030323786,1030323753,1 +118941,1030323789,1030323794,1 +135252,1030323791,1540905614,1 +118908,1030323792,1030323829,0 +118975,1030323792,1540878073,1 +118979,1030323794,1030323769,1 +118942,1030323794,1030323859,1 +45528,1030323795,1030323715,1 +119005,1030323797,1030313089,1 +118969,1030323800,1540878068,1 +45517,1030323801,360204339,1 +118976,1030323802,1030323846,1 +45537,1030323803,1540812064,1 +45536,1030323806,1540812062,1 +118914,1030323806,1540878030,1 +118943,1030323807,1030323838,1 +118906,1030323807,1540878026,0 +45458,1030323808,360202610,1 +118954,1030323810,1030323720,1 +118958,1030323810,1030323812,1 +118970,1030323812,1540878070,1 +119000,1030323813,1030323728,1 +118978,1030323813,1030323856,1 +119004,1030323815,1030323797,1 +118905,1030323815,1540878022,0 +118968,1030323821,1540878067,1 +121637,1030323821,1540881850,1 +45531,1030323822,1030323745,1 +45550,1030323823,360204435,1 +45556,1030323823,1540812072,1 +118983,1030323823,1540878075,1 +45509,1030323825,360203787,1 +118990,1030323825,1030323701,1 +119009,1030323827,1030323745,1 +119002,1030323827,1030323789,1 +118909,1030323829,1540878027,0 +45512,1030323830,360199280,1 +118959,1030323830,360204671,1 +83859,1030323833,360203933,1 +118957,1030323833,1030323810,1 +118944,1030323838,1030323718,1 +119003,1030323838,1030323797,1 +118966,1030323840,1030323719,1 +119013,1030323840,1030323759,1 +118993,1030323846,1030323723,1 +118977,1030323846,1030323813,1 +93485,1030323848,429286582,1 +118988,1030323848,1540878081,0 +45387,1030323851,360202618,1 +118965,1030323851,1030323727,1 +118946,1030323852,1030323728,1 +118992,1030323852,1030323846,1 +135255,1030323853,360191655,0 +118971,1030323853,1030323729,1 +121635,1030323854,1030323719,1 +45530,1030323856,1030323822,1 +45533,1030323859,1540812056,1 +45504,1030323861,360203940,1 +119011,1030323861,1540878084,1 +118964,1030323862,1540878066,1 +118949,1030323863,1030313287,1 +118940,1030323863,1030323789,1 +119032,1030328417,1030328528,1 +119051,1030328417,1030329007,1 +119086,1030328422,1030328532,1 +119117,1030328422,1030329153,1 +119044,1030328430,1030329153,0 +119123,1030328430,1540878316,1 +119045,1030328432,1030329033,1 +119071,1030328432,1540878197,1 +112193,1030328438,974066523,0 +119041,1030328438,1540878140,0 +119049,1030328445,1540878145,1 +119105,1030328445,1540878276,0 +119068,1030328450,1540878187,1 +119153,1030328450,1540878388,1 +119048,1030328458,1030328578,1 +119091,1030328458,1540878234,1 +119124,1030328461,1030334624,1 +119025,1030328461,1540878100,1 +119081,1030328463,1030328858,1 +119163,1030328463,1540878424,1 +119026,1030328465,1540878101,1 +119112,1030328471,1540878295,0 +119199,1030328471,1540878497,1 +119035,1030328487,1540878113,0 +119090,1030328498,1030328458,1 +135220,1030328498,1540905598,1 +119065,1030328500,1540878180,1 +119177,1030328500,1540878458,1 +119178,1030328501,1540878466,1 +119058,1030328502,1540878173,1 +119022,1030328503,1030328658,1 +119165,1030328503,1540878430,1 +119059,1030328505,1030329153,1 +119103,1030328511,1540878266,0 +119033,1030328528,1030328697,1 +119097,1030328528,1540878253,1 +119061,1030328532,974067413,1 +112272,1030328532,1030328643,0 +93448,1030328543,1030328976,1 +119076,1030328558,1030329033,1 +119119,1030328558,1030329099,1 +119116,1030328578,1540878309,0 +119029,1030328580,1030328785,1 +119057,1030328580,1540878171,1 +119017,1030328585,1030328858,1 +119095,1030328585,1540878252,1 +119024,1030328616,1540878095,1 +119075,1030328616,1540878201,1 +119179,1030328622,1030328824,1 +119132,1030328622,1540878346,1 +119098,1030328624,1030328505,1 +119040,1030328624,1540878139,0 +119122,1030328643,1030328430,1 +112273,1030328643,1540872986,0 +119067,1030328656,1540878089,1 +119137,1030328656,1540878348,1 +119023,1030328658,1540878091,1 +119175,1030328658,1540878454,1 +119016,1030328693,1540878085,1 +119050,1030328693,1540878155,1 +119109,1030328697,1540878283,0 +119062,1030328717,1030328735,1 +119027,1030328717,1540878104,1 +119110,1030328733,1540878287,0 +119063,1030328735,1540878174,1 +119094,1030328735,1540878244,1 +119064,1030328741,1540878178,1 +119082,1030328741,1540878203,1 +119030,1030328785,1030329000,1 +119066,1030328805,1540878186,1 +119111,1030328807,1540878292,0 +119114,1030328829,1540878303,0 +119018,1030328858,1030328501,1 +119078,1030328872,1030328926,0 +119102,1030328872,1540878263,0 +119080,1030328875,1540878202,1 +119131,1030328875,1540878343,1 +119015,1030328922,1030328693,1 +119028,1030328922,1540878109,1 +119038,1030328924,1540878125,0 +119072,1030328924,1540878198,1 +119034,1030328926,1540878112,0 +119118,1030328926,1540878311,1 +119070,1030328950,1030328432,1 +119104,1030328950,1540878273,0 +93449,1030328976,716888435,1 +119042,1030328979,1540878142,0 +119101,1030328994,1540878257,0 +119031,1030329000,1030328417,1 +119093,1030329000,1540878238,1 +119096,1030329007,1030328424,1 +119052,1030329007,1030329069,1 +119077,1030329033,716888426,1 +119046,1030329033,716888902,1 +119099,1030329048,1030328432,1 +119037,1030329048,1540878121,0 +119079,1030329069,1030328875,1 +119053,1030329069,1030334738,1 +119036,1030329073,1540878119,0 +93480,1030329080,1540856548,1 +119089,1030329080,1540878227,1 +119100,1030329094,716888493,1 +119039,1030329094,1540878130,0 +119113,1030329097,1540878297,0 +93481,1030329099,716888902,1 +119120,1030329099,1030328498,1 +119020,1030329114,1540878087,1 +119347,1030329114,1540878844,1 +119085,1030329116,1030328422,1 +119107,1030329116,1540878282,1 +119060,1030329153,1030328532,1 +119106,1030329155,1030328994,0 +119083,1030329155,1540878216,1 +119043,1030329157,1540878143,0 +119021,1030329177,1030328503,1 +119115,1030329188,1540878307,0 +119055,1030334547,1540878167,1 +119305,1030334548,1030689903,1 +119297,1030334552,1540878687,1 +119138,1030334557,1540878349,1 +119161,1030334557,1540878415,1 +119267,1030334559,1030689489,1 +119056,1030334560,1540878168,1 +119156,1030334560,1540878398,1 +119155,1030334568,1540878394,1 +119143,1030334572,1030334580,1 +119170,1030334572,1030334595,1 +119167,1030334575,1030334609,1 +119225,1030334575,1030689127,1 +119073,1030334580,1540878199,1 +119144,1030334580,1540878361,1 +119135,1030334581,1030334671,1 +119296,1030334581,1540878685,1 +119145,1030334585,1540878369,1 +119168,1030334585,1540878433,1 +119130,1030334586,1030334594,1 +119173,1030334586,1540878444,1 +119348,1030334594,1030688814,1 +119069,1030334595,1540878196,1 +119140,1030334597,1030334639,1 +119345,1030334597,1030334718,1 +119162,1030334604,1540878416,1 +119174,1030334604,1540878448,1 +119209,1030334609,1540878520,1 +119224,1030334620,1030334575,1 +119159,1030334620,1030334675,1 +119125,1030334624,1540878323,1 +119154,1030334626,1540878392,1 +119157,1030334626,1540878410,1 +119169,1030334630,1030328465,1 +119176,1030334630,1540878456,1 +119307,1030334636,1030689571,1 +119141,1030334639,1030689487,1 +119139,1030334659,1030334597,1 +119148,1030334659,1030334705,1 +119127,1030334670,1030334718,1 +119263,1030334670,1030689487,1 +119136,1030334671,1030334552,1 +119166,1030334671,1540878432,1 +119151,1030334675,1540878382,1 +119133,1030334687,1030334733,1 +119160,1030334687,1540878414,1 +119074,1030334689,1540878200,1 +119126,1030334689,1540878327,1 +119208,1030334694,1030334609,1 +119158,1030334694,1030334620,1 +119172,1030334700,1030328824,1 +119164,1030334700,1030334547,1 +119149,1030334705,1030334552,1 +119150,1030334711,1540878379,1 +119128,1030334718,1540878339,1 +119134,1030334733,1030334579,1 +119171,1030334733,1540878439,1 +119152,1030334736,1540878385,1 +119295,1030334736,1540878683,1 +119054,1030334738,1540878160,1 +119129,1030334741,1030334586,1 +119146,1030334741,1030689017,1 +119293,1030688806,1540878677,1 +119337,1030688806,1540878776,1 +119275,1030688810,1540878611,0 +119317,1030688810,1540878737,1 +107957,1030688812,1540869683,0 +119349,1030688814,1030689782,1 +119327,1030688814,1540878757,1 +119311,1030688835,1030689533,0 +107936,1030688835,1540869656,1 +119320,1030688837,1540878746,1 +142582,1030688859,278009636,1 +135217,1030688861,1030689545,0 +119183,1030688862,952161861,0 +119271,1030688862,1540878605,1 +119194,1030688867,1030689913,0 +107985,1030688867,1540869752,0 +119289,1030688896,1540878647,1 +119206,1030688899,1030328807,1 +119280,1030688899,1540878627,0 +119339,1030688900,1540878790,1 +119795,1030688900,1540879510,1 +119211,1030688902,1540878522,0 +119198,1030688913,1030689068,1 +119309,1030688913,1540878726,1 +119242,1030688929,1540878576,1 +107940,1030688937,952161121,1 +119266,1030688937,1540878604,1 +119294,1030688971,1540878681,1 +119245,1030688975,1030689148,1 +119202,1030688975,1030690020,1 +119319,1030688988,1540878742,1 +119338,1030688988,1540878789,1 +119286,1030688989,1030689782,1 +119207,1030688989,1540878510,1 +119269,1030689001,1030689262,1 +119264,1030689001,1030689948,1 +119147,1030689017,1030334659,1 +119261,1030689017,1540878596,1 +135216,1030689019,1540905590,0 +119232,1030689032,1540878558,0 +119283,1030689046,1540878635,1 +119329,1030689046,1540878771,1 +119248,1030689060,1030689225,1 +119778,1030689060,1540879466,1 +119333,1030689068,1030689248,1 +119318,1030689068,1540878740,1 +119342,1030689076,1540878797,1 +119213,1030689096,1540878528,0 +119312,1030689096,1540878731,1 +93479,1030689113,1030329080,1 +119237,1030689113,1030689032,0 +119196,1030689122,1540878481,1 +119228,1030689122,1540878548,1 +119230,1030689127,1030689230,1 +119182,1030689131,1540878473,0 +119235,1030689148,1540878567,0 +119229,1030689166,1540878553,1 +119281,1030689166,1540878630,1 +119315,1030689176,1030690008,1 +119240,1030689202,1540878572,1 +107976,1030689225,1540869721,0 +119249,1030689225,1540878586,1 +119231,1030689230,1540878557,1 +119334,1030689248,1030689358,1 +107956,1030689248,1540869679,0 +119310,1030689253,1030688812,1 +119243,1030689253,1540878578,1 +119270,1030689262,1030690037,1 +119282,1030689262,1540878631,1 +119274,1030689268,1030688810,0 +119330,1030689298,1030689465,1 +119272,1030689298,1540878607,1 +119336,1030689343,1030690069,1 +119222,1030689343,1540878542,1 +107978,1030689358,1540869737,0 +119335,1030689358,1540878775,1 +119247,1030689402,1540878584,1 +119741,1030689402,1540879379,1 +119259,1030689412,1030689874,1 +119200,1030689412,1030690015,1 +119734,1030689414,1540879372,1 +119223,1030689442,1540878543,1 +119236,1030689442,1540878569,0 +119226,1030689465,1540878546,1 +119331,1030689465,1540878773,1 +119187,1030689466,1030688859,0 +119465,1030689466,1540878923,1 +119304,1030689470,1540878711,1 +119142,1030689487,1540878352,1 +119260,1030689489,1030688841,1 +119268,1030689489,1030689001,1 +119204,1030689513,1030689651,1 +119192,1030689513,1030689731,0 +119324,1030689515,1030690106,1 +119188,1030689515,1540878474,1 +119252,1030689518,1030689677,1 +119212,1030689518,1540878524,0 +119277,1030689533,1540878616,0 +119238,1030689541,1030689925,1 +119322,1030689541,1540878748,1 +119299,1030689545,1030690015,1 +135218,1030689545,1540905594,0 +119290,1030689557,1540878648,1 +119346,1030689557,1540878837,1 +119197,1030689563,1540878496,1 +119215,1030689563,1540878533,0 +119276,1030689565,1540878614,0 +119332,1030689565,1540878774,0 +119308,1030689571,1540878720,1 +119328,1030689571,1540878770,1 +119301,1030689586,278009641,1 +119244,1030689586,1540878579,1 +119205,1030689592,1540878499,1 +119291,1030689592,1540878650,1 +119221,1030689640,1030689343,1 +119210,1030689640,1540878521,1 +119314,1030689645,1030689176,1 +107977,1030689645,1540869731,0 +119186,1030689651,1030689466,0 +119214,1030689653,1540878531,0 +119323,1030689672,1540878751,1 +119220,1030689677,1540878541,1 +119253,1030689677,1540878588,1 +119227,1030689686,1540878547,1 +142529,1030689697,278009638,1 +119193,1030689731,1030688867,0 +119241,1030689736,1540878574,1 +119340,1030689736,1540878793,1 +119256,1030689750,1030690020,1 +119234,1030689750,1540878564,0 +119278,1030689755,1540878619,0 +119285,1030689765,1540878638,1 +119344,1030689765,1540878824,1 +119287,1030689782,1030689470,1 +119216,1030689784,1030688902,0 +119313,1030689788,1030689645,1 +107958,1030689788,1540869686,0 +119251,1030689798,1030689518,1 +119255,1030689805,1540878590,1 +119292,1030689833,1540878656,1 +119288,1030689835,1540878645,1 +119341,1030689835,1540878795,1 +135219,1030689874,1540905596,0 +119284,1030689896,1030689765,1 +119279,1030689903,1030689896,1 +119306,1030689903,1540878717,1 +107952,1030689913,952161861,0 +119195,1030689913,1540878480,0 +119302,1030689920,1540878708,1 +119343,1030689920,1540878812,1 +119239,1030689925,1030689202,1 +119189,1030689925,1540878476,1 +119298,1030689934,1540878689,1 +119262,1030689961,1540878599,1 +119326,1030689961,1540878752,1 +107959,1030689974,1540869697,0 +119250,1030689974,1540878587,1 +119316,1030690008,1540878734,1 +119740,1030690008,1540879378,1 +119300,1030690015,1030689586,1 +119201,1030690015,1540878498,1 +119257,1030690020,278009638,1 +119203,1030690020,1030689513,1 +119233,1030690034,1540878562,0 +119273,1030690034,1540878608,1 +119254,1030690039,1540878589,1 +119218,1030690049,1036415511,1 +119731,1030690049,1036415559,1 +107951,1030690067,1540869663,0 +119019,1030690067,1540878086,1 +119088,1030690067,1540878222,1 +119321,1030690069,1030689541,1 +119325,1030690106,1030689835,1 +119303,1030690106,1540878710,1 +119362,1030974448,360202039,1 +46219,1030974473,1030975038,1 +119384,1030974501,1030975450,1 +45353,1030974504,360201324,1 +119427,1030974504,1030975309,1 +119464,1030974506,1030689466,1 +119191,1030974506,1030689513,0 +119389,1030974510,1030975171,1 +119439,1030974513,1030974515,1 +119418,1030974513,1030975348,1 +45401,1030974515,1030974873,1 +119372,1030974517,1540878858,1 +119457,1030974517,1540878912,1 +135233,1030974544,360202135,1 +119410,1030974544,1030975386,1 +119432,1030974558,1540878905,1 +119391,1030974564,1030975224,1 +119426,1030974568,1030974504,1 +119451,1030974609,1030975401,1 +119387,1030974609,1030975594,1 +119475,1030974620,1030689697,1 +119350,1030974620,1030974932,1 +119417,1030974629,1030974513,1 +119425,1030974629,1030974568,1 +119433,1030974633,1030974945,1 +119353,1030974633,1540878847,1 +83863,1030974636,1030975440,1 +119423,1030974636,1540878904,1 +119452,1030974662,1030975128,1 +119380,1030974662,1030975272,1 +119429,1030974670,1030975352,1 +119471,1030974698,1030974564,1 +119369,1030974698,1540878855,1 +119415,1030974704,1540878898,1 +45381,1030974750,1030975100,1 +119468,1030974750,1540878925,1 +45380,1030974753,1540812020,1 +119474,1030974758,1030974620,1 +119462,1030974758,1030974988,1 +119393,1030974762,278009632,1 +119454,1030974762,1030975149,1 +119412,1030974801,1030974670,1 +119435,1030974801,1030975670,1 +119357,1030974806,1030975180,1 +45294,1030974818,1540811983,1 +135225,1030974821,360235264,1 +119431,1030974861,360201710,1 +119354,1030974861,360202041,1 +119481,1030974870,1030975557,1 +107969,1030974870,1540869713,1 +45402,1030974873,360201944,1 +119472,1030974873,1030975348,1 +119478,1030974914,1030975597,1 +45356,1030974932,1540812011,1 +119434,1030974945,1030974801,1 +119445,1030974945,1030974989,1 +119463,1030974988,1540878919,1 +119371,1030974989,1030974517,1 +119446,1030974989,1030975081,1 +46222,1030974996,360235363,1 +46230,1030975035,360235265,1 +119382,1030975035,1030975460,1 +46220,1030975038,360235260,1 +119355,1030975038,1030975276,1 +119467,1030975049,1030974501,1 +119375,1030975049,1030975597,1 +119366,1030975056,1030975100,1 +119396,1030975075,1030975552,0 +119456,1030975081,1030974517,1 +119364,1030975084,1540878852,1 +119386,1030975084,1540878867,1 +119413,1030975092,1030975272,1 +135231,1030975092,1540905604,1 +45382,1030975100,1030975486,1 +119453,1030975128,560946140,1 +107945,1030975128,1540869657,1 +119483,1030975136,1030974753,1 +119394,1030975136,1030975056,1 +119450,1030975140,1030974609,1 +119477,1030975140,1030974914,1 +119441,1030975145,1030975489,1 +119461,1030975145,1540878918,1 +119352,1030975149,1030974633,1 +119455,1030975149,1540878911,1 +119390,1030975171,1540878868,1 +119484,1030975176,1030974764,1 +119469,1030975176,1540878927,1 +119470,1030975180,1030974698,1 +119358,1030975180,1030975434,1 +119392,1030975224,1540878869,1 +45292,1030975227,1540811979,1 +45409,1030975228,360202039,1 +119416,1030975238,1030974629,1 +45405,1030975238,1030975386,1 +119381,1030975272,1540878864,1 +45377,1030975276,360201709,1 +76201,1030975289,560946140,1 +119428,1030975309,1030974670,1 +119399,1030975309,1030975228,0 +119486,1030975324,1030974821,1 +119482,1030975324,1030975136,1 +142584,1030975335,278009637,1 +119363,1030975335,1540878850,0 +119480,1030975344,1030974870,1 +107943,1030975344,1030975541,1 +119473,1030975348,1030974758,1 +119419,1030975348,1030974988,1 +119430,1030975352,1030974861,1 +119444,1030975352,1030974945,1 +45406,1030975386,1030975591,1 +45399,1030975397,360201919,1 +119424,1030975397,1030974629,1 +119365,1030975401,1030975056,1 +119421,1030975408,1030975571,1 +119440,1030975408,1540878906,1 +119359,1030975434,1540878848,1 +119368,1030975434,1540878854,1 +83864,1030975440,600398870,1 +46225,1030975444,360236494,1 +119373,1030975444,1030974996,1 +119485,1030975450,1030975324,1 +119385,1030975450,1540878866,1 +119374,1030975460,1030975049,1 +119383,1030975460,1540878865,1 +45355,1030975482,1030974932,1 +119460,1030975482,1540878915,1 +119379,1030975484,1540878863,1 +119401,1030975484,1540878874,1 +119356,1030975486,1030974806,1 +45383,1030975486,1540812022,1 +119438,1030975489,1030974513,1 +119442,1030975489,1030974568,1 +45376,1030975499,1030975276,1 +119420,1030975499,1030975408,1 +119466,1030975541,1030975049,1 +107944,1030975541,1030975128,1 +142576,1030975549,952161496,1 +119449,1030975549,1030975140,1 +119459,1030975552,1030975482,1 +119397,1030975552,1030975670,0 +76199,1030975557,560946138,1 +119422,1030975571,1540878900,1 +45407,1030975591,360201323,1 +119388,1030975594,1030974510,1 +119476,1030975594,1540878931,1 +119376,1030975597,278009627,1 +119479,1030975597,1030975344,1 +119411,1030975623,1030974801,1 +119458,1030975623,1540878913,1 +119436,1030975670,360201324,1 +119398,1030975670,1030975309,0 +118033,1033229521,559939005,0 +119651,1033229521,1540879266,0 +118035,1033229536,1540876349,0 +119661,1033229536,1540879272,0 +119738,1036415319,1540879376,1 +119754,1036415319,1540879420,1 +119762,1036415320,1540879439,1 +119688,1036415322,1036415754,1 +119718,1036415357,1540879365,1 +119786,1036415357,1540879491,1 +119767,1036415362,1036415567,1 +119791,1036415372,1540879504,0 +119720,1036415374,1036628019,1 +119888,1036415374,1540879645,1 +119730,1036415400,1030690049,1 +119749,1036415400,1540879416,1 +119800,1036415401,1540879515,0 +119733,1036415416,1030689414,1 +119758,1036415416,1540879433,1 +119699,1036415417,1036415521,0 +119772,1036415418,1036415700,1 +119736,1036415421,1036415528,1 +119698,1036415421,1540879326,1 +135222,1036415436,1540905601,0 +119692,1036415442,1540879318,1 +119757,1036415442,1540879430,0 +119695,1036415445,1540879321,1 +119766,1036415446,1036415362,1 +119780,1036415446,1540879469,1 +119702,1036415452,1540879334,0 +119745,1036415452,1540879389,1 +119806,1036415461,1036415491,1 +135223,1036415461,1540905602,0 +119750,1036415463,1036415850,1 +119713,1036415463,1540879350,0 +119796,1036415464,1036415783,1 +119776,1036415464,1540879455,1 +119753,1036415465,1036415319,1 +119747,1036415466,1540879398,1 +119807,1036415491,1036415559,1 +119788,1036415499,1540879494,0 +119219,1036415511,1030689677,1 +119700,1036415521,1540879332,0 +119787,1036415521,1540879492,0 +119737,1036415528,1036415823,1 +119721,1036415528,1540879366,1 +119715,1036415534,1036415723,1 +119712,1036415534,1540879348,0 +119697,1036415543,1540879322,1 +119722,1036415543,1540879369,1 +119792,1036415557,1540879506,0 +93153,1036415558,1540856414,1 +119809,1036415558,1540879523,1 +119732,1036415559,1036415416,1 +119693,1036415566,560728686,1 +119768,1036415567,1036415833,1 +119681,1036415568,1036415362,1 +119743,1036415568,1540879383,1 +119803,1036415570,1036415711,0 +119794,1036415588,1030688900,1 +119735,1036415588,1540879375,1 +119711,1036415589,1540879347,0 +119691,1036415592,1036415442,1 +119707,1036415592,1540879340,0 +119894,1036415594,1036415589,1 +119728,1036415594,1036627969,1 +107974,1036415620,1540869714,0 +135221,1036415620,1540905599,0 +119759,1036415633,1036415722,1 +119777,1036415633,1540879462,1 +119704,1036415635,1540879336,0 +119765,1036415635,1540879442,1 +119687,1036415641,1036415322,1 +119714,1036415651,1540879351,0 +149783,1036415652,278009594,1 +119701,1036415654,1036415452,0 +119723,1036415657,1540879371,1 +119755,1036415657,1540879427,1 +119729,1036415661,1036415400,1 +107960,1036415661,1540869699,0 +119790,1036415680,1036415372,0 +119742,1036415693,1540879380,1 +119784,1036415693,1540879474,1 +119782,1036415695,1540879472,1 +119802,1036415695,1540879520,0 +149785,1036415699,278009596,1 +119717,1036415700,1540879360,1 +119773,1036415700,1540879451,1 +119708,1036415701,278009620,1 +119764,1036415701,1540879440,1 +119724,1036415710,1036415786,1 +119752,1036415710,1540879419,1 +119781,1036415711,1036415888,0 +119797,1036415711,1540879511,0 +119783,1036415718,1036415693,1 +142558,1036415720,278009613,1 +119760,1036415722,1540879437,1 +119727,1036415723,1036415594,1 +119716,1036415723,1036415821,1 +119798,1036415730,1540879513,0 +119804,1036415731,1540879522,1 +149782,1036415731,1540953310,1 +119683,1036415732,1540879290,1 +119690,1036415732,1540879314,1 +119774,1036415744,1036415816,1 +119771,1036415754,1036415418,1 +119689,1036415754,1540879312,1 +119709,1036415775,1540879345,1 +119770,1036415775,1540879443,1 +119719,1036415781,1036415374,1 +119686,1036415781,1540879310,1 +119725,1036415786,1036415850,1 +119246,1036415788,1540878581,1 +119801,1036415788,1540879517,0 +119696,1036415792,1036415543,1 +119746,1036415792,1540879395,1 +119779,1036415795,1540879467,1 +119785,1036415795,1540879479,1 +119705,1036415797,1540879337,0 +119703,1036415809,1540879335,0 +142560,1036415810,1540934757,1 +142563,1036415812,278009616,1 +119756,1036415812,1540879428,0 +119775,1036415816,1540879452,1 +119885,1036415816,1540879629,1 +119685,1036415821,1540879309,1 +119799,1036415822,1540879514,0 +119739,1036415823,278009592,1 +119769,1036415833,1036415775,1 +119726,1036415850,1036415723,1 +119751,1036415850,1540879417,1 +107975,1036415877,1540869716,0 +119805,1036415878,1036415465,1 +119748,1036415878,1540879402,1 +119793,1036415888,1036415730,0 +119789,1036415892,1036415680,0 +119744,1036415892,1540879385,1 +119881,1036627832,1036628161,1 +119854,1036627832,1036628273,1 +119847,1036627833,1540879580,1 +119859,1036627833,1540879603,1 +119850,1036627841,1540879595,1 +119924,1036627841,1540879677,1 +119846,1036627847,1540879575,1 +119909,1036627859,1036628062,1 +119874,1036627859,1036628102,1 +119896,1036627861,1036627954,1 +119872,1036627869,1036627854,1 +119849,1036627869,1540879593,1 +142550,1036627871,1540934741,1 +119929,1036627872,1036627998,1 +119937,1036627872,1540879698,1 +119822,1036627873,1036628162,1 +119827,1036627873,1036628251,1 +119870,1036627875,1540879622,1 +142554,1036627875,1540934743,1 +119893,1036627883,1540879653,1 +119884,1036627884,1036628029,1 +119931,1036627884,1540879689,1 +119912,1036627895,1540879662,1 +119824,1036627897,1036628042,1 +119922,1036627897,1036628267,1 +119817,1036627901,1036627914,1 +119813,1036627901,1036628012,1 +119853,1036627902,1036627832,1 +119903,1036627902,1036628011,1 +119899,1036627905,1036628029,1 +119865,1036627905,1540879611,1 +119818,1036627914,1036627859,1 +119840,1036627914,1540879556,1 +119918,1036627916,1036628162,1 +119995,1036627916,1540879784,1 +119815,1036627936,278009592,1 +120030,1036627940,1036628039,1 +119917,1036627940,1540879667,1 +119892,1036627941,1036627883,1 +119864,1036627941,1036628079,1 +119898,1036627942,1036627905,1 +119897,1036627954,1036627942,1 +119938,1036627954,1540879699,1 +119838,1036627969,1540879552,0 +119812,1036627974,1036627901,1 +149774,1036627996,278009586,1 +119880,1036627996,1036627832,1 +119930,1036627998,1036627884,1 +119833,1036627998,1036627942,1 +119911,1036628008,1036627895,1 +119905,1036628008,1036627932,1 +119904,1036628011,1036628008,1 +119908,1036628011,1037131074,1 +119814,1036628012,1036627936,1 +119808,1036628019,1036415558,1 +119900,1036628029,1036628134,1 +119873,1036628033,1036627859,1 +119871,1036628035,1036627869,1 +119855,1036628035,1036628130,1 +119895,1036628038,1540879654,1 +119927,1036628038,1540879687,1 +119829,1036628039,1037130927,1 +120031,1036628039,1540879816,1 +119852,1036628042,278009586,1 +119825,1036628042,1036628181,1 +119891,1036628043,1036627941,1 +119936,1036628043,1540879697,1 +119883,1036628062,1036627925,1 +119910,1036628062,1036628008,1 +119844,1036628066,1540879570,0 +119848,1036628066,1540879590,0 +119834,1036628089,1540879542,0 +119934,1036628094,1036628253,1 +119889,1036628094,1540879652,1 +119952,1036628098,1037131206,1 +119980,1036628098,1540879768,1 +119886,1036628101,1036628111,1 +119875,1036628102,1036628236,1 +119684,1036628104,1540879305,1 +119837,1036628104,1540879551,0 +119887,1036628111,1540879631,1 +119925,1036628111,1540879682,0 +119832,1036628116,1036627861,1 +119928,1036628116,1036627872,1 +119842,1036628123,1540879560,0 +142557,1036628123,1540934754,1 +119856,1036628130,1540879597,1 +119920,1036628132,1036628257,1 +119841,1036628134,1540879558,1 +119901,1036628134,1540879659,1 +119907,1036628161,1036628011,1 +119882,1036628161,1036628062,1 +119823,1036628162,1036628098,1 +119919,1036628162,1036628132,1 +119861,1036628165,278009601,0 +119923,1036628172,1540879674,1 +142552,1036628172,1540934742,1 +119826,1036628181,1036627873,1 +119933,1036628181,1540879691,1 +119810,1036628208,1540879524,1 +119869,1036628208,1540879619,1 +119819,1036628232,1540879536,0 +119710,1036628233,1036415589,0 +119839,1036628233,1540879553,0 +119906,1036628236,1036628161,1 +119876,1036628236,1036628273,1 +119994,1036628251,1036627916,1 +119828,1036628251,1540879540,1 +119836,1036628253,1540879548,0 +119851,1036628257,1036628042,1 +119921,1036628257,1540879670,1 +119858,1036628260,1036628123,1 +119868,1036628266,1036628130,1 +142555,1036628266,1540934747,1 +149776,1036628267,278009587,1 +119811,1036628268,1540879530,1 +119857,1036628268,1540879602,1 +119816,1036628271,1036627973,1 +149780,1036628271,1540953309,1 +119877,1036628273,278009587,1 +119835,1036628275,1540879544,0 +119939,1036628275,1540879701,0 +119843,1036628278,1540879566,0 +119986,1037130865,1037131227,1 +119913,1037130865,1540879663,1 +120016,1037130866,1037130933,1 +119976,1037130866,1540879758,1 +120024,1037130876,1540879803,0 +120048,1037130876,1540879848,1 +120028,1037130880,1037131021,1 +149766,1037130880,1540953297,1 +149770,1037130885,278009580,1 +119992,1037130885,1540879783,1 +120010,1037130890,1037131168,1 +119968,1037130900,1037131206,1 +119982,1037130900,1540879769,1 +120009,1037130909,1540879797,1 +119945,1037130916,1037130962,1 +119954,1037130925,1540879714,1 +120020,1037130926,1037131122,1 +120039,1037130926,1540879830,1 +120014,1037130927,1037130978,1 +120032,1037130928,1036627895,1 +120034,1037130928,1540879819,0 +120041,1037130933,1037130916,1 +120017,1037130933,1037131081,1 +120043,1037130951,1037131031,1 +119975,1037130951,1540879755,1 +119971,1037130954,1540879750,0 +119979,1037130954,1540879766,1 +119949,1037130962,1037131081,1 +119946,1037130962,1037131204,1 +119993,1037130972,1036628251,1 +119951,1037130976,1036628098,1 +120015,1037130978,1037131046,1 +119916,1037130978,1540879666,1 +120061,1037130992,1037219509,1 +119821,1037130993,1036627873,1 +119940,1037130993,1037130972,1 +120002,1037130997,1540879786,1 +120027,1037130997,1540879813,0 +120012,1037131016,278009575,1 +120040,1037131021,1540879840,1 +120033,1037131022,1540879817,0 +119999,1037131026,1037361717,1 +119915,1037131027,1037130978,1 +120057,1037131027,1037211908,1 +119914,1037131029,1540879664,1 +119974,1037131029,1540879754,1 +120008,1037131031,1037130909,1 +119944,1037131040,1037130916,1 +120022,1037131043,1540879798,1 +120038,1037131043,1540879829,0 +120025,1037131046,1540879807,0 +119961,1037131063,1037131100,1 +120007,1037131063,1540879795,1 +120035,1037131074,1540879823,0 +119950,1037131081,1037130909,1 +120018,1037131081,1037131260,1 +120059,1037131082,1037211856,1 +119966,1037131082,1540879734,1 +119956,1037131090,1540879719,1 +120036,1037131090,1540879825,0 +119958,1037131100,1037131230,1 +119962,1037131100,1037131247,1 +119996,1037131114,1037131143,1 +119989,1037131114,1540879780,1 +120021,1037131122,278009571,1 +119959,1037131122,1037131168,1 +119985,1037131125,1037130865,1 +120023,1037131125,1540879801,1 +119972,1037131133,1037131040,1 +119977,1037131133,1540879760,1 +119983,1037131138,1037131188,1 +119965,1037131141,1037131082,1 +120003,1037131141,1540879789,1 +119997,1037131143,1037361877,1 +120006,1037131143,1540879791,1 +120046,1037131150,1540879844,1 +120083,1037131158,1540879918,1 +120011,1037131168,1037131016,1 +119981,1037131174,1037130900,1 +119963,1037131174,1540879729,1 +119970,1037131186,1540879744,0 +119987,1037131186,1540879779,1 +119973,1037131187,1037131029,1 +149765,1037131187,1540953296,1 +120029,1037131188,1036627940,1 +119957,1037131188,1037131226,1 +119960,1037131188,1540879723,1 +149764,1037131191,1540953295,1 +119990,1037131193,1037131158,1 +119947,1037131204,1037131249,1 +119953,1037131206,1037130925,1 +119991,1037131224,1540879781,1 +120037,1037131224,1540879827,0 +119964,1037131226,1540879733,1 +119978,1037131230,1540879763,1 +119969,1037131233,1540879737,0 +120026,1037131244,1540879809,0 +120042,1037131245,1037130992,1 +119988,1037131245,1037131114,1 +119943,1037131247,1037131040,1 +119948,1037131249,1037131191,1 +120019,1037131260,1037130926,1 +119955,1037131260,1037131204,1 +50022,1037172821,360717441,1 +120052,1037211856,1540879860,1 +120051,1037211869,1540879857,1 +120049,1037211875,1540879849,1 +120053,1037211875,1540879862,1 +120054,1037211891,1037211909,1 +119967,1037211891,1540879736,1 +120045,1037211896,1540879843,1 +120050,1037211908,1540879853,1 +120055,1037211909,1540879872,1 +120047,1037211919,1540879847,1 +120058,1037211919,1540879875,1 +120060,1037219515,1540879876,1 +120120,1037361530,1037361546,1 +120127,1037361530,1540879954,1 +120186,1037361533,1540879988,1 +120077,1037361535,1037361768,1 +120592,1037361535,1037361919,1 +120138,1037361546,1540879961,1 +120157,1037361547,1540879970,1 +120072,1037361552,1540879914,1 +120750,1037361552,1540880675,1 +120178,1037361562,1037361564,1 +120170,1037361562,1540879981,1 +120199,1037361566,1540880000,1 +148312,1037361577,1037361614,1 +120142,1037361577,1037361878,1 +120176,1037361589,1037361566,1 +120134,1037361591,1037361640,1 +120105,1037361591,1540879936,1 +120152,1037361596,1037361931,1 +120091,1037361596,1540879920,1 +120086,1037361611,1037361992,1 +120171,1037361611,1540879982,1 +120162,1037361613,1037361915,1 +120102,1037361613,1540879929,1 +119941,1037361614,1540879708,1 +148313,1037361614,1540949523,1 +120194,1037361615,1037361978,1 +120065,1037361615,1540879889,1 +120154,1037361621,1037361770,1 +120107,1037361621,1037361877,1 +120132,1037361624,1037361878,1 +120001,1037361624,1540879785,1 +120122,1037361640,1037361849,1 +120135,1037361640,1037361888,1 +120097,1037361644,1037361846,1 +120182,1037361653,1037361888,1 +120196,1037361653,1037361894,1 +120179,1037361668,1037361810,1 +120605,1037361668,1038225134,1 +120106,1037361674,1540879937,1 +120174,1037361684,1037361533,1 +120101,1037361684,1037361613,1 +148311,1037361704,1037361577,1 +120187,1037361704,1037361977,1 +120151,1037361707,1037361596,1 +120131,1037361707,1037361624,1 +120066,1037361710,1037361990,1 +120081,1037361715,1037361808,1 +120158,1037361715,1540879971,1 +120090,1037361717,1037361545,1 +120000,1037361717,1037361624,1 +120112,1037361738,1037361938,1 +120137,1037361738,1540879960,1 +148308,1037361741,1037361955,1 +120092,1037361741,1540879921,0 +120117,1037361744,1540879943,1 +120088,1037361765,1037361972,1 +120177,1037361765,1540879985,1 +120078,1037361768,1037361889,1 +120119,1037361768,1540879945,1 +120005,1037361770,1037131143,1 +120155,1037361770,1540879967,1 +120099,1037361793,1037361970,1 +120202,1037361793,1037361992,1 +120121,1037361798,1037361812,1 +120189,1037361798,1540879991,1 +120082,1037361808,1540879916,1 +120200,1037361808,1540880001,1 +120180,1037361810,1037361938,1 +120129,1037361811,1540879956,1 +120168,1037361811,1540879980,1 +120118,1037361829,1540879944,1 +120111,1037361831,1037361738,1 +120062,1037361831,1540879880,1 +120084,1037361846,1037361972,1 +120098,1037361846,1540879928,1 +120115,1037361849,1037361929,1 +120093,1037361855,1540879922,0 +120169,1037361859,1037361562,1 +120004,1037361861,1037361770,1 +120175,1037361867,1037361589,1 +142546,1037361867,1540934733,1 +120193,1037361875,1037361574,1 +120160,1037361875,1037361953,1 +119998,1037361877,1037131026,1 +120133,1037361878,1540879959,1 +120183,1037361888,1540879987,1 +120079,1037361889,1037361940,1 +120110,1037361889,1540879939,1 +120156,1037361890,1540879968,1 +120201,1037361890,1540880003,1 +120136,1037361894,1037361738,1 +120197,1037361894,1540879995,1 +120063,1037361906,1540879884,1 +120198,1037361906,1540879998,1 +120108,1037361911,1037361961,1 +120139,1037361911,1540879962,1 +120163,1037361915,1037361931,1 +120165,1037361915,1037361959,1 +148310,1037361916,1540949522,1 +120125,1037361919,1540879950,1 +120593,1037361919,1540880446,1 +120116,1037361929,1037361744,1 +120149,1037361929,1037361930,1 +120150,1037361930,1037361707,1 +120104,1037361930,1540879931,1 +120153,1037361931,1037361621,1 +120164,1037361931,1540879978,1 +120167,1037361932,1540879979,1 +142545,1037361932,1540934728,1 +120181,1037361938,1037361653,1 +120113,1037361938,1371044111,1 +120080,1037361940,1037361715,1 +120140,1037361951,1038225240,1 +120594,1037361951,1038225242,1 +120185,1037361953,1037361533,1 +120161,1037361953,1037361613,1 +148309,1037361955,1037361916,1 +120173,1037361959,1037361684,1 +120166,1037361959,1037361861,1 +120126,1037361961,1540879952,1 +120143,1037361962,1037361977,1 +120100,1037361970,1037361684,1 +120172,1037361970,1540879983,1 +120089,1037361972,1037361709,1 +120085,1037361972,1540879919,1 +120064,1037361975,1540879885,1 +120159,1037361975,1540879974,1 +120188,1037361977,1037361798,1 +120144,1037361977,1037361855,1 +120195,1037361978,1037361564,1 +120109,1037361978,1037361859,1 +120130,1037361979,1540879958,1 +120128,1037361990,1037361811,1 +120067,1037361990,1540879891,1 +120087,1037361992,1037361765,1 +120184,1037362000,1037361953,1 +120103,1037362000,1540879930,1 +120328,1037804806,1037805202,1 +120358,1037804806,1037805223,1 +120368,1037804807,1037805138,1 +56944,1037804847,1540825067,1 +120257,1037804847,1540880097,1 +120356,1037804867,1037804893,1 +120332,1037804867,1037805280,1 +120306,1037804879,1038225174,1 +120635,1037804879,1038225195,1 +120404,1037804893,1037805062,1 +120357,1037804893,1037805170,1 +120304,1037804930,1037805041,1 +120384,1037804930,1037805343,1 +120366,1037804973,1037805223,1 +120393,1037804973,1540880187,1 +120323,1037804977,1540880143,1 +120403,1037805010,1037804893,1 +120324,1037805010,1037805179,1 +120326,1037805031,1037805062,1 +120394,1037805031,1540880189,1 +120395,1037805040,365388273,1 +120688,1037805040,1540880541,1 +120305,1037805041,1037804879,1 +120227,1037805041,1037805047,1 +120228,1037805047,1038225000,1 +120657,1037805047,1038225195,1 +120327,1037805062,1037804806,1 +56948,1037805077,365388274,1 +148454,1037805077,1540949752,1 +120336,1037805138,1540880151,1 +120369,1037805138,1540880168,1 +120334,1037805158,1037804863,1 +120402,1037805162,1037805010,1 +120611,1037805162,1540880402,1 +120689,1037805170,1540880544,1 +120690,1037805179,1540880545,1 +120331,1037805202,1037804867,1 +120329,1037805202,1037804928,1 +120367,1037805223,1037804955,1 +120359,1037805223,1037805341,1 +120433,1037805234,1037805306,1 +120303,1037805280,1037804930,1 +120333,1037805280,1037804977,1 +120383,1037805341,1540880176,1 +120656,1037805343,1037805047,1 +120385,1037805343,1038225123,1 +132169,1038214120,1540890525,1 +24093,1038214221,279591135,0 +120585,1038214221,279591274,1 +120681,1038225000,1038225123,1 +120601,1038225005,1038225220,1 +120604,1038225005,1540880452,1 +120245,1038225008,1540880084,1 +120666,1038225008,1540880512,1 +96688,1038225010,1038225041,1 +120591,1038225012,1037361668,1 +120322,1038225014,1540880136,1 +120646,1038225022,1038225055,1 +120650,1038225022,1540880490,1 +120680,1038225025,1038225000,1 +120608,1038225031,1038225248,1 +120603,1038225031,1540880451,1 +56952,1038225039,365388276,1 +96689,1038225041,1540859742,1 +120625,1038225045,1038225192,1 +120670,1038225045,1540880527,1 +120684,1038225053,1038225179,1 +120638,1038225053,1038225204,1 +120647,1038225055,1038225183,1 +120610,1038225056,1540880457,1 +120691,1038225056,1540880549,1 +120660,1038225063,1038225086,1 +120674,1038225063,1038225201,1 +120590,1038225065,1038225012,1 +120661,1038225065,1540880501,1 +120641,1038225068,1540880479,1 +120648,1038225068,1540880486,1 +120074,1038225074,1038225184,1 +120123,1038225074,1540879946,1 +120653,1038225075,1038225152,1 +120645,1038225078,1038225022,1 +120242,1038225086,1038225194,1 +120665,1038225094,1540880506,1 +120667,1038225094,1540880517,1 +120649,1038225095,1540880488,1 +96690,1038225098,789216065,1 +120588,1038225098,1038225120,1 +120321,1038225100,1038225014,1 +120683,1038225100,1038225053,1 +120617,1038225107,1540880462,1 +120589,1038225120,1038225065,1 +120682,1038225123,1038225100,1 +120386,1038225123,1038225158,1 +120401,1038225127,1037805162,1 +120686,1038225127,1038225150,1 +120597,1038225130,1038225152,1 +120630,1038225130,1038225204,1 +120662,1038225134,1371044125,1 +120606,1038225134,1540880453,1 +120640,1038225147,1038225068,1 +120241,1038225147,1540880082,1 +120687,1038225150,365388274,1 +120655,1038225150,1038225192,1 +120124,1038225151,1540879949,1 +120659,1038225155,1038225063,1 +120679,1038225155,1540880537,1 +120620,1038225157,1038225245,1 +120643,1038225157,1540880483,1 +120607,1038225158,1038225031,1 +120387,1038225158,1540880177,1 +120618,1038225159,1540880464,1 +120623,1038225159,1540880468,1 +148370,1038225162,1371044501,1 +120633,1038225170,1038225217,1 +120677,1038225170,1540880535,1 +120678,1038225174,1038225155,1 +120307,1038225174,1038225247,1 +120685,1038225179,1038225127,1 +120615,1038225179,1038225203,1 +120320,1038225180,1038225100,1 +120075,1038225184,1038225239,1 +120598,1038225187,1038225231,1 +120309,1038225190,1038225219,1 +120632,1038225190,1540880472,1 +120626,1038225192,1038225216,1 +120243,1038225194,1540880083,1 +120664,1038225194,1540880503,1 +120636,1038225195,1038225025,1 +120658,1038225195,1038225155,1 +120596,1038225197,1540880448,1 +120672,1038225197,1540880528,1 +120675,1038225201,1038225231,1 +120642,1038225201,1540880481,1 +120612,1038225203,1038225244,1 +120631,1038225204,1038225018,1 +120622,1038225206,1038225159,1 +120651,1038225206,1540880496,1 +120600,1038225207,1038225005,1 +120388,1038225207,1038225235,1 +120246,1038225210,1540880085,1 +120400,1038225216,1038225127,1 +120627,1038225216,1038225222,1 +120634,1038225217,1540880478,1 +120671,1038225218,1038225197,1 +120652,1038225218,1540880500,1 +120244,1038225219,1038225008,1 +120669,1038225220,1038225248,1 +120602,1038225220,1540880450,1 +120146,1038225221,1371044107,1 +120619,1038225222,1038225075,1 +120628,1038225222,1038225249,1 +120644,1038225228,1038225078,1 +96687,1038225229,1038225010,1 +120668,1038225229,1540880525,1 +120599,1038225231,1540880449,1 +120076,1038225239,1037361535,1 +120654,1038225239,1038225009,1 +120141,1038225240,1540879963,1 +120676,1038225240,1540880534,1 +120595,1038225242,1038225012,1 +120639,1038225242,1038225041,1 +120613,1038225244,1038225014,1 +120637,1038225244,1038225053,1 +120621,1038225245,1038225206,1 +120308,1038225247,1038225190,1 +120673,1038225247,1540880532,1 +120609,1038225248,1540880455,1 +120629,1038225249,1038225130,1 +120614,1038225249,1038225179,1 +56946,1038253611,1480413415,1 +120258,1038253639,1540880098,1 +120815,1038782254,1540880840,1 +133481,1038782254,1540894490,1 +120068,1038782279,1540879896,1 +120745,1038782279,1540880674,1 +120803,1038782279,1540880805,1 +120820,1038782279,1540880845,1 +120756,1038782283,1540880695,0 +120238,1038782286,1038782962,1 +120725,1038782286,1540880621,1 +120737,1038782294,1038782668,1 +120719,1038782294,1038783063,1 +120782,1038782320,1038782903,1 +120804,1038782320,1540880806,1 +120741,1038782339,1540880669,1 +120753,1038782339,1540880689,0 +120814,1038782359,1540880839,1 +120732,1038782371,1038782830,1 +120769,1038782371,1540880722,1 +120799,1038782375,1038783098,1 +120747,1038782398,1038782926,1 +120781,1038782398,1540880736,1 +120734,1038782419,1038782792,1 +120791,1038782419,1038782943,1 +120744,1038782479,1540880672,1 +120790,1038782510,1038782419,1 +120811,1038782510,1038782982,1 +120765,1038782522,1038782915,1 +120801,1038782522,1540880779,1 +120749,1038782526,1038782283,1 +120770,1038782528,1038783023,1 +120751,1038782530,1038782632,0 +120237,1038782555,1038782286,1 +120805,1038782555,1540880807,1 +120780,1038782570,1038782752,1 +120809,1038782570,1540880830,1 +120739,1038782597,1038782668,1 +120240,1038782617,1540880074,1 +120752,1038782632,1540880688,0 +120773,1038782632,1540880731,1 +120743,1038782642,1038782479,1 +120738,1038782659,1038782597,1 +120714,1038782659,1540880590,1 +120740,1038782668,1038782985,1 +120069,1038782689,1540879898,1 +120758,1038782689,1540880701,1 +120071,1038782708,1540879911,1 +120802,1038782708,1540880784,1 +120818,1038782743,1038782916,1 +120742,1038782752,1540880671,1 +120796,1038782755,1038782830,1 +120709,1038782755,1038782943,1 +120070,1038782761,1540879899,1 +120808,1038782761,1540880828,1 +120761,1038782792,1038782862,1 +120735,1038782792,1540880665,1 +120807,1038782821,1540880825,1 +120733,1038782830,1038782419,1 +120797,1038782830,1038782873,1 +120708,1038782854,1038782755,1 +120816,1038782854,1540880843,1 +120810,1038782862,1038782510,1 +133560,1038782862,1540895555,1 +120718,1038782876,1038782294,1 +120754,1038782876,1540880691,0 +120823,1038782893,1540880858,1 +120724,1038782903,1540880619,1 +120763,1038782904,1540880511,1 +120726,1038782904,1540880631,1 +120766,1038782915,1540880715,1 +120819,1038782916,1038782920,1 +120712,1038782916,1038783003,1 +120723,1038782920,1540880617,1 +120748,1038782926,1038782526,1 +120762,1038782926,1540880702,1 +120792,1038782943,1038782526,1 +120710,1038782943,1038783165,1 +120715,1038782946,1540880591,1 +120826,1038782946,1540880885,1 +120239,1038782962,1540880069,1 +120736,1038782962,1540880666,1 +120746,1038782969,1038782398,1 +120759,1038782969,1038783165,1 +120812,1038782982,1038782873,1 +120825,1038782982,1038782946,1 +120755,1038782985,1540880692,0 +120713,1038783003,1540880589,1 +120794,1038783005,1540880755,1 +120822,1038783005,1540880852,1 +120817,1038783021,1038782743,1 +120722,1038783021,1540880605,1 +120806,1038783030,1540880819,1 +120771,1038783063,1038782713,1 +120720,1038783063,1038783090,1 +120821,1038783070,1540880848,1 +120236,1038783082,1540880067,1 +120764,1038783082,1540880707,1 +120721,1038783090,1038783021,1 +120813,1038783090,1540880835,1 +120793,1038783098,1540880749,1 +120800,1038783098,1540880778,1 +120757,1038783148,1540880698,0 +120795,1038783148,1540880777,1 +120711,1038783165,1038782642,1 +120760,1038783165,1038782792,1 +79038,1041566398,1540841175,1 +121214,1041566605,1540881381,1 +119012,1060029297,1030323840,1 +83861,1060029297,1540846640,1 +122583,1085492553,1085492613,1 +96470,1085492553,1307354835,1 +96557,1085492577,788870489,1 +122585,1085492577,1085492620,1 +122578,1085492660,1085492692,1 +96469,1085492692,1085492553,1 +122579,1085492692,1085492744,1 +122582,1085492694,1085492553,1 +96556,1085492694,1085492577,1 +122581,1085492717,1085492694,1 +122580,1085492744,1085492545,1 +96555,1085492744,1085492694,1 +51667,1093091225,361434474,0 +122643,1093091230,361434507,1 +122638,1093091230,1540882659,0 +50203,1093091270,360730004,1 +122645,1093091270,1093091230,0 +50200,1093091279,360729958,1 +104448,1093091298,361434504,0 +122642,1093091298,1093091310,1 +127383,1093091310,360729807,0 +124894,1113195801,360012420,1 +124909,1113195801,972315191,1 +40902,1113233813,360013431,1 +124917,1113233813,1113233854,1 +124948,1113233817,1113233820,1 +124943,1113233817,1113233854,1 +40286,1113233818,795264088,1 +40288,1113233820,575189652,1 +97614,1113233820,1113233830,1 +124941,1113233822,1113233852,1 +124933,1113233822,1540883943,1 +124944,1113233823,1113233837,1 +124946,1113233823,1113233855,1 +124935,1113233829,360011306,1 +97615,1113233830,795264079,1 +124919,1113233837,360011578,1 +71807,1113233852,575189659,1 +124942,1113233852,1113233837,1 +124918,1113233854,1113233818,1 +40901,1113233855,1113233813,1 +124947,1113233855,1113233817,1 +66285,1113355734,512543954,1 +124994,1113355759,558986366,1 +124973,1113355818,559554572,1 +124987,1113355836,559940458,1 +125006,1113454648,985285846,1 +125051,1113561531,984606704,1 +125049,1113561541,1411198366,1 +125043,1113561562,1411198388,1 +125045,1113561564,984639869,1 +115413,1113561564,1540874530,0 +125086,1113756031,361217690,1 +125363,1119354090,938501936,1 +125356,1119354090,1145611255,1 +125358,1119354126,360476335,1 +125375,1119992514,1119992529,1 +107602,1119992514,1540869061,1 +40541,1129262188,1540810093,1 +126323,1131310896,347776878,1 +126436,1132701095,1540884439,1 +126464,1132701122,365310990,1 +126463,1132701122,1540884469,1 +107609,1132701153,1540869062,1 +80331,1139646180,1540843070,0 +103033,1139689411,360476910,1 +51409,1139689426,361198821,1 +127117,1139689426,1139689430,1 +134566,1139689430,360476306,1 +127118,1139689430,1139689445,1 +23956,1139689432,600918108,1 +127112,1139689439,1139689411,1 +51401,1139689445,361198836,0 +48474,1139714829,361198461,0 +127125,1139714829,1139714834,0 +125361,1139714834,797375676,0 +127127,1139744352,1139744382,1 +98089,1139744362,1139744432,0 +125366,1139744366,1139744376,1 +127141,1139744370,1139744419,1 +125367,1139744376,1139744382,1 +127137,1139744380,1139744432,1 +125368,1139744382,338485738,1 +98091,1139744419,797375843,0 +127126,1139744427,1139744362,1 +98090,1139744432,1139744419,0 +127142,1139744434,1139744366,1 +127128,1139744438,1139744376,1 +127689,1140945504,803745172,1 +127153,1140945511,803745213,1 +99892,1140945513,653316319,1 +127161,1140945513,1540884986,1 +127145,1140945526,1140945504,1 +98117,1140945527,803745068,1 +99985,1140945527,1540862339,1 +107561,1140966212,938501950,1 +127163,1140966212,1540884987,1 +89960,1141011954,653316193,1 +80535,1141011963,803745126,1 +99882,1141011964,1141011972,0 +127184,1141011964,1141011981,1 +99978,1141011965,803745059,0 +127174,1141011966,803745130,1 +99877,1141011966,803745244,1 +127177,1141011970,803745223,1 +99883,1141011972,1141011978,0 +99974,1141011977,1540862337,0 +99884,1141011978,1141011985,0 +99940,1141011979,803745189,1 +126657,1141011979,1141011970,0 +99980,1141011981,803745072,0 +127175,1141011983,803745031,1 +99984,1141011983,803745189,1 +99885,1141011985,803745241,0 +127172,1141034610,803745065,0 +127191,1141034610,1141034627,1 +89985,1141034627,803745155,1 +90032,1141054209,653317438,1 +90018,1141083851,1540853811,1 +107528,1141083851,1540869025,1 +90058,1141083874,656190163,1 +127205,1141083874,1540885007,1 +127204,1141083879,1141084014,1 +107527,1141083892,1540869023,1 +127195,1141083911,1540885000,0 +127209,1141083915,1540885030,1 +127206,1141083936,1540885014,1 +127217,1141083967,1540885047,1 +127208,1141084011,1540885024,1 +127218,1141084014,1540885053,1 +90061,1141084025,1540853855,1 +127216,1141084025,1540885042,1 +127215,1141084041,1141083911,1 +107478,1141084041,1540868989,1 +47920,1141159293,347502144,1 +47908,1141159297,360467920,1 +30778,1141159308,360468371,1 +47919,1141159312,1141159293,1 +30756,1141159336,347502147,1 +127272,1141159336,1141159305,1 +31695,1141192202,360473622,0 +127293,1141192204,1141192202,1 +137791,1141269201,1540920302,0 +47874,1141269207,706821681,1 +93426,1141269211,1540856520,0 +127307,1141269253,1141269211,1 +76413,1141269255,1540840712,0 +68182,1141269257,597692697,0 +127310,1141269257,1193464654,0 +127300,1141269259,1540885072,1 +48006,1141269279,360469368,1 +127308,1141269279,1141269242,1 +81774,1141269283,1540845688,0 +133737,1141269283,1540896930,0 +93329,1142305229,1540856483,1 +127348,1142305233,353245366,0 +31646,1142356856,705979302,1 +93367,1142356880,1540856495,1 +31640,1142420555,353244828,0 +104445,1142507815,361434507,0 +50205,1142507821,360730116,1 +127385,1142507821,1142507827,1 +93326,1142507845,705073957,1 +127379,1142507846,705073964,0 +134824,1142507856,361194353,1 +127386,1142507856,1142507853,1 +127389,1142507858,360730592,1 +127402,1142507858,705073961,1 +100340,1142589018,807184971,1 +100334,1142589018,1540862579,1 +31711,1142694898,353246572,1 +127426,1142694906,1142694898,1 +31707,1142694906,1236188092,0 +134894,1142694910,338484429,1 +134506,1143979807,1227726229,0 +138652,1143999566,1307600503,0 +127482,1143999566,1493259659,1 +149364,1144045151,365119713,0 +127524,1144045154,365970041,1 +127489,1144045154,1540885180,0 +127490,1144045155,365119893,1 +56143,1144045162,365970402,0 +127488,1144045162,1144045151,1 +98585,1144177918,559590848,1 +127591,1144177921,559590889,0 +96858,1144323593,1144277802,1 +96840,1144323593,1540859795,1 +107605,1144399667,938502182,1 +107592,1144399675,938502076,1 +127644,1144399675,1144399667,1 +127649,1144399715,938142916,1 +107203,1144399715,938502098,1 +127648,1144431643,1144399715,1 +127682,1144431654,1144431870,1 +23894,1144431654,1540793786,0 +143224,1144431660,1540936667,1 +23898,1144431684,294163738,0 +127666,1144431684,1144431698,1 +127667,1144431698,1540885240,1 +127673,1144431698,1540885242,1 +127670,1144431812,1343033247,1 +127679,1144431812,1540885252,1 +127683,1144431870,1343033250,1 +127678,1144431870,1540885251,1 +127680,1144431885,938142912,1 +96820,1145564253,579799880,1 +127685,1145564253,1145564254,1 +96829,1145564254,792056442,1 +98074,1145577411,797375595,1 +127686,1145577411,1540885258,1 +107547,1145611251,938502197,1 +125357,1145611255,1140945509,1 +98139,1145611257,797375778,1 +127690,1145611257,1540885259,1 +127692,1145611265,1540885261,1 +51430,1145611269,361198939,1 +127694,1145611269,1145611255,1 +107424,1145611279,938149141,1 +127687,1145611279,1145611280,1 +107486,1145611281,938502098,1 +51344,1145611285,360476619,1 +130420,1163936359,1540886617,1 +130422,1163936404,1540886626,1 +152294,1163936425,1540962406,1 +152609,1163936441,1540963280,1 +152607,1163936533,1540963260,1 +152606,1163936625,1540963241,1 +152605,1163936685,1540963226,1 +152296,1172380260,1540962426,1 +152299,1172380271,1540962448,1 +131580,1172380315,1540889589,1 +152297,1172380342,1540962429,1 +131583,1172380351,1540889606,1 +152298,1172380409,1540962440,1 +152295,1172380425,1540962417,1 +131581,1172380434,1540889598,1 +131582,1172380461,1540889599,1 +131584,1172380560,1540889609,1 +131585,1172381732,1540889624,1 +131588,1172388091,1540889634,1 +131586,1172388154,1540889628,1 +131593,1172388222,1540889776,1 +131591,1172388231,1540889744,1 +131594,1172388404,1540889820,1 +131592,1172388419,1540889775,1 +131589,1172388610,1540889676,1 +131590,1172388681,1540889696,1 +131595,1172389459,1540889844,1 +131587,1172389463,1540889632,1 +112281,1172477536,1540873015,1 +131596,1172479021,1540889848,1 +112200,1172480809,1540872855,1 +131597,1172481443,1540889850,1 +152608,1172485474,1540963269,1 +130421,1172498098,1163936404,1 +56930,1172574059,1540824962,1 +56929,1172576871,1540824946,1 +131598,1172576871,1540889858,1 +131605,1172607796,1540889910,1 +131614,1172607796,1540889922,1 +131602,1172607819,1540889894,1 +131609,1172607819,1540889918,1 +131604,1172607821,1540889905,1 +56926,1172607848,1540824944,1 +131611,1172609426,1540889921,1 +131619,1172609434,1540889949,1 +131612,1172609440,1172609443,1 +131613,1172609443,1540889633,1 +131603,1172609445,1540889896,1 +131615,1172609445,1540889924,1 +131610,1172609449,1172609426,1 +131608,1172612126,1540889917,1 +131620,1172612126,1540889950,1 +131606,1172612127,1540889911,1 +131607,1172612134,1172612126,1 +131616,1172613561,1540889926,1 +131617,1172614005,1540889933,1 +131618,1172615079,1540889946,1 +56927,1172615090,365378211,1 +56937,1172628276,1540825007,1 +20236,1172638693,278010746,1 +131625,1172655426,1540889967,1 +56936,1172662201,1540825001,1 +56935,1172666072,1172662201,1 +20290,1174605184,1540790435,1 +149802,1174782357,1411219073,1 +98016,1175924751,1540861239,1 +56931,1175941168,1540824966,1 +56932,1175941320,1540824967,1 +56933,1175941365,1540824976,1 +56934,1175946886,1540824993,1 +149740,1175962890,1540953219,1 +104461,1178850760,1411198413,1 +132159,1178859363,1178859414,1 +132158,1178859368,1540890508,1 +132165,1178859387,1540890515,1 +132176,1178859387,1540890541,1 +132163,1178859389,1540890514,1 +132168,1178859395,1038214120,1 +132167,1178859407,1540890524,1 +132182,1178859407,1540890555,1 +132162,1178859410,1540890513,1 +132160,1178859414,1540890510,1 +132179,1178859414,1540890548,1 +132166,1178859421,1540890522,1 +132174,1178859496,1178859517,1 +132173,1178859500,1540890538,1 +132172,1178859508,1540890533,1 +132175,1178859517,1540890539,1 +132185,1178859517,1540890565,1 +40329,1178859518,1540810037,0 +132180,1178859896,1540890551,1 +132178,1178859905,1540890547,1 +132171,1178880780,1540890531,1 +132170,1178880784,1540890528,1 +132184,1178881590,1540890558,1 +132183,1178881593,1540890556,1 +132161,1178893677,1540890512,1 +132164,1178893711,1178855975,1 +132181,1178909143,1540890553,1 +132177,1178909424,1540890542,1 +84036,1178910002,360007349,1 +87447,1179176144,615743482,1 +83877,1179187952,528298545,1 +83876,1179195098,1540846666,1 +132263,1179200499,1540890907,1 +109157,1181395177,1540870539,1 +133480,1184175914,1540894464,1 +133486,1184175914,1540894553,1 +133482,1184179151,1540894517,1 +133483,1184179155,1184189196,1 +133485,1184179165,1540894530,1 +133488,1184179165,1540894613,1 +133487,1184179517,1540894585,1 +133489,1184181057,1540894647,1 +133490,1184183961,1540894656,1 +133491,1184187437,1540894688,1 +133559,1184187437,1540895499,1 +133484,1184189196,1540894520,1 +133492,1184195345,1540894733,1 +133558,1184257540,1540895476,1 +96685,1184259745,1540859738,1 +133563,1184259745,1540895593,1 +133561,1184259750,1184257675,1 +133562,1184259750,1540895574,1 +96673,1184260710,789215967,1 +133564,1184260752,1540895598,1 +148671,1184260752,1540950122,1 +133567,1184265334,1540895605,1 +148581,1184265334,1540949917,1 +148651,1184265334,1540950106,1 +133569,1184266124,1540895610,1 +137780,1193464654,597692697,0 +127311,1193464654,1193464731,0 +81784,1193464694,1540845698,0 +80993,1193464731,1540844157,0 +127312,1193464731,1540885073,0 +81776,1193473230,1540845689,0 +133738,1193473230,1540896932,0 +133752,1196620816,1333878278,1 +109072,1196620816,1333878699,1 +133751,1196620819,1196620816,1 +109065,1196620819,1540870367,1 +141148,1196620820,1540929439,1 +56188,1227726229,694828951,0 +134507,1227726241,1227726229,1 +134803,1235833494,1235838543,1 +134802,1235835794,1235833494,1 +82530,1235838542,705063793,0 +92197,1235838543,38840254,1 +134804,1235838543,1235838542,1 +134884,1236107914,559590877,1 +135096,1236188089,694820205,0 +135099,1236188089,1236188106,0 +29615,1236188092,353246570,0 +31708,1236188092,1540802541,0 +48312,1236188097,360476090,1 +135101,1236188097,1236188112,0 +135093,1236188101,360476033,0 +135097,1236188101,683290785,1 +135098,1236188101,1236188089,0 +135100,1236188106,1236188097,0 +93025,1236188112,694820362,1 +135102,1236188112,1236189007,0 +93015,1236189006,694820283,1 +135104,1236189006,1236190946,0 +93014,1236189007,694820272,1 +135103,1236189007,1236189006,0 +93016,1236190946,1540856393,1 +135105,1236190946,1540905564,0 +76427,1236966607,1540840716,0 +135090,1239786736,353244969,0 +82542,1239786760,1239786834,0 +17690,1239786783,302897535,1 +48113,1239786783,360471305,0 +82543,1239786834,38842554,0 +24412,1239786834,302660617,0 +127124,1241999144,1540884978,1 +53910,1242034859,363974809,1 +111815,1242034859,972481814,0 +134517,1260448674,360475452,0 +136301,1285491807,1540909092,0 +136317,1285491807,1540909130,0 +136323,1285491807,1540909135,0 +30665,1285491813,1285491927,1 +136310,1285491813,1540909107,0 +136348,1285491813,1540909155,0 +136321,1285491814,1285491935,0 +136331,1285491814,1540909145,0 +136319,1285491817,1285491893,0 +136333,1285491818,566803329,0 +136294,1285491827,1540909078,0 +30826,1285491828,1540800304,0 +136325,1285491829,1540909137,0 +136352,1285491831,1285491939,0 +135006,1285491835,272554677,0 +136339,1285491836,272554421,0 +136316,1285491836,1285491807,0 +136303,1285491841,1285491866,0 +136359,1285491845,706854256,0 +136338,1285491845,706854268,0 +136298,1285491846,1540909085,0 +136347,1285491846,1540909153,0 +137788,1285491849,1285491854,0 +136312,1285491853,1540909112,0 +136315,1285491854,1540909124,0 +137789,1285491854,1540920292,0 +136296,1285491855,1540909084,0 +135004,1285491856,272554678,0 +136356,1285491861,1285491925,0 +136304,1285491866,695578773,0 +136332,1285491866,1285491818,0 +136324,1285491868,1285491813,0 +136309,1285491868,1540909105,0 +136351,1285491869,1285491831,0 +136349,1285491892,1285491898,0 +136354,1285491894,1285491937,0 +136350,1285491898,1285491869,0 +136318,1285491905,1540909132,0 +136297,1285491908,1285491829,0 +93442,1285491909,706854252,0 +47804,1285491925,360467530,0 +136357,1285491925,706854255,0 +96277,1285491927,272554420,1 +136293,1285491927,1540909077,0 +136308,1285491927,1540909104,0 +136311,1285491927,1540909110,0 +137786,1285491928,695578773,0 +136299,1285491930,1540909089,1 +136302,1285491930,1540909096,0 +93438,1285491932,706854184,0 +136327,1285491932,706854186,0 +136322,1285491935,1540909134,0 +136355,1285491937,1285491861,0 +30782,1285491937,1540800303,0 +136353,1285491939,1285491894,0 +136300,1285491942,566803329,1 +136330,1285491943,1285491814,0 +136472,1291955672,1540909238,1 +40467,1291955682,1540810073,1 +98684,1291955682,1540861513,1 +24109,1291955687,1540794030,0 +136466,1291955701,1540909236,1 +136473,1291955701,1540909241,1 +136474,1291955947,1291955946,1 +45810,1291955947,1540812181,1 +136476,1291956620,1291956624,1 +136477,1291956620,1540909243,1 +143861,1291956623,360206870,1 +152604,1291956623,1540963225,1 +148314,1298242187,1540949524,1 +56011,1305700915,1540824332,0 +56016,1305700915,1540824333,1 +22945,1305716360,1540792791,1 +137799,1305716360,1540920322,1 +22946,1305716361,286369862,1 +137800,1305716361,1305716358,1 +138132,1307354327,1307354386,1 +138276,1307354329,1307354788,1 +59356,1307354329,1540831980,1 +138164,1307354331,1307354491,1 +138243,1307354331,1307354689,1 +138124,1307354338,1307354454,1 +138133,1307354340,788870686,1 +138227,1307354340,1540922589,1 +138097,1307354348,1307354408,1 +138255,1307354348,1307354628,1 +138159,1307354350,1307354508,1 +138120,1307354350,1307354604,1 +138198,1307354355,1307354608,1 +138105,1307354355,1307354709,1 +138265,1307354356,1307354499,1 +138269,1307354356,1307354609,1 +138209,1307354357,1307354431,1 +138082,1307354357,1540922512,1 +138200,1307354359,1307354384,1 +138213,1307354359,1540922569,1 +138210,1307354360,1540922568,1 +138258,1307354360,1540922637,1 +138294,1307354363,1307354462,1 +138128,1307354363,1307354803,1 +87989,1307354366,1540851150,1 +138195,1307354370,1540922563,1 +138208,1307354373,1307354357,1 +138077,1307354374,1307354390,1 +105898,1307354374,1307354577,1 +138152,1307354377,1540922539,1 +138201,1307354384,1307354445,1 +138094,1307354390,1307354742,1 +138231,1307354394,1307354643,1 +138079,1307354394,1307354797,1 +138134,1307354399,1307354351,1 +138291,1307354399,1540922655,1 +138279,1307354405,1540922646,1 +138091,1307354407,1307354561,1 +138075,1307354407,1307354655,1 +138098,1307354408,1307354806,1 +138141,1307354427,1307354840,1 +138267,1307354427,1540922639,1 +138197,1307354429,1307354355,1 +138190,1307354429,1307354632,1 +138153,1307354431,1540922542,1 +96472,1307354438,788870489,1 +138087,1307354443,1307354615,1 +138137,1307354445,1540922535,1 +138202,1307354445,1540922565,1 +138263,1307354446,1307354791,1 +138229,1307354448,1540922593,1 +138246,1307354448,1540922631,1 +138170,1307354451,1307354675,1 +87982,1307354452,372800259,1 +138204,1307354452,1307354495,1 +138125,1307354454,1307354508,1 +138174,1307354454,1307354801,1 +138107,1307354458,1307354787,1 +138293,1307354458,1540922656,1 +138144,1307354462,1540922538,1 +138295,1307354462,1540922660,1 +138280,1307354464,1307354466,1 +138281,1307354466,1307354662,1 +138206,1307354467,1307354408,1 +138224,1307354467,1307354552,1 +138114,1307354469,1307354644,1 +138136,1307354469,1307354813,1 +138252,1307354471,1307354707,1 +138109,1307354471,1307354751,1 +138090,1307354479,1307354407,1 +87980,1307354481,1540851144,1 +105897,1307354488,1540868115,1 +138118,1307354491,1307354836,1 +138165,1307354491,1540922543,1 +138205,1307354495,1307354467,1 +138285,1307354495,1307354669,1 +138080,1307354498,1307354659,1 +138179,1307354499,1307354755,1 +87988,1307354505,1307354366,1 +138113,1307354506,1540922529,1 +138169,1307354506,1540922546,1 +138283,1307354507,1307354839,1 +138126,1307354508,1307354798,1 +138222,1307354518,1307354507,1 +138116,1307354529,1307354670,1 +138162,1307354529,1307354751,1 +138226,1307354540,1307354340,1 +96515,1307354540,1331276061,1 +138185,1307354542,1307354659,1 +138182,1307354544,1540922554,1 +138218,1307354547,1307354479,1 +105895,1307354547,1540868114,1 +96554,1307354549,1085492744,1 +138299,1307354549,1307354474,1 +138254,1307354552,1307354348,1 +138225,1307354552,1307354518,1 +138261,1307354553,1307354740,1 +138135,1307354553,1540922534,1 +138089,1307354555,1307354479,1 +138234,1307354556,1307354783,1 +138102,1307354556,1540922518,1 +138117,1307354559,1307354843,1 +138249,1307354559,1540922633,1 +138108,1307354561,1307354488,1 +138092,1307354561,1307354691,1 +138183,1307354563,1307354846,1 +138112,1307354563,1540922528,1 +138158,1307354566,1307354350,1 +138100,1307354566,1307354801,1 +138130,1307354574,788870619,1 +143800,1307354574,1307354743,1 +105899,1307354577,1540868118,1 +96465,1307354579,1540859679,1 +138194,1307354585,1307354370,1 +105837,1307354585,1540868003,1 +138121,1307354604,1307354405,1 +138274,1307354606,1307354369,1 +138250,1307354606,1540922634,1 +138188,1307354607,1540922556,1 +138199,1307354608,1540922564,1 +138270,1307354609,1307354544,1 +138301,1307354609,1307354755,1 +138088,1307354615,1307354555,1 +138103,1307354617,1540922519,1 +138147,1307354618,1307354806,1 +138230,1307354624,1307354394,1 +138256,1307354624,1307354432,1 +105901,1307354628,1540868120,1 +138191,1307354632,1331276060,1 +138296,1307354632,1540922662,1 +96518,1307354638,788870607,1 +138189,1307354638,1307354429,1 +138233,1307354641,1307354556,1 +138268,1307354641,1540922641,1 +138101,1307354643,1540922517,1 +138232,1307354643,1540922595,1 +143799,1307354644,1307354574,1 +138123,1307354648,1307354338,1 +105893,1307354651,1540868112,1 +138166,1307354651,1540922545,1 +138076,1307354655,1307354466,1 +138187,1307354655,1307354607,1 +138251,1307354658,1307354471,1 +138115,1307354658,1307354529,1 +138081,1307354659,1307354464,1 +138186,1307354659,1307354655,1 +138304,1307354660,1540922663,1 +138282,1307354662,1307354507,1 +138176,1307354664,1307354718,1 +138286,1307354669,1540922650,1 +138171,1307354675,1307354373,1 +138151,1307354675,1307354377,1 +138275,1307354678,1307354329,1 +138083,1307354678,1540922513,1 +138219,1307354679,1307354796,1 +105900,1307354679,1540868119,1 +143798,1307354683,1307354644,1 +138217,1307354687,1307354370,1 +138244,1307354689,1540922630,1 +138093,1307354691,1307354390,1 +138146,1307354691,1307354607,1 +138193,1307354692,1540922559,1 +143797,1307354692,1540937689,1 +138239,1307354694,1540922605,1 +138155,1307354699,1307354849,1 +105892,1307354700,1540868111,1 +138086,1307354700,1540922514,1 +138131,1307354707,1307354327,1 +138215,1307354707,1540922575,1 +138303,1307354709,1307354660,1 +138106,1307354709,1540922526,1 +138143,1307354713,1307354417,1 +138157,1307354713,1307354566,1 +138241,1307354715,1540922626,1 +138306,1307354717,1307354422,1 +138292,1307354717,1307354458,1 +138154,1307354718,1307354699,1 +138177,1307354718,1540922548,1 +138074,1307354727,1307354407,1 +105896,1307354727,1307354488,1 +138262,1307354740,1307354446,1 +138160,1307354742,1307354577,1 +138095,1307354742,1540922516,1 +138259,1307354743,1307354840,1 +138245,1307354744,1307354448,1 +138078,1307354744,1540922509,1 +138163,1307354751,1307354327,1 +138110,1307354751,1307354686,1 +105891,1307354755,1540868108,1 +138180,1307354755,1540922551,1 +138297,1307354761,1307354539,1 +138216,1307354761,1540922576,1 +138221,1307354762,1307354518,1 +138287,1307354773,1307354481,1 +143929,1307354773,1345652034,1 +138139,1307354774,1540922537,1 +138271,1307354774,1540922643,1 +138099,1307354775,1307354482,1 +138247,1307354775,1307354845,1 +138085,1307354780,1307354704,1 +138289,1307354780,1540922652,1 +105894,1307354781,1307354547,1 +138140,1307354781,1307354555,1 +138235,1307354783,1540922600,1 +138273,1307354788,1307354366,1 +138277,1307354788,1307354798,1 +138264,1307354791,1307354356,1 +138122,1307354791,1540922530,1 +138096,1307354796,1307354348,1 +138220,1307354796,1307354762,1 +138278,1307354798,1307354405,1 +138127,1307354798,1307354505,1 +138167,1307354799,1345222288,1 +138175,1307354801,1307354664,1 +138148,1307354806,1307354854,1 +105834,1307354809,1540867966,1 +138084,1307354820,1307354384,1 +138214,1307354820,1540922574,1 +138237,1307354824,1540922601,1 +138242,1307354824,1540922629,1 +138178,1307354826,1307354499,1 +138129,1307354826,1540922532,1 +138228,1307354829,1540922592,1 +138138,1307354831,1307354774,1 +138111,1307354833,1540922527,1 +138290,1307354833,1540922653,1 +96471,1307354835,788870488,1 +122584,1307354835,1085492577,1 +138119,1307354836,1307354715,1 +138238,1307354836,1540922602,1 +138284,1307354839,1307354495,1 +138253,1307354839,1307354552,1 +138260,1307354840,1307354553,1 +138173,1307354842,1307354454,1 +138272,1307354842,1307354788,1 +138145,1307354845,1307354410,1 +138248,1307354845,1307354559,1 +138184,1307354846,1307354446,1 +138300,1307354846,1307354609,1 +138236,1307354849,1307354664,1 +138156,1307354849,1307354713,1 +138223,1307354854,1307354467,1 +138149,1307354854,1307354669,1 +138161,1307354855,1307354529,1 +138211,1307354858,788870484,1 +138266,1307354858,1540922638,1 +138150,1307354868,1307354675,1 +143351,1307367186,1540936899,1 +138331,1307367191,1307367400,1 +138459,1307367191,1307367441,1 +138381,1307367196,1307367298,1 +138422,1307367196,1307367330,1 +138494,1307367197,1307367332,1 +138505,1307367198,1540922793,1 +138527,1307367206,1307367456,1 +138325,1307367206,1540922673,1 +138502,1307367209,1307367217,1 +138384,1307367209,1307367283,1 +138455,1307367212,1307367318,1 +96488,1307367212,1307367333,1 +138397,1307367216,1307367270,1 +138517,1307367216,1307367413,1 +138386,1307367216,1540922709,1 +138503,1307367217,1307367404,1 +138423,1307367217,1307367481,1 +138380,1307367218,1307367196,1 +138327,1307367220,1307367354,1 +138447,1307367220,1307367468,1 +138362,1307367224,1307367363,1 +138367,1307367224,1307367452,1 +96481,1307367225,1307367410,1 +138440,1307367225,1540922746,1 +138474,1307367226,1540922771,1 +138453,1307367233,625904132,1 +138462,1307367233,1307367352,1 +96462,1307367234,788870476,1 +138436,1307367234,1307367304,1 +138375,1307367235,1307367322,1 +138473,1307367235,1540922770,1 +138329,1307367237,1307367257,1 +138433,1307367237,1540922742,1 +138509,1307367239,625912059,1 +138393,1307367239,1307367307,1 +138468,1307367240,1307367342,1 +138315,1307367240,1540922667,1 +138444,1307367244,1307367264,1 +138512,1307367245,1307367379,1 +138354,1307367245,1540922698,1 +138481,1307367247,1540922779,1 +138485,1307367255,625912028,1 +138449,1307367255,1540922763,1 +138341,1307367256,1307367321,1 +138348,1307367258,1540922696,1 +138346,1307367260,1307367346,1 +138428,1307367260,1307367452,1 +138322,1307367262,1307367281,1 +138312,1307367262,1307367355,1 +96592,1307367263,1307367317,1 +138445,1307367264,1307367459,1 +138434,1307367267,1307367288,1 +138532,1307367270,1307367315,1 +138307,1307367274,1540922664,1 +138469,1307367275,1540922768,1 +138356,1307367277,1307367450,1 +138391,1307367278,1307367296,1 +138498,1307367278,1540922788,1 +138390,1307367281,1307367278,1 +138323,1307367281,1540922672,1 +138365,1307367282,1307367325,1 +138409,1307367282,1307367405,1 +138385,1307367283,1307367264,1 +138377,1307367283,1307367478,1 +138350,1307367284,1307367377,1 +138399,1307367284,1307367464,1 +138515,1307367285,1307367288,1 +96461,1307367286,1307367234,1 +138466,1307367286,1307367381,1 +138516,1307367288,1307367216,1 +138435,1307367288,1540922743,1 +138456,1307367290,1307367229,1 +138388,1307367290,1307367376,1 +138416,1307367291,1307367344,1 +138426,1307367291,1307367384,1 +138395,1307367293,1307367388,1 +138489,1307367293,1307367410,1 +138316,1307367294,1307367433,1 +138340,1307367294,1540922692,1 +138392,1307367296,1307367258,1 +138370,1307367296,1540922705,1 +138382,1307367298,1307367342,1 +138534,1307367298,1307367398,1 +138451,1307367302,1307367367,1 +138358,1307367314,1307367416,1 +138414,1307367314,1540922731,1 +138533,1307367315,1307367240,1 +96593,1307367317,625904139,1 +138396,1307367317,1540922716,1 +87994,1307367321,1540851169,1 +138318,1307367325,1307367197,1 +138366,1307367325,1307367224,1 +138311,1307367331,1307367262,1 +138497,1307367331,1307367278,1 +138361,1307367332,1307367224,1 +138495,1307367332,1307367421,1 +138465,1307367333,1307367366,1 +96489,1307367333,1540859686,1 +138472,1307367334,1307367235,1 +138491,1307367337,625912033,1 +138441,1307367337,1307367427,1 +138372,1307367338,1540922706,1 +138360,1307367341,1540922703,1 +138507,1307367341,1540922798,1 +138383,1307367342,1540922707,1 +138471,1307367344,1307367334,1 +138431,1307367344,1540922733,1 +138347,1307367346,1307367258,1 +138309,1307367346,1307367359,1 +138338,1307367347,1307367433,1 +138355,1307367347,1540922699,1 +138464,1307367348,1307367333,1 +96591,1307367348,1540859692,1 +138511,1307367352,1307367245,1 +138463,1307367352,1540922766,1 +138319,1307367355,1307367376,1 +138313,1307367355,1540922665,1 +138470,1307367357,625912033,1 +138467,1307367357,1307367448,1 +138369,1307367359,1307367296,1 +138310,1307367359,1307367331,1 +138475,1307367360,1540922772,1 +143931,1307367360,1540937970,1 +138345,1307367363,1307367260,1 +138363,1307367363,1307367455,1 +138353,1307367367,1307367245,1 +138452,1307367367,1540922764,1 +138480,1307367370,1307367247,1 +138522,1307367370,1540922802,1 +138421,1307367375,1307367196,1 +138531,1307367375,1307367270,1 +138389,1307367376,1307367281,1 +138320,1307367376,1540922671,1 +138425,1307367377,1307367291,1 +138351,1307367377,1307367334,1 +138314,1307367379,1307367302,1 +138513,1307367379,1307367424,1 +138387,1307367383,1307367290,1 +138476,1307367383,1540922778,1 +138432,1307367384,1540922736,1 +138501,1307367386,1307367209,1 +138418,1307367386,1307367478,1 +138439,1307367388,1540922745,1 +138427,1307367394,1307367260,1 +138412,1307367394,1307367407,1 +138403,1307367400,1307367189,1 +138332,1307367400,1307367471,1 +138376,1307367404,1307367283,1 +138504,1307367404,1540922790,1 +138343,1307367405,1540922694,1 +138410,1307367405,1540922724,1 +138379,1307367406,1307367218,1 +138326,1307367406,1307367220,1 +138308,1307367407,1307367346,1 +138413,1307367407,1540922730,1 +138342,1307367409,1307367405,1 +138490,1307367410,1307367337,1 +96482,1307367410,1307367471,1 +138518,1307367413,1307367420,1 +138477,1307367413,1307367472,1 +138359,1307367416,1307367428,1 +138349,1307367416,1540922697,1 +96490,1307367417,788870529,1 +138461,1307367417,1307367233,1 +138519,1307367420,1307367439,1 +138321,1307367420,1307367456,1 +138496,1307367421,1307367331,1 +138526,1307367422,1307367206,1 +138500,1307367422,1307367386,1 +138484,1307367424,1307367255,1 +138514,1307367424,1540922801,1 +138334,1307367427,788870476,1 +138371,1307367428,1307367338,1 +138339,1307367433,1540922680,1 +138520,1307367439,625912041,1 +138324,1307367439,1307367206,1 +138398,1307367443,1307367284,1 +138415,1307367443,1307367291,1 +138525,1307367444,1307367247,1 +138336,1307367446,1307367218,1 +138529,1307367446,1307367472,1 +138443,1307367450,1307367223,1 +138357,1307367450,1307367444,1 +138368,1307367452,1307367359,1 +138429,1307367452,1307367421,1 +143932,1307367454,625912059,1 +138402,1307367454,1307367259,1 +138411,1307367455,1307367394,1 +138364,1307367455,1540922704,1 +138528,1307367456,1307367446,1 +96492,1307367458,788870531,1 +96487,1307367458,1307367212,1 +138446,1307367459,1307367220,1 +138420,1307367459,1307367230,1 +138458,1307367460,1307367191,1 +138488,1307367460,1307367293,1 +138400,1307367464,1307367422,1 +138373,1307367464,1307367481,1 +138317,1307367466,1307367325,1 +138344,1307367466,1307367363,1 +138438,1307367467,1307367388,1 +138448,1307367467,1540922762,1 +138330,1307367469,1307367191,1 +138450,1307367469,1307367302,1 +138333,1307367471,1307367427,1 +96483,1307367471,1540859681,1 +138530,1307367472,1307367375,1 +138352,1307367473,1307367249,1 +138506,1307367473,1540922797,1 +138378,1307367478,1307367406,1 +138419,1307367478,1307367459,1 +138374,1307367481,1307367235,1 +138424,1307367481,1307367377,1 +138633,1307599921,1307599922,1 +138634,1307599922,365120340,1 +138653,1307600503,365121964,0 +138650,1307600504,562865751,0 +138651,1307600505,1307600504,0 +138656,1307601639,1307601640,0 +138657,1307601640,1307601795,0 +2946,1307601795,1540773478,0 +138910,1308321628,1540924000,1 +138909,1308321659,1540923998,1 +81976,1308321810,152805894,0 +138874,1308321838,1540923973,1 +138302,1331276060,1307354709,1 +138192,1331276060,1540922558,1 +96516,1331276061,788870606,1 +138257,1331276061,1540922635,1 +140838,1333798922,1540928528,1 +140892,1333798922,1540928681,1 +140839,1333798996,1540928529,1 +140885,1333798996,1540928655,1 +140840,1333799038,1540928533,1 +140841,1333799040,1540928538,1 +140837,1333799046,1540928527,1 +141201,1333810001,1333810269,1 +140874,1333810005,1540928614,1 +141200,1333810013,1540929680,1 +140873,1333810075,1540928613,1 +140897,1333810075,1540928686,1 +96247,1333810083,1333810282,1 +140872,1333810083,1540928611,1 +149800,1333810085,774085175,1 +140869,1333810085,1540928608,1 +141237,1333810123,1333810171,1 +140894,1333810123,1540928682,1 +140886,1333810171,1540928656,1 +141238,1333810171,1540929750,1 +140893,1333810242,1333810123,1 +140855,1333810269,1540928578,1 +141204,1333810269,1540929700,1 +140902,1333810270,1540928732,1 +149797,1333810274,1540953343,1 +140875,1333810280,1333810013,1 +140870,1333810280,1540928609,1 +96248,1333810282,1540859388,1 +140896,1333810282,1540928685,1 +141115,1333877820,1333878000,1 +141155,1333877840,1540929464,1 +141163,1333877840,1540929494,1 +141106,1333877843,1333878265,1 +141169,1333877843,1333878508,1 +109066,1333877875,1540870369,1 +141128,1333877875,1540929398,1 +141171,1333877887,1540929511,1 +141159,1333877895,1540929484,1 +141162,1333877895,1540929488,1 +141101,1333877903,1333878640,1 +141146,1333877903,1540929435,1 +141135,1333877956,1333878621,1 +109070,1333877969,1540870379,1 +141104,1333877969,1540929301,1 +141116,1333878000,1540929321,1 +141117,1333878000,1540929325,1 +141142,1333878003,1540929429,1 +141167,1333878003,1540929508,1 +141151,1333878028,1333878046,1 +141131,1333878028,1540929402,1 +141108,1333878043,1540929309,1 +141154,1333878043,1540929462,1 +141152,1333878046,1540929450,1 +141112,1333878133,1540929319,1 +141105,1333878140,1333877843,1 +141158,1333878172,1333877895,1 +109067,1333878172,1540870370,1 +109068,1333878189,1333878537,1 +141132,1333878200,1333878700,1 +141149,1333878200,1540929448,1 +141111,1333878225,1333878133,1 +141109,1333878225,1540929313,1 +141113,1333878262,1540929320,1 +141107,1333878265,1333878736,1 +141141,1333878265,1540929425,1 +133753,1333878278,1196620820,1 +141144,1333878278,1540929434,1 +141139,1333878315,1345691509,1 +141129,1333878315,1540929399,1 +141127,1333878341,1540929389,1 +109064,1333878370,1540870365,1 +141103,1333878370,1540929300,1 +141156,1333878425,1540929469,1 +141170,1333878508,1540929509,1 +109069,1333878537,1540870377,1 +141110,1333878537,1540929316,1 +141160,1333878539,1333878699,1 +109063,1333878542,1540870364,1 +141100,1333878591,1540929293,1 +141130,1333878591,1540929401,1 +141168,1333878621,1333877843,1 +141136,1333878621,1345691713,1 +141102,1333878640,1540929298,1 +141147,1333878640,1540929436,1 +109073,1333878699,965013913,1 +141161,1333878699,1333878731,1 +141133,1333878700,1540929412,1 +141166,1333878700,1540929507,1 +141150,1333878701,1540929449,1 +141145,1333878731,1333877903,1 +141134,1333878736,1540929416,1 +141153,1333878746,1540929451,1 +141262,1334277095,1540929817,1 +141251,1334277099,1334277165,1 +141243,1334277131,1540929776,1 +141253,1334277140,1334277145,1 +141254,1334277145,1540929800,1 +141250,1334277146,1334277099,1 +144054,1334277146,1540938192,1 +141260,1334277158,1540929816,1 +143919,1334277158,1540937946,1 +141248,1334277160,1540929796,1 +141252,1334277165,1334277140,1 +141245,1334277192,1540929786,1 +141256,1334277194,1540929804,1 +141264,1334277194,1540929828,1 +141258,1334277195,1345643912,1 +141255,1334277198,1540929802,1 +144014,1334277198,1540938127,1 +141247,1334277203,1334277160,1 +141244,1334277223,1334277192,1 +144091,1334277223,1540938277,1 +141263,1334278775,1540929818,1 +142631,1342036678,1540934948,1 +142629,1342036777,1540934912,1 +142630,1342036793,1540934927,1 +142632,1342036804,1342036793,1 +142633,1342036873,1540934954,1 +142635,1342038248,1540934965,1 +142637,1342038263,1540934968,1 +142638,1342038268,1540934970,1 +142639,1342038308,1342038309,1 +142640,1342038309,1540934982,1 +143222,1342038309,1540936657,1 +143005,1342497364,935855599,1 +143153,1342991986,1540936464,1 +143166,1342991986,1540936516,1 +143154,1342991989,1540936465,1 +143169,1342991989,1540936535,1 +143155,1342992002,1342992004,1 +143156,1342992004,1540936473,1 +143158,1342993133,1540936479,1 +143159,1342993144,1342993148,1 +143160,1342993148,1540936483,1 +143162,1342993148,1540936497,1 +143157,1342993433,1540936478,1 +143165,1342993565,1540936506,1 +143163,1342993881,1540936498,1 +143167,1342993881,1540936523,1 +143164,1342993888,1540936501,1 +143168,1342994387,1540936524,1 +143161,1342994403,1540936485,1 +143171,1342996091,1540936555,1 +143173,1342997754,1540936568,1 +143170,1342998570,1540936552,1 +143150,1342999507,984771377,1 +143175,1342999539,1540936573,1 +97987,1343000037,1540861203,1 +97990,1343000074,797175375,1 +143177,1343000595,1540936576,1 +98007,1343000610,1540861214,1 +98008,1343000736,797175451,1 +143180,1343001627,1540936585,1 +143183,1343001890,1540936607,1 +143185,1343001895,1540936615,1 +143179,1343002254,1540936581,1 +143187,1343003151,1540936624,1 +143202,1343003151,1540936645,1 +143188,1343003173,1343003174,1 +143279,1343003173,1540936738,1 +143189,1343003174,1540936629,1 +143212,1343003174,1540936649,1 +143207,1343003179,1343006075,1 +143191,1343003179,1540936631,1 +143201,1343003489,984772598,1 +143186,1343003489,1540936619,1 +143199,1343003730,1540936640,1 +143251,1343003730,1540936713,1 +143200,1343004240,1540936643,1 +143192,1343004351,1343004352,1 +143193,1343004352,1343021948,1 +143210,1343004352,1343024794,1 +143195,1343004354,1540936636,1 +143196,1343004356,1343022469,1 +143209,1343004731,1343004352,1 +143205,1343005030,1343021643,1 +143213,1343005049,1343005030,1 +143220,1343005396,1343005408,1 +143216,1343005396,1540936653,1 +143218,1343005408,1540936656,1 +143219,1343005413,294163568,1 +143221,1343005566,1343005413,1 +143215,1343005566,1540936651,1 +143208,1343006075,1343004731,1 +143217,1343006075,1540936655,1 +142641,1343007080,1540934987,1 +143225,1343007080,1540936670,1 +143226,1343007099,1343007108,1 +143230,1343007099,1540936682,1 +143227,1343007108,1343007114,1 +143228,1343007114,1540936674,1 +143229,1343007114,1540936681,1 +23892,1343007170,1540793773,0 +57774,1343009871,1540827673,1 +57773,1343010177,1540827672,1 +143223,1343010433,1540936660,1 +127676,1343011215,1540885248,1 +143238,1343011215,1540936700,1 +127668,1343011715,1343012220,1 +143231,1343011715,1540936684,1 +143232,1343011717,1540936685,1 +143240,1343012210,1343011717,1 +143284,1343012210,1540936756,1 +127669,1343012220,1144431765,1 +143242,1343013705,1343013708,1 +143243,1343013708,1540936709,1 +143250,1343013708,1540936712,1 +143244,1343013713,1343013715,1 +143247,1343013713,1540936711,1 +143260,1343013715,1540936726,1 +143245,1343013744,1343013745,1 +143263,1343013744,1343013851,1 +143246,1343013745,1540936710,1 +143253,1343013745,1540936714,1 +143248,1343013851,1343013852,1 +143264,1343013851,1540936728,1 +143249,1343013852,1343013708,1 +143262,1343014892,1540936727,1 +143252,1343015137,1343014892,1 +143255,1343015138,1540936718,1 +143256,1343015142,1343015137,1 +143257,1343015142,1540936721,1 +143254,1343015493,1540936715,1 +143258,1343015493,1540936722,1 +143259,1343015532,1343013715,1 +142636,1343015534,1540934966,1 +143261,1343015679,1343014892,1 +143198,1343015679,1540936639,1 +143265,1343018563,1540936730,1 +143268,1343018563,1540936733,1 +143204,1343018567,1343005030,1 +143267,1343019339,1343018563,1 +143269,1343021640,1343021641,1 +143266,1343021641,1540936731,1 +143270,1343021641,1540936734,1 +143206,1343021643,1343003179,1 +143194,1343021948,1343004354,1 +143271,1343021948,1343021949,1 +143275,1343021949,1343004731,1 +143272,1343021949,1343021950,1 +143190,1343021950,1540936630,1 +143273,1343022286,1540936735,1 +143278,1343022286,1540936737,1 +143211,1343022330,1540936648,1 +143274,1343022330,1540936736,1 +143276,1343022466,1343022467,1 +143277,1343022467,1343022286,1 +143197,1343022469,1540936637,1 +143280,1343023238,1540936739,1 +143281,1343024794,1540936741,1 +143241,1343025546,1540936703,1 +143283,1343025546,1540936747,1 +143239,1343026052,1540936701,1 +143282,1343026052,1540936742,1 +127675,1343029630,1540885247,1 +143285,1343029630,1540936758,1 +143296,1343029632,1343029646,1 +143286,1343029632,1540936759,1 +143235,1343029634,1540936693,1 +127674,1343029643,1540885246,1 +143287,1343029643,1540936760,1 +143288,1343029646,1540936762,1 +143297,1343029646,1540936764,1 +143234,1343029648,1540936692,1 +127672,1343029774,1343029776,1 +143289,1343029774,1343033254,1 +143236,1343029776,1540936696,1 +127677,1343029892,1540885249,1 +143291,1343029892,1540936763,1 +143295,1343032353,1343029632,1 +143237,1343032353,1540936698,1 +143233,1343032358,1540936689,1 +143292,1343033247,1343033250,1 +127671,1343033247,1540885241,1 +143293,1343033250,1343033254,1 +143290,1343033254,1343029892,1 +143294,1343033254,1343032353,1 +107242,1343037492,938143007,1 +107241,1343037582,1343037492,1 +143299,1343038885,1540936766,1 +143300,1343038887,1540936767,1 +143301,1343038907,1540936778,1 +143308,1343038907,1540936790,1 +143302,1343038909,1343038910,1 +143327,1343038909,1540936850,1 +143303,1343038910,1540936779,1 +143330,1343038910,1540936861,1 +143304,1343038912,1343038913,1 +143338,1343038912,1540936867,1 +143305,1343038913,1343047818,1 +57772,1343039237,1343010177,1 +143298,1343039237,1540936765,1 +143307,1343039924,1540936788,1 +143311,1343039924,1540936801,1 +57775,1343039951,1540827674,1 +143309,1343040202,1540936793,1 +143312,1343040231,1540936802,1 +143313,1343040246,1540936806,1 +143314,1343040253,1540936812,1 +143319,1343040253,1540936824,1 +143315,1343040256,1540936814,1 +143322,1343040256,1540936841,1 +143316,1343040691,1540936818,1 +143317,1343040693,1540936819,1 +143323,1343040693,1540936842,1 +143318,1343040698,1540936823,1 +143320,1343042135,1540936825,1 +143359,1343042135,1540936905,1 +143321,1343042207,1540936836,1 +143324,1343043922,1540936843,1 +143325,1343043952,1540936849,1 +57776,1343044019,1343045382,1 +143326,1343044127,1343038909,1 +143331,1343045380,1540936862,1 +143335,1343045380,1540936866,1 +57777,1343045382,1343048609,1 +143310,1343045617,1540936798,1 +143328,1343045617,1540936853,1 +143329,1343045621,1540936856,1 +143332,1343046944,938142867,1 +23961,1343047805,938142843,1 +143333,1343047805,1540936863,1 +143341,1343047808,1343047814,1 +143342,1343047814,1343047816,1 +143343,1343047816,1540936868,1 +143306,1343047818,1540936780,1 +143337,1343048608,1343048609,1 +57778,1343048609,600920086,1 +143336,1343048642,1343047816,1 +84004,1343049092,938143143,1 +143339,1343049092,1343049094,1 +143340,1343049094,1343047808,1 +23964,1343049691,1540793875,1 +143344,1343049691,1540936869,1 +107023,1343052619,1540868903,1 +107024,1343052621,1540868904,1 +143423,1343052621,1540937078,1 +107025,1343052623,1540868905,1 +143346,1343053028,1540936888,1 +143392,1343053028,1540936983,1 +143347,1343053044,1540936891,1 +143348,1343053061,1540936893,1 +143350,1343053076,1307367186,1 +143402,1343053076,1540937014,1 +143352,1343053078,1540936900,1 +143353,1343053080,1343053081,1 +143407,1343053080,1540937034,1 +143354,1343053081,1540936901,1 +143409,1343053081,1540937038,1 +143355,1343053083,1540936902,1 +143357,1343053087,1343053088,1 +143412,1343053087,1540937048,1 +143358,1343053088,1343042135,1 +143360,1343053090,1540936906,1 +143361,1343053092,1343063967,1 +143418,1343053092,1540937073,1 +143368,1343054276,1540936925,1 +143370,1343054282,1343054283,1 +143371,1343054283,1540936930,1 +143372,1343054287,1540936933,1 +143373,1343054297,1540936942,1 +143394,1343054297,1540936990,1 +143374,1343054304,1540936948,1 +57769,1343054372,1540827670,1 +143363,1343054372,1540936912,1 +143365,1343054383,1540936922,1 +143366,1343054385,1343055888,1 +143375,1343055176,1540936953,1 +57770,1343055179,365925662,1 +143376,1343055180,1540936955,1 +143377,1343055185,1540936959,1 +143378,1343055251,1540936964,1 +143379,1343055255,1343055185,1 +143380,1343055382,1343055386,1 +143364,1343055386,1343054383,1 +143381,1343055720,1540936966,1 +143382,1343055727,1540936972,1 +143369,1343055731,1540936926,1 +143383,1343055846,1343054385,1 +143384,1343055877,1540936975,1 +143385,1343055885,1540936976,1 +143367,1343055888,1540936923,1 +143386,1343055990,1540936978,1 +143387,1343056303,1540936979,1 +143388,1343056328,1343056330,1 +143389,1343056330,1343054297,1 +143390,1343056778,1343056330,1 +143391,1343056830,1343056831,1 +143393,1343056831,1540936988,1 +143395,1343058473,1540936991,1 +143396,1343058486,1540936992,1 +143397,1343058486,1540936996,1 +143398,1343059375,1343058473,1 +143349,1343060791,1540936897,1 +143399,1343061706,1540936998,1 +143400,1343061709,1540937000,1 +143401,1343061714,1540937004,1 +143405,1343061729,1540937026,1 +143403,1343061730,1540937018,1 +143404,1343061733,1540937020,1 +143406,1343061747,1540937033,1 +143408,1343061799,1540937036,1 +143410,1343061981,1540937042,1 +143411,1343062008,1540937044,1 +143356,1343062012,1540936904,1 +143413,1343062877,1540937053,1 +143414,1343063208,1540937057,1 +107020,1343063215,1343067056,1 +143415,1343063230,1540937062,1 +143416,1343063250,1540937066,1 +143417,1343063366,1540937070,1 +143421,1343063967,1343063968,1 +143362,1343063967,1540936907,1 +143422,1343063968,1540937075,1 +143419,1343065078,1343065083,1 +143424,1343065938,1343065078,1 +143425,1343067054,1540937079,1 +107021,1343067056,361199635,1 +143426,1343067056,1540937080,1 +143427,1343067312,1540937086,1 +143429,1343067314,1343067315,1 +143432,1343067314,1343067335,1 +143430,1343067315,1343067316,1 +143434,1343067315,1343067370,1 +143438,1343067316,1343068265,1 +107108,1343067319,1540868920,1 +143431,1343067334,1343067314,1 +143442,1343067335,1343067370,1 +143433,1343067369,1343067315,1 +143437,1343067369,1540937089,1 +143435,1343067370,1540937087,1 +143443,1343067370,1540937098,1 +143445,1343067373,1343068268,1 +143436,1343067373,1540937088,1 +143439,1343068265,1343068268,1 +143440,1343068268,1540937094,1 +143444,1343070508,1343067373,1 +143448,1343071761,1540937100,1 +143447,1343074677,1540937099,1 +143453,1343076830,1540937104,1 +107016,1343076833,1540868888,1 +143455,1343077290,1343074677,1 +143345,1343082653,1540936870,1 +143457,1343082653,1540937114,1 +96085,1343084389,1540859004,1 +143456,1343084432,1540937111,1 +143458,1343084488,1540937122,1 +143459,1343084494,1540937126,1 +143460,1343085161,1540937155,1 +143461,1343085165,1540937158,1 +143464,1343085165,1540937168,1 +143462,1343085169,1540937161,1 +143463,1343085192,1540937164,1 +143467,1343085192,1540937174,1 +143465,1343085659,1540937172,1 +138523,1343085694,1540922803,1 +143466,1343085884,1343085192,1 +143469,1343086013,1540937191,1 +96083,1343086030,1540858994,1 +143473,1343086632,1540937211,1 +143470,1343086640,1540937194,1 +143474,1343086640,1540937214,1 +143471,1343086645,1540937198,1 +143475,1343086645,1540937218,1 +143468,1343087271,1540937185,1 +143472,1343087271,1540937201,1 +143476,1343087273,1540937224,1 +96080,1343088144,1540858985,1 +96077,1343088169,788870783,1 +88578,1343088172,625909073,1 +143477,1343089321,1540937234,1 +96623,1343089345,788870788,1 +143478,1343089639,1540937242,1 +57768,1343090479,1540827655,1 +143580,1343906174,279590130,1 +53841,1343906174,363971772,1 +96167,1345207351,775866112,1 +96263,1345209590,1345215796,1 +96265,1345212086,775868545,1 +96264,1345215796,1540859416,1 +138305,1345217922,788870762,1 +96261,1345217966,1540859411,1 +96258,1345218166,1540859400,1 +96260,1345218450,1540859409,1 +138168,1345222288,1307354506,1 +138181,1345222622,1307354544,1 +143803,1345227245,1540937717,1 +143807,1345227245,1540937730,1 +143808,1345227250,1540937734,1 +143809,1345227264,1540937747,1 +143810,1345227269,1540937751,1 +143801,1345227506,1540937690,1 +143802,1345227526,1540937709,1 +143804,1345227663,1540937719,1 +143805,1345227669,1540937724,1 +143806,1345227673,1540937727,1 +143811,1345227883,1540937759,1 +143812,1345228045,1540937766,1 +143813,1345228049,1345228050,1 +143814,1345228050,1540937769,1 +143815,1345228054,1540937770,1 +143818,1345228056,1345228057,1 +143816,1345228056,1540937771,1 +143819,1345228057,1540937774,1 +143825,1345228057,1540937785,1 +141249,1345228064,1334277146,1 +143817,1345228517,1345228518,1 +143820,1345228517,1345228645,1 +143823,1345228644,1345228645,1 +143821,1345228645,1540937777,1 +143824,1345228645,1540937783,1 +143822,1345228744,1540937781,1 +143828,1345228744,1540937796,1 +143826,1345229405,1540937788,1 +143827,1345229891,1540937794,1 +143829,1345230438,1540937797,1 +143831,1345230438,1540937812,1 +143830,1345231627,1540937808,1 +143832,1345231627,1540937817,1 +143909,1345231643,1540937922,1 +148897,1345231643,1540950391,1 +143833,1345231655,1540937824,1 +143835,1345233464,1540937837,1 +143836,1345233476,1540937845,1 +105836,1345233480,1540867993,1 +143834,1345234441,1540937832,1 +143837,1345234805,1540937847,1 +143868,1345508956,1540937872,0 +143873,1345509027,360209953,1 +45811,1345509027,1540812184,1 +143881,1345509354,1540937886,0 +143882,1345509357,1345509358,0 +143884,1345509357,1540937888,1 +143883,1345509358,1345509359,0 +143879,1345509359,1540937884,0 +143889,1345509416,360210159,1 +143880,1345509423,1540937885,0 +143854,1345509870,1540937866,0 +143894,1345509870,1540937900,0 +143908,1345639386,1540937918,1 +143910,1345641511,1540937925,1 +143911,1345641518,1345227269,1 +143912,1345641536,1540937932,1 +141257,1345642872,1540929807,1 +143913,1345642872,1540937934,1 +143923,1345642880,1345642978,1 +143914,1345642880,1540937935,1 +143924,1345642978,1345643346,1 +143915,1345642978,1540937936,1 +105829,1345642983,1540867960,1 +143917,1345643341,1540937941,1 +143918,1345643346,1540937943,1 +105669,1345643909,1540867739,1 +143920,1345643909,1540937949,1 +141259,1345643912,1540929810,1 +143922,1345644464,1540937957,1 +143921,1345644504,1540937950,1 +143925,1345645182,1540937960,1 +143926,1345645491,1540937961,1 +105835,1345645494,1540867967,1 +141261,1345646386,1334277095,1 +143927,1345646386,1540937962,1 +105825,1345647041,935854427,1 +143928,1345647041,1540937963,1 +105700,1345651509,1540867801,1 +105694,1345651540,1540867793,1 +143930,1345652034,1540937964,1 +105693,1345652044,1540867789,1 +94862,1345657694,625911762,1 +97507,1345657694,1540859990,1 +94861,1345658067,1345657694,1 +143933,1345658067,1540937972,1 +97508,1345658074,745090323,1 +143941,1345658489,1345658511,1 +143934,1345658489,1540937974,1 +143935,1345658491,1345658492,1 +143946,1345658491,1345659582,1 +84194,1345658492,1540847203,1 +97512,1345658511,1345659064,1 +143950,1345658967,1540937982,1 +143952,1345658969,1540937983,1 +97511,1345658992,1345658511,1 +143939,1345658992,1345660439,1 +143947,1345659064,1345659189,1 +97513,1345659064,1540859993,1 +143942,1345659189,1540937978,1 +143948,1345659189,1540937981,1 +143943,1345659192,1540937980,1 +143951,1345659198,1345658969,1 +143944,1345659198,1345659306,1 +143945,1345659306,1345658491,1 +143949,1345659306,1345658967,1 +143963,1345660136,1345660137,1 +143937,1345660136,1540937975,1 +97510,1345660137,1345658992,1 +143938,1345660368,1345658992,1 +143964,1345660437,1345660439,1 +143940,1345660439,1540937976,1 +143936,1345660694,1345660136,1 +143966,1345660694,1540937990,1 +2177,1345660761,937378304,1 +84193,1345660761,1540847194,1 +143967,1345662632,1540937991,1 +87984,1345665604,355921355,1 +143968,1345665604,1307354662,1 +144024,1345680604,1345684255,1 +144019,1345680604,1540938142,1 +144020,1345680614,1345680619,1 +36831,1345680614,1540805342,0 +143018,1345680619,1540936002,0 +144015,1345680895,1540938136,1 +144017,1345680899,1540938139,1 +144018,1345680901,1540938140,1 +144021,1345681709,1540938143,1 +144016,1345683061,1540938137,1 +144025,1345684255,1345680901,1 +36830,1345684263,1540805340,0 +144026,1345684263,1540938154,1 +144027,1345684280,1345684281,1 +144028,1345684280,1540938156,1 +144029,1345684362,1540938157,1 +144030,1345684365,1540938158,1 +144031,1345684839,1540938160,1 +144032,1345684844,1345684845,1 +144033,1345684845,1345684847,1 +144023,1345684847,1540938144,1 +144034,1345684847,1540938164,1 +144035,1345684852,1345684853,1 +144036,1345684853,1345684854,1 +144044,1345684853,1345685997,1 +144046,1345684854,1540938183,1 +144047,1345684861,1345684365,1 +144022,1345685044,1345684847,1 +144041,1345685044,1540938177,1 +144037,1345685137,1345684845,1 +144038,1345685145,1345684844,1 +144039,1345685954,1540938168,1 +144040,1345685959,1540938169,1 +144042,1345685994,1345685996,1 +144043,1345685996,1540938179,1 +144048,1345685997,1345685996,1 +144045,1345685997,1540938180,1 +144049,1345686374,1540938188,1 +144050,1345686408,1345684861,1 +141246,1345686502,1540929791,1 +144051,1345686502,1540938189,1 +144052,1345686699,1540938191,1 +144053,1345686701,1345686704,1 +144055,1345687083,1334277140,1 +36828,1345688863,1540805336,0 +144057,1345688945,1540938217,1 +144081,1345688956,1345691497,1 +144059,1345688956,1540938225,1 +144060,1345688960,1540938228,1 +144070,1345688960,1540938239,1 +144061,1345688963,1345688964,1 +144066,1345688963,1345689014,1 +144062,1345688964,1345688965,1 +144063,1345688965,1540938230,1 +144064,1345688971,1345688972,1 +144065,1345688972,1540938234,1 +144067,1345689014,1345689016,1 +144068,1345689016,1345689017,1 +144069,1345689017,1540938238,1 +144076,1345689091,1345689014,1 +144071,1345689091,1540938242,1 +144078,1345689094,1345689016,1 +144072,1345689094,1540938243,1 +144075,1345689096,1345689017,1 +144073,1345689096,1540938244,1 +144077,1345689358,1345689101,1 +144079,1345690767,1345688965,1 +144080,1345690799,1345688964,1 +144084,1345691497,1345691537,1 +144082,1345691497,1540938250,1 +141140,1345691509,1540929423,1 +144083,1345691511,1345691497,1 +144086,1345691537,1345691552,1 +144085,1345691537,1540938260,1 +144058,1345691552,1540938222,1 +141137,1345691713,1540929419,1 +144056,1345691713,1540938194,1 +144087,1345691755,1540938261,1 +144094,1345691755,1540938285,1 +144088,1345691757,1540938262,1 +144090,1345691757,1540938272,1 +144089,1345691764,1540938268,1 +144092,1345692023,1345692024,1 +144093,1345692024,1540938283,1 +144095,1345692028,1540938286,1 +144096,1345692030,1345692031,1 +144097,1345692031,1345692818,1 +144099,1345692047,1345692031,1 +144100,1345692177,1345692030,1 +144101,1345692686,1345692024,1 +144102,1345692816,1345692818,1 +144098,1345692818,1540938287,1 +144103,1345692824,1345692023,1 +144104,1345692908,1345692028,1 +144105,1345694269,1540938291,1 +144111,1345694274,1540938360,1 +144110,1345694817,1540938331,1 +149762,1371043802,278009570,1 +148345,1371043803,1371043802,1 +100574,1371043816,810716447,1 +148344,1371043816,1540949584,1 +148363,1371043820,1540949632,1 +148439,1371043820,1540949746,1 +148567,1371043825,1540949887,1 +100581,1371043836,1540862737,1 +148317,1371043839,1540949541,1 +148450,1371043839,1540949750,1 +148329,1371043849,1540949550,1 +148386,1371043850,1371043849,1 +148425,1371043850,1540949706,1 +96651,1371043857,1540859732,1 +148413,1371043861,1371043857,1 +148362,1371043861,1540949627,1 +148412,1371043865,1371043861,1 +148426,1371043865,1540949708,1 +148522,1371043871,1540949792,1 +148415,1371043887,1371043902,1 +148427,1371043887,1540949710,1 +148328,1371043888,1540949546,1 +148316,1371043890,1540949534,1 +148433,1371043890,1540949726,1 +148373,1371043896,1371043888,1 +148434,1371043896,1371043902,1 +148361,1371043899,1540949623,1 +148327,1371043902,1371043888,1 +148416,1371043902,1371043930,1 +148435,1371043902,1540949727,1 +148432,1371043907,1540949722,1 +148551,1371043907,1540949824,1 +96650,1371043908,1371043857,1 +148360,1371043909,1371043899,1 +148389,1371043909,1371043908,1 +148376,1371043915,1371043899,1 +148428,1371043915,1540949711,1 +148347,1371043930,1540949596,1 +148392,1371043944,1371043965,1 +148348,1371043944,1540949602,1 +148346,1371043947,1540949594,1 +148438,1371043965,1540949741,1 +148436,1371043983,1540949731,1 +148526,1371043983,1540949796,1 +148525,1371043988,1371043983,1 +148429,1371043988,1540949716,1 +148524,1371043995,1371043988,1 +96648,1371043995,1540859728,1 +148437,1371043996,1540949735,1 +148530,1371043996,1540949802,1 +148402,1371044000,1540949676,1 +148531,1371044000,1540949803,1 +119942,1371044002,1540879709,1 +148430,1371044014,1371044018,1 +148506,1371044016,1371044030,1 +148431,1371044018,1540949720,1 +96697,1371044026,1540859744,1 +148381,1371044029,1371044014,1 +96646,1371044029,1540859722,1 +120191,1371044030,1371044032,1 +148507,1371044030,1371044040,1 +148388,1371044032,1371044015,1 +120192,1371044032,1540879993,1 +148446,1371044034,1371044008,1 +120190,1371044034,1540879992,1 +148508,1371044040,1540949788,1 +96696,1371044048,1371044026,1 +148378,1371044054,1371044027,1 +148504,1371044054,1371044038,1 +96645,1371044056,1540859720,1 +148503,1371044061,1371044054,1 +96665,1371044074,789216020,1 +96667,1371044076,789215924,1 +148391,1371044076,1371044053,1 +96669,1371044077,789216011,1 +148502,1371044077,1540949783,1 +96671,1371044078,789215914,1 +148380,1371044078,1371044055,1 +120096,1371044092,1540879927,0 +148505,1371044092,1540949784,1 +96678,1371044100,789216035,1 +148382,1371044100,1371044105,1 +148403,1371044106,1371044125,1 +120148,1371044106,1540879966,1 +96676,1371044107,789216033,1 +120147,1371044107,1371044106,1 +120114,1371044111,1540879941,1 +120145,1371044114,1540879964,1 +148528,1371044114,1540949801,1 +148404,1371044125,1037361810,1 +120663,1371044125,1371044111,1 +148529,1371044128,789215995,1 +148414,1371044128,1540949678,1 +148417,1371044130,1540949679,1 +148466,1371044130,1540949775,1 +148418,1371044144,1540949688,1 +148419,1371044166,1371044172,1 +148401,1371044167,1371044165,1 +148516,1371044167,1540949791,1 +148400,1371044169,1371044167,1 +148420,1371044172,1540949692,1 +148489,1371044172,1540949780,1 +148515,1371044182,1371044167,1 +148497,1371044182,1371044179,1 +148421,1371044184,1371044201,1 +148495,1371044184,1540949782,1 +148496,1371044185,1371044182,1 +148490,1371044185,1371044202,1 +148514,1371044200,1371044182,1 +148494,1371044200,1371044199,1 +148422,1371044201,1540949694,1 +148492,1371044201,1540949781,1 +148493,1371044202,1371044200,1 +148491,1371044202,1371044222,1 +148513,1371044220,1371044200,1 +148302,1371044220,1540949521,1 +148301,1371044222,1371044220,1 +148303,1371044228,1371044232,1 +148390,1371044228,1371044317,1 +148300,1371044229,1371044222,1 +148423,1371044229,1540949697,1 +148304,1371044232,1371044236,1 +148408,1371044232,1371044255,1 +148305,1371044236,1371044243,1 +148306,1371044243,1371044250,1 +148481,1371044243,1371044264,1 +148465,1371044248,1540949768,1 +148307,1371044250,1371044248,1 +148532,1371044250,1371044268,1 +148442,1371044255,1371044257,1 +148409,1371044255,1371044281,1 +148512,1371044257,1371044236,1 +148443,1371044257,1371044264,1 +148464,1371044262,1371044248,1 +148374,1371044262,1371044285,1 +148444,1371044264,1371044272,1 +148482,1371044264,1371044316,1 +148533,1371044268,1371044272,1 +148498,1371044268,1371044285,1 +148534,1371044272,1371044302,1 +148480,1371044281,1371044273,1 +148499,1371044285,1371044287,1 +148500,1371044287,1371044314,1 +148467,1371044287,1371044318,1 +148511,1371044297,1371044257,1 +148479,1371044297,1371044281,1 +148451,1371044302,1371044318,1 +148535,1371044302,1371044322,1 +148333,1371044306,1371044317,1 +148501,1371044314,1371044320,1 +148485,1371044314,1371044351,1 +148463,1371044315,1540949765,1 +148478,1371044316,1371044297,1 +148483,1371044316,1371044379,1 +148334,1371044317,1371044358,1 +148452,1371044318,1371044351,1 +148468,1371044318,1371044367,1 +148343,1371044320,1371044315,1 +148477,1371044322,1371044316,1 +148536,1371044322,1371044342,1 +148462,1371044332,1371044315,1 +148349,1371044332,1371044356,1 +148447,1371044342,1371044367,1 +148537,1371044342,1371044393,1 +148453,1371044351,1371044373,1 +148486,1371044351,1371044399,1 +148366,1371044354,1540949655,1 +148350,1371044356,1540949605,1 +148335,1371044358,1371044363,1 +148377,1371044358,1371044435,1 +148510,1371044363,1371044297,1 +148336,1371044363,1371044379,1 +148461,1371044365,1371044332,1 +148365,1371044365,1540949651,1 +148448,1371044367,1371044399,1 +148469,1371044367,1371044430,1 +148342,1371044373,1371044320,1 +148337,1371044379,1371044393,1 +148484,1371044379,1371044464,1 +56955,1371044384,1540825072,1 +148385,1371044387,1371044384,1 +148358,1371044387,1540949618,1 +148406,1371044389,1371044354,1 +148338,1371044393,1371044430,1 +148367,1371044398,1371044423,1 +148449,1371044399,1371044433,1 +148487,1371044399,1371044470,1 +148352,1371044405,1540949609,1 +148315,1371044417,1540949525,1 +148351,1371044417,1540949608,1 +148460,1371044419,1540949764,1 +148368,1371044423,1540949656,1 +148339,1371044430,1371044470,1 +148470,1371044430,1371044508,1 +148341,1371044433,1371044373,1 +148405,1371044437,1371044389,1 +148459,1371044437,1540949763,1 +148383,1371044448,1371044398,1 +148397,1371044448,1540949673,0 +148357,1371044449,1540949616,1 +148369,1371044449,1540949659,1 +148509,1371044451,1540949790,1 +148379,1371044459,1371044389,1 +148396,1371044459,1540949669,0 +148488,1371044470,1371044514,1 +148340,1371044470,1540949583,1 +148393,1371044471,1371044475,0 +148471,1371044475,1371044510,1 +148394,1371044475,1540949661,0 +148387,1371044480,1371044511,1 +148395,1371044480,1540949665,0 +148521,1371044490,1371044419,1 +148364,1371044490,1540949634,1 +148520,1371044500,1371044490,1 +148371,1371044501,1540949660,1 +148440,1371044501,1540949748,1 +148542,1371044502,1371044518,1 +148356,1371044510,1540949615,1 +148472,1371044510,1540949778,1 +148458,1371044511,1540949762,1 +148375,1371044517,1371044500,1 +148541,1371044517,1540949806,1 +148474,1371044518,1371044547,1 +148543,1371044518,1540949808,1 +148519,1371044521,1371044500,1 +148318,1371044521,1371044539,1 +148372,1371044523,1371044533,1 +148550,1371044533,1540949823,1 +148473,1371044534,1371044540,1 +148441,1371044534,1371044555,1 +148544,1371044538,1371044551,1 +148410,1371044538,1371044556,1 +148540,1371044539,1371044517,1 +148319,1371044539,1371044547,1 +148326,1371044540,1540949543,1 +148407,1371044541,1540949677,1 +148549,1371044541,1540949822,1 +148518,1371044542,1371044521,1 +148355,1371044543,1371044510,1 +148457,1371044543,1540949760,1 +148320,1371044547,1371044556,1 +148475,1371044547,1540949779,1 +56950,1371044549,365388275,1 +148548,1371044549,1540949819,1 +148398,1371044551,1371044566,1 +148545,1371044551,1540949810,1 +148539,1371044553,1371044539,1 +148476,1371044553,1371044542,1 +148456,1371044555,1540949758,1 +148321,1371044556,1371044566,1 +148411,1371044556,1371044570,1 +148325,1371044561,1371044540,1 +148455,1371044561,1540949756,1 +148354,1371044562,1371044543,1 +148546,1371044562,1371044572,1 +148517,1371044565,1371044542,1 +148322,1371044566,1371044573,1 +148399,1371044566,1371044575,1 +148538,1371044568,1371044553,1 +148324,1371044572,1371044561,1 +148547,1371044572,1540949811,1 +148353,1371044573,1371044562,1 +148323,1371044573,1371044572,1 +20249,1371124898,1540790317,1 +148585,1371124902,1540949926,1 +148669,1371124902,1540950118,1 +93170,1371124921,1540856443,1 +148660,1371124921,1540950111,1 +149755,1371124946,278009557,1 +148683,1371124946,1540950138,0 +148607,1371124947,1371124956,1 +20309,1371124956,278012134,1 +148682,1371124965,1540950137,1 +148590,1371124993,1540949942,1 +148653,1371125001,1371125030,1 +149758,1371125001,1540953283,1 +148600,1371125005,1540949986,1 +148587,1371125024,1540949930,1 +148681,1371125024,1540950136,1 +148654,1371125030,1371125090,1 +148558,1371125030,1540949865,1 +148646,1371125039,1371124993,1 +148617,1371125039,1540950026,1 +93164,1371125074,704804617,1 +148611,1371125074,1371125089,1 +148645,1371125077,1371125039,1 +148591,1371125078,1540949945,1 +148680,1371125078,1540950134,1 +148332,1371125090,1540949572,1 +148684,1371125094,1371125111,1 +96635,1371125094,1540859712,0 +148595,1371125098,1371125066,1 +148557,1371125104,1540949861,1 +148678,1371125104,1540950132,1 +148589,1371125105,1540949935,1 +148662,1371125105,1540950113,1 +148685,1371125111,789215837,1 +148661,1371125111,1371125105,1 +148679,1371125115,1371043803,1 +148677,1371125119,1371125104,1 +148331,1371125119,1540949565,1 +148629,1371125131,1371125159,1 +148594,1371125131,1540949960,1 +148606,1371125135,1371125206,1 +148628,1371125135,1540950065,1 +148570,1371125139,1540949895,1 +148636,1371125139,1540950085,1 +148618,1371125158,1540950030,1 +148630,1371125159,1371125188,1 +148676,1371125161,1371125119,1 +148627,1371125161,1371125135,1 +148648,1371125170,1371125158,1 +148596,1371125170,1540949974,1 +148635,1371125181,1371125139,1 +148647,1371125184,1371125170,1 +148588,1371125184,1540949934,1 +148559,1371125188,1371125256,1 +148631,1371125188,1540950067,1 +148644,1371125206,1540950102,1 +148562,1371125217,1371125181,1 +148592,1371125217,1540949946,1 +148569,1371125234,1540949892,1 +148560,1371125256,1540949868,1 +148667,1371125290,1371125234,1 +148561,1371125290,1540949872,1 +148605,1371125295,1371125358,1 +148597,1371125295,1540949976,1 +148637,1371125324,1540950086,1 +148616,1371125325,1540950016,1 +148643,1371125350,1540950099,1 +148634,1371125355,1540950080,1 +93167,1371125358,1540856440,1 +148614,1371125360,1371125350,1 +148626,1371125360,1540950060,1 +148666,1371125372,1371125290,1 +148593,1371125372,1540949953,1 +148599,1371125375,1540949983,1 +148612,1371125380,1371125325,1 +148598,1371125380,1371125375,1 +148632,1371125421,1540950074,1 +148608,1371125427,1371125355,1 +148638,1371125427,1540950089,1 +148665,1371125435,1371125372,1 +148633,1371125435,1540950077,1 +148565,1371125437,1371125534,1 +148673,1371125437,1540950125,1 +148613,1371125449,1371125458,1 +133568,1371125449,1540895609,1 +148609,1371125454,1371125534,1 +148639,1371125454,1540950090,1 +148615,1371125457,1371125421,1 +148642,1371125457,1540950094,1 +148580,1371125458,1540949916,1 +148664,1371125466,1371125435,1 +148640,1371125466,1540950091,1 +148641,1371125477,1540950093,1 +148625,1371125497,1540950056,1 +148566,1371125534,1540949884,1 +133566,1371125536,1184265334,1 +148553,1371125538,1540949838,1 +148571,1371125554,1540949902,1 +148604,1371125554,1540950010,1 +148610,1371125558,1371125477,1 +148568,1371125558,1540949888,1 +148582,1371125565,1540949918,1 +148655,1371125565,1540950108,1 +100584,1371125567,789215847,1 +148656,1371125567,789215849,1 +148579,1371125571,1371125458,1 +148572,1371125591,1540949906,1 +148650,1371125591,1540950105,1 +148658,1371125593,1371125613,1 +148583,1371125593,1540949919,1 +148578,1371125598,1540949915,1 +148674,1371125598,1540950128,1 +148577,1371125613,1371125598,1 +148573,1371125618,1540949908,1 +148663,1371125618,1540950114,1 +148675,1371125634,1540950130,1 +148563,1371125638,1540949874,1 +148692,1371125638,1540950145,1 +148576,1371125640,1540949913,1 +148670,1371125640,1540950119,1 +148603,1371125642,1540950004,1 +148619,1371125656,1540950035,1 +148574,1371125661,1540949911,1 +148564,1371125662,1540949875,1 +148602,1371125672,1540950001,1 +148620,1371125672,1540950038,1 +148621,1371125684,1540950040,1 +148659,1371125684,1540950109,1 +148623,1371125686,1540950047,1 +148652,1371125686,1540950107,1 +148556,1371125688,1540949853,1 +148622,1371125688,1540950044,1 +96655,1371477967,789215988,1 +148852,1371477967,1371477969,1 +96702,1371477972,1540859746,1 +148851,1371477972,1540950317,1 +141126,1374266416,1540929388,1 +141138,1374266416,1540929421,1 +143019,1374274158,1540936005,0 +148924,1374274158,1540950447,0 +96084,1375294972,1540859003,1 +110247,1382818844,360019433,1 +149221,1385836393,278007878,1 +149316,1387911658,1540951344,1 +149315,1387911689,1540951342,1 +2743,1387911917,1540773195,1 +149321,1387915776,1540951381,1 +149359,1387915847,1387915776,1 +149358,1387915860,279591451,1 +149360,1387915874,1540951343,0 +40359,1411198108,360009117,1 +149685,1411198108,1411198112,1 +40358,1411198110,1411198108,1 +149706,1411198110,1540953173,1 +40312,1411198112,1411198113,1 +149705,1411198113,1411198110,1 +40313,1411198113,1540810006,1 +149686,1411198131,360007537,1 +149732,1411198131,1540953204,0 +149652,1411198134,360007552,1 +149733,1411198134,1411198143,0 +149728,1411198139,360006486,0 +149704,1411198139,1411198113,1 +40364,1411198143,1540810050,1 +149734,1411198143,1540953205,0 +149690,1411198148,360006660,1 +149735,1411198148,1540953207,0 +40298,1411198158,360006480,1 +149736,1411198158,1411198160,0 +149737,1411198160,1411198162,0 +40407,1411198162,360007510,1 +149738,1411198162,1540953208,0 +40440,1411198169,360007597,1 +115373,1411198170,1540874504,1 +149694,1411198175,1540953159,1 +149699,1411198175,1540953165,1 +149677,1411198187,981693535,1 +149712,1411198187,1540953178,1 +149664,1411198190,1540953135,1 +149675,1411198197,981693528,1 +149697,1411198197,1540953161,1 +114714,1411198203,981693560,1 +149666,1411198209,1540953142,1 +149674,1411198213,1411198197,1 +149688,1411198232,981693512,1 +149673,1411198232,1411198213,1 +149692,1411198239,981693560,1 +149721,1411198242,1411198239,1 +40432,1411198242,1540810068,1 +149682,1411198243,737307345,1 +149659,1411198243,1540952864,1 +149720,1411198252,1540953199,1 +149672,1411198256,1411198232,1 +149719,1411198256,1540953196,1 +149658,1411198270,1540952863,1 +149660,1411198270,1540952868,1 +149657,1411198272,1411198270,1 +149671,1411198277,1540953156,1 +149667,1411198289,1540953143,1 +149670,1411198289,1540953155,1 +125048,1411198293,1540883977,1 +149669,1411198297,1411198289,1 +149661,1411198297,1540953128,1 +149656,1411198305,1411198272,1 +115421,1411198305,1540874545,1 +149707,1411198314,1540953174,1 +149715,1411198314,1540953182,1 +149714,1411198315,1411198314,1 +149713,1411198323,1411198315,1 +149662,1411198323,1540953130,1 +125050,1411198366,1113561537,1 +149703,1411198366,1540953170,1 +149716,1411198387,1540953185,1 +149718,1411198387,1540953194,1 +125044,1411198388,891523976,1 +149717,1411198399,1540953191,1 +149711,1411198401,1411198388,1 +104463,1411198403,891523976,1 +149684,1411198403,1411198401,1 +149710,1411198409,1540953177,1 +149695,1411198411,1411198420,1 +149701,1411198411,1540953167,1 +104462,1411198413,1411198403,1 +149700,1411198413,1411198411,1 +149709,1411198419,1411198409,1 +149696,1411198420,1540953160,1 +149702,1411198420,1540953168,1 +149708,1411198425,1411198419,1 +104472,1411198429,891523971,1 +115725,1411198431,1540874859,1 +149698,1411198431,1540953163,1 +96382,1411219064,788840127,1 +149804,1411219066,788840127,1 +149791,1411219066,1540953332,1 +96375,1411219070,788840127,1 +149792,1411219070,1540953333,1 +141373,1411219073,1540930292,1 +133570,1424068459,1540895611,1 +20240,1424068577,278010626,1 +131626,1424068577,1540889969,1 +56947,1480413415,1037805077,1 +152187,1482899198,737311480,1 +125018,1493090224,1493090226,0 +125019,1493090226,428468592,0 +29652,1493227230,338485185,1 +138632,1493227268,1227726241,1 +94828,1493227274,1540857348,1 +56199,1493229599,1540824357,0 +127483,1493259659,1143999568,1 +2865,1493262720,360730614,1 +133748,1493262724,360475202,1 +50142,1520838821,360720713,0 +81319,1539669150,1540844666,1 +153447,1540770079,1540770080,0 +153448,1540770080,1540770081,0 +153449,1540770081,1540770082,0 +153450,1540770082,1540770083,0 +153451,1540770083,1540770084,0 +153452,1540770084,35839642,0 +153453,1540770085,35839643,0 +153454,1540770086,1540770087,0 +153455,1540770087,1540770088,0 +153456,1540770088,549775654,0 +153457,1540770089,295775157,0 +153458,1540770090,1540770091,0 +153459,1540770091,1540770092,0 +153460,1540770092,1540770093,0 +153461,1540770093,1540770094,0 +153462,1540770094,549775669,0 +153463,1540770095,800140483,0 +153464,1540770096,1540770097,0 +153465,1540770097,1540770098,0 +153466,1540770098,1540770099,0 +153467,1540770099,1540770100,0 +153468,1540770100,549775677,0 +153469,1540770101,1540770102,0 +153470,1540770102,1540770103,0 +153471,1540770103,1540770104,0 +153472,1540770104,1540770105,0 +153473,1540770105,359997700,0 +153474,1540770106,1540770107,0 +153475,1540770107,1540770108,0 +153476,1540770108,549785476,0 +153477,1540770109,1540770110,0 +153478,1540770110,35840828,0 +153479,1540770111,1540770112,0 +153480,1540770112,1540770113,0 +153481,1540770113,1540770114,0 +153482,1540770114,800140466,0 +153496,1540770128,1540770129,0 +153497,1540770129,1540770130,0 +153498,1540770130,1013465133,0 +153567,1540770199,1540770200,1 +153568,1540770200,1540770201,1 +153569,1540770201,1540770202,1 +153570,1540770202,1540770203,1 +153571,1540770203,1540770204,1 +153572,1540770204,1540770205,1 +153573,1540770205,1540770206,1 +153574,1540770206,549775695,1 +153622,1540770254,1540770255,0 +153623,1540770255,592381652,0 +154491,1540771123,361227781,0 +154492,1540771124,1540771125,0 +154493,1540771125,1540771126,0 +154494,1540771126,1540771127,0 +154495,1540771127,1540771128,0 +154496,1540771128,1540771129,0 +154497,1540771129,1540771130,0 +154498,1540771130,1540771131,0 +154499,1540771131,1540771132,0 +154500,1540771132,1540771133,0 +154501,1540771133,1540771134,0 +154502,1540771134,1540771135,0 +154503,1540771135,294112227,0 +154504,1540771136,1540771137,0 +154505,1540771137,1540771138,0 +154506,1540771138,1540771139,0 +154507,1540771139,1540771140,0 +154508,1540771140,1540771141,0 +154509,1540771141,1540771142,0 +154510,1540771142,1540771143,0 +154511,1540771143,1540771144,0 +154512,1540771144,1540771145,0 +154513,1540771145,1540771146,0 +154514,1540771146,1540771147,0 +154515,1540771147,295775659,0 +154516,1540771148,1540771149,0 +154517,1540771149,1540771150,0 +154518,1540771150,1540771151,0 +154519,1540771151,1540771152,0 +154520,1540771152,1540771153,0 +154521,1540771153,1540771154,0 +154522,1540771154,1540771155,0 +154523,1540771155,1540771156,0 +154524,1540771156,1540771157,0 +154525,1540771157,1540771158,0 +154526,1540771158,1540771159,0 +154527,1540771159,1540771160,0 +154528,1540771160,1540771161,0 +154529,1540771161,1540771162,0 +154530,1540771162,1540771163,0 +154531,1540771163,1540771164,0 +154532,1540771164,577419526,0 +154533,1540771165,1540771166,0 +154534,1540771166,1540771167,0 +154535,1540771167,1540771168,0 +154536,1540771168,1540771169,0 +154537,1540771169,577419538,0 +154772,1540771404,694758816,1 +154773,1540771405,360474181,1 +154774,1540771406,694758721,1 +154775,1540771407,360474653,1 +154776,1540771408,1540771409,1 +154777,1540771409,360474887,1 +154778,1540771410,360475456,1 +154779,1540771411,338484351,1 +154780,1540771412,360476002,1 +154781,1540771413,353246658,1 +154847,1540771479,1540771480,0 +154848,1540771480,1540771481,0 +154849,1540771481,973037227,0 +154850,1540771482,1540771483,0 +154851,1540771483,360226491,0 +154894,1540771526,360214094,0 +155007,1540771639,1540771640,0 +155008,1540771640,560582519,0 +155009,1540771641,560582522,0 +155010,1540771642,1540771643,0 +155011,1540771643,1540771644,0 +155012,1540771644,1540771645,0 +155013,1540771645,1540771646,0 +155014,1540771646,559940483,0 +155015,1540771647,359995915,1 +155142,1540771774,1540771775,0 +155143,1540771775,361444021,0 +155144,1540771776,1540771777,0 +155145,1540771777,1540771778,0 +155146,1540771778,579786585,0 +155147,1540771779,1540771780,0 +155148,1540771780,1540771781,0 +155149,1540771781,1540771782,0 +155150,1540771782,361444012,0 +155151,1540771783,361445222,0 +155152,1540771784,961664584,1 +155153,1540771785,360016390,1 +155154,1540771786,360016392,1 +155155,1540771787,360016395,1 +155156,1540771788,1540771789,0 +155157,1540771789,1540771790,0 +155158,1540771790,1540771791,0 +155159,1540771791,1540771792,0 +155160,1540771792,1540771793,0 +155161,1540771793,1540771794,0 +155162,1540771794,1540771795,0 +155163,1540771795,1540771796,0 +155164,1540771796,1540771797,0 +155165,1540771797,1540771798,0 +155166,1540771798,152947902,0 +155167,1540771799,584361250,0 +155423,1540772055,549556862,0 +155424,1540772056,1540772057,0 +155425,1540772057,1540772058,0 +155426,1540772058,1540772059,0 +155427,1540772059,1540772060,0 +155428,1540772060,1540772061,0 +155429,1540772061,1540772062,0 +155430,1540772062,1540772063,0 +155431,1540772063,1540772064,0 +155432,1540772064,1540772065,0 +155433,1540772065,1540772066,0 +155434,1540772066,1540772067,0 +155435,1540772067,1540772068,0 +155436,1540772068,153879588,0 +155437,1540772069,1540772070,0 +155438,1540772070,153879592,0 +155713,1540772345,1540772346,0 +155714,1540772346,1540772347,0 +155715,1540772347,1540772348,0 +155716,1540772348,273143707,0 +155717,1540772349,1540772350,0 +155718,1540772350,1540772351,0 +155719,1540772351,1540772352,0 +155720,1540772352,1540772353,0 +155721,1540772353,1540772354,0 +155722,1540772354,963987465,0 +155723,1540772355,360213853,0 +155724,1540772356,1540772357,0 +155725,1540772357,1540772358,0 +155726,1540772358,155587359,0 +155727,1540772359,600629186,0 +155728,1540772360,585199960,0 +155729,1540772361,1540772362,0 +155730,1540772362,1540772363,0 +155731,1540772363,1540772364,0 +155732,1540772364,1540772365,0 +155733,1540772365,1540772366,0 +155734,1540772366,155587524,0 +155735,1540772367,360200612,0 +156543,1540773175,360201218,0 +156544,1540773176,920605600,0 +156545,1540773177,920605603,0 +156546,1540773178,600400238,0 +156547,1540773179,1540773180,0 +156548,1540773180,155869226,0 +156549,1540773181,155866226,1 +156550,1540773182,1540773183,1 +156551,1540773183,1540773184,1 +156552,1540773184,1540773185,1 +156553,1540773185,1540773186,1 +156554,1540773186,1540773187,1 +156555,1540773187,1540773188,1 +156556,1540773188,1540773189,1 +156557,1540773189,155867053,1 +156558,1540773190,1540773191,1 +156559,1540773191,1540773192,1 +156560,1540773192,1540773193,1 +156561,1540773193,1540773194,1 +156562,1540773194,1387911917,1 +156563,1540773195,155868078,1 +156564,1540773196,1540773197,1 +156565,1540773197,1540773198,1 +156566,1540773198,1540773199,1 +156567,1540773199,1540773200,1 +156568,1540773200,1540773201,1 +156569,1540773201,1540773202,1 +156570,1540773202,1540773203,1 +156571,1540773203,1540773204,1 +156572,1540773204,1540773205,1 +156573,1540773205,1540773206,1 +156574,1540773206,1540773207,1 +156575,1540773207,913575786,1 +156584,1540773216,1540773217,0 +156585,1540773217,1540773218,0 +156586,1540773218,1540773219,0 +156587,1540773219,1540773220,0 +156588,1540773220,1540773221,0 +156631,1540773263,155869169,0 +156632,1540773264,1540773265,0 +156633,1540773265,1540773266,0 +156634,1540773266,155864979,0 +156635,1540773267,1540773268,0 +156636,1540773268,35494035,0 +156753,1540773385,1540773386,0 +156754,1540773386,1540773387,0 +156755,1540773387,1540773388,0 +156756,1540773388,360201192,0 +156757,1540773389,1540773390,0 +156758,1540773390,1540773391,0 +156759,1540773391,1540773392,0 +156760,1540773392,1540773393,0 +156761,1540773393,1540773394,0 +156762,1540773394,35487981,0 +156763,1540773395,365309671,0 +156764,1540773396,1540773397,0 +156765,1540773397,1540773398,0 +156766,1540773398,1540773399,0 +156767,1540773399,938502049,0 +156768,1540773400,1540773401,0 +156769,1540773401,365309669,0 +156770,1540773402,938502392,0 +156771,1540773403,938149142,0 +156772,1540773404,1540773405,0 +156773,1540773405,938149155,0 +156774,1540773406,1540773407,0 +156775,1540773407,361199410,0 +156776,1540773408,1540773409,0 +156777,1540773409,1540773410,0 +156778,1540773410,792071803,0 +156779,1540773411,361198788,0 +156780,1540773412,361440808,0 +156781,1540773413,175678152,0 +156782,1540773414,1540773415,0 +156783,1540773415,1540773416,0 +156784,1540773416,1540773417,0 +156785,1540773417,1540773418,0 +156786,1540773418,581286089,0 +156787,1540773419,361435532,0 +156788,1540773420,365119398,0 +156789,1540773421,1540773422,0 +156790,1540773422,365119318,0 +156791,1540773423,1540773424,0 +156792,1540773424,338484231,0 +156793,1540773425,360476120,1 +156794,1540773426,1540773427,1 +156795,1540773427,175678297,1 +156796,1540773428,361435530,1 +156797,1540773429,1540773430,0 +156798,1540773430,360473623,0 +156799,1540773431,1540773432,0 +156800,1540773432,360473825,0 +156801,1540773433,360472856,0 +156802,1540773434,360473933,0 +156803,1540773435,1540773436,0 +156804,1540773436,175678407,0 +156805,1540773437,1540773438,1 +156806,1540773438,1540773439,1 +156807,1540773439,360474589,1 +156808,1540773440,1540773441,1 +156809,1540773441,175678410,1 +156810,1540773442,705073963,1 +156811,1540773443,705073998,1 +156812,1540773444,704832137,1 +156813,1540773445,1540773446,1 +156814,1540773446,1540773447,1 +156815,1540773447,581288199,1 +156816,1540773448,581288189,1 +156817,1540773449,1540773450,1 +156818,1540773450,1540773451,1 +156819,1540773451,1540773452,1 +156820,1540773452,579805587,1 +156821,1540773453,338484242,1 +156822,1540773454,353244588,1 +156823,1540773455,360473103,1 +156824,1540773456,1540773457,1 +156825,1540773457,338484169,1 +156826,1540773458,360468057,1 +156827,1540773459,360467922,1 +156828,1540773460,175678477,1 +156829,1540773461,706854261,0 +156830,1540773462,1285491855,0 +156831,1540773463,1285491930,1 +156832,1540773464,1540773465,0 +156833,1540773465,1540773466,0 +156834,1540773466,1540773467,0 +156835,1540773467,1540773468,0 +156836,1540773468,560712653,0 +156837,1540773469,560712677,0 +156838,1540773470,527804372,0 +156842,1540773474,597692611,0 +156843,1540773475,1540773476,0 +156844,1540773476,1540773477,0 +156845,1540773477,1307601795,0 +156846,1540773478,1540773479,0 +156847,1540773479,365117670,0 +156848,1540773480,365117964,0 +156849,1540773481,365118244,0 +156850,1540773482,1540773483,0 +156851,1540773483,338484240,0 +156852,1540773484,1540773485,1 +156853,1540773485,1540773486,1 +156854,1540773486,352701561,1 +156855,1540773487,1540773488,1 +156856,1540773488,352701565,1 +156857,1540773489,176173994,1 +156858,1540773490,352701572,1 +156859,1540773491,347780926,1 +156860,1540773492,1540773493,1 +156861,1540773493,1540773494,1 +156862,1540773494,176173984,1 +156863,1540773495,560712643,1 +157530,1540774162,360476715,1 +157531,1540774163,1540774164,0 +157532,1540774164,1540774165,0 +157533,1540774165,656189031,0 +157534,1540774166,1540774167,0 +157535,1540774167,1540774168,0 +157536,1540774168,1540774169,0 +157537,1540774169,360476887,0 +157538,1540774170,1540774171,0 +157539,1540774171,1540774172,0 +157540,1540774172,247152817,0 +157541,1540774173,1540774174,0 +157542,1540774174,1540774175,0 +157543,1540774175,247152813,0 +158954,1540775586,1540775587,0 +158955,1540775587,153874050,0 +158987,1540775619,1540775620,0 +158988,1540775620,153874640,0 +158989,1540775621,152937997,0 +158993,1540775625,939551644,1 +159321,1540775953,592567324,0 +159322,1540775954,36243628,0 +170508,1540787140,1540787141,1 +170509,1540787141,1540787142,1 +170510,1540787142,1540787143,1 +170511,1540787143,272554977,1 +170524,1540787156,347774612,1 +170560,1540787192,272554478,0 +170567,1540787199,272554602,1 +170568,1540787200,1540787201,1 +170569,1540787201,1540787202,1 +170570,1540787202,272498944,1 +170571,1540787203,1540787204,1 +170572,1540787204,1540787205,1 +170573,1540787205,272499416,1 +170574,1540787206,272499261,1 +170575,1540787207,272499222,1 +170576,1540787208,272554677,1 +170577,1540787209,1540787210,1 +170578,1540787210,272499414,1 +170579,1540787211,1540787212,1 +170580,1540787212,1540787213,1 +170581,1540787213,1540787214,1 +170582,1540787214,1540787215,1 +170583,1540787215,1540787216,1 +170584,1540787216,1540787217,1 +170585,1540787217,272499019,1 +170586,1540787218,1540787219,1 +170587,1540787219,1540787220,1 +170588,1540787220,272554778,1 +170589,1540787221,1540787222,1 +170590,1540787222,272561524,1 +170591,1540787223,1540787224,1 +170592,1540787224,1540787225,1 +170593,1540787225,272554942,1 +170594,1540787226,1540787227,1 +170595,1540787227,272554946,1 +170596,1540787228,1540787229,1 +170597,1540787229,272554713,1 +170599,1540787231,272554977,1 +170600,1540787232,706836672,1 +170601,1540787233,1540787234,1 +170602,1540787234,272560240,1 +170603,1540787235,1540787236,1 +170604,1540787236,1540787237,1 +170605,1540787237,272560242,1 +170606,1540787238,1540787239,1 +170607,1540787239,272560244,1 +170608,1540787240,1540787241,1 +170609,1540787241,1540787242,1 +170610,1540787242,706836643,1 +170611,1540787243,1540787244,1 +170612,1540787244,1540787245,1 +170613,1540787245,272560305,1 +170614,1540787246,272560961,1 +170615,1540787247,1540787248,1 +170616,1540787248,1540787249,1 +170617,1540787249,272560350,1 +170618,1540787250,1540787251,1 +170619,1540787251,272560351,1 +170620,1540787252,1540787253,1 +170621,1540787253,272560464,1 +170622,1540787254,1540787255,1 +170623,1540787255,272560541,1 +170624,1540787256,1540787257,1 +170625,1540787257,1540787258,1 +170626,1540787258,272560545,1 +170627,1540787259,1540787260,1 +170628,1540787260,272560606,1 +170653,1540787285,1540787286,1 +170654,1540787286,1540787287,1 +170668,1540787300,1540787301,1 +170669,1540787301,1540787302,1 +170670,1540787302,272499074,1 +170722,1540787354,272561327,1 +170734,1540787366,1540787367,1 +170735,1540787367,1540787368,1 +170736,1540787368,272561547,1 +170751,1540787383,1540787384,1 +170752,1540787384,351950262,1 +170848,1540787480,584361305,0 +170849,1540787481,1540787482,0 +170850,1540787482,1540787483,0 +170851,1540787483,1540787484,0 +170852,1540787484,1540787485,0 +170853,1540787485,1540787486,0 +170854,1540787486,1540787487,0 +170855,1540787487,1540787488,0 +170856,1540787488,1540787489,0 +170857,1540787489,1540787490,0 +170858,1540787490,1540787491,0 +170859,1540787491,1540787492,0 +170860,1540787492,1540787493,0 +170861,1540787493,1540787494,0 +170862,1540787494,1540787495,0 +170878,1540787510,1540787511,0 +170879,1540787511,1540787512,0 +170880,1540787512,1540787513,0 +170881,1540787513,445393419,0 +170904,1540787536,1540787537,0 +170905,1540787537,1540787538,0 +170906,1540787538,1540787539,0 +170907,1540787539,1540787540,0 +170908,1540787540,1540787541,0 +170909,1540787541,1540787542,0 +170910,1540787542,1540787543,0 +170911,1540787543,1540787544,0 +170912,1540787544,1540787545,0 +170913,1540787545,1540787546,0 +170914,1540787546,301343729,0 +170915,1540787547,793252682,0 +170916,1540787548,801063202,0 +170917,1540787549,1540787550,0 +170918,1540787550,272567908,0 +171062,1540787694,1540787695,1 +171063,1540787695,1540787696,1 +171064,1540787696,1540787697,1 +171065,1540787697,1540787698,1 +171066,1540787698,1540787699,1 +171067,1540787699,1540787700,1 +171068,1540787700,1019990282,1 +171069,1540787701,1540787702,1 +171070,1540787702,1540787703,1 +171071,1540787703,973037242,1 +171129,1540787761,302363454,1 +171130,1540787762,1540787763,1 +171131,1540787763,1540787764,1 +171132,1540787764,1540787765,1 +171133,1540787765,1540787766,1 +171134,1540787766,1540787767,1 +171135,1540787767,302045960,1 +171136,1540787768,1540787769,1 +171137,1540787769,1540787770,1 +171138,1540787770,302661528,1 +171139,1540787771,1540787772,1 +171140,1540787772,1540787773,1 +171141,1540787773,1540787774,1 +171142,1540787774,1540787775,1 +171143,1540787775,1540787776,1 +171144,1540787776,302044723,1 +171145,1540787777,1239786783,1 +171146,1540787778,360713245,1 +171147,1540787779,360714124,1 +171148,1540787780,38840244,1 +171149,1540787781,1540787782,1 +171150,1540787782,360714725,1 +171151,1540787783,360717180,1 +171152,1540787784,360718527,1 +171153,1540787785,1540787786,1 +171154,1540787786,1540787787,1 +171155,1540787787,360718737,1 +171156,1540787788,361435845,1 +171157,1540787789,1540787790,1 +171158,1540787790,286537277,1 +173552,1540790184,1540790185,1 +173553,1540790185,1540790186,1 +173554,1540790186,1540790187,1 +173555,1540790187,1540790188,1 +173556,1540790188,1540790189,1 +173557,1540790189,1540790190,1 +173558,1540790190,1540790191,1 +173559,1540790191,1540790192,1 +173560,1540790192,1540790193,1 +173561,1540790193,1540790194,1 +173562,1540790194,1540790195,1 +173563,1540790195,1540790196,1 +173564,1540790196,1540790197,1 +173565,1540790197,1540790198,1 +173566,1540790198,1540790199,1 +173567,1540790199,1540790200,1 +173568,1540790200,1540790201,1 +173569,1540790201,1540790202,1 +173570,1540790202,1540790203,1 +173571,1540790203,1540790204,1 +173572,1540790204,1540790205,1 +173573,1540790205,1540790206,1 +173574,1540790206,278008681,1 +173575,1540790207,1540790208,1 +173576,1540790208,1540790209,1 +173577,1540790209,1540790210,1 +173578,1540790210,1540790211,1 +173579,1540790211,1540790212,1 +173580,1540790212,1540790213,1 +173581,1540790213,1540790214,1 +173582,1540790214,1540790215,1 +173583,1540790215,278008693,1 +173584,1540790216,1540790217,1 +173585,1540790217,1540790218,1 +173586,1540790218,1540790219,1 +173587,1540790219,1540790220,1 +173588,1540790220,1540790221,1 +173589,1540790221,1540790222,1 +173590,1540790222,1540790223,1 +173591,1540790223,278010346,1 +173592,1540790224,1540790225,1 +173593,1540790225,1540790226,1 +173594,1540790226,1540790227,1 +173595,1540790227,278010102,1 +173596,1540790228,1540790229,1 +173597,1540790229,1540790230,1 +173598,1540790230,1540790231,1 +173599,1540790231,1540790232,1 +173600,1540790232,1540790233,1 +173601,1540790233,1540790234,1 +173602,1540790234,278010401,1 +173603,1540790235,1540790236,1 +173604,1540790236,1540790237,1 +173605,1540790237,1540790238,1 +173606,1540790238,1540790239,1 +173607,1540790239,1540790240,1 +173608,1540790240,1540790241,1 +173609,1540790241,1540790242,1 +173610,1540790242,1540790243,1 +173611,1540790243,1540790244,1 +173612,1540790244,1540790245,1 +173613,1540790245,278010455,1 +173614,1540790246,278010532,1 +173615,1540790247,1540790248,1 +173616,1540790248,278010459,1 +173617,1540790249,1540790250,1 +173618,1540790250,278009544,1 +173619,1540790251,1540790252,1 +173620,1540790252,278010402,1 +173621,1540790253,278010532,1 +173622,1540790254,1540790255,1 +173623,1540790255,278010353,1 +173624,1540790256,1540790257,1 +173625,1540790257,1540790258,1 +173626,1540790258,278010538,1 +173627,1540790259,1540790260,1 +173628,1540790260,278010542,1 +173629,1540790261,1540790262,1 +173630,1540790262,1540790263,1 +173631,1540790263,278010577,1 +173632,1540790264,278010352,1 +173633,1540790265,1540790266,1 +173634,1540790266,278010590,1 +173635,1540790267,1540790268,1 +173636,1540790268,1540790269,1 +173637,1540790269,278010596,1 +173638,1540790270,1540790271,1 +173639,1540790271,278010620,1 +173640,1540790272,1540790273,1 +173641,1540790273,278010623,1 +173642,1540790274,1540790275,1 +173643,1540790275,278010626,1 +173644,1540790276,1540790277,1 +173645,1540790277,278010629,1 +173646,1540790278,1540790279,1 +173647,1540790279,1540790280,1 +173648,1540790280,278010567,1 +173649,1540790281,1540790282,1 +173650,1540790282,278010652,1 +173651,1540790283,1540790284,1 +173652,1540790284,1540790285,1 +173653,1540790285,278010656,1 +173654,1540790286,1540790287,1 +173655,1540790287,1540790288,1 +173656,1540790288,1540790289,1 +173657,1540790289,278010687,1 +173658,1540790290,1540790291,1 +173659,1540790291,1540790292,1 +173660,1540790292,1540790293,1 +173661,1540790293,278010692,1 +173662,1540790294,278010687,1 +173663,1540790295,1540790296,1 +173664,1540790296,1540790297,1 +173665,1540790297,1540790298,1 +173666,1540790298,1540790299,1 +173667,1540790299,278010746,1 +173668,1540790300,1540790301,1 +173669,1540790301,1540790302,1 +173670,1540790302,1540790303,1 +173671,1540790303,1540790304,1 +173672,1540790304,1540790305,1 +173673,1540790305,1540790306,1 +173674,1540790306,278010766,1 +173675,1540790307,1540790308,1 +173676,1540790308,1540790309,1 +173677,1540790309,278010565,1 +173678,1540790310,1540790311,1 +173679,1540790311,1540790312,1 +173680,1540790312,1371124894,1 +173681,1540790313,1540790314,1 +173682,1540790314,1540790315,1 +173683,1540790315,1540790316,1 +173684,1540790316,1371124898,1 +173685,1540790317,810713382,1 +173686,1540790318,1540790319,1 +173687,1540790319,1540790320,1 +173688,1540790320,1540790321,1 +173689,1540790321,1540790322,1 +173690,1540790322,1540790323,1 +173691,1540790323,1540790324,1 +173692,1540790324,1540790325,1 +173693,1540790325,1540790326,1 +173694,1540790326,1540790327,1 +173695,1540790327,1540790328,1 +173696,1540790328,1540790329,1 +173697,1540790329,1540790330,1 +173698,1540790330,1540790331,1 +173699,1540790331,1540790332,1 +173700,1540790332,1540790333,1 +173701,1540790333,1540790334,1 +173702,1540790334,1540790335,1 +173703,1540790335,1540790336,1 +173704,1540790336,1540790337,1 +173705,1540790337,278011134,1 +173706,1540790338,278011279,1 +173707,1540790339,1540790340,1 +173708,1540790340,1540790341,1 +173709,1540790341,1540790342,1 +173710,1540790342,1540790343,1 +173711,1540790343,278011285,1 +173712,1540790344,1540790345,1 +173713,1540790345,1540790346,1 +173714,1540790346,1540790347,1 +173715,1540790347,1540790348,1 +173716,1540790348,1540790349,1 +173717,1540790349,1540790350,1 +173718,1540790350,1540790351,1 +173719,1540790351,1540790352,1 +173720,1540790352,1540790353,1 +173721,1540790353,1540790354,1 +173722,1540790354,1540790355,1 +173723,1540790355,1540790356,1 +173724,1540790356,1540790357,1 +173725,1540790357,1540790358,1 +173726,1540790358,1540790359,1 +173727,1540790359,1540790360,1 +173728,1540790360,1540790361,1 +173729,1540790361,278011304,1 +173730,1540790362,278011306,1 +173731,1540790363,1540790364,1 +173732,1540790364,278011309,1 +173733,1540790365,1540790366,1 +173734,1540790366,1540790367,1 +173735,1540790367,1540790368,1 +173736,1540790368,1540790369,1 +173737,1540790369,1540790370,1 +173738,1540790370,1540790371,1 +173739,1540790371,1540790372,1 +173740,1540790372,1540790373,1 +173741,1540790373,1540790374,1 +173742,1540790374,1540790375,1 +173743,1540790375,1540790376,1 +173744,1540790376,1540790377,1 +173745,1540790377,1540790378,1 +173746,1540790378,1540790379,1 +173747,1540790379,1540790380,1 +173748,1540790380,1540790381,1 +173749,1540790381,278011378,1 +173750,1540790382,1540790383,1 +173751,1540790383,278011422,1 +173752,1540790384,1540790385,1 +173753,1540790385,278010566,1 +173754,1540790386,1540790387,1 +173755,1540790387,1540790388,1 +173756,1540790388,278011536,1 +173757,1540790389,1540790390,1 +173758,1540790390,1540790391,1 +173759,1540790391,278011504,1 +173760,1540790392,1172528348,1 +173761,1540790393,1540790394,1 +173762,1540790394,1540790395,1 +173763,1540790395,278011628,1 +173764,1540790396,1540790397,1 +173765,1540790397,1540790398,1 +173766,1540790398,1540790399,1 +173767,1540790399,278011722,1 +173768,1540790400,278011724,1 +173769,1540790401,1540790402,1 +173770,1540790402,1540790403,1 +173771,1540790403,278011736,1 +173772,1540790404,1540790405,1 +173773,1540790405,1540790406,1 +173774,1540790406,278011740,1 +173775,1540790407,1540790408,1 +173776,1540790408,1540790409,1 +173777,1540790409,278011835,1 +173778,1540790410,1540790411,1 +173779,1540790411,1540790412,1 +173780,1540790412,1540790413,1 +173781,1540790413,1540790414,1 +173782,1540790414,278011742,1 +173783,1540790415,1540790416,1 +173784,1540790416,1540790417,1 +173785,1540790417,1540790418,1 +173786,1540790418,1540790419,1 +173787,1540790419,1540790420,1 +173788,1540790420,278011847,1 +173789,1540790421,1540790422,1 +173790,1540790422,1540790423,1 +173791,1540790423,1540790424,1 +173792,1540790424,1540790425,1 +173793,1540790425,1540790426,1 +173794,1540790426,1540790427,1 +173795,1540790427,1540790428,1 +173796,1540790428,1540790429,1 +173797,1540790429,1540790430,1 +173798,1540790430,1540790431,1 +173799,1540790431,1540790432,1 +173800,1540790432,1540790433,1 +173801,1540790433,1540790434,1 +173802,1540790434,1174605184,1 +173803,1540790435,1540790436,1 +173804,1540790436,1540790437,1 +173805,1540790437,278011865,1 +173806,1540790438,1540790439,1 +173807,1540790439,278011906,1 +173808,1540790440,278010545,1 +173809,1540790441,278012063,1 +173810,1540790442,601643782,1 +173811,1540790443,278012067,1 +173812,1540790444,1540790445,1 +173813,1540790445,1540790446,1 +173814,1540790446,1540790447,1 +173815,1540790447,1540790448,1 +173816,1540790448,1540790449,1 +173817,1540790449,1540790450,1 +173818,1540790450,278011997,1 +173819,1540790451,278012081,1 +173820,1540790452,1540790453,1 +173821,1540790453,278011908,1 +173822,1540790454,278011471,1 +173823,1540790455,1540790456,1 +173824,1540790456,278012067,1 +173825,1540790457,1540790458,1 +173826,1540790458,278012120,1 +173827,1540790459,1371124956,1 +173828,1540790460,1540790461,1 +173829,1540790461,1540790462,1 +173830,1540790462,278012171,1 +173831,1540790463,1540790464,1 +173832,1540790464,1540790465,1 +173833,1540790465,1540790466,1 +173834,1540790466,1540790467,1 +173835,1540790467,1540790468,1 +173836,1540790468,278012179,1 +173837,1540790469,1540790470,1 +173838,1540790470,1540790471,1 +173839,1540790471,1540790472,1 +173840,1540790472,278012479,1 +173893,1540790525,1540790526,1 +173894,1540790526,278013033,1 +174334,1540790966,1030313274,0 +174335,1540790967,1540790968,0 +174336,1540790968,1540790969,0 +174337,1540790969,1540790970,0 +174338,1540790970,716889345,0 +174339,1540790971,279591485,0 +174340,1540790972,279591486,0 +174341,1540790973,1540790974,0 +174342,1540790974,279589687,0 +174343,1540790975,279589617,0 +174344,1540790976,279590088,1 +174345,1540790977,985968900,1 +174346,1540790978,279590362,1 +174347,1540790979,974030468,0 +174348,1540790980,1540790981,0 +174349,1540790981,279591120,0 +174350,1540790982,1540790983,0 +174351,1540790983,1540790984,0 +174352,1540790984,363973774,0 +174353,1540790985,974030571,1 +174354,1540790986,363970709,1 +174355,1540790987,1540790988,1 +174356,1540790988,1540790989,1 +174357,1540790989,279591058,1 +174358,1540790990,1540790991,1 +174359,1540790991,279591449,1 +174360,1540790992,1387915860,1 +174361,1540790993,279591656,1 +174362,1540790994,279591658,1 +174363,1540790995,279591660,1 +174364,1540790996,1540790997,1 +174365,1540790997,279591764,1 +174366,1540790998,279591766,1 +174367,1540790999,360191585,1 +174368,1540791000,279591769,1 +174369,1540791001,1540791002,1 +174370,1540791002,1540791003,1 +174371,1540791003,279591881,1 +174372,1540791004,1540791005,1 +174373,1540791005,279591848,1 +174374,1540791006,1540791007,1 +174375,1540791007,1540791008,1 +174376,1540791008,279592059,1 +174377,1540791009,1540791010,1 +174378,1540791010,1540791011,1 +174379,1540791011,1540791012,1 +174380,1540791012,279591973,1 +174381,1540791013,1540791014,1 +174382,1540791014,1540791015,1 +174383,1540791015,1540791016,1 +174384,1540791016,279591857,1 +174385,1540791017,1540791018,1 +174386,1540791018,1540791019,1 +174387,1540791019,1540791020,1 +174388,1540791020,1540791021,1 +174389,1540791021,1540791022,1 +174390,1540791022,279592064,1 +174391,1540791023,1540791024,1 +174392,1540791024,1540791025,1 +174393,1540791025,1540791026,1 +174394,1540791026,279591863,1 +174395,1540791027,1540791028,1 +174396,1540791028,1540791029,1 +174397,1540791029,1540791030,1 +174398,1540791030,1540791031,1 +174399,1540791031,1540791032,1 +174400,1540791032,1540791033,1 +174401,1540791033,279591843,1 +174402,1540791034,1540791035,1 +174403,1540791035,1540791036,1 +174404,1540791036,1540791037,1 +174405,1540791037,279591921,1 +174406,1540791038,1540791039,1 +174407,1540791039,1540791040,1 +174408,1540791040,1540791041,1 +174409,1540791041,279591926,1 +174410,1540791042,360200258,1 +174411,1540791043,360200318,1 +174412,1540791044,279591918,1 +174413,1540791045,360223134,1 +174414,1540791046,360210533,0 +174415,1540791047,1540791048,0 +174416,1540791048,279592206,0 +174417,1540791049,1540791050,0 +174418,1540791050,1540791051,0 +174419,1540791051,279592283,0 +174420,1540791052,1540791053,0 +174421,1540791053,279592285,0 +174422,1540791054,279592213,0 +174423,1540791055,279592280,0 +174424,1540791056,279592091,0 +174425,1540791057,1540791058,0 +174426,1540791058,360195141,0 +174427,1540791059,360222287,0 +174428,1540791060,360195142,0 +174429,1540791061,360224583,0 +175835,1540792467,1540792468,1 +175836,1540792468,1540792469,1 +175837,1540792469,1540792470,1 +175838,1540792470,1540792471,1 +175839,1540792471,1540792472,1 +175840,1540792472,286077933,1 +176159,1540792791,1305716361,1 +176160,1540792792,286367801,1 +176161,1540792793,286369864,1 +176162,1540792794,1540792795,1 +176163,1540792795,1540792796,1 +176164,1540792796,359997070,1 +176165,1540792797,1540792798,1 +176166,1540792798,1540792799,1 +176167,1540792799,1540792800,1 +176168,1540792800,1540792801,1 +176169,1540792801,1540792802,1 +176170,1540792802,1540792803,1 +176171,1540792803,359997063,1 +176172,1540792804,1540792805,0 +176173,1540792805,549785476,0 +176174,1540792806,745985519,1 +176175,1540792807,286535486,0 +176176,1540792808,1540792809,0 +176177,1540792809,286537366,0 +176178,1540792810,360718714,0 +176179,1540792811,286537277,0 +176180,1540792812,286541742,0 +176181,1540792813,286541743,0 +176182,1540792814,1540792815,0 +176183,1540792815,1540792816,0 +176184,1540792816,1540792817,0 +176185,1540792817,571449843,0 +176186,1540792818,286541787,0 +176187,1540792819,1540792820,0 +176188,1540792820,1540792821,0 +176189,1540792821,1540792822,0 +176190,1540792822,1540792823,0 +176191,1540792823,1540792824,0 +176192,1540792824,360720505,0 +176798,1540793430,1540793431,1 +176799,1540793431,1540793432,1 +176800,1540793432,294114237,1 +177118,1540793750,1540793751,0 +177119,1540793751,295771556,0 +177120,1540793752,1540793753,0 +177121,1540793753,1540793754,0 +177122,1540793754,1540793755,0 +177123,1540793755,1540793756,0 +177124,1540793756,1540793757,0 +177125,1540793757,936804192,0 +177126,1540793758,1540793759,0 +177127,1540793759,1540793760,0 +177128,1540793760,1540793761,0 +177129,1540793761,1540793762,0 +177130,1540793762,1540793763,0 +177131,1540793763,1540793764,0 +177132,1540793764,1540793765,0 +177133,1540793765,549778901,0 +177134,1540793766,1540793767,1 +177135,1540793767,294114238,1 +177136,1540793768,1540793769,1 +177137,1540793769,294114600,1 +177138,1540793770,1540793771,0 +177139,1540793771,1540793772,0 +177140,1540793772,1343007170,0 +177141,1540793773,1540793774,0 +177142,1540793774,1540793775,0 +177143,1540793775,1540793776,0 +177144,1540793776,1540793777,0 +177145,1540793777,294184231,0 +177146,1540793778,1540793779,0 +177147,1540793779,1540793780,0 +177148,1540793780,1540793781,0 +177149,1540793781,1540793782,0 +177150,1540793782,1540793783,0 +177151,1540793783,1540793784,0 +177152,1540793784,1540793785,0 +177153,1540793785,1144431654,0 +177154,1540793786,1540793787,0 +177155,1540793787,294163854,0 +177156,1540793788,1540793789,0 +177157,1540793789,600205146,0 +177158,1540793790,1540793791,0 +177159,1540793791,1540793792,0 +177160,1540793792,1144431684,0 +177161,1540793793,1540793794,0 +177162,1540793794,1540793795,0 +177163,1540793795,1540793796,0 +177164,1540793796,1540793797,0 +177165,1540793797,294184327,0 +177166,1540793798,803745185,0 +177167,1540793799,653316931,0 +177168,1540793800,938502297,0 +177169,1540793801,1540793802,0 +177170,1540793802,938502108,0 +177171,1540793803,294163284,0 +177172,1540793804,803745017,0 +177173,1540793805,294163209,0 +177174,1540793806,1540793807,0 +177175,1540793807,938502187,0 +177176,1540793808,1540793809,0 +177177,1540793809,1540793810,0 +177178,1540793810,1540793811,0 +177179,1540793811,1540793812,0 +177180,1540793812,1540793813,0 +177181,1540793813,1540793814,0 +177182,1540793814,1540793815,0 +177183,1540793815,737309706,0 +177184,1540793816,1540793817,0 +177185,1540793817,1540793818,0 +177186,1540793818,1540793819,0 +177187,1540793819,1540793820,0 +177188,1540793820,1540793821,0 +177189,1540793821,984332645,0 +177190,1540793822,1540793823,0 +177191,1540793823,1540793824,0 +177192,1540793824,1540793825,0 +177193,1540793825,1540793826,0 +177194,1540793826,984332451,0 +177195,1540793827,294144924,0 +177196,1540793828,1540793829,0 +177197,1540793829,1540793830,0 +177198,1540793830,1540793831,0 +177199,1540793831,294145134,0 +177200,1540793832,984606649,0 +177201,1540793833,1540793834,0 +177202,1540793834,1540793835,0 +177203,1540793835,294144611,0 +177204,1540793836,984415654,0 +177205,1540793837,984415682,0 +177206,1540793838,1540793839,0 +177207,1540793839,984364552,0 +177208,1540793840,1540793841,0 +177209,1540793841,984364168,0 +177210,1540793842,1540793843,0 +177211,1540793843,984364113,0 +177212,1540793844,1540793845,0 +177213,1540793845,1540793846,0 +177214,1540793846,294114238,0 +177215,1540793847,1540793848,0 +177216,1540793848,1540793849,0 +177217,1540793849,984364890,0 +177218,1540793850,1540793851,0 +177219,1540793851,1540793852,0 +177220,1540793852,984364428,0 +177221,1540793853,1540793854,0 +177222,1540793854,737307275,0 +177223,1540793855,984415674,0 +177224,1540793856,294144491,0 +177225,1540793857,1540793858,0 +177226,1540793858,294144482,0 +177227,1540793859,1540793860,0 +177228,1540793860,1540793861,0 +177229,1540793861,1540793862,0 +177230,1540793862,984606704,0 +177231,1540793863,984634174,0 +177232,1540793864,1540793865,1 +177233,1540793865,1540793866,1 +177234,1540793866,1540793867,1 +177235,1540793867,1540793868,1 +177236,1540793868,1540793869,1 +177237,1540793869,1540793870,1 +177238,1540793870,1540793871,1 +177239,1540793871,981693526,1 +177240,1540793872,938502165,0 +177241,1540793873,1343047805,1 +177242,1540793874,1343049691,1 +177243,1540793875,600927600,1 +177244,1540793876,938142896,1 +177245,1540793877,294203215,1 +177246,1540793878,294203214,1 +177247,1540793879,1540793880,1 +177248,1540793880,1540793881,1 +177249,1540793881,361199380,1 +177250,1540793882,1540793883,1 +177251,1540793883,294203208,1 +177252,1540793884,937365462,1 +177253,1540793885,793428405,1 +177254,1540793886,1540793887,1 +177255,1540793887,294244884,1 +177256,1540793888,1540793889,1 +177257,1540793889,745090943,1 +177258,1540793890,294203310,1 +177259,1540793891,1540793892,0 +177260,1540793892,1540793893,0 +177261,1540793893,1540793894,0 +177262,1540793894,1540793895,0 +177263,1540793895,1540793896,0 +177264,1540793896,1540793897,0 +177265,1540793897,294207775,0 +177266,1540793898,1540793899,0 +177267,1540793899,599162325,0 +177268,1540793900,1540793901,0 +177269,1540793901,1540793902,0 +177270,1540793902,1540793903,0 +177271,1540793903,1540793904,0 +177272,1540793904,1540793905,0 +177273,1540793905,1540793906,0 +177274,1540793906,294207130,0 +177275,1540793907,1540793908,0 +177276,1540793908,1540793909,0 +177277,1540793909,1540793910,0 +177278,1540793910,1540793911,0 +177279,1540793911,36245092,0 +177280,1540793912,361196558,0 +177281,1540793913,1540793914,0 +177282,1540793914,1540793915,0 +177283,1540793915,294244984,0 +177284,1540793916,1540793917,0 +177285,1540793917,1540793918,0 +177286,1540793918,1540793919,0 +177287,1540793919,745990625,0 +177288,1540793920,1540793921,0 +177289,1540793921,598495549,0 +177290,1540793922,294244999,0 +177291,1540793923,793385707,0 +177292,1540793924,1540793925,1 +177293,1540793925,1540793926,1 +177294,1540793926,294250799,1 +177295,1540793927,360720581,1 +177296,1540793928,745988385,1 +177297,1540793929,1540793930,1 +177298,1540793930,745988380,1 +177299,1540793931,360718927,0 +177398,1540794030,1540794031,0 +177399,1540794031,801479955,0 +177400,1540794032,1540794033,0 +177401,1540794033,1540794034,0 +177402,1540794034,801480054,0 +177601,1540794233,294112451,0 +177602,1540794234,1540794235,0 +177603,1540794235,1540794236,0 +177604,1540794236,1540794237,0 +177605,1540794237,279591129,0 +177606,1540794238,1540794239,0 +177607,1540794239,1540794240,0 +177608,1540794240,1540794241,0 +177609,1540794241,279591134,0 +177610,1540794242,1540794243,0 +177611,1540794243,279591139,0 +177612,1540794244,583433055,0 +177613,1540794245,1540794246,0 +177614,1540794246,1540794247,0 +177615,1540794247,1540794248,0 +177616,1540794248,1540794249,0 +177617,1540794249,1540794250,0 +177618,1540794250,1540794251,0 +177619,1540794251,1540794252,0 +177620,1540794252,1540794253,0 +177621,1540794253,1540794254,0 +177622,1540794254,1540794255,0 +177623,1540794255,932361967,0 +177624,1540794256,1540794257,0 +177625,1540794257,279591159,0 +177626,1540794258,1540794259,0 +177627,1540794259,1540794260,0 +177628,1540794260,1540794261,0 +177629,1540794261,286367976,0 +177630,1540794262,1540794263,0 +177631,1540794263,1540794264,0 +177632,1540794264,985945881,0 +177633,1540794265,1540794266,0 +177634,1540794266,1540794267,0 +177635,1540794267,1540794268,0 +177636,1540794268,1540794269,0 +177637,1540794269,1540794270,0 +177638,1540794270,1540794271,0 +177639,1540794271,1540794272,0 +177640,1540794272,1540794273,0 +177641,1540794273,1540794274,0 +177642,1540794274,1540794275,0 +177643,1540794275,1540794276,0 +177644,1540794276,35840949,0 +177780,1540794412,1540794413,1 +177781,1540794413,359997466,1 +177782,1540794414,359997705,1 +177783,1540794415,1540794416,1 +177784,1540794416,1540794417,1 +177785,1540794417,359997467,1 +177786,1540794418,359997196,1 +178898,1540795530,982077226,1 +179109,1540795741,302552971,0 +179110,1540795742,360714198,0 +179111,1540795743,360712926,0 +179112,1540795744,1540795745,0 +179113,1540795745,302660640,0 +179114,1540795746,1540795747,0 +179115,1540795747,302660584,0 +179116,1540795748,360712973,0 +179117,1540795749,302555273,0 +179130,1540795762,360713719,0 +179152,1540795784,360713021,1 +179153,1540795785,302656922,1 +179552,1540796184,1540796185,1 +179553,1540796185,302552971,1 +179554,1540796186,303698831,1 +182346,1540798978,1540798979,1 +182347,1540798979,1540798980,1 +182348,1540798980,1540798981,1 +182349,1540798981,797347639,1 +182350,1540798982,1540798983,1 +182351,1540798983,1540798984,1 +182352,1540798984,1540798985,1 +182353,1540798985,1540798986,1 +182354,1540798986,1540798987,1 +182355,1540798987,797347631,1 +182356,1540798988,338485324,0 +182357,1540798989,360475636,0 +182358,1540798990,360475451,0 +182359,1540798991,1540798992,1 +182360,1540798992,246588551,1 +182361,1540798993,338485123,1 +182362,1540798994,1540798995,1 +182363,1540798995,338485125,1 +182364,1540798996,360475953,0 +182365,1540798997,338484638,0 +182366,1540798998,338485328,1 +182367,1540798999,353246387,1 +182368,1540799000,338485327,0 +182369,1540799001,338485327,1 +182370,1540799002,599162412,1 +182371,1540799003,1540799004,1 +182372,1540799004,984332219,1 +182373,1540799005,1540799006,1 +182374,1540799006,1540799007,1 +182375,1540799007,1540799008,1 +182376,1540799008,984332297,1 +182377,1540799009,1540799010,1 +182378,1540799010,984332545,1 +182379,1540799011,1540799012,1 +182380,1540799012,363970923,1 +182381,1540799013,1540799014,1 +182382,1540799014,974031112,1 +182383,1540799015,1540799016,1 +182384,1540799016,1540799017,1 +182385,1540799017,1540799018,1 +182386,1540799018,974030923,1 +182387,1540799019,1540799020,1 +182388,1540799020,1540799021,1 +182389,1540799021,1540799022,1 +182390,1540799022,338487728,1 +182391,1540799023,338487814,1 +182392,1540799024,338487817,1 +182393,1540799025,1540799026,1 +182394,1540799026,360219894,1 +182395,1540799027,360232912,1 +183653,1540800285,1285491813,1 +183654,1540800286,1540800287,0 +183655,1540800287,1540800288,0 +183656,1540800288,360467245,0 +183657,1540800289,360467606,0 +183658,1540800290,360467240,0 +183661,1540800293,347502370,0 +183662,1540800294,1540800295,1 +183663,1540800295,360467366,1 +183664,1540800296,347502144,1 +183665,1540800297,1141159336,1 +183666,1540800298,360468011,1 +183667,1540800299,1540800300,1 +183668,1540800300,360467997,1 +183669,1540800301,360467919,1 +183670,1540800302,360467207,1 +183671,1540800303,360467470,0 +183672,1540800304,1540800305,0 +183673,1540800305,706854250,0 +183675,1540800307,1540800308,1 +183676,1540800308,347774612,1 +183677,1540800309,1540800310,1 +183678,1540800310,347769466,1 +183679,1540800311,1540800312,1 +183680,1540800312,347774803,1 +183681,1540800313,1540800314,1 +183682,1540800314,1540800315,1 +183683,1540800315,1540800316,1 +183684,1540800316,347776931,1 +183685,1540800317,1540800318,1 +183686,1540800318,347777405,1 +183687,1540800319,1540800320,1 +183688,1540800320,1540800321,1 +183689,1540800321,1540800322,1 +183690,1540800322,1540800323,1 +183691,1540800323,1540800324,1 +183692,1540800324,1540800325,1 +183693,1540800325,1540800326,1 +183694,1540800326,272554703,1 +183695,1540800327,1540800328,1 +183696,1540800328,347778141,1 +183697,1540800329,1540800330,1 +183698,1540800330,1540800331,1 +183699,1540800331,1540800332,1 +183700,1540800332,1540800333,1 +183701,1540800333,347777730,1 +183702,1540800334,1540800335,1 +183703,1540800335,1540800336,1 +183704,1540800336,1540800337,1 +183705,1540800337,1540800338,1 +183706,1540800338,347778153,1 +183707,1540800339,1540800340,1 +183708,1540800340,1540800341,1 +183709,1540800341,272554693,1 +183710,1540800342,352705488,1 +183711,1540800343,347781598,1 +183712,1540800344,347781137,1 +183713,1540800345,1540800346,1 +183714,1540800346,347782208,1 +183715,1540800347,347781363,1 +183716,1540800348,347781394,1 +183717,1540800349,1540800350,1 +183718,1540800350,347780903,1 +183719,1540800351,347780925,0 +183720,1540800352,352705353,0 +183721,1540800353,1540800354,1 +183722,1540800354,1540800355,1 +183723,1540800355,1540800356,1 +183724,1540800356,1540800357,1 +183725,1540800357,1540800358,1 +183726,1540800358,347784875,1 +183727,1540800359,1540800360,1 +183728,1540800360,347784877,1 +183729,1540800361,1540800362,1 +183730,1540800362,1540800363,1 +183731,1540800363,1540800364,1 +183732,1540800364,347784880,1 +183733,1540800365,1540800366,1 +183734,1540800366,1540800367,1 +183735,1540800367,347784872,1 +183736,1540800368,347780795,1 +183792,1540800424,1540800425,1 +183793,1540800425,351948867,1 +183794,1540800426,351948869,1 +183795,1540800427,351953840,1 +183796,1540800428,1540800429,1 +183797,1540800429,1540800430,1 +183798,1540800430,351954011,1 +183799,1540800431,351953846,1 +183800,1540800432,352678239,1 +183810,1540800442,1540800443,1 +183811,1540800443,351949742,1 +183812,1540800444,1540800445,1 +183813,1540800445,351949745,1 +183814,1540800446,1540800447,1 +183815,1540800447,351949750,1 +183816,1540800448,1540800449,1 +183817,1540800449,351949127,1 +183819,1540800451,351950580,1 +183820,1540800452,1540800453,1 +183821,1540800453,351950737,1 +183822,1540800454,351950739,1 +183823,1540800455,1540800456,1 +183824,1540800456,1540800457,1 +183825,1540800457,351950742,1 +183826,1540800458,351950743,1 +183827,1540800459,1540800460,1 +183828,1540800460,1540800461,1 +183829,1540800461,1540800462,1 +183830,1540800462,1540800463,1 +183831,1540800463,351950701,1 +183832,1540800464,351952159,1 +183833,1540800465,351951722,1 +183834,1540800466,351952523,1 +183835,1540800467,351952253,1 +183836,1540800468,1540800469,1 +183837,1540800469,351952253,1 +183838,1540800470,1540800471,1 +183839,1540800471,351952392,1 +183840,1540800472,1540800473,1 +183841,1540800473,351954078,1 +183842,1540800474,1540800475,1 +183843,1540800475,351953801,1 +183844,1540800476,1540800477,1 +183845,1540800477,1540800478,1 +183846,1540800478,1540800479,1 +183847,1540800479,1540800480,1 +183848,1540800480,1540800481,1 +183849,1540800481,1540800482,1 +183850,1540800482,351953949,1 +183851,1540800483,351954130,1 +183852,1540800484,1540800485,1 +183853,1540800485,1540800486,1 +183854,1540800486,351954135,1 +183855,1540800487,1540800488,1 +183856,1540800488,352678752,1 +183857,1540800489,351954078,1 +183961,1540800593,352678239,0 +183962,1540800594,352678241,0 +183963,1540800595,1540800596,0 +183964,1540800596,352678244,0 +183965,1540800597,352678176,0 +183970,1540800602,351953573,1 +183971,1540800603,1540800604,1 +183972,1540800604,1540800605,1 +183973,1540800605,352725210,1 +183974,1540800606,351953573,1 +183975,1540800607,1540800608,1 +183976,1540800608,351953949,1 +183977,1540800609,1540800610,1 +183978,1540800610,352679008,1 +183979,1540800611,352679010,1 +183980,1540800612,351953573,1 +183981,1540800613,1540800614,1 +183982,1540800614,352679259,1 +183983,1540800615,352679008,1 +183984,1540800616,352683317,1 +183985,1540800617,352683319,1 +183986,1540800618,352683320,1 +183987,1540800619,347785539,1 +183988,1540800620,1540800621,0 +183989,1540800621,1540800622,0 +183990,1540800622,1540800623,0 +183991,1540800623,1540800624,0 +183992,1540800624,1540800625,0 +183993,1540800625,1540800626,0 +183994,1540800626,1540800627,0 +183995,1540800627,1540800628,0 +183996,1540800628,1540800629,0 +183997,1540800629,1540800630,0 +183998,1540800630,1540800631,0 +183999,1540800631,1540800632,0 +184000,1540800632,1540800633,0 +184001,1540800633,1540800634,0 +184002,1540800634,1540800635,0 +184003,1540800635,1540800636,0 +184004,1540800636,352702555,0 +184005,1540800637,1540800638,0 +184006,1540800638,1540800639,0 +184007,1540800639,1540800640,0 +184008,1540800640,1540800641,0 +184009,1540800641,1540800642,0 +184010,1540800642,1540800643,0 +184011,1540800643,1540800644,0 +184012,1540800644,1540800645,0 +184013,1540800645,1540800646,0 +184014,1540800646,1540800647,0 +184015,1540800647,1540800648,0 +184016,1540800648,1540800649,0 +184017,1540800649,1540800650,0 +184018,1540800650,1540800651,0 +184019,1540800651,1540800652,0 +184020,1540800652,352702713,0 +184021,1540800653,352702992,0 +184022,1540800654,347781387,0 +184023,1540800655,352706476,1 +184024,1540800656,352706645,1 +184025,1540800657,1540800658,1 +184026,1540800658,1540800659,1 +184027,1540800659,352706650,1 +184028,1540800660,1540800661,1 +184029,1540800661,1540800662,1 +184030,1540800662,175702594,1 +184031,1540800663,1540800664,0 +184032,1540800664,1540800665,0 +184033,1540800665,1540800666,0 +184034,1540800666,1540800667,0 +184035,1540800667,1540800668,0 +184036,1540800668,1540800669,0 +184037,1540800669,1540800670,0 +184038,1540800670,1540800671,0 +184039,1540800671,1540800672,0 +184040,1540800672,1540800673,0 +184041,1540800673,1540800674,0 +184042,1540800674,1540800675,0 +184043,1540800675,1540800676,0 +184044,1540800676,1540800677,0 +184045,1540800677,1540800678,0 +184046,1540800678,1540800679,0 +184047,1540800679,1540800680,0 +184048,1540800680,352706146,0 +184049,1540800681,352706516,0 +184050,1540800682,352706518,0 +184051,1540800683,352706544,1 +184052,1540800684,1540800685,0 +184053,1540800685,1540800686,0 +184054,1540800686,1540800687,0 +184055,1540800687,1540800688,0 +184056,1540800688,1540800689,0 +184057,1540800689,1540800690,0 +184058,1540800690,352706574,0 +184059,1540800691,1540800692,0 +184060,1540800692,1540800693,0 +184061,1540800693,1540800694,0 +184062,1540800694,1540800695,0 +184063,1540800695,1540800696,0 +184064,1540800696,1540800697,0 +184065,1540800697,1540800698,0 +184066,1540800698,1540800699,0 +184067,1540800699,352706544,0 +184068,1540800700,352706581,1 +184069,1540800701,352707216,1 +184070,1540800702,352706697,0 +184071,1540800703,1540800704,0 +184072,1540800704,352706700,0 +184073,1540800705,1540800706,1 +184074,1540800706,352706872,1 +184075,1540800707,352706874,1 +184076,1540800708,1540800709,1 +184077,1540800709,352706874,1 +184078,1540800710,352706896,1 +184079,1540800711,1540800712,1 +184080,1540800712,352706987,1 +184081,1540800713,1540800714,1 +184082,1540800714,352706890,1 +184083,1540800715,1540800716,1 +184084,1540800716,352707053,1 +184085,1540800717,1540800718,1 +184086,1540800718,352707056,1 +184087,1540800719,1540800720,1 +184088,1540800720,352707071,1 +184089,1540800721,1540800722,1 +184090,1540800722,352706584,1 +184091,1540800723,1540800724,0 +184092,1540800724,1540800725,0 +184093,1540800725,1540800726,0 +184094,1540800726,1540800727,0 +184095,1540800727,1540800728,0 +184096,1540800728,1540800729,0 +184097,1540800729,1540800730,0 +184098,1540800730,352707228,0 +184099,1540800731,1540800732,0 +184100,1540800732,1540800733,0 +184101,1540800733,1540800734,0 +184102,1540800734,1540800735,0 +184103,1540800735,1540800736,0 +184104,1540800736,1540800737,0 +184105,1540800737,352707216,0 +184106,1540800738,352706584,1 +184107,1540800739,1540800740,0 +184108,1540800740,1540800741,0 +184109,1540800741,1141269201,0 +184110,1540800742,1540800743,0 +184111,1540800743,352708533,0 +184112,1540800744,1540800745,0 +184113,1540800745,1540800746,0 +184114,1540800746,1540800747,0 +184115,1540800747,1540800748,0 +184116,1540800748,1540800749,0 +184117,1540800749,1540800750,0 +184118,1540800750,1540800751,0 +184119,1540800751,1540800752,0 +184120,1540800752,1540800753,0 +184121,1540800753,1540800754,0 +184122,1540800754,1540800755,0 +184123,1540800755,1540800756,0 +184124,1540800756,352708531,0 +184125,1540800757,352708636,1 +184126,1540800758,1540800759,1 +184127,1540800759,352708639,1 +184128,1540800760,352708657,1 +184129,1540800761,352706987,1 +184130,1540800762,352708777,1 +184131,1540800763,1540800764,1 +184132,1540800764,1540800765,1 +184133,1540800765,352708786,1 +184134,1540800766,352708902,1 +184135,1540800767,352707056,1 +184136,1540800768,1540800769,1 +184137,1540800769,1540800770,1 +184138,1540800770,352709181,1 +184139,1540800771,352709189,1 +184140,1540800772,1540800773,1 +184141,1540800773,352708639,1 +184142,1540800774,352709387,1 +184143,1540800775,1540800776,1 +184144,1540800776,352708786,1 +184145,1540800777,1540800778,1 +184146,1540800778,1540800779,1 +184147,1540800779,1540800780,1 +184148,1540800780,1540800781,1 +184149,1540800781,352679010,1 +184150,1540800782,351953505,1 +184151,1540800783,352723520,1 +184152,1540800784,1540800785,1 +184153,1540800785,1540800786,1 +184154,1540800786,352723284,1 +184155,1540800787,352723286,1 +184156,1540800788,352724179,1 +184157,1540800789,352723638,1 +184158,1540800790,352723692,1 +184159,1540800791,352724386,0 +184160,1540800792,1540800793,0 +184161,1540800793,1540800794,0 +184162,1540800794,1540800795,0 +184163,1540800795,352724713,0 +184164,1540800796,1540800797,0 +184165,1540800797,1540800798,0 +184166,1540800798,1540800799,0 +184167,1540800799,352724702,0 +184168,1540800800,1540800801,0 +184169,1540800801,1540800802,0 +184170,1540800802,1540800803,0 +184171,1540800803,352724696,0 +184172,1540800804,1540800805,1 +184173,1540800805,352724179,1 +184174,1540800806,1540800807,1 +184175,1540800807,1540800808,1 +184176,1540800808,352723567,1 +185885,1540802517,695556369,1 +185886,1540802518,1540802519,1 +185887,1540802519,353243344,1 +185888,1540802520,353243956,1 +185889,1540802521,365118255,0 +185890,1540802522,1540802523,1 +185891,1540802523,353244382,1 +185892,1540802524,353244587,1 +185893,1540802525,365118244,1 +185894,1540802526,365117377,0 +185895,1540802527,1540802528,0 +185896,1540802528,353244833,0 +185897,1540802529,360473975,0 +185898,1540802530,353245557,1 +185899,1540802531,353245603,1 +185900,1540802532,353245634,1 +185901,1540802533,353245557,1 +185902,1540802534,1540802535,1 +185903,1540802535,353245398,1 +185904,1540802536,1540802537,1 +185905,1540802537,353245555,1 +185906,1540802538,353245716,1 +185907,1540802539,705979340,0 +185908,1540802540,353246170,0 +185909,1540802541,1236188101,0 +185910,1540802542,353246570,1 +185911,1540802543,1142694898,1 +185912,1540802544,353246458,1 +185913,1540802545,360476020,1 +186624,1540803256,1540803257,1 +186625,1540803257,1540803258,1 +186626,1540803258,372799421,1 +186639,1540803271,1540803272,0 +186640,1540803272,1540803273,0 +186641,1540803273,1540803274,0 +186642,1540803274,1540803275,0 +186643,1540803275,1540803276,0 +186644,1540803276,1540803277,0 +186645,1540803277,1540803278,0 +186646,1540803278,1540803279,0 +186647,1540803279,1540803280,0 +186648,1540803280,1540803281,0 +186649,1540803281,1540803282,0 +186650,1540803282,1540803283,0 +186651,1540803283,1540803284,0 +186652,1540803284,1540803285,0 +186653,1540803285,1540803286,0 +186654,1540803286,1540803287,0 +186655,1540803287,745988414,0 +186656,1540803288,745988380,0 +188290,1540804922,1540804923,0 +188291,1540804923,1540804924,0 +188292,1540804924,1540804925,0 +188293,1540804925,1540804926,0 +188294,1540804926,600930461,0 +188704,1540805336,1540805337,0 +188705,1540805337,445393446,0 +188706,1540805338,1540805339,0 +188707,1540805339,1345684263,0 +188708,1540805340,1540805341,0 +188709,1540805341,1345680614,0 +188710,1540805342,1540805343,0 +188711,1540805343,277535693,0 +188721,1540805353,1540805354,0 +188722,1540805354,935855575,0 +188723,1540805355,1540805356,0 +188724,1540805356,1540805357,0 +188725,1540805357,445393420,0 +188747,1540805379,1374274153,0 +189697,1540806329,966153913,1 +189698,1540806330,966154120,1 +189699,1540806331,363988496,1 +189700,1540806332,583435261,1 +189701,1540806333,1540806334,1 +189702,1540806334,966314856,1 +189703,1540806335,1540806336,1 +189704,1540806336,1540806337,1 +189705,1540806337,583435270,1 +193251,1540809883,985946279,0 +193252,1540809884,152802872,1 +193253,1540809885,359996114,1 +193254,1540809886,1540809887,1 +193255,1540809887,1540809888,1 +193256,1540809888,359996135,1 +193257,1540809889,1540809890,1 +193258,1540809890,152942456,1 +193259,1540809891,559564599,1 +193260,1540809892,1540809893,1 +193261,1540809893,1540809894,1 +193262,1540809894,1540809895,1 +193263,1540809895,286367801,1 +193264,1540809896,1540809897,1 +193265,1540809897,1540809898,1 +193266,1540809898,286367804,1 +193267,1540809899,1540809900,1 +193268,1540809900,359997003,1 +193269,1540809901,1540809902,1 +193270,1540809902,1540809903,1 +193271,1540809903,1540809904,1 +193272,1540809904,1540809905,1 +193273,1540809905,1540809906,1 +193274,1540809906,1540809907,1 +193275,1540809907,1540809908,1 +193276,1540809908,1540809909,1 +193277,1540809909,359997013,1 +193278,1540809910,359997016,1 +193279,1540809911,359997018,1 +193280,1540809912,984726066,1 +193281,1540809913,1025767737,1 +193282,1540809914,1540809915,1 +193283,1540809915,359996729,1 +193284,1540809916,1540809917,1 +193285,1540809917,359997138,1 +193286,1540809918,559564590,1 +193287,1540809919,1540809920,1 +193288,1540809920,1540809921,1 +193289,1540809921,985946214,1 +193290,1540809922,1540809923,1 +193291,1540809923,152802117,1 +193292,1540809924,1540809925,1 +193293,1540809925,1540809926,1 +193294,1540809926,359997940,1 +193295,1540809927,359997885,1 +193296,1540809928,1540809929,1 +193297,1540809929,1540809930,1 +193298,1540809930,985945971,1 +193299,1540809931,359997380,1 +193300,1540809932,359997940,1 +193301,1540809933,359999162,1 +193302,1540809934,1540809935,1 +193303,1540809935,359998944,1 +193304,1540809936,559939186,1 +193305,1540809937,359998480,1 +193306,1540809938,956787101,1 +193307,1540809939,359998484,1 +193308,1540809940,1540809941,1 +193309,1540809941,1540809942,1 +193310,1540809942,359998489,1 +193311,1540809943,1540809944,1 +193312,1540809944,1540809945,1 +193313,1540809945,961664697,1 +193314,1540809946,365970554,1 +193315,1540809947,1540809948,1 +193316,1540809948,359998585,1 +193317,1540809949,359998946,1 +193318,1540809950,1540809951,1 +193319,1540809951,549777920,1 +193320,1540809952,961664505,1 +193321,1540809953,1013433823,0 +193322,1540809954,1540809955,0 +193323,1540809955,1540809956,0 +193324,1540809956,1540809957,0 +193325,1540809957,560576460,0 +193326,1540809958,1540809959,0 +193327,1540809959,1540809960,0 +193328,1540809960,1540809961,0 +193329,1540809961,560583695,0 +193330,1540809962,559939230,1 +193331,1540809963,1540809964,1 +193332,1540809964,1540809965,1 +193333,1540809965,1540809966,1 +193334,1540809966,360000423,1 +193335,1540809967,1540809968,1 +193336,1540809968,360000540,1 +193337,1540809969,360000542,1 +193338,1540809970,1540809971,0 +193339,1540809971,1540809972,0 +193340,1540809972,360002692,0 +193341,1540809973,1540809974,1 +193342,1540809974,1540809975,1 +193343,1540809975,1540809976,1 +193344,1540809976,559939216,1 +193345,1540809977,360003283,0 +193346,1540809978,1540809979,1 +193347,1540809979,1540809980,1 +193348,1540809980,1540809981,1 +193349,1540809981,1540809982,1 +193350,1540809982,1540809983,1 +193351,1540809983,360003653,1 +193352,1540809984,1540809985,1 +193353,1540809985,1540809986,1 +193354,1540809986,1540809987,1 +193355,1540809987,360003406,1 +193356,1540809988,1540809989,1 +193357,1540809989,1540809990,1 +193358,1540809990,1540809991,1 +193359,1540809991,360003715,1 +193360,1540809992,360013939,1 +193361,1540809993,360007327,1 +193362,1540809994,360006602,1 +193363,1540809995,1540809996,1 +193364,1540809996,360009333,1 +193365,1540809997,1540809998,1 +193366,1540809998,1540809999,1 +193367,1540809999,1540810000,1 +193368,1540810000,1540810001,1 +193369,1540810001,1540810002,1 +193370,1540810002,1540810003,1 +193371,1540810003,1540810004,1 +193372,1540810004,1540810005,1 +193373,1540810005,360006210,1 +193374,1540810006,549785183,1 +193375,1540810007,1540810008,0 +193376,1540810008,1540810009,0 +193377,1540810009,1540810010,0 +193378,1540810010,801479968,0 +193379,1540810011,1540810012,0 +193380,1540810012,1540810013,0 +193381,1540810013,35839960,0 +193382,1540810014,360008931,0 +193383,1540810015,279590737,0 +193384,1540810016,1540810017,0 +193385,1540810017,360009036,0 +193386,1540810018,1540810019,0 +193387,1540810019,1540810020,0 +193388,1540810020,360005629,0 +193389,1540810021,360007391,0 +193390,1540810022,1540810023,0 +193391,1540810023,1540810024,0 +193392,1540810024,1540810025,0 +193393,1540810025,1540810026,0 +193394,1540810026,1540810027,0 +193395,1540810027,1540810028,0 +193396,1540810028,1540810029,0 +193397,1540810029,1540810030,0 +193398,1540810030,1540810031,0 +193399,1540810031,1540810032,0 +193400,1540810032,1540810033,0 +193401,1540810033,1540810034,0 +193402,1540810034,1540810035,0 +193403,1540810035,279591274,0 +193404,1540810036,1178859518,0 +193405,1540810037,1540810038,0 +193406,1540810038,279591275,0 +193407,1540810039,1540810040,0 +193408,1540810040,363972646,0 +193409,1540810041,1540810042,0 +193410,1540810042,279591280,0 +193411,1540810043,1540810044,0 +193412,1540810044,363971113,0 +193413,1540810045,360006483,1 +193414,1540810046,360006600,1 +193415,1540810047,360006740,1 +193416,1540810048,601025729,1 +193417,1540810049,360006825,1 +193418,1540810050,1540810051,1 +193419,1540810051,360007057,1 +193420,1540810052,360007062,1 +193421,1540810053,601015865,1 +193422,1540810054,360006823,1 +193423,1540810055,360007510,1 +193424,1540810056,360007214,1 +193425,1540810057,601013512,1 +193426,1540810058,1540810059,1 +193427,1540810059,360007327,1 +193428,1540810060,360007063,1 +193429,1540810061,360008076,1 +193430,1540810062,360007554,1 +193431,1540810063,360007537,1 +193432,1540810064,1540810065,1 +193433,1540810065,1540810066,1 +193434,1540810066,1540810067,1 +193435,1540810067,360007717,1 +193436,1540810068,1540810069,1 +193437,1540810069,1540810070,1 +193438,1540810070,1540810071,1 +193439,1540810071,360007910,1 +193440,1540810072,360008371,1 +193441,1540810073,1540810074,1 +193442,1540810074,1540810075,1 +193443,1540810075,360008388,1 +193444,1540810076,599532941,1 +193445,1540810077,360010440,1 +193446,1540810078,1540810079,1 +193447,1540810079,1540810080,1 +193448,1540810080,360008750,1 +193449,1540810081,1540810082,1 +193450,1540810082,360009853,1 +193451,1540810083,360008917,1 +193452,1540810084,360009080,1 +193453,1540810085,360008825,1 +193454,1540810086,1025767715,1 +193455,1540810087,1540810088,1 +193456,1540810088,360010296,1 +193457,1540810089,360006487,1 +193458,1540810090,360006486,1 +193459,1540810091,1540810092,1 +193460,1540810092,360009077,1 +193461,1540810093,1540810094,1 +193462,1540810094,1540810095,1 +193463,1540810095,1540810096,1 +193464,1540810096,360009233,1 +193465,1540810097,1540810098,1 +193466,1540810098,1540810099,1 +193467,1540810099,1540810100,1 +193468,1540810100,1540810101,1 +193469,1540810101,360009255,1 +193470,1540810102,1540810103,1 +193471,1540810103,360009421,1 +193472,1540810104,1540810105,1 +193473,1540810105,360009554,1 +193474,1540810106,1540810107,1 +193475,1540810107,1540810108,1 +193476,1540810108,1540810109,1 +193477,1540810109,360009572,1 +193478,1540810110,360009591,1 +193479,1540810111,360009658,1 +193480,1540810112,1025767739,1 +193481,1540810113,1540810114,1 +193482,1540810114,360009848,1 +193483,1540810115,1540810116,1 +193484,1540810116,1540810117,1 +193485,1540810117,1540810118,1 +193486,1540810118,1540810119,1 +193487,1540810119,1540810120,1 +193488,1540810120,1025767724,1 +193489,1540810121,1540810122,1 +193490,1540810122,360009848,1 +193491,1540810123,360008829,1 +193492,1540810124,360008005,1 +193493,1540810125,360010311,1 +193494,1540810126,966653507,1 +193495,1540810127,1540810128,1 +193496,1540810128,360011965,1 +193497,1540810129,1540810130,1 +193498,1540810130,360008371,1 +193499,1540810131,360010646,1 +193507,1540810139,1540810140,1 +193508,1540810140,360011364,1 +193509,1540810141,360013175,1 +193510,1540810142,1540810143,1 +193511,1540810143,1540810144,1 +193512,1540810144,566679103,1 +193523,1540810155,1540810156,1 +193524,1540810156,1540810157,1 +193525,1540810157,360011585,1 +193526,1540810158,360012508,1 +193530,1540810162,360012189,1 +193531,1540810163,360011954,1 +193533,1540810165,360012348,1 +193545,1540810177,360011078,1 +193546,1540810178,972315449,1 +193547,1540810179,566678846,1 +193548,1540810180,1540810181,1 +193549,1540810181,1030300202,1 +193551,1540810183,360011369,1 +193554,1540810186,1540810187,1 +193555,1540810187,360013769,1 +193556,1540810188,360013062,1 +193569,1540810201,1540810202,1 +193570,1540810202,360013486,1 +193571,1540810203,1540810204,1 +193572,1540810204,360012038,1 +193573,1540810205,536580033,1 +193581,1540810213,1540810214,1 +193582,1540810214,1540810215,1 +193583,1540810215,1540810216,1 +193584,1540810216,1540810217,1 +193585,1540810217,360014313,1 +193586,1540810218,1540810219,1 +193587,1540810219,360014629,1 +193588,1540810220,360010644,1 +193589,1540810221,360008281,1 +193592,1540810224,360015396,1 +193593,1540810225,1540810226,1 +193594,1540810226,360015400,1 +193596,1540810228,1540810229,0 +193597,1540810229,1540810230,0 +193598,1540810230,1540810231,0 +193599,1540810231,1540810232,0 +193600,1540810232,360005638,0 +193614,1540810246,800140505,1 +193615,1540810247,633036610,1 +193616,1540810248,801467918,1 +193617,1540810249,801480013,1 +193627,1540810259,558970290,1 +193628,1540810260,1540810261,1 +193629,1540810261,558970405,1 +193630,1540810262,1540810263,1 +193631,1540810263,360019195,1 +193632,1540810264,558969811,1 +193633,1540810265,360019197,1 +193634,1540810266,1540810267,1 +193635,1540810267,360019201,1 +193636,1540810268,1540810269,1 +193637,1540810269,967240558,1 +193638,1540810270,967199729,1 +193639,1540810271,360018879,1 +193640,1540810272,1540810273,1 +193641,1540810273,1540810274,1 +193646,1540810278,360019570,1 +193647,1540810279,1540810280,1 +193648,1540810280,1540810281,1 +193649,1540810281,967199443,1 +193650,1540810282,1540810283,1 +193651,1540810283,1540810284,1 +193652,1540810284,360019574,1 +193653,1540810285,966279592,1 +193654,1540810286,363984892,1 +193655,1540810287,360019574,1 +193658,1540810290,360019718,1 +193659,1540810291,967240665,1 +193660,1540810292,360019722,1 +193661,1540810293,360019884,1 +193662,1540810294,1540810295,1 +193663,1540810295,967331616,1 +193664,1540810296,1540810297,1 +193665,1540810297,1540810298,1 +193666,1540810298,1540810299,1 +193667,1540810299,360019863,1 +193668,1540810300,360019972,1 +193669,1540810301,1540810302,1 +193670,1540810302,1540810303,1 +193671,1540810303,1540810304,1 +193672,1540810304,360019863,1 +193673,1540810305,360020007,1 +193674,1540810306,966278877,1 +193817,1540810449,1540810450,1 +193818,1540810450,1540810451,1 +193819,1540810451,1540810452,1 +193820,1540810452,1540810453,1 +193821,1540810453,1540810454,1 +193822,1540810454,1540810455,1 +193823,1540810455,1540810456,1 +193824,1540810456,1540810457,1 +193825,1540810457,1540810458,1 +193826,1540810458,1540810459,1 +193827,1540810459,360022641,1 +195252,1540811884,360189339,1 +195253,1540811885,360189342,1 +195254,1540811886,1540811887,1 +195255,1540811887,360189449,1 +195256,1540811888,1540811889,1 +195257,1540811889,360189453,1 +195258,1540811890,1540811891,1 +195259,1540811891,1540811892,1 +195260,1540811892,1540811893,1 +195261,1540811893,1540811894,1 +195262,1540811894,360189460,1 +195263,1540811895,360189540,1 +195264,1540811896,360189635,1 +195265,1540811897,972481575,1 +195266,1540811898,1540811899,1 +195267,1540811899,1540811900,1 +195268,1540811900,972481866,1 +195269,1540811901,972481699,1 +195270,1540811902,1540811903,1 +195271,1540811903,1540811904,1 +195272,1540811904,1540811905,1 +195273,1540811905,1540811906,1 +195274,1540811906,1540811907,1 +195275,1540811907,912014335,1 +195276,1540811908,1540811909,1 +195277,1540811909,360190380,1 +195278,1540811910,1540811911,1 +195279,1540811911,360190664,1 +195280,1540811912,1540811913,1 +195281,1540811913,360224995,1 +195282,1540811914,360190684,1 +195283,1540811915,360190819,1 +195284,1540811916,360190821,1 +195285,1540811917,360190819,1 +195286,1540811918,360191001,1 +195287,1540811919,1540811920,1 +195288,1540811920,360190928,1 +195289,1540811921,360191004,1 +195290,1540811922,360191085,1 +195291,1540811923,1540811924,1 +195292,1540811924,360194178,1 +195293,1540811925,360194110,1 +195294,1540811926,360190821,1 +195295,1540811927,360191413,1 +195296,1540811928,360191535,1 +195297,1540811929,360191564,1 +195298,1540811930,360193041,0 +195299,1540811931,360191826,1 +195300,1540811932,1540811933,1 +195301,1540811933,1540811934,1 +195302,1540811934,1540811935,1 +195303,1540811935,360191909,1 +195304,1540811936,1540811937,1 +195305,1540811937,360192310,1 +195306,1540811938,360192492,1 +195307,1540811939,1540811940,1 +195308,1540811940,360192258,1 +195309,1540811941,360192594,1 +195310,1540811942,1540811943,1 +195311,1540811943,1540811944,1 +195312,1540811944,360191090,1 +195313,1540811945,1540811946,1 +195314,1540811946,360193230,1 +195315,1540811947,360193343,1 +195316,1540811948,279589608,1 +195317,1540811949,360205146,1 +195318,1540811950,360210375,1 +195319,1540811951,360196535,1 +195320,1540811952,360196827,1 +195321,1540811953,360196617,1 +195322,1540811954,360198456,1 +195323,1540811955,1540811956,1 +195324,1540811956,1540811957,1 +195325,1540811957,1540811958,1 +195326,1540811958,360197965,1 +195327,1540811959,360213207,1 +195328,1540811960,1540811961,1 +195329,1540811961,360212244,1 +195330,1540811962,1540811963,1 +195331,1540811963,1540811964,1 +195332,1540811964,360212067,1 +195333,1540811965,360219367,1 +195334,1540811966,913575820,1 +195335,1540811967,360212924,1 +195336,1540811968,360199069,1 +195337,1540811969,360199226,1 +195338,1540811970,360197086,1 +195339,1540811971,360200389,1 +195340,1540811972,1540811973,1 +195341,1540811973,360200488,1 +195342,1540811974,360200591,1 +195343,1540811975,360200725,1 +195344,1540811976,1540811977,1 +195345,1540811977,360200086,1 +195346,1540811978,1030975227,1 +195347,1540811979,1540811980,1 +195348,1540811980,1540811981,1 +195349,1540811981,1540811982,1 +195350,1540811982,360236026,1 +195351,1540811983,1540811984,1 +195352,1540811984,1540811985,1 +195353,1540811985,360200098,1 +195354,1540811986,360200101,1 +195355,1540811987,360199759,1 +195356,1540811988,360214031,0 +195357,1540811989,35487986,0 +195358,1540811990,1540811991,1 +195359,1540811991,360199759,1 +195360,1540811992,360200214,1 +195361,1540811993,1540811994,1 +195362,1540811994,1540811995,1 +195363,1540811995,360199435,1 +195364,1540811996,1540811997,1 +195365,1540811997,360200219,1 +195366,1540811998,360198635,1 +195367,1540811999,1540812000,1 +195368,1540812000,360200223,1 +195369,1540812001,1540812002,1 +195370,1540812002,360199245,1 +195371,1540812003,360199519,1 +195372,1540812004,360203285,1 +195373,1540812005,360200485,1 +195374,1540812006,360200488,1 +195375,1540812007,360200750,0 +195376,1540812008,360201318,1 +195377,1540812009,360201319,1 +195378,1540812010,360201323,1 +195379,1540812011,360201326,1 +195380,1540812012,1540812013,1 +195381,1540812013,1540812014,1 +195382,1540812014,360200086,1 +195383,1540812015,360201490,1 +195384,1540812016,1540812017,1 +195385,1540812017,360201318,1 +195386,1540812018,1540812019,1 +195387,1540812019,360201676,1 +195388,1540812020,1540812021,1 +195389,1540812021,1030974750,1 +195390,1540812022,1030974510,1 +195391,1540812023,1540812024,1 +195392,1540812024,360201850,1 +195393,1540812025,360201910,1 +195394,1540812026,360201912,1 +195395,1540812027,1540812028,1 +195396,1540812028,278009641,1 +195397,1540812029,1030975591,1 +195398,1540812030,360202278,1 +195399,1540812031,1540812032,1 +195400,1540812032,1540812033,1 +195401,1540812033,360202609,1 +195402,1540812034,360202814,1 +195403,1540812035,360203053,1 +195404,1540812036,1540812037,1 +195405,1540812037,360203097,1 +195406,1540812038,360200486,1 +195407,1540812039,360203239,1 +195408,1540812040,360203285,1 +195409,1540812041,360203379,1 +195410,1540812042,360203398,1 +195411,1540812043,360203410,1 +195412,1540812044,360203626,1 +195413,1540812045,1540812046,1 +195414,1540812046,360204332,1 +195415,1540812047,1540812048,1 +195416,1540812048,1540812049,1 +195417,1540812049,360204457,1 +195418,1540812050,1540812051,1 +195419,1540812051,360204585,1 +195420,1540812052,1540812053,1 +195421,1540812053,1030323771,1 +195422,1540812054,360204362,1 +195423,1540812055,360204402,1 +195424,1540812056,1540812057,1 +195425,1540812057,1540812058,1 +195426,1540812058,1540812059,1 +195427,1540812059,1540812060,1 +195428,1540812060,1030323778,1 +195429,1540812061,1030323806,1 +195430,1540812062,1540812063,1 +195431,1540812063,1030323803,1 +195432,1540812064,278009645,1 +195433,1540812065,360204457,1 +195434,1540812066,360204844,1 +195435,1540812067,360204671,1 +195436,1540812068,360204332,1 +195437,1540812069,1540812070,1 +195438,1540812070,360203356,1 +195439,1540812071,360204671,1 +195440,1540812072,360204792,1 +195441,1540812073,1540812074,1 +195442,1540812074,360204865,1 +195443,1540812075,1540812076,1 +195444,1540812076,360193343,1 +195445,1540812077,1540812078,1 +195446,1540812078,1540812079,1 +195447,1540812079,360205161,1 +195448,1540812080,1540812081,1 +195449,1540812081,1540812082,1 +195450,1540812082,1540812083,1 +195451,1540812083,1540812084,1 +195452,1540812084,1540812085,1 +195453,1540812085,360205801,1 +195454,1540812086,360194057,1 +195455,1540812087,1540812088,1 +195456,1540812088,279591661,1 +195457,1540812089,360192174,1 +195458,1540812090,360205522,1 +195459,1540812091,360193671,1 +195460,1540812092,1540812093,0 +195461,1540812093,1540812094,0 +195462,1540812094,1540812095,0 +195463,1540812095,360205803,0 +195464,1540812096,360205625,0 +195465,1540812097,1540812098,0 +195466,1540812098,360205629,0 +195467,1540812099,1540812100,0 +195468,1540812100,1540812101,0 +195469,1540812101,1030313151,0 +195470,1540812102,1540812103,0 +195471,1540812103,1540812104,0 +195472,1540812104,1540812105,0 +195473,1540812105,1540812106,0 +195474,1540812106,278009654,0 +195475,1540812107,1540812108,0 +195476,1540812108,1540812109,0 +195477,1540812109,716888879,0 +195478,1540812110,360194052,1 +195479,1540812111,360205625,1 +195480,1540812112,360205413,1 +195481,1540812113,360205415,1 +195482,1540812114,360205320,1 +195483,1540812115,1540812116,1 +195484,1540812116,360205477,1 +195485,1540812117,1540812118,1 +195486,1540812118,360205872,1 +195487,1540812119,1540812120,1 +195488,1540812120,360205693,1 +195489,1540812121,360205803,1 +195490,1540812122,360190871,1 +195491,1540812123,1540812124,1 +195492,1540812124,360206034,1 +195493,1540812125,1540812126,1 +195494,1540812126,360206038,1 +195495,1540812127,716889049,1 +195496,1540812128,360206842,1 +195497,1540812129,360206846,1 +195498,1540812130,1540812131,1 +195499,1540812131,974066401,1 +195500,1540812132,1540812133,1 +195501,1540812133,360207173,1 +195502,1540812134,1540812135,1 +195503,1540812135,360207242,1 +195504,1540812136,1540812137,1 +195505,1540812137,1540812138,1 +195506,1540812138,1540812139,1 +195507,1540812139,1540812140,1 +195508,1540812140,1540812141,1 +195509,1540812141,1540812142,1 +195510,1540812142,1540812143,1 +195511,1540812143,1540812144,1 +195512,1540812144,1540812145,1 +195513,1540812145,360209873,1 +195514,1540812146,360209875,1 +195515,1540812147,1540812148,1 +195516,1540812148,360209880,1 +195517,1540812149,360209774,1 +195518,1540812150,360207810,1 +195519,1540812151,1540812152,1 +195520,1540812152,1540812153,1 +195521,1540812153,1540812154,1 +195522,1540812154,360210151,1 +195523,1540812155,1540812156,1 +195524,1540812156,360209873,1 +195525,1540812157,1540812158,1 +195526,1540812158,1540812159,1 +195527,1540812159,1540812160,1 +195528,1540812160,1540812161,1 +195529,1540812161,974066961,1 +195530,1540812162,1540812163,1 +195531,1540812163,1540812164,1 +195532,1540812164,1540812165,1 +195533,1540812165,360207867,1 +195534,1540812166,360207888,1 +195535,1540812167,360207928,1 +195536,1540812168,360207177,1 +195537,1540812169,1540812170,1 +195538,1540812170,1540812171,1 +195539,1540812171,360207182,1 +195540,1540812172,1540812173,1 +195541,1540812173,1540812174,1 +195542,1540812174,360207027,1 +195543,1540812175,1540812176,1 +195544,1540812176,1540812177,1 +195545,1540812177,1540812178,1 +195546,1540812178,1540812179,1 +195547,1540812179,360209448,1 +195548,1540812180,360209399,0 +195549,1540812181,1540812182,1 +195550,1540812182,1540812183,1 +195551,1540812183,360210055,1 +195552,1540812184,583434231,1 +195553,1540812185,360207812,1 +195554,1540812186,1540812187,1 +195555,1540812187,360223133,1 +195556,1540812188,360219439,1 +195557,1540812189,1540812190,1 +195558,1540812190,360210541,1 +195559,1540812191,360211126,1 +195560,1540812192,1540812193,1 +195561,1540812193,1540812194,1 +195562,1540812194,1540812195,1 +195563,1540812195,1540812196,1 +195564,1540812196,1540812197,1 +195565,1540812197,1540812198,1 +195566,1540812198,360218565,1 +195567,1540812199,1540812200,1 +195568,1540812200,1540812201,1 +195569,1540812201,1540812202,1 +195570,1540812202,360197965,1 +195571,1540812203,1540812204,1 +195572,1540812204,1540812205,1 +195573,1540812205,360213603,1 +195574,1540812206,1540812207,1 +195575,1540812207,1540812208,1 +195576,1540812208,1540812209,1 +195577,1540812209,1540812210,1 +195578,1540812210,360213042,1 +195579,1540812211,1540812212,1 +195580,1540812212,360213042,1 +195581,1540812213,360213534,1 +195582,1540812214,1540812215,1 +195583,1540812215,360198249,1 +195584,1540812216,1540812217,0 +195585,1540812217,1540812218,0 +195586,1540812218,1540812219,0 +195587,1540812219,1540812220,0 +195588,1540812220,1540812221,0 +195589,1540812221,1540812222,0 +195590,1540812222,1540812223,0 +195591,1540812223,1540812224,0 +195592,1540812224,1540812225,0 +195593,1540812225,360211732,0 +195594,1540812226,1540812227,0 +195595,1540812227,1540812228,0 +195596,1540812228,1540812229,0 +195597,1540812229,1540812230,0 +195598,1540812230,1540812231,0 +195599,1540812231,1540812232,0 +195600,1540812232,360213838,0 +195601,1540812233,1540812234,1 +195602,1540812234,360214769,1 +195603,1540812235,360214772,1 +195604,1540812236,913523106,1 +195605,1540812237,1540812238,1 +195606,1540812238,1540812239,1 +195607,1540812239,360196124,1 +195608,1540812240,360197259,1 +195609,1540812241,360198192,1 +195610,1540812242,1540812243,1 +195611,1540812243,1540812244,1 +195612,1540812244,1540812245,1 +195613,1540812245,1540812246,1 +195614,1540812246,1540812247,1 +195615,1540812247,1540812248,1 +195616,1540812248,360197739,1 +195617,1540812249,1540812250,1 +195618,1540812250,360200750,1 +195619,1540812251,1540812252,0 +195620,1540812252,360199588,0 +195621,1540812253,360195888,1 +195622,1540812254,1540812255,1 +195623,1540812255,360214904,1 +195624,1540812256,920589763,1 +195625,1540812257,1540812258,1 +195626,1540812258,360215023,1 +195627,1540812259,360232131,1 +195628,1540812260,1540812261,1 +195629,1540812261,1540812262,1 +195630,1540812262,1540812263,1 +195631,1540812263,1540812264,1 +195632,1540812264,1540812265,1 +195633,1540812265,360215586,1 +195634,1540812266,1540812267,1 +195635,1540812267,1540812268,1 +195636,1540812268,1540812269,1 +195637,1540812269,1540812270,1 +195638,1540812270,973037250,1 +195639,1540812271,360221716,1 +195640,1540812272,360216881,1 +195641,1540812273,1540812274,1 +195642,1540812274,1540812275,1 +195643,1540812275,360217073,1 +195644,1540812276,360215771,1 +195645,1540812277,360216012,1 +195646,1540812278,1540812279,1 +195647,1540812279,973054068,1 +195648,1540812280,1540812281,1 +195649,1540812281,1540812282,1 +195650,1540812282,1540812283,1 +195651,1540812283,1540812284,1 +195652,1540812284,1540812285,1 +195653,1540812285,1540812286,1 +195654,1540812286,1540812287,1 +195655,1540812287,1540812288,1 +195656,1540812288,1540812289,1 +195657,1540812289,360216351,1 +195658,1540812290,1540812291,1 +195659,1540812291,360216187,1 +195660,1540812292,360216387,1 +195661,1540812293,360216189,1 +195662,1540812294,360215730,1 +195663,1540812295,1540812296,1 +195664,1540812296,1540812297,1 +195665,1540812297,1540812298,1 +195666,1540812298,1540812299,1 +195667,1540812299,360220151,1 +195668,1540812300,1540812301,1 +195669,1540812301,1540812302,1 +195670,1540812302,1540812303,1 +195671,1540812303,360195889,1 +195672,1540812304,1540812305,1 +195673,1540812305,1540812306,1 +195674,1540812306,360217429,1 +195675,1540812307,1540812308,1 +195676,1540812308,360217196,1 +195677,1540812309,360217235,1 +195678,1540812310,1540812311,1 +195679,1540812311,360233631,1 +195680,1540812312,1540812313,1 +195681,1540812313,1540812314,1 +195682,1540812314,360217511,1 +195683,1540812315,360217516,1 +195684,1540812316,1540812317,1 +195685,1540812317,360217654,1 +195686,1540812318,360217657,1 +195687,1540812319,1540812320,1 +195688,1540812320,360217713,1 +195689,1540812321,360217651,1 +195690,1540812322,1540812323,1 +195691,1540812323,360213072,1 +195692,1540812324,360219202,1 +195693,1540812325,1540812326,1 +195694,1540812326,360218763,1 +195695,1540812327,360213562,1 +195696,1540812328,1540812329,1 +195697,1540812329,1540812330,1 +195698,1540812330,360221296,1 +195699,1540812331,1540812332,1 +195700,1540812332,360217693,1 +195701,1540812333,338488119,1 +195702,1540812334,1540812335,1 +195703,1540812335,1540812336,1 +195704,1540812336,1540812337,1 +195705,1540812337,1540812338,1 +195706,1540812338,1540812339,1 +195707,1540812339,1540812340,1 +195708,1540812340,1540812341,1 +195709,1540812341,1540812342,1 +195710,1540812342,1540812343,1 +195711,1540812343,1540812344,1 +195712,1540812344,1540812345,1 +195713,1540812345,1540812346,1 +195714,1540812346,1540812347,1 +195715,1540812347,1540812348,1 +195716,1540812348,1540812349,1 +195717,1540812349,1540812350,1 +195718,1540812350,1540812351,1 +195719,1540812351,1540812352,1 +195720,1540812352,1540812353,1 +195721,1540812353,1540812354,1 +195722,1540812354,1540812355,1 +195723,1540812355,1540812356,1 +195724,1540812356,1540812357,1 +195725,1540812357,1540812358,1 +195726,1540812358,1540812359,1 +195727,1540812359,1540812360,1 +195728,1540812360,279596073,1 +195729,1540812361,1540812362,1 +195730,1540812362,1540812363,1 +195731,1540812363,360222688,1 +195732,1540812364,360225738,1 +195733,1540812365,973053975,1 +195734,1540812366,360216407,1 +195735,1540812367,360216351,1 +195736,1540812368,1540812369,1 +195737,1540812369,973017226,1 +195745,1540812377,1540812378,0 +195746,1540812378,1540812379,0 +195747,1540812379,155578062,0 +195748,1540812380,1540812381,0 +195749,1540812381,1540812382,0 +195750,1540812382,1540812383,0 +195751,1540812383,1540812384,0 +195752,1540812384,1540812385,0 +195753,1540812385,1540812386,0 +195754,1540812386,1540812387,0 +195755,1540812387,963987465,0 +195756,1540812388,1540812389,0 +195757,1540812389,1540812390,0 +195758,1540812390,1540812391,0 +195759,1540812391,1540812392,0 +195760,1540812392,35487997,0 +195761,1540812393,1540812394,1 +195762,1540812394,360227132,1 +195763,1540812395,360227135,1 +195764,1540812396,1540812397,1 +195765,1540812397,1540812398,1 +195766,1540812398,360227863,1 +195767,1540812399,1540812400,1 +195768,1540812400,360227482,1 +195769,1540812401,1540812402,1 +195770,1540812402,360227135,1 +195771,1540812403,1540812404,1 +195772,1540812404,360215586,1 +195773,1540812405,360227312,1 +195774,1540812406,360227600,1 +195775,1540812407,1540812408,1 +195776,1540812408,1540812409,1 +195777,1540812409,1540812410,1 +195778,1540812410,360231279,1 +195779,1540812411,1540812412,1 +195780,1540812412,1540812413,1 +195781,1540812413,600629250,1 +195782,1540812414,1540812415,1 +195783,1540812415,1540812416,1 +195784,1540812416,1540812417,1 +195785,1540812417,360227597,1 +195786,1540812418,1540812419,1 +195787,1540812419,1540812420,1 +195788,1540812420,1540812421,1 +195789,1540812421,1540812422,1 +195790,1540812422,360024126,1 +195791,1540812423,1540812424,1 +195792,1540812424,1540812425,1 +195793,1540812425,1540812426,1 +195794,1540812426,273143718,1 +195796,1540812428,1540812429,0 +195797,1540812429,1540812430,0 +195798,1540812430,1540812431,0 +195799,1540812431,155585179,0 +195800,1540812432,1540812433,1 +195801,1540812433,1540812434,1 +195802,1540812434,1540812435,1 +195803,1540812435,1540812436,1 +195804,1540812436,273143897,1 +195805,1540812437,360230603,1 +195806,1540812438,360230969,1 +195807,1540812439,1540812440,1 +195808,1540812440,360231279,1 +195809,1540812441,1540812442,1 +195810,1540812442,1540812443,1 +195811,1540812443,1540812444,1 +195812,1540812444,360231624,1 +195813,1540812445,1540812446,1 +195814,1540812446,360217752,1 +195815,1540812447,1540812448,1 +195816,1540812448,1540812449,1 +195817,1540812449,360217713,1 +195818,1540812450,360232073,0 +195819,1540812451,1540812452,0 +195820,1540812452,1540812453,0 +195821,1540812453,360232131,0 +195822,1540812454,1540812455,0 +195823,1540812455,1540812456,0 +195824,1540812456,1540812457,0 +195825,1540812457,1540812458,0 +195826,1540812458,360218756,0 +195827,1540812459,360232762,1 +195828,1540812460,1540812461,1 +195829,1540812461,360219890,1 +195830,1540812462,1540812463,1 +195831,1540812463,1540812464,1 +195832,1540812464,1540812465,1 +195833,1540812465,1540812466,1 +195834,1540812466,1540812467,1 +195835,1540812467,1540812468,1 +195836,1540812468,1540812469,1 +195837,1540812469,1540812470,1 +195838,1540812470,1540812471,1 +195839,1540812471,1540812472,1 +195840,1540812472,1540812473,1 +195841,1540812473,1540812474,1 +195842,1540812474,1540812475,1 +195843,1540812475,1540812476,1 +195844,1540812476,360233051,1 +195845,1540812477,1540812478,1 +195846,1540812478,360221296,1 +195847,1540812479,1540812480,1 +195848,1540812480,360233812,1 +195849,1540812481,360234085,1 +195850,1540812482,360234459,1 +195851,1540812483,1540812484,1 +195852,1540812484,1540812485,1 +195853,1540812485,1540812486,1 +195854,1540812486,1540812487,1 +195855,1540812487,1540812488,1 +195856,1540812488,1540812489,1 +195857,1540812489,360234481,1 +195858,1540812490,1540812491,1 +195859,1540812491,1540812492,1 +195860,1540812492,360234487,1 +195861,1540812493,1030974996,1 +195862,1540812494,1540812495,1 +195863,1540812495,1540812496,1 +195864,1540812496,1540812497,1 +195865,1540812497,360236026,1 +195866,1540812498,1540812499,1 +195867,1540812499,1540812500,1 +195868,1540812500,1540812501,1 +195869,1540812501,1540812502,1 +195870,1540812502,1540812503,1 +195871,1540812503,155866218,1 +195872,1540812504,1540812505,1 +195873,1540812505,1540812506,1 +195874,1540812506,1540812507,1 +195875,1540812507,360241349,1 +195876,1540812508,1540812509,1 +195877,1540812509,1540812510,1 +195878,1540812510,1540812511,1 +195879,1540812511,1540812512,1 +195880,1540812512,1540812513,1 +195881,1540812513,1540812514,1 +195882,1540812514,1540812515,1 +195883,1540812515,1540812516,1 +195884,1540812516,1540812517,1 +195885,1540812517,1540812518,1 +195886,1540812518,1540812519,1 +195887,1540812519,1540812520,1 +195888,1540812520,1540812521,1 +195889,1540812521,1540812522,1 +195890,1540812522,1540812523,1 +195891,1540812523,1540812524,1 +195892,1540812524,1540812525,1 +195893,1540812525,1540812526,1 +195894,1540812526,1540812527,1 +195895,1540812527,1540812528,1 +195896,1540812528,360241191,1 +195897,1540812529,1540812530,1 +195898,1540812530,1540812531,1 +195899,1540812531,1540812532,1 +195900,1540812532,1540812533,1 +195901,1540812533,360237154,1 +195902,1540812534,1540812535,1 +195903,1540812535,1540812536,1 +195904,1540812536,1540812537,1 +195905,1540812537,155866218,1 +195906,1540812538,1540812539,1 +195907,1540812539,1540812540,1 +195908,1540812540,1540812541,1 +195909,1540812541,360241636,1 +195931,1540812563,155868078,1 +196910,1540813542,360467124,0 +196967,1540813599,360467604,0 +196968,1540813600,1540813601,0 +196969,1540813601,706854285,0 +196970,1540813602,1540813603,0 +196971,1540813603,360467832,0 +196972,1540813604,360467834,0 +196975,1540813607,360469244,1 +196976,1540813608,360469483,1 +196977,1540813609,360469063,1 +196978,1540813610,360469197,1 +196979,1540813611,360468381,1 +196980,1540813612,360468331,1 +196981,1540813613,360467992,1 +196982,1540813614,360468108,1 +196983,1540813615,360468331,1 +196984,1540813616,706821907,1 +196985,1540813617,360468332,1 +196986,1540813618,360468507,1 +196987,1540813619,360469107,1 +196988,1540813620,360469061,1 +196989,1540813621,360469018,1 +196990,1540813622,360469288,1 +197148,1540813780,360469044,1 +197149,1540813781,360469345,1 +197150,1540813782,360469345,1 +197151,1540813783,1540813784,1 +197152,1540813784,360470135,1 +197204,1540813836,1540813837,1 +197205,1540813837,1540813838,1 +197206,1540813838,360469544,1 +197207,1540813839,1540813840,1 +197208,1540813840,1540813841,1 +197209,1540813841,360469548,1 +197210,1540813842,360469590,1 +197211,1540813843,353246260,1 +197213,1540813845,360469631,1 +197220,1540813852,360469889,1 +197221,1540813853,1540813854,1 +197222,1540813854,706002880,1 +197227,1540813859,360470377,1 +197228,1540813860,360470978,0 +197229,1540813861,360471733,1 +197230,1540813862,706002702,1 +197231,1540813863,360472354,1 +197232,1540813864,360727947,1 +197233,1540813865,360472487,0 +197234,1540813866,705990492,0 +197235,1540813867,1540813868,0 +197236,1540813868,360473547,0 +197237,1540813869,360473545,0 +197238,1540813870,360473806,0 +197239,1540813871,360473100,0 +197240,1540813872,360473097,0 +197241,1540813873,1540813874,0 +197242,1540813874,706821622,0 +197243,1540813875,1540813876,0 +197244,1540813876,1540813877,0 +197245,1540813877,360727836,0 +197246,1540813878,353246170,1 +197247,1540813879,1540813880,1 +197248,1540813880,706002880,1 +197249,1540813881,365122021,0 +197250,1540813882,1540813883,0 +197251,1540813883,360475371,0 +197252,1540813884,1540813885,0 +197253,1540813885,360475455,0 +197254,1540813886,360474653,0 +197255,1540813887,365122579,0 +197256,1540813888,694758725,0 +197257,1540813889,360474735,0 +197258,1540813890,360475399,1 +197259,1540813891,360475315,0 +197260,1540813892,1540813893,0 +197261,1540813893,360475278,0 +197262,1540813894,360475277,0 +197263,1540813895,360475339,0 +197264,1540813896,360475452,0 +197265,1540813897,1540813898,0 +197266,1540813898,1540813899,0 +197267,1540813899,1540813900,0 +197268,1540813900,360475563,0 +197269,1540813901,1540813902,0 +197270,1540813902,360475785,0 +197271,1540813903,360475521,0 +197272,1540813904,360475229,0 +197273,1540813905,360475885,0 +197274,1540813906,1236188097,1 +197275,1540813907,694820213,0 +197276,1540813908,694820205,0 +197277,1540813909,360476358,0 +197278,1540813910,360476549,1 +197279,1540813911,360476863,0 +197280,1540813912,984752628,1 +197281,1540813913,1540813914,1 +197282,1540813914,984752891,1 +197283,1540813915,1540813916,1 +197284,1540813916,984752920,1 +197285,1540813917,360477184,0 +197286,1540813918,656189124,0 +197287,1540813919,360477147,0 +197288,1540813920,360477223,1 +197289,1540813921,360477261,1 +197290,1540813922,1139714829,0 +197291,1540813923,360476344,0 +198340,1540814972,1540814973,1 +198341,1540814973,1540814974,1 +198342,1540814974,1540814975,1 +198343,1540814975,1239786686,1 +198344,1540814976,360713891,0 +198345,1540814977,360713984,0 +198356,1540814988,1540814989,1 +198357,1540814989,360714800,1 +198370,1540815002,1540815003,1 +198371,1540815003,360716311,1 +198372,1540815004,360716731,1 +198373,1540815005,1540815006,0 +198374,1540815006,360716814,0 +198375,1540815007,360716552,0 +198376,1540815008,1540815009,1 +198377,1540815009,1540815010,1 +198378,1540815010,360715006,1 +198379,1540815011,1540815012,1 +198380,1540815012,360717010,1 +198381,1540815013,1540815014,0 +198382,1540815014,1540815015,0 +198383,1540815015,1540815016,0 +198384,1540815016,1540815017,0 +198385,1540815017,360717180,0 +198386,1540815018,1540815019,0 +198387,1540815019,360718557,0 +198388,1540815020,1540815021,0 +198389,1540815021,360716820,0 +198390,1540815022,360714804,1 +198399,1540815031,1540815032,1 +198404,1540815036,360718527,0 +198410,1540815042,360719526,1 +198413,1540815045,360719961,0 +198414,1540815046,360720095,0 +198415,1540815047,360719961,1 +198416,1540815048,360720195,1 +198417,1540815049,745988707,0 +198418,1540815050,360720623,0 +198419,1540815051,1540815052,0 +198420,1540815052,360720525,0 +198421,1540815053,360720581,1 +198422,1540815054,1540815055,1 +198423,1540815055,1540815056,1 +198424,1540815056,745988389,1 +198425,1540815057,1540815058,0 +198426,1540815058,360720713,0 +198427,1540815059,1540815060,1 +198428,1540815060,1540815061,1 +198429,1540815061,1540815062,1 +198430,1540815062,353245716,1 +198431,1540815063,1540815064,0 +198432,1540815064,695552903,0 +198433,1540815065,360727951,0 +198434,1540815066,360471854,0 +198435,1540815067,1540815068,0 +198436,1540815068,353244899,0 +198437,1540815069,1540815070,0 +198438,1540815070,360472354,0 +198439,1540815071,360473621,0 +198440,1540815072,353246120,0 +198441,1540815073,353246125,0 +198442,1540815074,360474041,0 +198443,1540815075,360728394,1 +198444,1540815076,1540815077,1 +198445,1540815077,360728403,1 +198446,1540815078,1540815079,1 +198447,1540815079,1540815080,1 +198448,1540815080,705971032,1 +198449,1540815081,1540815082,1 +198450,1540815082,705971035,1 +198451,1540815083,1540815084,1 +198452,1540815084,360728176,1 +198453,1540815085,360729807,1 +198454,1540815086,360730443,0 +198455,1540815087,360730443,1 +198456,1540815088,360730174,1 +198457,1540815089,1540815090,1 +198458,1540815090,360730912,1 +198459,1540815091,705060397,1 +198460,1540815092,360731050,0 +198461,1540815093,1540815094,0 +198462,1540815094,360731155,0 +198463,1540815095,1540815096,0 +198464,1540815096,360731219,0 +198465,1540815097,1540815098,0 +198466,1540815098,360730830,0 +198467,1540815099,361193913,0 +198468,1540815100,746691518,0 +198469,1540815101,360731407,0 +198470,1540815102,361196370,1 +198471,1540815103,705066617,1 +199290,1540815922,361193309,1 +199291,1540815923,1540815924,1 +199292,1540815924,361194122,1 +199293,1540815925,361194797,1 +199294,1540815926,361195695,1 +199295,1540815927,361195395,1 +199296,1540815928,1540815929,0 +199297,1540815929,736618839,0 +199298,1540815930,361196285,0 +199299,1540815931,361196747,0 +199300,1540815932,360731668,1 +199301,1540815933,746691498,1 +199302,1540815934,1540815935,1 +199303,1540815935,361197140,1 +199304,1540815936,745990617,1 +199305,1540815937,1540815938,0 +199306,1540815938,792054055,0 +199307,1540815939,361198461,1 +199308,1540815940,797375721,1 +199309,1540815941,361198161,1 +199310,1540815942,338485978,1 +199311,1540815943,361198788,1 +199312,1540815944,361198819,1 +199313,1540815945,797375736,0 +199314,1540815946,361198931,1 +199315,1540815947,361199477,1 +199316,1540815948,361199479,1 +199317,1540815949,1540815950,1 +199318,1540815950,1540815951,1 +199319,1540815951,937216123,1 +199320,1540815952,361199497,1 +199321,1540815953,1540815954,1 +199322,1540815954,361199499,1 +199323,1540815955,938140826,1 +199324,1540815956,1540815957,1 +199325,1540815957,361199622,1 +199326,1540815958,361199623,1 +199327,1540815959,361199746,1 +199328,1540815960,1540815961,1 +199329,1540815961,937216277,1 +199330,1540815962,793781779,1 +199331,1540815963,361199839,1 +199332,1540815964,793781785,1 +199333,1540815965,1540815966,1 +199334,1540815966,793781731,1 +199335,1540815967,1540815968,1 +199336,1540815968,361200011,1 +199337,1540815969,359999824,0 +199338,1540815970,967241205,0 +199339,1540815971,1540815972,1 +199340,1540815972,1540815973,1 +199341,1540815973,361407397,1 +199342,1540815974,361227927,1 +199343,1540815975,1540815976,0 +199344,1540815976,1540815977,0 +199345,1540815977,1540815978,0 +199346,1540815978,1540815979,0 +199347,1540815979,1540815980,0 +199348,1540815980,1540815981,0 +199349,1540815981,1540815982,0 +199350,1540815982,1540815983,0 +199351,1540815983,1540815984,0 +199352,1540815984,1540815985,0 +199353,1540815985,1540815986,0 +199354,1540815986,1540815987,0 +199355,1540815987,1540815988,0 +199356,1540815988,1540815989,0 +199357,1540815989,1540815990,0 +199358,1540815990,1540815991,0 +199359,1540815991,1540815992,0 +199360,1540815992,361224781,0 +199361,1540815993,1540815994,0 +199362,1540815994,1540815995,0 +199363,1540815995,1540815996,0 +199364,1540815996,1540815997,0 +199365,1540815997,1540815998,0 +199366,1540815998,1540815999,0 +199367,1540815999,1540816000,0 +199368,1540816000,152940375,0 +199369,1540816001,1540816002,0 +199370,1540816002,1540816003,0 +199371,1540816003,1540816004,0 +199372,1540816004,1540816005,0 +199373,1540816005,1540816006,0 +199374,1540816006,1540816007,0 +199375,1540816007,1540816008,0 +199376,1540816008,1540816009,0 +199377,1540816009,1540816010,0 +199378,1540816010,1540816011,0 +199379,1540816011,361227771,0 +199443,1540816075,1540816076,1 +199444,1540816076,1540816077,1 +199445,1540816077,1540816078,1 +199446,1540816078,363984889,1 +199447,1540816079,1540816080,0 +199448,1540816080,1540816081,0 +199449,1540816081,1540816082,0 +199450,1540816082,1540816083,0 +199451,1540816083,1540816084,0 +199452,1540816084,1540816085,0 +199453,1540816085,1540816086,0 +199454,1540816086,1540816087,0 +199455,1540816087,1540816088,0 +199456,1540816088,153875447,0 +199457,1540816089,1540816090,0 +199458,1540816090,1540816091,0 +199459,1540816091,361227771,0 +199460,1540816092,1540816093,1 +199461,1540816093,152939864,1 +199462,1540816094,1540816095,1 +199463,1540816095,792045741,1 +199464,1540816096,1540816097,1 +199465,1540816097,1540816098,1 +199466,1540816098,1540816099,1 +199467,1540816099,1540816100,1 +199468,1540816100,559556410,1 +199469,1540816101,792045759,1 +199470,1540816102,361409658,1 +199471,1540816103,361409660,1 +199472,1540816104,1540816105,1 +199473,1540816105,361407935,1 +199474,1540816106,1540816107,1 +199475,1540816107,1540816108,1 +199476,1540816108,1540816109,1 +199477,1540816109,1540816110,1 +199478,1540816110,1540816111,1 +199479,1540816111,1540816112,1 +199480,1540816112,1540816113,1 +199481,1540816113,1540816114,1 +199482,1540816114,361407943,1 +199483,1540816115,1540816116,0 +199484,1540816116,361227781,0 +199485,1540816117,1540816118,0 +199486,1540816118,1540816119,0 +199487,1540816119,1540816120,0 +199488,1540816120,1540816121,0 +199489,1540816121,1540816122,0 +199490,1540816122,1540816123,0 +199491,1540816123,1540816124,0 +199492,1540816124,936804372,0 +199493,1540816125,1540816126,1 +199494,1540816126,1540816127,1 +199495,1540816127,1540816128,1 +199496,1540816128,1540816129,1 +199497,1540816129,152801180,1 +199498,1540816130,1540816131,1 +199499,1540816131,1540816132,1 +199500,1540816132,1540816133,1 +199501,1540816133,361424352,1 +199502,1540816134,1540816135,0 +199503,1540816135,801467951,0 +199504,1540816136,1540816137,1 +199505,1540816137,1540816138,1 +199506,1540816138,1540816139,1 +199507,1540816139,1540816140,1 +199508,1540816140,792045747,1 +199509,1540816141,361434467,0 +199510,1540816142,1540816143,0 +199511,1540816143,1093091225,0 +199512,1540816144,597897194,0 +199513,1540816145,1540816146,0 +199514,1540816146,361434518,0 +199515,1540816147,583222422,0 +199516,1540816148,360728403,0 +199517,1540816149,792056469,1 +199518,1540816150,1540816151,0 +199519,1540816151,1540816152,0 +199520,1540816152,361442462,0 +199521,1540816153,792051103,0 +199522,1540816154,1540816155,0 +199523,1540816155,1540816156,0 +199524,1540816156,1540816157,0 +199525,1540816157,1540816158,0 +199526,1540816158,1540816159,0 +199527,1540816159,1540816160,0 +199528,1540816160,1540816161,0 +199529,1540816161,581286086,0 +199530,1540816162,1540816163,0 +199531,1540816163,1540816164,0 +199532,1540816164,361442902,0 +199533,1540816165,1540816166,0 +199534,1540816166,1540816167,0 +199535,1540816167,1540816168,0 +199536,1540816168,1540816169,0 +199537,1540816169,1540816170,0 +199538,1540816170,1540816171,0 +199539,1540816171,1540816172,0 +199540,1540816172,1540816173,0 +199541,1540816173,1540816174,0 +199542,1540816174,36244147,0 +199543,1540816175,1540816176,0 +199544,1540816176,1540816177,0 +199545,1540816177,1540816178,0 +199546,1540816178,1540816179,0 +199547,1540816179,1540816180,0 +199548,1540816180,1540816181,0 +199549,1540816181,1540816182,0 +199550,1540816182,361444006,0 +199551,1540816183,1540816184,0 +199552,1540816184,1540816185,0 +199553,1540816185,1540816186,0 +199554,1540816186,1540816187,0 +199555,1540816187,1540816188,0 +199556,1540816188,1540816189,0 +199557,1540816189,1540816190,0 +199558,1540816190,1540816191,0 +199559,1540816191,1540816192,0 +199560,1540816192,1540816193,0 +199561,1540816193,1540816194,0 +199562,1540816194,1540816195,0 +199563,1540816195,361444012,0 +199564,1540816196,361444085,0 +199565,1540816197,1540816198,0 +199566,1540816198,1540816199,0 +199567,1540816199,1540816200,0 +199568,1540816200,1540816201,0 +199569,1540816201,1540816202,0 +199570,1540816202,1540816203,0 +199571,1540816203,1540816204,0 +199572,1540816204,361444098,0 +199573,1540816205,1540816206,0 +199574,1540816206,1540816207,0 +199575,1540816207,36244146,0 +199576,1540816208,1540816209,0 +199577,1540816209,1540816210,0 +199578,1540816210,1540816211,0 +199579,1540816211,36244147,0 +199580,1540816212,36244148,0 +199581,1540816213,152943683,0 +199582,1540816214,683296017,0 +199583,1540816215,1540816216,0 +199584,1540816216,361442460,0 +199585,1540816217,1540816218,0 +199586,1540816218,361442465,0 +199587,1540816219,361442466,0 +199588,1540816220,678178650,1 +199589,1540816221,1540816222,0 +199590,1540816222,683295969,0 +199591,1540816223,1540816224,0 +199592,1540816224,1540816225,0 +199593,1540816225,1540816226,0 +199594,1540816226,1540816227,0 +199595,1540816227,361447140,0 +199596,1540816228,361447140,0 +199597,1540816229,1540816230,0 +199598,1540816230,579786595,0 +199599,1540816231,577419381,1 +199600,1540816232,1540816233,0 +199601,1540816233,1540816234,0 +199602,1540816234,1540816235,0 +199603,1540816235,1540816236,0 +199604,1540816236,1540816237,0 +199605,1540816237,246588462,0 +199606,1540816238,1540816239,0 +199607,1540816239,1540816240,0 +199608,1540816240,1540816241,0 +199609,1540816241,1540816242,0 +199610,1540816242,1540816243,0 +199611,1540816243,1540816244,0 +199612,1540816244,1540816245,0 +199613,1540816245,792051090,0 +199614,1540816246,1540816247,0 +199615,1540816247,1540816248,0 +199616,1540816248,1540816249,0 +199617,1540816249,1540816250,0 +199618,1540816250,1540816251,0 +199619,1540816251,1540816252,0 +199620,1540816252,1540816253,0 +199621,1540816253,1540816254,0 +199622,1540816254,1540816255,0 +199623,1540816255,36245082,0 +203527,1540820159,1540820160,0 +203528,1540820160,1540820161,0 +203529,1540820161,1540820162,0 +203530,1540820162,1540820163,0 +203531,1540820163,1540820164,0 +203532,1540820164,1540820165,0 +203533,1540820165,1540820166,0 +203534,1540820166,246588466,0 +203847,1540820479,972481906,1 +203848,1540820480,972481671,1 +203849,1540820481,1540820482,1 +203850,1540820482,1540820483,1 +203851,1540820483,1540820484,1 +203852,1540820484,1540820485,1 +203853,1540820485,972481699,1 +203854,1540820486,1540820487,1 +203855,1540820487,1540820488,1 +203856,1540820488,1540820489,1 +203857,1540820489,1540820490,1 +203858,1540820490,1540820491,1 +203859,1540820491,1540820492,1 +203860,1540820492,972481704,1 +203861,1540820493,1540820494,1 +203862,1540820494,1540820495,1 +203863,1540820495,1540820496,1 +203864,1540820496,1540820497,1 +203865,1540820497,972481641,1 +203866,1540820498,972481975,1 +203867,1540820499,576508600,1 +203868,1540820500,363970702,1 +203869,1540820501,1540820502,1 +203870,1540820502,1540820503,1 +203871,1540820503,1540820504,1 +203872,1540820504,1540820505,1 +203873,1540820505,1540820506,1 +203874,1540820506,1540820507,1 +203875,1540820507,363971335,1 +203876,1540820508,363971068,1 +203877,1540820509,279591280,1 +203878,1540820510,363971068,1 +203879,1540820511,363973128,1 +203880,1540820512,1540820513,1 +203881,1540820513,363973219,1 +203882,1540820514,1540820515,1 +203883,1540820515,363971710,1 +203884,1540820516,363971715,1 +203885,1540820517,363971828,1 +203886,1540820518,1540820519,1 +203887,1540820519,1540820520,1 +203888,1540820520,974031117,1 +203889,1540820521,1540820522,1 +203890,1540820522,974031112,1 +203891,1540820523,363972283,1 +203892,1540820524,1540820525,1 +203893,1540820525,1540820526,1 +203894,1540820526,363971828,1 +203895,1540820527,363972022,1 +203896,1540820528,279591059,1 +203897,1540820529,1540820530,1 +203898,1540820530,360207366,1 +203899,1540820531,549787401,1 +203900,1540820532,974031058,1 +203901,1540820533,1540820534,1 +203902,1540820534,363973123,1 +203903,1540820535,363973219,1 +203904,1540820536,1540820537,1 +203905,1540820537,363973302,1 +203906,1540820538,973982981,1 +203907,1540820539,363973306,1 +203908,1540820540,973983241,1 +203909,1540820541,363973310,1 +203910,1540820542,360189343,1 +203911,1540820543,1540820544,1 +203912,1540820544,1540820545,1 +203913,1540820545,1540820546,1 +203914,1540820546,363973416,1 +203915,1540820547,360189542,1 +203916,1540820548,363973496,1 +203917,1540820549,1540820550,1 +203918,1540820550,1540820551,1 +203919,1540820551,279591120,1 +203920,1540820552,363973757,1 +203921,1540820553,363973496,1 +203922,1540820554,973983698,1 +203923,1540820555,973983115,1 +203924,1540820556,1540820557,1 +203925,1540820557,973982981,1 +203926,1540820558,363976091,1 +207689,1540824321,1540824322,0 +207690,1540824322,353244213,0 +207691,1540824323,1540824324,0 +207692,1540824324,695556374,0 +207693,1540824325,1540824326,0 +207694,1540824326,1540824327,0 +207695,1540824327,1540824328,0 +207696,1540824328,1540824329,0 +207697,1540824329,1540824330,0 +207698,1540824330,1540824331,0 +207699,1540824331,1305700915,0 +207700,1540824332,36645001,0 +207701,1540824333,695553009,1 +207702,1540824334,597692639,1 +207703,1540824335,694738293,1 +207704,1540824336,365122021,1 +207705,1540824337,365118708,0 +207706,1540824338,1540824339,0 +207707,1540824339,338484231,0 +207708,1540824340,1540824341,0 +207709,1540824341,1540824342,0 +207710,1540824342,1540824343,0 +207711,1540824343,1540824344,0 +207712,1540824344,365118707,0 +207713,1540824345,360473964,0 +207714,1540824346,365119239,0 +207715,1540824347,360474739,0 +207716,1540824348,365119686,0 +207717,1540824349,365119839,0 +207718,1540824350,365120338,1 +207719,1540824351,1540824352,0 +207720,1540824352,1540824353,0 +207721,1540824353,562865725,0 +207722,1540824354,1540824355,0 +207723,1540824355,365122021,0 +207724,1540824356,1493229599,0 +207725,1540824357,365970495,0 +208239,1540824871,353243056,0 +208240,1540824872,365309031,0 +208241,1540824873,1540824874,0 +208242,1540824874,1540824875,0 +208243,1540824875,360476335,0 +208244,1540824876,1540824877,0 +208245,1540824877,1540824878,0 +208246,1540824878,360476528,0 +208247,1540824879,294145226,0 +208309,1540824941,365378192,1 +208310,1540824942,1540824943,1 +208311,1540824943,365378203,1 +208312,1540824944,1540824945,1 +208313,1540824945,1172615090,1 +208314,1540824946,1540824947,1 +208315,1540824947,1540824948,1 +208316,1540824948,1540824949,1 +208317,1540824949,1540824950,1 +208318,1540824950,1540824951,1 +208319,1540824951,1540824952,1 +208320,1540824952,1540824953,1 +208321,1540824953,1540824954,1 +208322,1540824954,1540824955,1 +208323,1540824955,1540824956,1 +208324,1540824956,1540824957,1 +208325,1540824957,1540824958,1 +208326,1540824958,1540824959,1 +208327,1540824959,1540824960,1 +208328,1540824960,1540824961,1 +208329,1540824961,1172574059,1 +208330,1540824962,1540824963,1 +208331,1540824963,1540824964,1 +208332,1540824964,1540824965,1 +208333,1540824965,1175941168,1 +208334,1540824966,1175941320,1 +208335,1540824967,1540824968,1 +208336,1540824968,1540824969,1 +208337,1540824969,1540824970,1 +208338,1540824970,1540824971,1 +208339,1540824971,1540824972,1 +208340,1540824972,1540824973,1 +208341,1540824973,1540824974,1 +208342,1540824974,1540824975,1 +208343,1540824975,1175941365,1 +208344,1540824976,1540824977,1 +208345,1540824977,1540824978,1 +208346,1540824978,1540824979,1 +208347,1540824979,1540824980,1 +208348,1540824980,1540824981,1 +208349,1540824981,1540824982,1 +208350,1540824982,1540824983,1 +208351,1540824983,1540824984,1 +208352,1540824984,1540824985,1 +208353,1540824985,1540824986,1 +208354,1540824986,1540824987,1 +208355,1540824987,1540824988,1 +208356,1540824988,1540824989,1 +208357,1540824989,1540824990,1 +208358,1540824990,1540824991,1 +208359,1540824991,1540824992,1 +208360,1540824992,1175946886,1 +208361,1540824993,1540824994,1 +208362,1540824994,1540824995,1 +208363,1540824995,1540824996,1 +208364,1540824996,1540824997,1 +208365,1540824997,1540824998,1 +208366,1540824998,1540824999,1 +208367,1540824999,1540825000,1 +208368,1540825000,1172666072,1 +208369,1540825001,1540825002,1 +208370,1540825002,1540825003,1 +208371,1540825003,1540825004,1 +208372,1540825004,1540825005,1 +208373,1540825005,1540825006,1 +208374,1540825006,1172628276,1 +208375,1540825007,1540825008,1 +208376,1540825008,1540825009,1 +208377,1540825009,1540825010,1 +208434,1540825066,1037804847,1 +208435,1540825067,1540825068,1 +208436,1540825068,365388273,1 +208437,1540825069,1540825070,1 +208438,1540825070,1540825071,1 +208439,1540825071,365388278,1 +208440,1540825072,1540825073,1 +208441,1540825073,1540825074,1 +208442,1540825074,1540825075,1 +208443,1540825075,1540825076,1 +208444,1540825076,1540825077,1 +208445,1540825077,1540825078,1 +208446,1540825078,365388286,1 +210994,1540827626,1540827627,1 +210995,1540827627,1540827628,1 +210996,1540827628,1540827629,1 +210997,1540827629,1540827630,1 +210998,1540827630,365925014,1 +210999,1540827631,1540827632,1 +211000,1540827632,1540827633,1 +211001,1540827633,1540827634,1 +211002,1540827634,1540827635,1 +211003,1540827635,797196065,1 +211004,1540827636,1540827637,1 +211005,1540827637,1540827638,1 +211006,1540827638,1540827639,1 +211007,1540827639,1540827640,1 +211008,1540827640,1540827641,1 +211009,1540827641,1540827642,1 +211010,1540827642,1540827643,1 +211011,1540827643,1540827644,1 +211012,1540827644,1540827645,1 +211013,1540827645,1540827646,1 +211014,1540827646,1540827647,1 +211015,1540827647,1540827648,1 +211016,1540827648,365311002,1 +211017,1540827649,797159527,1 +211018,1540827650,365925632,1 +211019,1540827651,1540827652,1 +211020,1540827652,1540827653,1 +211021,1540827653,797175462,1 +211022,1540827654,1343090479,1 +211023,1540827655,1540827656,1 +211024,1540827656,1540827657,1 +211025,1540827657,1540827658,1 +211026,1540827658,1540827659,1 +211027,1540827659,1540827660,1 +211028,1540827660,1540827661,1 +211029,1540827661,1540827662,1 +211030,1540827662,1540827663,1 +211031,1540827663,1540827664,1 +211032,1540827664,1540827665,1 +211033,1540827665,1540827666,1 +211034,1540827666,1540827667,1 +211035,1540827667,1540827668,1 +211036,1540827668,1540827669,1 +211037,1540827669,1343054372,1 +211038,1540827670,1540827671,1 +211039,1540827671,1343055179,1 +211040,1540827672,1343009871,1 +211041,1540827673,1343039951,1 +211042,1540827674,1343044019,1 +211043,1540827675,1540827676,0 +211044,1540827676,1540827677,0 +211045,1540827677,561406804,0 +211046,1540827678,1540827679,0 +211047,1540827679,561407126,0 +211048,1540827680,1540827681,0 +211049,1540827681,365120903,0 +211050,1540827682,365120906,1 +211051,1540827683,1540827684,1 +211052,1540827684,365970555,1 +211053,1540827685,365970638,0 +211054,1540827686,365970526,0 +211055,1540827687,365970557,0 +211056,1540827688,365970584,0 +215336,1540831968,1540831969,1 +215337,1540831969,372789204,1 +215338,1540831970,1540831971,1 +215339,1540831971,1540831972,1 +215340,1540831972,1540831973,1 +215341,1540831973,372786538,1 +215342,1540831974,1540831975,1 +215343,1540831975,372786481,1 +215344,1540831976,1540831977,1 +215345,1540831977,1540831978,1 +215346,1540831978,1540831979,1 +215347,1540831979,372787664,1 +215348,1540831980,372787085,1 +215349,1540831981,600924197,0 +215350,1540831982,1540831983,0 +215351,1540831983,1540831984,0 +215352,1540831984,1540831985,0 +215353,1540831985,1540831986,0 +215354,1540831986,1540831987,0 +215355,1540831987,1540831988,0 +215356,1540831988,84568354,0 +216887,1540833519,1540833520,0 +216888,1540833520,417278006,0 +216889,1540833521,417278833,1 +216890,1540833522,745090390,0 +216891,1540833523,745090852,0 +216892,1540833524,1540833525,0 +216893,1540833525,600924052,0 +216894,1540833526,417279716,1 +216895,1540833527,1540833528,0 +216896,1540833528,1540833529,0 +216897,1540833529,603748683,0 +216925,1540833557,1540833558,1 +216926,1540833558,1540833559,1 +216927,1540833559,1540833560,1 +216928,1540833560,1540833561,1 +216929,1540833561,1540833562,1 +216930,1540833562,418771177,1 +216931,1540833563,972316145,1 +216932,1540833564,1540833565,1 +216933,1540833565,1540833566,1 +216934,1540833566,966639633,1 +216935,1540833567,966639659,1 +216936,1540833568,1540833569,1 +216937,1540833569,418771174,1 +216938,1540833570,360012912,1 +216939,1540833571,418771192,1 +216940,1540833572,1540833573,1 +216941,1540833573,1540833574,1 +216942,1540833574,583433376,1 +216943,1540833575,1540833576,1 +216944,1540833576,583433378,1 +216945,1540833577,418771193,1 +216946,1540833578,973983737,1 +216947,1540833579,1540833580,1 +216948,1540833580,972315864,1 +216949,1540833581,1540833582,1 +216950,1540833582,1540833583,1 +216951,1540833583,1540833584,1 +216952,1540833584,1540833585,1 +216953,1540833585,1540833586,1 +216954,1540833586,1540833587,1 +216955,1540833587,360189339,1 +216956,1540833588,418771201,1 +217025,1540833657,428468066,1 +217026,1540833658,1540833659,0 +217027,1540833659,429286579,0 +217028,1540833660,429286582,0 +217029,1540833661,1540833662,0 +217030,1540833662,429286584,0 +217031,1540833663,1540833664,0 +217032,1540833664,716888435,0 +217294,1540833926,1540833927,0 +217295,1540833927,1540833928,0 +217296,1540833928,1540833929,0 +217297,1540833929,1540833930,0 +217298,1540833930,1540833931,0 +217299,1540833931,1540833932,0 +217300,1540833932,1540833933,0 +217301,1540833933,1540833934,0 +217302,1540833934,1540833935,0 +217303,1540833935,445393431,0 +217515,1540834147,360718711,0 +217516,1540834148,360719138,0 +217517,1540834149,1540834150,1 +217518,1540834150,1540834151,1 +217519,1540834151,1540834152,1 +217520,1540834152,1540834153,1 +217521,1540834153,1540834154,1 +217522,1540834154,1540834155,1 +217523,1540834155,1540834156,1 +217524,1540834156,1540834157,1 +217525,1540834157,1540834158,1 +217526,1540834158,1540834159,1 +217527,1540834159,1540834160,1 +217528,1540834160,1540834161,1 +217529,1540834161,1540834162,1 +217530,1540834162,1540834163,1 +217531,1540834163,1540834164,1 +217532,1540834164,1540834165,1 +217533,1540834165,1540834166,1 +217534,1540834166,1540834167,1 +217535,1540834167,1540834168,1 +217536,1540834168,1540834169,1 +217537,1540834169,457230371,1 +217538,1540834170,1540834171,1 +217583,1540834215,1540834216,0 +217584,1540834216,745091042,0 +217585,1540834217,793385723,0 +217586,1540834218,457240513,0 +217587,1540834219,1540834220,0 +217588,1540834220,1540834221,0 +217589,1540834221,286537369,0 +217590,1540834222,294253784,1 +217591,1540834223,1540834224,0 +217592,1540834224,1540834225,0 +217593,1540834225,1540834226,0 +217594,1540834226,1540834227,0 +217595,1540834227,457248414,0 +217596,1540834228,1540834229,0 +217597,1540834229,1540834230,0 +217598,1540834230,1540834231,0 +217599,1540834231,360719402,0 +217600,1540834232,286537125,1 +217601,1540834233,745985492,1 +217602,1540834234,38842545,0 +217603,1540834235,1540834236,0 +217604,1540834236,1540834237,0 +217605,1540834237,1540834238,0 +217606,1540834238,457240513,0 +217607,1540834239,1540834240,0 +217608,1540834240,1540834241,0 +217609,1540834241,457421308,0 +217610,1540834242,1540834243,0 +217611,1540834243,1540834244,0 +217612,1540834244,360716628,0 +217616,1540834248,360717317,0 +217948,1540834580,1540834581,0 +217949,1540834581,1540834582,0 +217950,1540834582,1540834583,0 +217951,1540834583,462754210,0 +218364,1540834996,1540834997,0 +218365,1540834997,1540834998,0 +218366,1540834998,1540834999,0 +218367,1540834999,1540835000,0 +218368,1540835000,1540835001,0 +218369,1540835001,1540835002,0 +218370,1540835002,1540835003,0 +218371,1540835003,1540835004,0 +218372,1540835004,566679830,0 +218373,1540835005,1540835006,0 +218374,1540835006,1540835007,0 +218375,1540835007,1540835008,0 +218376,1540835008,1540835009,0 +218377,1540835009,1540835010,0 +218378,1540835010,1540835011,0 +218379,1540835011,1540835012,0 +218380,1540835012,1540835013,0 +218381,1540835013,1540835014,0 +218382,1540835014,475012901,0 +218383,1540835015,1540835016,0 +218384,1540835016,1540835017,0 +218385,1540835017,1540835018,0 +218386,1540835018,475013808,0 +218387,1540835019,1540835020,1 +218388,1540835020,475012901,1 +218389,1540835021,1540835022,0 +218390,1540835022,1540835023,0 +218391,1540835023,1540835024,0 +218392,1540835024,1540835025,0 +218393,1540835025,1540835026,0 +218394,1540835026,1540835027,0 +218395,1540835027,1540835028,0 +218396,1540835028,1540835029,0 +218397,1540835029,939569799,0 +218398,1540835030,1540835031,0 +218399,1540835031,1540835032,0 +218400,1540835032,1540835033,0 +218401,1540835033,1540835034,0 +218402,1540835034,1540835035,0 +218403,1540835035,1540835036,0 +218404,1540835036,1540835037,0 +218405,1540835037,1540835038,0 +218406,1540835038,360015838,0 +220574,1540837206,509726746,1 +220578,1540837210,1540837211,1 +220579,1540837211,1540837212,1 +220580,1540837212,1540837213,1 +220581,1540837213,509730716,1 +220582,1540837214,558986653,1 +220583,1540837215,509822990,1 +220595,1540837227,1540837228,0 +220596,1540837228,363989204,0 +220597,1540837229,509801624,0 +220598,1540837230,363989215,1 +220613,1540837245,1540837246,0 +220614,1540837246,559494761,0 +220615,1540837247,1540837248,1 +220616,1540837248,1540837249,1 +220617,1540837249,510958216,1 +220618,1540837250,510958263,1 +220638,1540837270,1540837271,1 +220639,1540837271,510958707,1 +220721,1540837353,512543929,1 +220722,1540837354,512543943,1 +220723,1540837355,512543946,1 +220724,1540837356,1540837357,1 +220725,1540837357,1540837358,1 +220726,1540837358,512543951,1 +220727,1540837359,512543914,1 +220728,1540837360,559554572,1 +220729,1540837361,512543957,1 +220730,1540837362,512543967,1 +220731,1540837363,512543970,1 +220732,1540837364,1540837365,1 +220733,1540837365,512543974,1 +220734,1540837366,512543971,1 +221451,1540838083,1540838084,0 +221452,1540838084,352725257,0 +221453,1540838085,352725111,0 +221454,1540838086,352724109,0 +221455,1540838087,175702585,0 +221456,1540838088,175702594,0 +221457,1540838089,1540838090,0 +221458,1540838090,1540838091,0 +221459,1540838091,1540838092,0 +221460,1540838092,1540838093,0 +221461,1540838093,597692690,0 +221662,1540838294,272499028,1 +221663,1540838295,600919186,1 +221664,1540838296,1540838297,1 +221665,1540838297,523552911,1 +221666,1540838298,523552914,1 +221667,1540838299,1540838300,1 +221668,1540838300,1540838301,1 +221669,1540838301,1540838302,1 +221670,1540838302,984634444,1 +221671,1540838303,1540838304,1 +221672,1540838304,523552923,1 +221673,1540838305,523552926,1 +221674,1540838306,1540838307,1 +221675,1540838307,1540838308,1 +221676,1540838308,1540838309,1 +221677,1540838309,737656394,1 +221919,1540838551,1540838552,1 +221920,1540838552,527804364,1 +221921,1540838553,1540838554,1 +221922,1540838554,1540838555,1 +221923,1540838555,1540838556,1 +221924,1540838556,527804372,1 +221925,1540838557,1540838558,1 +221926,1540838558,527804390,1 +221927,1540838559,1540838560,1 +221928,1540838560,527804393,1 +221929,1540838561,1540838562,1 +221930,1540838562,1540838563,1 +221931,1540838563,527804397,1 +221932,1540838564,1540838565,1 +221933,1540838565,527804400,1 +221934,1540838566,1540838567,1 +221935,1540838567,527804385,1 +221936,1540838568,1540838569,1 +221937,1540838569,1540838570,1 +221938,1540838570,1540838571,1 +221939,1540838571,527804407,1 +221940,1540838572,1540838573,1 +221941,1540838573,1540838574,1 +221942,1540838574,559494772,1 +221943,1540838575,1540838576,1 +221944,1540838576,1540838577,1 +221945,1540838577,1540838578,1 +221946,1540838578,527804439,1 +221947,1540838579,1540838580,1 +221948,1540838580,1540838581,1 +221949,1540838581,527804384,1 +221950,1540838582,1540838583,1 +221951,1540838583,1540838584,1 +221952,1540838584,1540838585,1 +221953,1540838585,575177978,1 +221954,1540838586,1540838587,1 +221955,1540838587,1540838588,1 +221956,1540838588,510957511,1 +221957,1540838589,1540838590,1 +221958,1540838590,527804416,1 +221959,1540838591,1540838592,1 +221960,1540838592,1540838593,1 +221961,1540838593,1540838594,1 +221962,1540838594,527804413,1 +221963,1540838595,510960690,1 +221964,1540838596,1540838597,1 +221965,1540838597,527804461,1 +221966,1540838598,527804383,1 +221967,1540838599,527804695,1 +221968,1540838600,527804647,1 +221969,1540838601,1540838602,1 +221970,1540838602,527804386,1 +221971,1540838603,527804460,1 +221972,1540838604,527804473,1 +221973,1540838605,527804703,1 +221974,1540838606,528489683,1 +221975,1540838607,528489634,1 +221976,1540838608,360011306,0 +221977,1540838609,1540838610,0 +221978,1540838610,1540838611,0 +221979,1540838611,1540838612,0 +221980,1540838612,1540838613,0 +221981,1540838613,566679118,0 +221982,1540838614,528489749,0 +221983,1540838615,528489780,0 +221984,1540838616,1540838617,0 +221985,1540838617,528489785,0 +221986,1540838618,528489802,0 +221987,1540838619,1540838620,1 +221988,1540838620,528505105,1 +221989,1540838621,528505111,1 +222314,1540838946,1540838947,0 +222315,1540838947,536579208,0 +222316,1540838948,536579202,0 +222317,1540838949,1540838950,0 +222318,1540838950,1540838951,0 +222319,1540838951,536579195,0 +222320,1540838952,575190278,0 +222321,1540838953,575190243,0 +222322,1540838954,1540838955,0 +222323,1540838955,1540838956,0 +222324,1540838956,1540838957,0 +222325,1540838957,575189658,0 +222326,1540838958,566679103,0 +222327,1540838959,1540838960,1 +222328,1540838960,536578912,1 +222329,1540838961,536579336,1 +222330,1540838962,1540838963,1 +222331,1540838963,1540838964,1 +222332,1540838964,528490485,1 +222333,1540838965,1540838966,1 +222334,1540838966,536580047,1 +222335,1540838967,1540838968,1 +222336,1540838968,536580126,1 +222337,1540838969,1540838970,1 +222338,1540838970,558986427,1 +222339,1540838971,558986648,1 +222340,1540838972,1540838973,1 +222341,1540838973,1540838974,1 +222342,1540838974,558998737,1 +222343,1540838975,558998855,1 +222344,1540838976,360019730,1 +222345,1540838977,1540838978,1 +222346,1540838978,360019727,1 +222347,1540838979,360019724,1 +222348,1540838980,360019823,1 +222349,1540838981,360019791,1 +222350,1540838982,558970405,1 +222351,1540838983,558949277,1 +222353,1540838985,536580557,1 +222354,1540838986,536600462,1 +222355,1540838987,536600468,1 +222356,1540838988,536600470,1 +222357,1540838989,536600481,1 +222358,1540838990,1540838991,1 +222359,1540838991,536600484,1 +222360,1540838992,536600519,1 +222361,1540838993,1540838994,1 +222362,1540838994,1540838995,1 +222363,1540838995,1540838996,1 +222364,1540838996,536600528,1 +222365,1540838997,1540838998,1 +222366,1540838998,536600538,1 +222367,1540838999,1540839000,1 +222368,1540839000,536600549,1 +222369,1540839001,536600564,1 +222370,1540839002,536600569,1 +222371,1540839003,536600626,1 +222372,1540839004,1540839005,1 +222373,1540839005,536600652,1 +222374,1540839006,967331623,1 +222375,1540839007,1540839008,1 +222376,1540839008,1540839009,1 +222377,1540839009,1540839010,1 +222378,1540839010,536600876,1 +222379,1540839011,1540839012,1 +222380,1540839012,575191614,1 +222381,1540839013,1540839014,1 +222382,1540839014,536600876,1 +222383,1540839015,536600879,1 +222384,1540839016,536600908,1 +222385,1540839017,1540839018,1 +222386,1540839018,536601028,1 +222387,1540839019,536601038,1 +222388,1540839020,536601042,1 +222389,1540839021,560935844,1 +222390,1540839022,1540839023,1 +222391,1540839023,360013423,1 +222392,1540839024,536601102,1 +222393,1540839025,536600791,1 +222394,1540839026,536601228,1 +222395,1540839027,1540839028,1 +222396,1540839028,1540839029,1 +222397,1540839029,536600786,1 +222398,1540839030,536601049,1 +222399,1540839031,528489623,1 +222992,1540839624,1540839625,0 +222993,1540839625,153874640,0 +223015,1540839647,1540839648,0 +223016,1540839648,1540839649,0 +223017,1540839649,1540839650,0 +223018,1540839650,1540839651,0 +223019,1540839651,1540839652,0 +223020,1540839652,1540839653,0 +223021,1540839653,1540839654,0 +223022,1540839654,1540839655,0 +223023,1540839655,1540839656,0 +223024,1540839656,1540839657,0 +223025,1540839657,1540839658,0 +223026,1540839658,1540839659,0 +223027,1540839659,1540839660,0 +223028,1540839660,1540839661,0 +223029,1540839661,1540839662,0 +223030,1540839662,152939465,0 +223031,1540839663,967240681,0 +223032,1540839664,153879592,0 +223033,1540839665,558986385,0 +223034,1540839666,1540839667,0 +223035,1540839667,536580108,0 +223036,1540839668,1540839669,0 +223037,1540839669,1540839670,0 +223038,1540839670,475013802,0 +223039,1540839671,1540839672,0 +223040,1540839672,1540839673,0 +223041,1540839673,361215419,0 +223042,1540839674,1540839675,0 +223043,1540839675,559494705,0 +223044,1540839676,559938981,0 +223045,1540839677,1540839678,0 +223046,1540839678,1540839679,0 +223047,1540839679,1540839680,0 +223048,1540839680,1540839681,0 +223049,1540839681,800140476,0 +223050,1540839682,559938954,0 +223051,1540839683,932361972,1 +223052,1540839684,932361982,1 +223053,1540839685,1540839686,1 +223054,1540839686,1540839687,1 +223055,1540839687,418771211,1 +223056,1540839688,600396750,1 +223057,1540839689,549791264,1 +223058,1540839690,1540839691,1 +223059,1540839691,1540839692,1 +223060,1540839692,1540839693,1 +223061,1540839693,972481629,1 +223062,1540839694,549791316,1 +223063,1540839695,549791335,1 +223064,1540839696,549791343,1 +223065,1540839697,1540839698,0 +223066,1540839698,1540839699,0 +223067,1540839699,1540839700,0 +223068,1540839700,549791351,0 +223069,1540839701,1540839702,0 +223070,1540839702,549791279,0 +223071,1540839703,1540839704,0 +223072,1540839704,549791359,0 +223073,1540839705,1540839706,0 +223074,1540839706,1540839707,0 +223075,1540839707,1540839708,0 +223076,1540839708,549791344,0 +223077,1540839709,1540839710,1 +223078,1540839710,549791375,1 +223079,1540839711,360190667,1 +223080,1540839712,576508579,1 +223081,1540839713,360189874,1 +223082,1540839714,1540839715,1 +223083,1540839715,967199406,1 +223084,1540839716,967199544,1 +223085,1540839717,1540839718,1 +223086,1540839718,363984910,1 +223098,1540839730,1540839731,1 +223099,1540839731,361406202,1 +223100,1540839732,795263003,1 +223101,1540839733,795263019,1 +223102,1540839734,1540839735,1 +223103,1540839735,795263012,1 +223104,1540839736,361406205,1 +223468,1540840100,1540840101,1 +223469,1540840101,558970277,1 +223470,1540840102,1540840103,1 +223471,1540840103,558970108,1 +223498,1540840130,558969662,1 +223499,1540840131,558969794,1 +223500,1540840132,1540840133,1 +223501,1540840133,1540840134,1 +223502,1540840134,558969967,1 +223503,1540840135,536580362,1 +223506,1540840138,558972579,1 +223507,1540840139,1540840140,1 +223508,1540840140,558985998,1 +223509,1540840141,1540840142,1 +223510,1540840142,1540840143,1 +223511,1540840143,1540840144,1 +223512,1540840144,1540840145,1 +223513,1540840145,1540840146,1 +223514,1540840146,1540840147,1 +223515,1540840147,1540840148,1 +223516,1540840148,1540840149,1 +223517,1540840149,1540840150,1 +223518,1540840150,558986107,1 +223519,1540840151,1540840152,1 +223520,1540840152,1540840153,1 +223521,1540840153,558986129,1 +223522,1540840154,1540840155,1 +223523,1540840155,152941465,1 +223524,1540840156,1540840157,1 +223525,1540840157,558998863,1 +223526,1540840158,558986043,1 +223527,1540840159,558986313,1 +223528,1540840160,558998608,1 +223529,1540840161,558998737,1 +223530,1540840162,558998573,1 +223531,1540840163,558986071,1 +223532,1540840164,1540840165,1 +223533,1540840165,1540840166,1 +223534,1540840166,509781962,1 +223535,1540840167,558998719,1 +223536,1540840168,1540840169,1 +223537,1540840169,558998796,1 +223538,1540840170,558998806,1 +223539,1540840171,1540840172,1 +223540,1540840172,1540840173,1 +223541,1540840173,152941465,1 +223542,1540840174,1540840175,1 +223543,1540840175,1540840176,1 +223544,1540840176,1540840177,1 +223545,1540840177,559481046,1 +223546,1540840178,1540840179,1 +223547,1540840179,559481057,1 +223548,1540840180,1540840181,1 +223549,1540840181,1540840182,1 +223550,1540840182,1540840183,1 +223551,1540840183,558986129,1 +223552,1540840184,1540840185,1 +223553,1540840185,1540840186,1 +223554,1540840186,1540840187,1 +223555,1540840187,559481038,1 +223556,1540840188,1540840189,1 +223557,1540840189,1540840190,1 +223558,1540840190,1540840191,1 +223559,1540840191,1540840192,1 +223560,1540840192,558986107,1 +223564,1540840196,939570206,0 +223565,1540840197,559554564,0 +223566,1540840198,559498297,0 +223567,1540840199,1540840200,0 +223568,1540840200,559494677,0 +223569,1540840201,1540840202,0 +223570,1540840202,1540840203,0 +223571,1540840203,559494659,0 +223572,1540840204,475012900,0 +223573,1540840205,566679830,0 +223574,1540840206,1540840207,0 +223575,1540840207,1540840208,0 +223576,1540840208,361215543,0 +223577,1540840209,1540840210,0 +223578,1540840210,152800568,0 +223579,1540840211,559494694,0 +223580,1540840212,559494711,0 +223581,1540840213,559494702,0 +223582,1540840214,559498300,1 +223583,1540840215,1540840216,1 +223584,1540840216,559498301,1 +223586,1540840218,510958841,0 +223587,1540840219,361217690,0 +223588,1540840220,361217683,0 +223589,1540840221,660481539,0 +223590,1540840222,1540840223,0 +223591,1540840223,1540840224,0 +223592,1540840224,1540840225,0 +223593,1540840225,1540840226,0 +223594,1540840226,1540840227,0 +223595,1540840227,560712538,0 +223596,1540840228,1540840229,0 +223597,1540840229,1540840230,0 +223598,1540840230,1540840231,0 +223599,1540840231,1540840232,0 +223600,1540840232,1540840233,0 +223601,1540840233,1540840234,0 +223602,1540840234,1540840235,0 +223603,1540840235,1540840236,0 +223604,1540840236,1540840237,0 +223605,1540840237,1540840238,0 +223606,1540840238,360000101,0 +223607,1540840239,1540840240,0 +223608,1540840240,560583718,0 +223609,1540840241,1540840242,0 +223610,1540840242,360002696,0 +223611,1540840243,559547580,1 +223614,1540840246,559554576,1 +223615,1540840247,559564602,1 +223616,1540840248,359997265,1 +223617,1540840249,1540840250,1 +223618,1540840250,1540840251,1 +223619,1540840251,1540840252,1 +223620,1540840252,359995958,1 +223621,1540840253,984725796,1 +223622,1540840254,1540840255,1 +223623,1540840255,984725976,1 +223624,1540840256,559564609,1 +223625,1540840257,359998626,1 +223626,1540840258,1540840259,1 +223627,1540840259,559564870,1 +223628,1540840260,1540840261,1 +223629,1540840261,559564600,1 +223630,1540840262,1540840263,1 +223631,1540840263,559564937,1 +223632,1540840264,559590207,1 +223633,1540840265,559590281,1 +223634,1540840266,559590499,0 +223635,1540840267,365970585,0 +223636,1540840268,559590250,1 +223637,1540840269,1540840270,1 +223638,1540840270,1540840271,1 +223639,1540840271,1540840272,1 +223640,1540840272,1540840273,1 +223641,1540840273,1540840274,1 +223642,1540840274,678158876,1 +223643,1540840275,559591046,1 +223644,1540840276,559590901,0 +223645,1540840277,559591347,1 +223646,1540840278,559591449,1 +223647,1540840279,36645010,1 +223648,1540840280,559939127,1 +223649,1540840281,1540840282,1 +223650,1540840282,1540840283,1 +223651,1540840283,1540840284,1 +223652,1540840284,1540840285,1 +223653,1540840285,1540840286,1 +223654,1540840286,1540840287,1 +223655,1540840287,559938830,1 +223656,1540840288,1540840289,0 +223657,1540840289,1540840290,0 +223658,1540840290,1540840291,0 +223659,1540840291,1540840292,0 +223660,1540840292,1540840293,0 +223661,1540840293,1540840294,0 +223662,1540840294,1540840295,0 +223663,1540840295,1540840296,0 +223664,1540840296,1540840297,0 +223665,1540840297,1540840298,0 +223666,1540840298,1540840299,0 +223667,1540840299,1540840300,0 +223668,1540840300,1540840301,0 +223669,1540840301,1540840302,0 +223670,1540840302,1540840303,0 +223671,1540840303,1540840304,0 +223672,1540840304,1540840305,0 +223673,1540840305,1540840306,0 +223674,1540840306,359999826,0 +223675,1540840307,359999824,0 +223676,1540840308,1540840309,0 +223677,1540840309,1540840310,0 +223678,1540840310,1540840311,0 +223679,1540840311,1540840312,0 +223680,1540840312,1540840313,0 +223681,1540840313,1540840314,0 +223682,1540840314,1540840315,0 +223683,1540840315,1540840316,0 +223684,1540840316,1540840317,0 +223685,1540840317,1540840318,0 +223686,1540840318,1540840319,0 +223687,1540840319,1540840320,0 +223688,1540840320,1540840321,0 +223689,1540840321,1540840322,0 +223690,1540840322,1540840323,0 +223691,1540840323,1540840324,0 +223692,1540840324,1540840325,0 +223693,1540840325,559939230,0 +223694,1540840326,1540840327,0 +223695,1540840327,1540840328,0 +223696,1540840328,1540840329,0 +223697,1540840329,1540840330,0 +223698,1540840330,1540840331,0 +223699,1540840331,1540840332,0 +223700,1540840332,800140482,0 +223701,1540840333,528505113,1 +223702,1540840334,1540840335,0 +223703,1540840335,559940357,0 +223704,1540840336,1540840337,1 +223705,1540840337,1540840338,1 +223706,1540840338,1540840339,1 +223707,1540840339,1540840340,1 +223708,1540840340,1540840341,1 +223709,1540840341,549775624,1 +223710,1540840342,1540840343,0 +223711,1540840343,1540840344,0 +223712,1540840344,1540840345,0 +223713,1540840345,1540840346,0 +223714,1540840346,559938656,0 +223715,1540840347,359999720,0 +223716,1540840348,1540840349,0 +223717,1540840349,1540840350,0 +223718,1540840350,559938954,0 +223719,1540840351,1540840352,0 +223720,1540840352,1540840353,0 +223721,1540840353,1540840354,0 +223722,1540840354,559939021,0 +223723,1540840355,1540840356,0 +223724,1540840356,549777920,0 +223725,1540840357,1013465133,0 +223726,1540840358,1540840359,1 +223727,1540840359,1540840360,1 +223728,1540840360,1540840361,1 +223729,1540840361,1540840362,1 +223730,1540840362,1540840363,1 +223731,1540840363,559939040,1 +223732,1540840364,559939061,0 +223733,1540840365,1540840366,0 +223734,1540840366,559939047,0 +223735,1540840367,559939045,0 +223736,1540840368,1540840369,0 +223737,1540840369,360003281,0 +223738,1540840370,1540840371,0 +223739,1540840371,1540840372,0 +223740,1540840372,1540840373,0 +223741,1540840373,559939044,0 +223742,1540840374,1540840375,1 +223743,1540840375,1540840376,1 +223744,1540840376,1540840377,1 +223745,1540840377,559940452,1 +223746,1540840378,1540840379,0 +223747,1540840379,1540840380,0 +223748,1540840380,1540840381,0 +223749,1540840381,1540840382,0 +223750,1540840382,1540840383,0 +223751,1540840383,1540840384,0 +223752,1540840384,1540840385,0 +223753,1540840385,1540840386,0 +223754,1540840386,559940357,0 +223755,1540840387,559940461,1 +223812,1540840444,1540840445,1 +223813,1540840445,1540840446,1 +223814,1540840446,597692580,1 +223815,1540840447,560582517,1 +223816,1540840448,359998946,1 +223817,1540840449,1540840450,1 +223818,1540840450,560582515,1 +223819,1540840451,560582733,1 +223820,1540840452,1540840453,1 +223821,1540840453,1540840454,1 +223822,1540840454,1540840455,1 +223823,1540840455,560583762,1 +223824,1540840456,1540840457,1 +223825,1540840457,1540840458,1 +223826,1540840458,1540840459,1 +223827,1540840459,1540840460,1 +223828,1540840460,1540840461,1 +223829,1540840461,1540840462,1 +223830,1540840462,560583718,1 +223831,1540840463,1540840464,1 +223832,1540840464,1540840465,1 +223833,1540840465,527804424,1 +223834,1540840466,560712450,0 +223835,1540840467,1540840468,1 +223836,1540840468,1540840469,1 +223837,1540840469,1540840470,1 +223838,1540840470,560712538,1 +223839,1540840471,1540840472,0 +223840,1540840472,560712552,0 +223841,1540840473,1540840474,1 +223842,1540840474,1540840475,1 +223843,1540840475,1540840476,1 +223844,1540840476,560712557,1 +223845,1540840477,560712559,0 +223846,1540840478,560712544,0 +223847,1540840479,1540840480,1 +223848,1540840480,1540840481,1 +223849,1540840481,560712583,1 +223850,1540840482,560712586,1 +223851,1540840483,560712591,1 +223852,1540840484,560712594,1 +223853,1540840485,560712594,1 +223854,1540840486,560712578,1 +223855,1540840487,1540840488,1 +223856,1540840488,560712604,1 +223857,1540840489,1540840490,1 +223858,1540840490,1540840491,1 +223859,1540840491,560712497,1 +223860,1540840492,560712583,1 +223861,1540840493,1540840494,1 +223862,1540840494,1540840495,1 +223863,1540840495,560712616,1 +223864,1540840496,560712625,1 +223865,1540840497,1540840498,1 +223866,1540840498,560712628,1 +223867,1540840499,1540840500,1 +223868,1540840500,1540840501,1 +223869,1540840501,1540840502,1 +223870,1540840502,560712633,1 +223871,1540840503,560583808,1 +223872,1540840504,1540840505,1 +223873,1540840505,1540840506,1 +223874,1540840506,560583809,1 +223875,1540840507,560712645,1 +223876,1540840508,560712645,1 +223877,1540840509,352709360,1 +223878,1540840510,176178421,1 +223879,1540840511,560712659,1 +223880,1540840512,1540840513,1 +223881,1540840513,560712664,1 +223882,1540840514,560712641,1 +223883,1540840515,560712679,1 +223884,1540840516,560712682,0 +223885,1540840517,1540840518,1 +223886,1540840518,1540840519,1 +223887,1540840519,560712667,1 +223888,1540840520,1540840521,1 +223889,1540840521,560712692,1 +223890,1540840522,1540840523,1 +223891,1540840523,560712668,1 +223892,1540840524,560712673,1 +223893,1540840525,1540840526,1 +223894,1540840526,1540840527,1 +223895,1540840527,1540840528,1 +223896,1540840528,560712675,1 +223897,1540840529,1540840530,1 +223898,1540840530,1540840531,1 +223899,1540840531,1540840532,1 +223900,1540840532,560712679,1 +223901,1540840533,560712672,1 +223902,1540840534,560712669,1 +223903,1540840535,560712696,1 +223904,1540840536,1540840537,1 +223905,1540840537,560712693,1 +223906,1540840538,560712689,0 +223907,1540840539,560945167,1 +223908,1540840540,1540840541,1 +223909,1540840541,1540840542,1 +223910,1540840542,560728599,1 +223911,1540840543,1540840544,1 +223912,1540840544,560728603,1 +223913,1540840545,1540840546,1 +223914,1540840546,560728609,1 +223915,1540840547,1540840548,1 +223916,1540840548,1540840549,1 +223917,1540840549,560728617,1 +223918,1540840550,1540840551,1 +223919,1540840551,560728586,1 +223920,1540840552,560944988,0 +223921,1540840553,1540840554,1 +223922,1540840554,1540840555,1 +223923,1540840555,560728637,1 +223924,1540840556,560728640,1 +223925,1540840557,1540840558,1 +223926,1540840558,560945159,1 +223927,1540840559,560728630,1 +223928,1540840560,1540840561,1 +223929,1540840561,560728650,1 +223930,1540840562,560728654,1 +223931,1540840563,1540840564,1 +223932,1540840564,1540840565,1 +223933,1540840565,1540840566,1 +223934,1540840566,1540840567,1 +223935,1540840567,1540840568,1 +223936,1540840568,1540840569,1 +223937,1540840569,1540840570,1 +223938,1540840570,1540840571,1 +223939,1540840571,560728654,1 +223940,1540840572,560728574,1 +223941,1540840573,1540840574,1 +223942,1540840574,1540840575,1 +223943,1540840575,560728631,1 +223944,1540840576,1540840577,1 +223945,1540840577,1540840578,1 +223946,1540840578,560728649,1 +223947,1540840579,1540840580,1 +223948,1540840580,1540840581,1 +223949,1540840581,560728633,1 +223950,1540840582,1540840583,1 +223951,1540840583,1540840584,1 +223952,1540840584,560728629,1 +223953,1540840585,560945014,1 +223954,1540840586,1540840587,1 +223955,1540840587,560728647,1 +223956,1540840588,560728651,1 +223957,1540840589,278009614,1 +223958,1540840590,1540840591,1 +223959,1540840591,560728681,1 +223960,1540840592,1540840593,1 +223961,1540840593,1540840594,1 +223962,1540840594,278009615,1 +223963,1540840595,536579504,1 +223964,1540840596,560944912,1 +223965,1540840597,1540840598,1 +223966,1540840598,1540840599,1 +223967,1540840599,1540840600,1 +223968,1540840600,560944921,1 +223969,1540840601,1540840602,1 +223970,1540840602,1540840603,1 +223971,1540840603,1540840604,1 +223972,1540840604,1540840605,1 +223973,1540840605,560944929,1 +223974,1540840606,1540840607,1 +223975,1540840607,1540840608,1 +223976,1540840608,560944934,1 +223977,1540840609,1540840610,1 +223978,1540840610,1540840611,1 +223979,1540840611,1540840612,1 +223980,1540840612,1540840613,1 +223981,1540840613,1540840614,1 +223982,1540840614,560944906,1 +223983,1540840615,560944916,1 +223984,1540840616,560944913,1 +223985,1540840617,1540840618,1 +223986,1540840618,1540840619,1 +223987,1540840619,560944958,1 +223988,1540840620,1540840621,1 +223989,1540840621,560944961,1 +223990,1540840622,1540840623,1 +223991,1540840623,560728625,1 +223992,1540840624,1540840625,1 +223993,1540840625,1540840626,1 +223994,1540840626,560944969,1 +223995,1540840627,560728624,1 +223996,1540840628,1540840629,1 +223997,1540840629,1540840630,1 +223998,1540840630,1540840631,1 +223999,1540840631,1540840632,1 +224000,1540840632,1540840633,1 +224001,1540840633,1540840634,1 +224002,1540840634,1540840635,1 +224003,1540840635,560944969,1 +224004,1540840636,1030975557,1 +224005,1540840637,1540840638,1 +224006,1540840638,1540840639,1 +224007,1540840639,560944956,1 +224008,1540840640,560944963,1 +224009,1540840641,560944992,1 +224010,1540840642,560944990,1 +224011,1540840643,560728625,1 +224012,1540840644,1540840645,1 +224013,1540840645,1540840646,1 +224014,1540840646,1540840647,1 +224015,1540840647,560945005,1 +224016,1540840648,560945007,1 +224017,1540840649,560945014,1 +224018,1540840650,560944988,0 +224019,1540840651,1540840652,1 +224020,1540840652,1540840653,1 +224021,1540840653,560728641,1 +224022,1540840654,1540840655,1 +224023,1540840655,560944999,1 +224024,1540840656,1540840657,1 +224025,1540840657,1540840658,1 +224026,1540840658,560945007,1 +224027,1540840659,1540840660,1 +224028,1540840660,560945000,1 +224029,1540840661,1540840662,1 +224030,1540840662,560946138,1 +224031,1540840663,560944922,0 +224032,1540840664,1540840665,0 +224033,1540840665,560945079,0 +224034,1540840666,1540840667,0 +224035,1540840667,560944920,0 +224036,1540840668,560945159,0 +224071,1540840703,561406781,1 +224072,1540840704,1540840705,0 +224073,1540840705,695549703,0 +224074,1540840706,1540840707,0 +224075,1540840707,1540840708,0 +224076,1540840708,1540840709,0 +224077,1540840709,561406896,0 +224078,1540840710,561406781,0 +224079,1540840711,561406920,0 +224080,1540840712,561406925,0 +224081,1540840713,561406933,0 +224082,1540840714,561406946,0 +224083,1540840715,1236966607,0 +224084,1540840716,360474036,0 +224085,1540840717,1540840718,0 +224086,1540840718,1540840719,0 +224087,1540840719,365969981,0 +224088,1540840720,1540840721,0 +224089,1540840721,562865739,0 +224090,1540840722,1540840723,0 +224091,1540840723,1540840724,0 +224092,1540840724,562865746,0 +224093,1540840725,1540840726,0 +224094,1540840726,562865751,0 +224095,1540840727,562865754,0 +224096,1540840728,1540840729,0 +224097,1540840729,562865725,0 +224098,1540840730,1540840731,0 +224099,1540840731,562865805,0 +224490,1540841122,153879588,0 +224491,1540841123,1540841124,0 +224492,1540841124,1540841125,0 +224493,1540841125,1540841126,0 +224494,1540841126,1540841127,0 +224495,1540841127,1540841128,0 +224496,1540841128,1540841129,0 +224497,1540841129,1540841130,0 +224498,1540841130,566678846,0 +224499,1540841131,1540841132,0 +224500,1540841132,1540841133,0 +224501,1540841133,566678875,0 +224502,1540841134,973983301,0 +224503,1540841135,1540841136,0 +224504,1540841136,1540841137,0 +224505,1540841137,1540841138,0 +224506,1540841138,1540841139,0 +224507,1540841139,536600671,0 +224508,1540841140,1540841141,0 +224509,1540841141,1540841142,0 +224510,1540841142,536600956,0 +224511,1540841143,1540841144,0 +224512,1540841144,1540841145,0 +224513,1540841145,1540841146,0 +224514,1540841146,1540841147,0 +224515,1540841147,536600658,0 +224516,1540841148,1540841149,0 +224517,1540841149,536600942,0 +224518,1540841150,528489811,1 +224519,1540841151,1540841152,1 +224520,1540841152,1540841153,1 +224521,1540841153,967240633,1 +224522,1540841154,1540841155,1 +224523,1540841155,1540841156,1 +224524,1540841156,1540841157,1 +224525,1540841157,1540841158,1 +224526,1540841158,1540841159,1 +224527,1540841159,966315443,1 +224528,1540841160,528489826,1 +224529,1540841161,1540841162,1 +224530,1540841162,1540841163,1 +224531,1540841163,1540841164,1 +224532,1540841164,1540841165,1 +224533,1540841165,1540841166,1 +224534,1540841166,360011965,1 +224535,1540841167,360011969,1 +224536,1540841168,966666270,1 +224543,1540841175,1540841176,1 +224544,1540841176,366360714,1 +224545,1540841177,360194966,1 +224546,1540841178,279589619,0 +224547,1540841179,1540841180,0 +224548,1540841180,1540841181,0 +224549,1540841181,360205411,0 +224550,1540841182,1540841183,0 +224551,1540841183,279589608,0 +224552,1540841184,1540841185,0 +224553,1540841185,279589624,0 +224554,1540841186,1540841187,0 +224555,1540841187,1540841188,0 +224556,1540841188,278009537,0 +224557,1540841189,1030313078,0 +224558,1540841190,1540841191,1 +224559,1540841191,360198977,1 +224560,1540841192,1540841193,1 +224561,1540841193,1540841194,1 +224562,1540841194,360198847,1 +224563,1540841195,1540841196,1 +224564,1540841196,360196300,1 +224565,1540841197,1540841198,1 +224566,1540841198,360210541,1 +224567,1540841199,1540841200,1 +224568,1540841200,1540841201,1 +224569,1540841201,360199117,1 +224570,1540841202,973983444,1 +224571,1540841203,568806865,1 +225231,1540841863,575187165,1 +225232,1540841864,967331658,1 +225233,1540841865,536600453,1 +225234,1540841866,536600453,1 +225301,1540841933,576508579,1 +225302,1540841934,568806867,1 +225303,1540841935,568806869,1 +225304,1540841936,972481579,1 +225305,1540841937,1540841938,1 +225306,1540841938,1540841939,1 +225307,1540841939,972481647,1 +226395,1540843027,559590880,0 +226396,1540843028,1540843029,0 +226397,1540843029,559564628,0 +226398,1540843030,1540843031,0 +226399,1540843031,560582523,0 +226400,1540843032,1540843033,0 +226401,1540843033,559564601,0 +226402,1540843034,286367654,0 +226403,1540843035,1540843036,0 +226404,1540843036,1540843037,0 +226405,1540843037,1540843038,0 +226406,1540843038,1540843039,0 +226407,1540843039,1540843040,0 +226408,1540843040,1540843041,0 +226409,1540843041,577419381,0 +226410,1540843042,1540843043,0 +226411,1540843043,577419395,0 +226412,1540843044,577419403,1 +226413,1540843045,1540843046,1 +226414,1540843046,577419456,1 +226415,1540843047,1540843048,0 +226416,1540843048,1540843049,0 +226417,1540843049,1540843050,0 +226418,1540843050,577419395,0 +226419,1540843051,577419344,0 +226420,1540843052,577419388,0 +226421,1540843053,1540843054,0 +226422,1540843054,936853817,0 +226423,1540843055,577419456,1 +226424,1540843056,581267843,1 +226425,1540843057,577419525,0 +226426,1540843058,936853855,0 +226427,1540843059,1540843060,0 +226428,1540843060,577419498,0 +226429,1540843061,577419475,0 +226430,1540843062,1540843063,0 +226431,1540843063,1540843064,0 +226432,1540843064,1540843065,0 +226433,1540843065,936853887,0 +226434,1540843066,1540843067,0 +226435,1540843067,1540843068,0 +226436,1540843068,1540843069,0 +226437,1540843069,936853720,0 +226438,1540843070,1540843071,0 +226439,1540843071,984752586,0 +226440,1540843072,1540843073,0 +226441,1540843073,1540843074,0 +226442,1540843074,936853776,0 +226443,1540843075,1540843076,0 +226444,1540843076,936853681,0 +226445,1540843077,1540843078,0 +226446,1540843078,1540843079,0 +226447,1540843079,360476538,0 +226448,1540843080,1540843081,0 +226449,1540843081,1540843082,0 +226450,1540843082,1540843083,0 +226451,1540843083,1540843084,0 +226452,1540843084,1540843085,0 +226453,1540843085,1540843086,0 +226454,1540843086,577419530,0 +226455,1540843087,1540843088,0 +226456,1540843088,1540843089,0 +226457,1540843089,577419525,0 +226458,1540843090,1540843091,0 +226459,1540843091,1540843092,0 +226460,1540843092,1540843093,0 +226461,1540843093,1540843094,0 +226462,1540843094,1540843095,0 +226463,1540843095,1540843096,0 +226464,1540843096,1540843097,0 +226465,1540843097,1540843098,0 +226466,1540843098,1540843099,0 +226467,1540843099,577419535,0 +226468,1540843100,1540843101,0 +226469,1540843101,1540843102,0 +226470,1540843102,1540843103,0 +226471,1540843103,577419535,0 +226472,1540843104,1540843105,0 +226473,1540843105,1540843106,0 +226474,1540843106,1540843107,0 +226475,1540843107,1540843108,0 +226476,1540843108,1540843109,0 +226477,1540843109,1540843110,0 +226478,1540843110,1540843111,0 +226479,1540843111,1540843112,0 +226480,1540843112,1540843113,0 +226481,1540843113,1540843114,0 +226482,1540843114,1540843115,0 +226483,1540843115,1540843116,0 +226484,1540843116,1540843117,0 +226485,1540843117,1540843118,0 +226486,1540843118,1540843119,0 +226487,1540843119,1540843120,0 +226488,1540843120,1540843121,0 +226489,1540843121,295776661,0 +226490,1540843122,1540843123,0 +226491,1540843123,1540843124,0 +226492,1540843124,1540843125,0 +226493,1540843125,1540843126,0 +226494,1540843126,1540843127,0 +226495,1540843127,1540843128,0 +226496,1540843128,1540843129,0 +226497,1540843129,1540843130,0 +226498,1540843130,1540843131,0 +226499,1540843131,1540843132,0 +226500,1540843132,1540843133,0 +226501,1540843133,1540843134,0 +226502,1540843134,1540843135,0 +226503,1540843135,936804372,0 +226504,1540843136,1540843137,0 +226505,1540843137,1540843138,0 +226506,1540843138,1540843139,0 +226507,1540843139,1540843140,0 +226508,1540843140,1540843141,0 +226509,1540843141,1540843142,0 +226510,1540843142,1540843143,0 +226511,1540843143,1540843144,0 +226512,1540843144,1540843145,0 +226513,1540843145,1540843146,0 +226514,1540843146,361224674,0 +226515,1540843147,152939465,0 +226559,1540843191,1540843192,0 +226560,1540843192,1540843193,0 +226561,1540843193,581290412,0 +226562,1540843194,1540843195,0 +226563,1540843195,1540843196,0 +226564,1540843196,246588469,0 +226565,1540843197,1540843198,0 +226566,1540843198,1540843199,0 +226567,1540843199,1540843200,0 +226568,1540843200,1540843201,0 +226569,1540843201,1540843202,0 +226570,1540843202,1540843203,0 +226571,1540843203,1540843204,0 +226572,1540843204,1540843205,0 +226573,1540843205,792056475,0 +226574,1540843206,1540843207,0 +226575,1540843207,361447852,0 +226576,1540843208,1540843209,0 +226577,1540843209,1540843210,0 +226578,1540843210,1540843211,0 +226579,1540843211,1540843212,0 +226580,1540843212,1540843213,0 +226581,1540843213,361447852,0 +226582,1540843214,579794572,1 +226583,1540843215,792071791,1 +226584,1540843216,1540843217,0 +226585,1540843217,1540843218,0 +226586,1540843218,1540843219,0 +226587,1540843219,361444006,0 +226588,1540843220,1540843221,0 +226589,1540843221,1540843222,0 +226590,1540843222,1540843223,0 +226591,1540843223,1540843224,0 +226592,1540843224,361441554,0 +226616,1540843248,1540843249,1 +226617,1540843249,803745208,1 +226618,1540843250,1540843251,0 +226619,1540843251,1540843252,0 +226620,1540843252,1540843253,0 +226621,1540843253,1540843254,0 +226622,1540843254,581290412,0 +226623,1540843255,1540843256,0 +226624,1540843256,1540843257,0 +226625,1540843257,579805282,0 +226626,1540843258,1540843259,0 +226627,1540843259,361441552,0 +226628,1540843260,1540843261,0 +226629,1540843261,792071790,0 +226630,1540843262,579794578,0 +226631,1540843263,792071819,0 +226632,1540843264,1540843265,0 +226633,1540843265,1540843266,0 +226634,1540843266,792071787,0 +226635,1540843267,600205087,0 +226636,1540843268,600205102,0 +226637,1540843269,600205118,0 +226638,1540843270,1540843271,0 +226639,1540843271,938143134,0 +226640,1540843272,1540843273,0 +226641,1540843273,1540843274,0 +226642,1540843274,1540843275,0 +226643,1540843275,1540843276,0 +226644,1540843276,600205127,0 +226645,1540843277,1540843278,0 +226646,1540843278,1540843279,0 +226647,1540843279,1540843280,0 +226648,1540843280,1540843281,0 +226649,1540843281,1540843282,0 +226650,1540843282,579805328,0 +226651,1540843283,1540843284,0 +226652,1540843284,581286085,0 +226653,1540843285,1540843286,1 +226654,1540843286,1540843287,1 +226655,1540843287,1540843288,1 +226656,1540843288,361441551,1 +226657,1540843289,1540843290,0 +226658,1540843290,1540843291,0 +226659,1540843291,1540843292,0 +226660,1540843292,1540843293,0 +226661,1540843293,1540843294,0 +226662,1540843294,1540843295,0 +226663,1540843295,1540843296,0 +226664,1540843296,1540843297,0 +226665,1540843297,1540843298,0 +226666,1540843298,1540843299,0 +226667,1540843299,1540843300,0 +226668,1540843300,581288214,0 +226669,1540843301,581290413,0 +226670,1540843302,581290410,0 +226671,1540843303,338485329,0 +226672,1540843304,353246389,0 +226673,1540843305,581291048,0 +227515,1540844147,1540844148,0 +227516,1540844148,561406865,0 +227517,1540844149,365119749,0 +227518,1540844150,365119860,0 +227519,1540844151,561407122,0 +227520,1540844152,1540844153,0 +227521,1540844153,1540844154,0 +227522,1540844154,1540844155,0 +227523,1540844155,1540844156,0 +227524,1540844156,597692693,0 +227525,1540844157,175702450,0 +227529,1540844161,991240614,0 +227530,1540844162,418771183,1 +227531,1540844163,1540844164,1 +227532,1540844164,418771204,1 +227533,1540844165,1540844166,1 +227534,1540844166,1345509423,1 +227535,1540844167,1540844168,1 +227536,1540844168,1540844169,1 +227537,1540844169,1540844170,1 +227538,1540844170,1540844171,1 +227539,1540844171,1540844172,1 +227540,1540844172,1540844173,1 +227541,1540844173,1540844174,1 +227542,1540844174,1540844175,1 +227543,1540844175,1540844176,1 +227544,1540844176,1540844177,1 +227545,1540844177,1540844178,1 +227546,1540844178,1540844179,1 +227547,1540844179,1540844180,1 +227548,1540844180,1540844181,1 +227549,1540844181,1540844182,1 +227550,1540844182,583435297,1 +227551,1540844183,363988499,1 +227552,1540844184,1540844185,1 +227553,1540844185,583435303,1 +227554,1540844186,1540844187,1 +227555,1540844187,940611040,1 +227556,1540844188,1540844189,1 +227557,1540844189,1540844190,1 +227558,1540844190,1540844191,1 +227559,1540844191,1540844192,1 +227560,1540844192,966314782,1 +227561,1540844193,1540844194,1 +227562,1540844194,966315332,1 +227563,1540844195,1540844196,1 +227564,1540844196,1540844197,1 +227565,1540844197,940611048,1 +227566,1540844198,966315271,1 +227717,1540844349,152805378,0 +227718,1540844350,1540844351,0 +227719,1540844351,1540844352,0 +227720,1540844352,935855245,0 +227751,1540844383,1540844384,0 +227752,1540844384,1540844385,0 +227753,1540844385,584361281,0 +227754,1540844386,1540844387,0 +227755,1540844387,1540844388,0 +227756,1540844388,584361305,0 +227757,1540844389,417279720,0 +227758,1540844390,1540844391,0 +227759,1540844391,417276966,0 +227760,1540844392,598498286,0 +227761,1540844393,1540844394,0 +227762,1540844394,598495511,0 +227818,1540844450,1540844451,0 +227819,1540844451,1540844452,0 +227820,1540844452,1540844453,0 +227821,1540844453,1540844454,0 +227822,1540844454,1540844455,0 +227823,1540844455,1540844456,0 +227824,1540844456,1540844457,0 +227825,1540844457,1540844458,0 +227826,1540844458,1540844459,0 +227827,1540844459,1540844460,0 +227828,1540844460,1540844461,0 +227829,1540844461,585200697,0 +227970,1540844602,585200692,0 +227971,1540844603,1540844604,0 +227972,1540844604,1540844605,0 +227973,1540844605,1540844606,0 +227974,1540844606,1540844607,0 +227975,1540844607,1540844608,0 +227976,1540844608,1540844609,0 +227977,1540844609,1540844610,0 +227978,1540844610,1540844611,0 +227979,1540844611,1540844612,0 +227980,1540844612,1540844613,0 +227981,1540844613,1540844614,0 +227982,1540844614,1540844615,0 +227983,1540844615,662948267,0 +227984,1540844616,1540844617,0 +227985,1540844617,1540844618,0 +227986,1540844618,1540844619,0 +227987,1540844619,1540844620,0 +227988,1540844620,973016840,0 +227989,1540844621,600629036,0 +227990,1540844622,1540844623,0 +227991,1540844623,973040045,0 +227992,1540844624,1540844625,0 +227993,1540844625,662948321,0 +228033,1540844665,1539669150,1 +228034,1540844666,1540844667,1 +228035,1540844667,585203872,1 +228411,1540845043,1540845044,0 +228412,1540845044,592380850,0 +228413,1540845045,1540845046,0 +228414,1540845046,1540845047,0 +228415,1540845047,1540845048,0 +228416,1540845048,272567495,0 +228425,1540845057,1540845058,0 +228426,1540845058,1540845059,0 +228427,1540845059,1540845060,0 +228428,1540845060,1540845061,0 +228429,1540845061,1540845062,0 +228430,1540845062,36243712,0 +228431,1540845063,355929441,0 +228432,1540845064,1540845065,0 +228433,1540845065,1540845066,0 +228434,1540845066,36245102,0 +228435,1540845067,1540845068,0 +228436,1540845068,1540845069,0 +228437,1540845069,1540845070,0 +228438,1540845070,592561536,0 +228439,1540845071,1540845072,0 +228440,1540845072,1540845073,0 +228441,1540845073,1540845074,0 +228442,1540845074,1540845075,0 +228443,1540845075,1540845076,0 +228444,1540845076,1540845077,0 +228445,1540845077,1540845078,0 +228446,1540845078,1540845079,0 +228447,1540845079,592381081,0 +228448,1540845080,355929441,0 +228449,1540845081,1540845082,0 +228450,1540845082,1540845083,0 +228451,1540845083,592561550,0 +228452,1540845084,1540845085,0 +228453,1540845085,1540845086,0 +228454,1540845086,1540845087,0 +228455,1540845087,1540845088,0 +228456,1540845088,1540845089,0 +228457,1540845089,1540845090,0 +228458,1540845090,1540845091,0 +228459,1540845091,1540845092,0 +228460,1540845092,1540845093,0 +228461,1540845093,1540845094,0 +228462,1540845094,1540845095,0 +228463,1540845095,1540845096,0 +228464,1540845096,1540845097,0 +228465,1540845097,1540845098,0 +228466,1540845098,1540845099,0 +228467,1540845099,1540845100,0 +228468,1540845100,1540845101,0 +228469,1540845101,1540845102,0 +228470,1540845102,1540845103,0 +228471,1540845103,1540845104,0 +228472,1540845104,1540845105,0 +228473,1540845105,272567495,0 +228474,1540845106,1540845107,0 +228475,1540845107,1540845108,0 +228476,1540845108,1540845109,0 +228477,1540845109,1540845110,0 +228478,1540845110,1540845111,0 +228479,1540845111,1540845112,0 +228480,1540845112,1540845113,0 +228481,1540845113,1540845114,0 +228482,1540845114,1540845115,0 +228483,1540845115,592561605,0 +228484,1540845116,1540845117,0 +228485,1540845117,745988413,0 +228486,1540845118,1540845119,0 +228487,1540845119,1540845120,0 +228488,1540845120,1540845121,0 +228489,1540845121,1540845122,0 +228490,1540845122,1540845123,0 +228491,1540845123,1540845124,0 +228492,1540845124,1540845125,0 +228493,1540845125,1540845126,0 +228494,1540845126,592561614,0 +228495,1540845127,1540845128,0 +228496,1540845128,1540845129,0 +228497,1540845129,1540845130,0 +228498,1540845130,592381000,0 +228499,1540845131,1540845132,0 +228500,1540845132,1540845133,0 +228501,1540845133,1540845134,0 +228502,1540845134,1540845135,0 +228503,1540845135,1540845136,0 +228504,1540845136,592383588,0 +228505,1540845137,592381002,0 +228506,1540845138,1540845139,0 +228507,1540845139,1540845140,0 +228508,1540845140,1540845141,0 +228509,1540845141,592381275,0 +228510,1540845142,1540845143,0 +228511,1540845143,1540845144,0 +228512,1540845144,1540845145,0 +228513,1540845145,1540845146,0 +228514,1540845146,592561637,0 +228515,1540845147,1540845148,0 +228516,1540845148,1540845149,0 +228517,1540845149,1540845150,0 +228518,1540845150,1540845151,0 +228519,1540845151,1540845152,0 +228520,1540845152,1540845153,0 +228521,1540845153,1540845154,0 +228522,1540845154,745988431,0 +228523,1540845155,1540845156,0 +228524,1540845156,1540845157,0 +228525,1540845157,1540845158,0 +228526,1540845158,1540845159,0 +228527,1540845159,1540845160,0 +228528,1540845160,1540845161,0 +228529,1540845161,1540845162,0 +228530,1540845162,1540845163,0 +228531,1540845163,1540845164,0 +228532,1540845164,1540845165,0 +228533,1540845165,1540845166,0 +228534,1540845166,1540845167,0 +228535,1540845167,1540845168,0 +228536,1540845168,1540845169,0 +228537,1540845169,793252679,0 +228538,1540845170,1540845171,0 +228539,1540845171,1540845172,0 +228540,1540845172,1540845173,0 +228541,1540845173,1540845174,0 +228542,1540845174,1540845175,0 +228543,1540845175,592567268,0 +228544,1540845176,1540845177,0 +228545,1540845177,1540845178,0 +228546,1540845178,592567296,0 +228547,1540845179,1540845180,0 +228548,1540845180,301343710,0 +228549,1540845181,1540845182,0 +228550,1540845182,1540845183,0 +228551,1540845183,1540845184,0 +228552,1540845184,1540845185,0 +228553,1540845185,1540845186,0 +228554,1540845186,1540845187,0 +228555,1540845187,1540845188,0 +228556,1540845188,1540845189,0 +228557,1540845189,1540845190,0 +228558,1540845190,1540845191,0 +228559,1540845191,592380930,0 +228963,1540845595,1540845596,0 +228964,1540845596,1540845597,0 +228965,1540845597,347782338,0 +229050,1540845682,1540845683,0 +229051,1540845683,561406933,0 +229052,1540845684,561406925,0 +229053,1540845685,1540845686,0 +229054,1540845686,1540845687,0 +229055,1540845687,1141269283,0 +229056,1540845688,597692611,0 +229057,1540845689,1540845690,0 +229058,1540845690,597692623,0 +229059,1540845691,175702450,0 +229060,1540845692,1540845693,0 +229061,1540845693,1540845694,0 +229062,1540845694,36643968,0 +229063,1540845695,1540845696,0 +229064,1540845696,36643971,0 +229065,1540845697,1193464694,0 +229066,1540845698,560712653,0 +229112,1540845744,1540845745,0 +229113,1540845745,1540845746,0 +229114,1540845746,462754220,0 +229115,1540845747,801062884,0 +229116,1540845748,801062905,0 +229117,1540845749,272562945,0 +229118,1540845750,584361252,0 +229119,1540845751,1308321810,0 +229120,1540845752,598495520,0 +229121,1540845753,1540845754,0 +229122,1540845754,598495533,0 +229123,1540845755,462754219,0 +229124,1540845756,462754220,0 +229125,1540845757,598495542,0 +229126,1540845758,1540845759,0 +229127,1540845759,1540845760,0 +229128,1540845760,1540845761,0 +229129,1540845761,1540845762,0 +229130,1540845762,598495891,0 +229131,1540845763,360731454,0 +229132,1540845764,1540845765,0 +229133,1540845765,1540845766,0 +229134,1540845766,1540845767,0 +229135,1540845767,1540845768,0 +229136,1540845768,1540845769,0 +229137,1540845769,1540845770,0 +229138,1540845770,1540845771,0 +229139,1540845771,1540845772,0 +229140,1540845772,1540845773,0 +229141,1540845773,1540845774,0 +229142,1540845774,1540845775,0 +229143,1540845775,592381242,0 +229144,1540845776,1540845777,0 +229145,1540845777,1540845778,0 +229146,1540845778,1540845779,0 +229147,1540845779,1540845780,0 +229148,1540845780,294207609,0 +229149,1540845781,800448656,0 +229150,1540845782,1540845783,0 +229151,1540845783,1540845784,0 +229152,1540845784,1540845785,0 +229153,1540845785,1540845786,0 +229154,1540845786,1540845787,0 +229155,1540845787,1540845788,0 +229156,1540845788,1540845789,0 +229157,1540845789,1540845790,0 +229158,1540845790,1540845791,0 +229159,1540845791,1540845792,0 +229160,1540845792,1540845793,0 +229161,1540845793,1540845794,0 +229162,1540845794,592381024,0 +229163,1540845795,592381248,0 +229164,1540845796,598495892,0 +229195,1540845827,1540845828,1 +229196,1540845828,1540845829,1 +229197,1540845829,1540845830,1 +229198,1540845830,1540845831,1 +229199,1540845831,1540845832,1 +229200,1540845832,1540845833,1 +229201,1540845833,1540845834,1 +229202,1540845834,1540845835,1 +229203,1540845835,1540845836,1 +229204,1540845836,1540845837,1 +229205,1540845837,598497217,1 +229206,1540845838,1540845839,1 +229207,1540845839,1540845840,1 +229208,1540845840,1540845841,1 +229209,1540845841,1540845842,1 +229210,1540845842,1540845843,1 +229211,1540845843,1540845844,1 +229212,1540845844,1540845845,1 +229213,1540845845,1540845846,1 +229214,1540845846,1540845847,1 +229215,1540845847,1540845848,1 +229216,1540845848,1540845849,1 +229217,1540845849,1540845850,1 +229218,1540845850,1540845851,1 +229219,1540845851,1540845852,1 +229220,1540845852,1540845853,1 +229221,1540845853,1540845854,1 +229228,1540845860,1540845861,1 +229229,1540845861,1540845862,1 +229230,1540845862,1540845863,1 +229231,1540845863,1540845864,1 +229232,1540845864,598497285,1 +229239,1540845871,801062755,0 +229240,1540845872,1540845873,0 +229241,1540845873,1540845874,0 +229242,1540845874,1540845875,0 +229243,1540845875,1540845876,0 +229244,1540845876,598498283,0 +229245,1540845877,598498285,0 +229246,1540845878,800448890,0 +229247,1540845879,598498290,0 +229248,1540845880,1540845881,0 +229249,1540845881,800448632,0 +229264,1540845896,272568021,0 +229679,1540846311,1540846312,0 +229680,1540846312,1540846313,0 +229681,1540846313,1540846314,0 +229682,1540846314,1540846315,0 +229683,1540846315,1540846316,0 +229684,1540846316,360731454,0 +229685,1540846317,746691510,0 +229686,1540846318,360731577,0 +229687,1540846319,361194245,0 +229688,1540846320,1235838542,0 +229689,1540846321,38842542,0 +229690,1540846322,360731219,0 +229691,1540846323,1540846324,0 +229692,1540846324,38842545,0 +229693,1540846325,1540846326,0 +229694,1540846326,360728936,0 +229695,1540846327,705971069,0 +229696,1540846328,1540846329,0 +229697,1540846329,1540846330,0 +229698,1540846330,1540846331,0 +229699,1540846331,360727493,0 +229700,1540846332,1540846333,0 +229701,1540846333,1239786760,0 +229702,1540846334,360471305,0 +229703,1540846335,360470694,0 +229704,1540846336,1540846337,0 +229705,1540846337,1540846338,0 +229706,1540846338,360470729,0 +229707,1540846339,360470197,0 +229708,1540846340,1540846341,0 +229709,1540846341,360469654,0 +229710,1540846342,1540846343,0 +229711,1540846343,1540846344,0 +229712,1540846344,1540846345,0 +229713,1540846345,38842565,0 +229714,1540846346,360468380,0 +229741,1540846373,599162401,0 +229742,1540846374,246588460,0 +229743,1540846375,1540846376,0 +229744,1540846376,1540846377,0 +229745,1540846377,1540846378,0 +229746,1540846378,599162401,0 +229747,1540846379,1540846380,0 +229748,1540846380,1540846381,0 +229749,1540846381,1540846382,0 +229750,1540846382,579794613,0 +230007,1540846639,568806865,1 +230008,1540846640,1030323854,1 +230009,1540846641,1540846642,1 +230010,1540846642,1540846643,1 +230011,1540846643,1540846644,1 +230012,1540846644,1540846645,1 +230013,1540846645,1540846646,1 +230014,1540846646,1540846647,1 +230015,1540846647,1540846648,1 +230016,1540846648,560946147,1 +230017,1540846649,1030975440,1 +230018,1540846650,1540846651,1 +230019,1540846651,1540846652,1 +230020,1540846652,1540846653,1 +230021,1540846653,1540846654,1 +230022,1540846654,1540846655,1 +230023,1540846655,1540846656,1 +230024,1540846656,1540846657,1 +230025,1540846657,1540846658,1 +230026,1540846658,1540846659,1 +230027,1540846659,1540846660,1 +230028,1540846660,1540846661,1 +230029,1540846661,1540846662,1 +230030,1540846662,1540846663,1 +230031,1540846663,1540846664,1 +230032,1540846664,1540846665,1 +230033,1540846665,1387911689,1 +230034,1540846666,1179187952,1 +230035,1540846667,1540846668,0 +230036,1540846668,1540846669,0 +230037,1540846669,1540846670,0 +230038,1540846670,360200740,0 +230039,1540846671,1540846672,0 +230040,1540846672,1540846673,0 +230041,1540846673,1540846674,0 +230042,1540846674,600400244,0 +230043,1540846675,600629014,0 +230044,1540846676,1540846677,0 +230045,1540846677,1540846678,0 +230046,1540846678,1540846679,0 +230047,1540846679,600629016,0 +230048,1540846680,1540846681,0 +230049,1540846681,1540846682,0 +230050,1540846682,1540846683,0 +230051,1540846683,1540846684,0 +230052,1540846684,1540846685,0 +230053,1540846685,1540846686,0 +230054,1540846686,600629016,0 +230055,1540846687,1540846688,0 +230056,1540846688,1540846689,0 +230057,1540846689,1540846690,0 +230058,1540846690,1540846691,0 +230059,1540846691,1540846692,0 +230060,1540846692,1540846693,0 +230061,1540846693,600629071,0 +230062,1540846694,600629094,1 +230063,1540846695,1540846696,0 +230064,1540846696,973037254,0 +230065,1540846697,1540846698,0 +230066,1540846698,1540846699,0 +230067,1540846699,1540846700,0 +230068,1540846700,1540846701,0 +230069,1540846701,1540846702,0 +230070,1540846702,1540846703,0 +230071,1540846703,1540846704,0 +230072,1540846704,973017371,0 +230073,1540846705,1540846706,0 +230074,1540846706,1540846707,0 +230075,1540846707,973017226,0 +230076,1540846708,1540846709,1 +230077,1540846709,1540846710,1 +230078,1540846710,1540846711,1 +230079,1540846711,1540846712,1 +230080,1540846712,1540846713,1 +230081,1540846713,1540846714,1 +230082,1540846714,360230284,1 +230083,1540846715,1540846716,1 +230084,1540846716,1540846717,1 +230085,1540846717,1540846718,1 +230086,1540846718,1540846719,1 +230087,1540846719,1540846720,1 +230088,1540846720,155585179,1 +230089,1540846721,600629166,0 +230090,1540846722,600629071,0 +230091,1540846723,1540846724,0 +230092,1540846724,1540846725,0 +230093,1540846725,585199965,0 +230094,1540846726,1540846727,0 +230095,1540846727,1540846728,0 +230096,1540846728,1540846729,0 +230097,1540846729,600629186,0 +230098,1540846730,1540846731,0 +230099,1540846731,1540846732,0 +230100,1540846732,1540846733,0 +230101,1540846733,1540846734,0 +230102,1540846734,1540846735,0 +230103,1540846735,1540846736,0 +230104,1540846736,155587662,0 +230105,1540846737,1540846738,0 +230106,1540846738,1540846739,0 +230107,1540846739,973040049,0 +230108,1540846740,585199960,0 +230109,1540846741,1540846742,0 +230110,1540846742,1540846743,0 +230111,1540846743,1540846744,0 +230112,1540846744,1540846745,0 +230113,1540846745,155587662,0 +230114,1540846746,1540846747,1 +230115,1540846747,1540846748,1 +230116,1540846748,1540846749,1 +230117,1540846749,1540846750,1 +230118,1540846750,360216482,1 +230123,1540846755,1540846756,1 +230124,1540846756,936853776,1 +230125,1540846757,1540846758,0 +230126,1540846758,1540846759,0 +230127,1540846759,600917286,0 +230128,1540846760,1540846761,0 +230129,1540846761,1540846762,0 +230130,1540846762,1540846763,0 +230131,1540846763,360476648,0 +230132,1540846764,1540846765,0 +230133,1540846765,1540846766,0 +230134,1540846766,1540846767,0 +230135,1540846767,368362870,0 +230136,1540846768,1540846769,0 +230137,1540846769,1540846770,0 +230138,1540846770,368362871,0 +230139,1540846771,1540846772,0 +230140,1540846772,1540846773,0 +230141,1540846773,1540846774,0 +230142,1540846774,368362874,0 +230143,1540846775,1540846776,0 +230144,1540846776,1540846777,0 +230145,1540846777,1540846778,0 +230146,1540846778,368362875,0 +230147,1540846779,1540846780,0 +230148,1540846780,1540846781,0 +230149,1540846781,600917284,0 +230150,1540846782,1540846783,0 +230151,1540846783,1540846784,0 +230152,1540846784,1540846785,0 +230153,1540846785,368362872,0 +230154,1540846786,600926419,1 +230155,1540846787,600926420,1 +230156,1540846788,745090597,1 +230157,1540846789,793810058,1 +230158,1540846790,745090377,1 +230159,1540846791,1540846792,1 +230160,1540846792,603748696,1 +230161,1540846793,1540846794,0 +230162,1540846794,1540846795,0 +230163,1540846795,1540846796,0 +230164,1540846796,1540846797,0 +230165,1540846797,1540846798,0 +230166,1540846798,1540846799,0 +230167,1540846799,1540846800,0 +230168,1540846800,600926427,0 +230169,1540846801,600926437,1 +230170,1540846802,1540846803,1 +230171,1540846803,600926457,1 +230172,1540846804,937216256,1 +230173,1540846805,937216460,1 +230174,1540846806,937216157,1 +230175,1540846807,600927575,1 +230176,1540846808,1540846809,0 +230177,1540846809,600927578,0 +230178,1540846810,1540846811,0 +230179,1540846811,1540846812,0 +230180,1540846812,600927575,0 +230181,1540846813,600927586,1 +230182,1540846814,938140792,1 +230183,1540846815,1540846816,1 +230184,1540846816,938140803,1 +230185,1540846817,600927594,1 +230186,1540846818,1540846819,1 +230187,1540846819,600927598,1 +230188,1540846820,1540846821,1 +230189,1540846821,938142924,1 +230190,1540846822,1540846823,1 +230191,1540846823,938143087,1 +230192,1540846824,1540846825,1 +230193,1540846825,600930452,1 +230194,1540846826,1540846827,1 +230195,1540846827,417279548,1 +230196,1540846828,1540846829,0 +230197,1540846829,1540846830,0 +230198,1540846830,1540846831,0 +230199,1540846831,1540846832,0 +230200,1540846832,1540846833,0 +230201,1540846833,1540846834,0 +230202,1540846834,272564781,0 +230203,1540846835,1540846836,0 +230204,1540846836,1540846837,0 +230205,1540846837,1540846838,0 +230206,1540846838,1540846839,0 +230207,1540846839,1540846840,0 +230208,1540846840,1540846841,0 +230209,1540846841,1540846842,0 +230210,1540846842,1540846843,0 +230211,1540846843,1540846844,0 +230212,1540846844,1540846845,0 +230213,1540846845,1540846846,0 +230214,1540846846,600936021,0 +230215,1540846847,1540846848,0 +230216,1540846848,1540846849,0 +230217,1540846849,1540846850,0 +230218,1540846850,1540846851,0 +230219,1540846851,1540846852,0 +230220,1540846852,1540846853,0 +230222,1540846854,1540846855,0 +230223,1540846855,1540846856,0 +230224,1540846856,1540846857,0 +230225,1540846857,1540846858,0 +230226,1540846858,1540846859,0 +230227,1540846859,36243995,0 +230228,1540846860,1540846861,1 +230229,1540846861,937216498,1 +230230,1540846862,937216397,1 +230231,1540846863,601002970,1 +230232,1540846864,1540846865,1 +230233,1540846865,601017562,1 +230234,1540846866,360007323,1 +230235,1540846867,1540846868,1 +230236,1540846868,1540846869,1 +230237,1540846869,1540846870,1 +230238,1540846870,1540846871,1 +230239,1540846871,1540846872,1 +230240,1540846872,360007063,1 +230241,1540846873,1540846874,1 +230242,1540846874,1540846875,1 +230243,1540846875,601017585,1 +230244,1540846876,1540846877,1 +230245,1540846877,1540846878,1 +230246,1540846878,1540846879,1 +230247,1540846879,601026602,1 +230528,1540847160,603748683,0 +230529,1540847161,603748691,0 +230530,1540847162,1540847163,0 +230531,1540847163,603748684,0 +230532,1540847164,1540847165,1 +230533,1540847165,603753183,1 +230534,1540847166,603753251,1 +230535,1540847167,1540847168,1 +230536,1540847168,603748692,1 +230537,1540847169,1540847170,1 +230538,1540847170,603753180,1 +230539,1540847171,1540847172,1 +230540,1540847172,603753191,1 +230541,1540847173,1540847174,1 +230542,1540847174,1540847175,1 +230543,1540847175,1540847176,1 +230544,1540847176,1540847177,1 +230545,1540847177,1540847178,1 +230546,1540847178,1540847179,1 +230547,1540847179,1540847180,1 +230548,1540847180,1540847181,1 +230549,1540847181,1540847182,1 +230550,1540847182,1540847183,1 +230551,1540847183,1540847184,1 +230552,1540847184,1540847185,1 +230553,1540847185,1540847186,1 +230554,1540847186,1540847187,1 +230555,1540847187,1540847188,1 +230556,1540847188,1540847189,1 +230557,1540847189,1540847190,1 +230558,1540847190,1540847191,1 +230559,1540847191,1540847192,1 +230560,1540847192,1540847193,1 +230561,1540847193,1345660761,1 +230562,1540847194,1540847195,1 +230563,1540847195,1540847196,1 +230564,1540847196,1540847197,1 +230565,1540847197,1540847198,1 +230566,1540847198,1540847199,1 +230567,1540847199,1540847200,1 +230568,1540847200,1540847201,1 +230569,1540847201,1540847202,1 +230570,1540847202,1345658492,1 +230571,1540847203,1345658967,1 +231072,1540847704,1540847705,1 +231073,1540847705,1540847706,1 +231074,1540847706,1540847707,1 +231075,1540847707,1540847708,1 +231076,1540847708,1540847709,1 +231077,1540847709,1540847710,1 +231078,1540847710,1540847711,1 +231079,1540847711,1540847712,1 +231080,1540847712,1540847713,1 +231081,1540847713,1540847714,1 +231082,1540847714,1540847715,1 +231083,1540847715,1540847716,1 +231084,1540847716,1540847717,1 +231085,1540847717,1540847718,1 +231086,1540847718,1540847719,1 +231087,1540847719,1540847720,1 +231088,1540847720,1540847721,1 +231089,1540847721,1540847722,1 +231090,1540847722,1540847723,1 +231091,1540847723,1540847724,1 +231092,1540847724,1540847725,1 +231093,1540847725,1540847726,1 +231094,1540847726,1540847727,1 +231095,1540847727,1540847728,1 +231096,1540847728,1540847729,1 +231097,1540847729,1540847730,1 +231098,1540847730,1540847731,1 +231099,1540847731,1540847732,1 +231100,1540847732,1540847733,1 +231101,1540847733,1540847734,1 +231102,1540847734,1540847735,1 +231103,1540847735,1540847736,1 +231104,1540847736,1540847737,1 +231105,1540847737,1540847738,1 +231106,1540847738,1540847739,1 +231107,1540847739,1540847740,1 +231108,1540847740,1540847741,1 +231109,1540847741,1540847742,1 +231110,1540847742,1540847743,1 +231111,1540847743,1540847744,1 +231112,1540847744,1540847745,1 +231113,1540847745,1540847746,1 +231114,1540847746,1540847747,1 +231115,1540847747,1540847748,1 +231116,1540847748,1540847749,1 +231117,1540847749,1540847750,1 +231118,1540847750,1540847751,1 +231119,1540847751,1540847752,1 +231120,1540847752,600400026,1 +231237,1540847869,1540847870,0 +231238,1540847870,1540847871,0 +231239,1540847871,1540847872,0 +231240,1540847872,1540847873,0 +231241,1540847873,1540847874,0 +231242,1540847874,35494034,0 +231583,1540848215,1540848216,1 +231584,1540848216,1540848217,1 +231585,1540848217,1540848218,1 +231586,1540848218,614381224,1 +232124,1540848756,615868091,1 +232125,1540848757,615868020,1 +232126,1540848758,1540848759,1 +232127,1540848759,615868035,1 +232128,1540848760,1540848761,1 +232129,1540848761,1540848762,1 +232130,1540848762,1540848763,1 +232131,1540848763,1540848764,1 +232132,1540848764,1540848765,1 +232133,1540848765,1540848766,1 +232134,1540848766,1540848767,1 +232135,1540848767,1540848768,1 +232136,1540848768,1540848769,1 +232137,1540848769,1540848770,1 +232138,1540848770,1540848771,1 +232139,1540848771,1540848772,1 +232140,1540848772,1540848773,1 +232141,1540848773,1540848774,1 +232142,1540848774,615868149,1 +232143,1540848775,1540848776,1 +232144,1540848776,616320089,1 +232191,1540848823,1540848824,1 +232192,1540848824,1540848825,1 +232193,1540848825,1540848826,1 +232194,1540848826,1540848827,1 +232195,1540848827,1540848828,1 +232196,1540848828,1540848829,1 +232197,1540848829,1540848830,1 +232198,1540848830,1540848831,1 +232199,1540848831,1540848832,1 +232200,1540848832,1540848833,1 +232201,1540848833,1540848834,1 +232202,1540848834,1540848835,1 +232203,1540848835,1540848836,1 +232204,1540848836,1540848837,1 +232205,1540848837,1540848838,1 +232206,1540848838,1540848839,1 +232207,1540848839,1540848840,1 +232208,1540848840,1540848841,1 +232209,1540848841,1540848842,1 +232210,1540848842,616326208,1 +232211,1540848843,1540848844,1 +232212,1540848844,1540848845,1 +232213,1540848845,1540848846,1 +232214,1540848846,1540848847,1 +232215,1540848847,1540848848,1 +232216,1540848848,1540848849,1 +232217,1540848849,1540848850,1 +232218,1540848850,1540848851,1 +232219,1540848851,1540848852,1 +232220,1540848852,1540848853,1 +232221,1540848853,1540848854,1 +232222,1540848854,1540848855,1 +232223,1540848855,1540848856,1 +232224,1540848856,1540848857,1 +232225,1540848857,615891203,1 +232226,1540848858,1540848859,1 +232227,1540848859,1540848860,1 +232228,1540848860,1540848861,1 +232229,1540848861,1540848862,1 +232230,1540848862,1540848863,1 +232306,1540848938,1540848939,1 +232307,1540848939,1540848940,1 +232308,1540848940,616326256,1 +232309,1540848941,1540848942,1 +232310,1540848942,1540848943,1 +232311,1540848943,1540848944,1 +232312,1540848944,1540848945,1 +232313,1540848945,616320034,1 +232333,1540848965,1540848966,1 +232334,1540848966,1540848967,1 +232335,1540848967,1540848968,1 +232336,1540848968,1540848969,1 +232337,1540848969,1540848970,1 +232338,1540848970,1540848971,1 +232339,1540848971,1540848972,1 +232340,1540848972,1540848973,1 +232341,1540848973,1540848974,1 +232342,1540848974,1540848975,1 +232343,1540848975,616320100,1 +232344,1540848976,1540848977,1 +232345,1540848977,1540848978,1 +232346,1540848978,1540848979,1 +232347,1540848979,1540848980,1 +232348,1540848980,1540848981,1 +232349,1540848981,1540848982,1 +232350,1540848982,1540848983,1 +232351,1540848983,1540848984,1 +232352,1540848984,1540848985,1 +232353,1540848985,1540848986,1 +232354,1540848986,1540848987,1 +232355,1540848987,1540848988,1 +232356,1540848988,1540848989,1 +232357,1540848989,1540848990,1 +232358,1540848990,1540848991,1 +232359,1540848991,1540848992,1 +232360,1540848992,1540848993,1 +232361,1540848993,1540848994,1 +232362,1540848994,616326256,1 +233409,1540850041,1540850042,1 +233410,1540850042,1540850043,1 +233411,1540850043,1540850044,1 +233412,1540850044,1540850045,1 +233413,1540850045,1540850046,1 +233414,1540850046,1540850047,1 +233415,1540850047,1540850048,1 +233416,1540850048,1540850049,1 +233417,1540850049,620844469,1 +233418,1540850050,1540850051,1 +233419,1540850051,1540850052,1 +233420,1540850052,1540850053,1 +233421,1540850053,1540850054,1 +233422,1540850054,1540850055,1 +233423,1540850055,1540850056,1 +233424,1540850056,1540850057,1 +233425,1540850057,1540850058,1 +233426,1540850058,1540850059,1 +233427,1540850059,600400237,1 +234501,1540851133,1540851134,1 +234502,1540851134,1540851135,1 +234503,1540851135,1540851136,1 +234504,1540851136,1540851137,1 +234505,1540851137,1540851138,1 +234506,1540851138,625903678,1 +234507,1540851139,1540851140,1 +234508,1540851140,625903693,1 +234509,1540851141,1540851142,1 +234510,1540851142,1540851143,1 +234511,1540851143,1307354481,1 +234512,1540851144,1540851145,1 +234513,1540851145,1540851146,1 +234514,1540851146,1540851147,1 +234515,1540851147,1540851148,1 +234516,1540851148,355921354,1 +234517,1540851149,372786607,1 +234518,1540851150,355921358,1 +234519,1540851151,1540851152,1 +234520,1540851152,1540851153,1 +234521,1540851153,355921360,1 +234522,1540851154,1540851155,1 +234523,1540851155,1540851156,1 +234524,1540851156,1540851157,1 +234525,1540851157,1540851158,1 +234526,1540851158,1540851159,1 +234527,1540851159,1540851160,1 +234528,1540851160,1540851161,1 +234529,1540851161,1540851162,1 +234530,1540851162,1540851163,1 +234531,1540851163,1540851164,1 +234532,1540851164,1540851165,1 +234533,1540851165,788870724,1 +234534,1540851166,1540851167,1 +234535,1540851167,1540851168,1 +234536,1540851168,625912804,1 +234537,1540851169,625911966,1 +234538,1540851170,625912824,1 +234904,1540851536,1540851537,1 +234905,1540851537,1540851538,1 +234906,1540851538,801480054,1 +234907,1540851539,633036606,1 +234908,1540851540,1540851541,1 +234909,1540851541,1540851542,1 +234910,1540851542,633036610,1 +234911,1540851543,800150217,1 +234928,1540851560,1343088172,1 +234929,1540851561,625904181,1 +234930,1540851562,1540851563,1 +234931,1540851563,625912837,1 +234932,1540851564,1540851565,1 +234933,1540851565,625912824,1 +235488,1540852120,1540852121,0 +235489,1540852121,1540852122,0 +235490,1540852122,1540852123,0 +235491,1540852123,984332456,0 +235492,1540852124,1540852125,0 +235493,1540852125,737656124,0 +235494,1540852126,984332586,0 +235495,1540852127,294144767,0 +235496,1540852128,1540852129,0 +235497,1540852129,1540852130,0 +235498,1540852130,1540852131,0 +235499,1540852131,294144919,0 +235500,1540852132,984332534,0 +235501,1540852133,1540852134,0 +235502,1540852134,1540852135,0 +235503,1540852135,984332222,0 +235504,1540852136,1540852137,0 +235505,1540852137,1540852138,0 +235506,1540852138,294138057,0 +235507,1540852139,1540852140,0 +235508,1540852140,1540852141,0 +235509,1540852141,294114683,0 +235510,1540852142,1540852143,0 +235511,1540852143,1540852144,0 +235512,1540852144,803747942,0 +235513,1540852145,1540852146,0 +235514,1540852146,1540852147,0 +235515,1540852147,294162875,0 +235516,1540852148,803745094,0 +235517,1540852149,803745081,0 +235518,1540852150,1540852151,0 +235519,1540852151,1540852152,0 +235520,1540852152,938502252,0 +235521,1540852153,1540852154,0 +235522,1540852154,1540852155,0 +235523,1540852155,1540852156,0 +235524,1540852156,1540852157,0 +235525,1540852157,1540852158,0 +235526,1540852158,294163697,0 +235527,1540852159,1540852160,0 +235528,1540852160,365309671,0 +235529,1540852161,1540852162,0 +235530,1540852162,1540852163,0 +235531,1540852163,1540852164,0 +235532,1540852164,938142985,0 +235533,1540852165,1540852166,0 +235534,1540852166,1540852167,0 +235535,1540852167,938502212,0 +235536,1540852168,938502304,0 +235537,1540852169,938502036,0 +235538,1540852170,1540852171,0 +235539,1540852171,1540852172,0 +235540,1540852172,1540852173,0 +235541,1540852173,1540852174,0 +235542,1540852174,1540852175,0 +235543,1540852175,1540852176,0 +235544,1540852176,1540852177,0 +235545,1540852177,294184359,0 +237124,1540853756,984725839,1 +237125,1540853757,984725759,1 +237126,1540853758,653315865,1 +237127,1540853759,1540853760,1 +237128,1540853760,1540853761,1 +237129,1540853761,1540853762,1 +237130,1540853762,1540853763,1 +237131,1540853763,1540853764,1 +237132,1540853764,653316027,1 +237133,1540853765,984752930,1 +237134,1540853766,653316151,1 +237135,1540853767,653316108,1 +237136,1540853768,1540853769,1 +237137,1540853769,1540853770,1 +237138,1540853770,1540853771,1 +237139,1540853771,1540853772,1 +237140,1540853772,653316109,1 +237141,1540853773,985285937,1 +237142,1540853774,1540853775,1 +237143,1540853775,1540853776,1 +237144,1540853776,1540853777,1 +237145,1540853777,1540853778,1 +237146,1540853778,1540853779,1 +237147,1540853779,1540853780,1 +237148,1540853780,1540853781,1 +237149,1540853781,1540853782,1 +237150,1540853782,1540853783,1 +237151,1540853783,1540853784,1 +237152,1540853784,1540853785,1 +237153,1540853785,1540853786,1 +237154,1540853786,1540853787,1 +237155,1540853787,1540853788,1 +237156,1540853788,1540853789,1 +237157,1540853789,1540853790,1 +237158,1540853790,1540853791,1 +237159,1540853791,1540853792,1 +237160,1540853792,653316148,1 +237161,1540853793,1540853794,1 +237162,1540853794,1540853795,1 +237163,1540853795,1540853796,1 +237164,1540853796,1540853797,1 +237165,1540853797,1540853798,1 +237166,1540853798,1540853799,1 +237167,1540853799,359997003,1 +237168,1540853800,1540853801,1 +237169,1540853801,1540853802,1 +237170,1540853802,653316903,1 +237171,1540853803,653316935,1 +237172,1540853804,667221929,1 +237173,1540853805,653316912,1 +237174,1540853806,653316922,1 +237175,1540853807,653316942,1 +237176,1540853808,667221930,1 +237177,1540853809,938502353,1 +237178,1540853810,653316959,1 +237179,1540853811,1540853812,1 +237180,1540853812,1540853813,1 +237181,1540853813,1540853814,1 +237182,1540853814,1540853815,1 +237183,1540853815,1540853816,1 +237184,1540853816,1540853817,1 +237185,1540853817,1540853818,1 +237186,1540853818,1540853819,1 +237187,1540853819,1540853820,1 +237188,1540853820,1540853821,1 +237189,1540853821,1540853822,1 +237190,1540853822,1540853823,1 +237191,1540853823,1540853824,1 +237192,1540853824,1540853825,1 +237193,1540853825,653316968,1 +237194,1540853826,653316954,1 +237195,1540853827,653317014,0 +237196,1540853828,1343005049,1 +237197,1540853829,938502399,0 +237198,1540853830,653317016,1 +237199,1540853831,984772503,1 +237200,1540853832,984772377,1 +237201,1540853833,984772024,1 +237202,1540853834,1540853835,1 +237203,1540853835,1540853836,1 +237204,1540853836,1540853837,1 +237205,1540853837,1540853838,1 +237206,1540853838,1540853839,1 +237207,1540853839,1540853840,1 +237208,1540853840,1540853841,1 +237209,1540853841,1540853842,1 +237210,1540853842,1540853843,1 +237211,1540853843,984772403,1 +237212,1540853844,1540853845,1 +237213,1540853845,1540853846,1 +237214,1540853846,1540853847,1 +237215,1540853847,984771697,1 +237216,1540853848,1540853849,1 +237217,1540853849,984771495,1 +237218,1540853850,656190174,1 +237219,1540853851,1540853852,1 +237220,1540853852,1141083874,1 +237221,1540853853,653318072,1 +237222,1540853854,1141084025,1 +237223,1540853855,1540853856,1 +237224,1540853856,656190187,1 +237225,1540853857,653318193,1 +237226,1540853858,1540853859,1 +237227,1540853859,1540853860,1 +237228,1540853860,656190187,1 +237229,1540853861,1540853862,1 +237230,1540853862,1540853863,1 +237231,1540853863,1540853864,1 +237232,1540853864,1540853865,1 +237233,1540853865,1540853866,1 +237234,1540853866,1540853867,1 +237235,1540853867,1540853868,1 +237236,1540853868,1540853869,1 +237237,1540853869,1540853870,1 +237238,1540853870,1540853871,1 +237239,1540853871,1540853872,1 +237240,1540853872,1540853873,1 +237241,1540853873,984772415,1 +237242,1540853874,1540853875,1 +237243,1540853875,1540853876,1 +237244,1540853876,1540853877,1 +237245,1540853877,1540853878,1 +237246,1540853878,1540853879,1 +237247,1540853879,1540853880,1 +237248,1540853880,1540853881,1 +237249,1540853881,984772269,1 +237250,1540853882,1540853883,1 +237251,1540853883,1540853884,1 +237252,1540853884,1540853885,1 +237253,1540853885,1540853886,1 +237254,1540853886,1540853887,1 +237255,1540853887,984771572,1 +237256,1540853888,1540853889,1 +237257,1540853889,1540853890,1 +237258,1540853890,653318192,1 +237713,1540854345,656190174,1 +238739,1540855371,1540855372,1 +238740,1540855372,1540855373,1 +238741,1540855373,1540855374,1 +238742,1540855374,1540855375,1 +238743,1540855375,1540855376,1 +238744,1540855376,1540855377,1 +238745,1540855377,1540855378,1 +238746,1540855378,1540855379,1 +238747,1540855379,1540855380,1 +238748,1540855380,620796409,1 +238749,1540855381,279592736,1 +238750,1540855382,1540855383,1 +238751,1540855383,279592740,1 +239145,1540855777,1540855778,0 +239146,1540855778,1540855779,0 +239147,1540855779,1540855780,0 +239148,1540855780,1540855781,0 +239149,1540855781,1540855782,0 +239150,1540855782,1540855783,0 +239151,1540855783,1540855784,0 +239152,1540855784,662948310,0 +239153,1540855785,1540855786,0 +239154,1540855786,1540855787,0 +239155,1540855787,662948253,0 +239156,1540855788,1540855789,0 +239157,1540855789,1540855790,0 +239158,1540855790,1540855791,0 +239159,1540855791,1540855792,0 +239160,1540855792,1540855793,0 +239161,1540855793,1540855794,0 +239162,1540855794,1540855795,0 +239163,1540855795,1540855796,0 +239164,1540855796,662948267,0 +239165,1540855797,1540855798,0 +239166,1540855798,1540855799,0 +239167,1540855799,1540855800,0 +239168,1540855800,1540855801,0 +239169,1540855801,1540855802,0 +239170,1540855802,1540855803,0 +239171,1540855803,1540855804,0 +239172,1540855804,1540855805,0 +239173,1540855805,1540855806,0 +239174,1540855806,662948320,0 +239175,1540855807,1540855808,0 +239176,1540855808,662948314,0 +239177,1540855809,1540855810,0 +239178,1540855810,1540855811,0 +239179,1540855811,1540855812,0 +239180,1540855812,1540855813,0 +239181,1540855813,1540855814,0 +239182,1540855814,585200697,0 +239183,1540855815,1540855816,1 +239184,1540855816,1540855817,1 +239185,1540855817,1540855818,1 +239186,1540855818,1540855819,1 +239187,1540855819,1540855820,1 +239188,1540855820,1540855821,1 +239189,1540855821,1540855822,1 +239190,1540855822,662948320,1 +239191,1540855823,1540855824,0 +239192,1540855824,662948248,0 +239193,1540855825,1540855826,0 +239194,1540855826,662948245,0 +239195,1540855827,1540855828,1 +239196,1540855828,1540855829,1 +239197,1540855829,1540855830,1 +239198,1540855830,1540855831,1 +239199,1540855831,1540855832,1 +239200,1540855832,1540855833,1 +239201,1540855833,1540855834,1 +239202,1540855834,1540855835,1 +239203,1540855835,1540855836,1 +239204,1540855836,1540855837,1 +239205,1540855837,1540855838,1 +239206,1540855838,1540855839,1 +239207,1540855839,1540855840,1 +239208,1540855840,1540855841,1 +239209,1540855841,620796409,1 +239210,1540855842,1540855843,1 +239211,1540855843,1540855844,1 +239212,1540855844,1540855845,1 +239213,1540855845,1540855846,1 +239214,1540855846,1540855847,1 +239215,1540855847,1540855848,1 +239216,1540855848,1540855849,1 +239217,1540855849,1540855850,1 +239218,1540855850,662948253,1 +239219,1540855851,1540855852,0 +239220,1540855852,662948315,0 +239221,1540855853,1540855854,1 +239222,1540855854,1540855855,1 +239223,1540855855,1540855856,1 +239224,1540855856,1540855857,1 +239225,1540855857,1540855858,1 +239226,1540855858,1540855859,1 +239227,1540855859,1540855860,1 +239228,1540855860,1540855861,1 +239229,1540855861,1540855862,1 +239230,1540855862,1540855863,1 +239231,1540855863,1540855864,1 +239232,1540855864,1540855865,1 +239233,1540855865,1540855866,1 +239234,1540855866,1540855867,1 +239235,1540855867,1540855868,1 +239236,1540855868,1540855869,1 +239237,1540855869,1540855870,1 +239238,1540855870,1540855871,1 +239239,1540855871,1540855872,1 +239240,1540855872,662949764,1 +239288,1540855920,1540855921,1 +239289,1540855921,1540855922,1 +239290,1540855922,1540855923,1 +239291,1540855923,1540855924,1 +239292,1540855924,1540855925,1 +239293,1540855925,1540855926,1 +239294,1540855926,1540855927,1 +239295,1540855927,360024126,1 +239317,1540855949,279592740,1 +239563,1540856195,1540856196,1 +239564,1540856196,360720466,1 +239565,1540856197,745988368,1 +239566,1540856198,745988398,1 +239567,1540856199,1540856200,1 +239568,1540856200,1540856201,1 +239569,1540856201,1540856202,1 +239570,1540856202,598495494,1 +239571,1540856203,457428510,1 +239572,1540856204,1540856205,1 +239573,1540856205,1540856206,1 +239574,1540856206,1540856207,1 +239575,1540856207,1540856208,1 +239576,1540856208,1540856209,1 +239577,1540856209,1540856210,1 +239578,1540856210,678158799,1 +239579,1540856211,1540856212,1 +239580,1540856212,1540856213,1 +239581,1540856213,1540856214,1 +239582,1540856214,1540856215,1 +239583,1540856215,1540856216,1 +239584,1540856216,678158820,1 +239585,1540856217,1540856218,1 +239586,1540856218,1540856219,1 +239587,1540856219,678158834,1 +239588,1540856220,1540856221,1 +239589,1540856221,678158866,1 +239590,1540856222,678178640,1 +239591,1540856223,678178642,0 +239592,1540856224,353246430,0 +239593,1540856225,678178653,1 +239708,1540856340,361445756,0 +239709,1540856341,1540856342,0 +239710,1540856342,1540856343,0 +239711,1540856343,1540856344,0 +239712,1540856344,1540856345,0 +239713,1540856345,1540856346,0 +239714,1540856346,36244146,0 +239715,1540856347,683301242,1 +239716,1540856348,1540856349,1 +239717,1540856349,683301242,1 +239760,1540856392,694758816,0 +239761,1540856393,1540856394,1 +239762,1540856394,694820287,1 +239763,1540856395,694820349,1 +239764,1540856396,338485095,1 +239765,1540856397,1540856398,0 +239766,1540856398,694829015,0 +239767,1540856399,365118106,1 +239768,1540856400,1540856401,1 +239769,1540856401,695552921,1 +239770,1540856402,695553011,1 +239771,1540856403,1540856404,1 +239772,1540856404,695556395,1 +239782,1540856414,1540856415,1 +239783,1540856415,278009596,1 +239784,1540856416,704804605,1 +239785,1540856417,1540856418,1 +239786,1540856418,704804607,1 +239787,1540856419,1540856420,1 +239788,1540856420,1540856421,1 +239789,1540856421,704804611,1 +239790,1540856422,1540856423,1 +239791,1540856423,1540856424,1 +239792,1540856424,1540856425,1 +239793,1540856425,1540856426,1 +239794,1540856426,1540856427,1 +239795,1540856427,1540856428,1 +239796,1540856428,1540856429,1 +239797,1540856429,704804617,1 +239798,1540856430,1540856431,1 +239799,1540856431,1540856432,1 +239800,1540856432,1540856433,1 +239801,1540856433,1540856434,1 +239802,1540856434,810713373,1 +239803,1540856435,810713373,1 +239804,1540856436,1540856437,1 +239805,1540856437,1540856438,1 +239806,1540856438,704804634,1 +239807,1540856439,1371125358,1 +239808,1540856440,704804636,1 +239809,1540856441,704804655,1 +239810,1540856442,1371124921,1 +239811,1540856443,704804657,1 +239812,1540856444,1540856445,1 +239813,1540856445,1540856446,1 +239814,1540856446,1540856447,1 +239815,1540856447,1540856448,1 +239816,1540856448,704804601,1 +239817,1540856449,1540856450,1 +239818,1540856450,704804662,1 +239819,1540856451,704826065,1 +239820,1540856452,704826074,1 +239821,1540856453,705065834,1 +239822,1540856454,704826082,1 +239823,1540856455,704832134,1 +239824,1540856456,1540856457,1 +239825,1540856457,361194477,1 +239826,1540856458,704832150,1 +239827,1540856459,360730763,1 +239828,1540856460,361197327,1 +239829,1540856461,361195482,1 +239830,1540856462,705059053,1 +239831,1540856463,1540856464,1 +239832,1540856464,705059089,1 +239833,1540856465,361194196,1 +239834,1540856466,705060400,1 +239835,1540856467,705063972,1 +239836,1540856468,361196558,1 +239837,1540856469,705073924,1 +239838,1540856470,1540856471,1 +239839,1540856471,1540856472,1 +239840,1540856472,705073936,1 +239841,1540856473,1540856474,1 +239842,1540856474,1540856475,1 +239843,1540856475,705073947,1 +239844,1540856476,705073950,1 +239845,1540856477,1540856478,1 +239846,1540856478,360730453,1 +239847,1540856479,1540856480,1 +239848,1540856480,1540856481,1 +239849,1540856481,1540856482,1 +239850,1540856482,705073986,1 +239851,1540856483,705970929,1 +239852,1540856484,360731050,1 +239853,1540856485,360730989,1 +239854,1540856486,705971053,1 +239855,1540856487,1540856488,1 +239856,1540856488,1540856489,1 +239857,1540856489,360728170,1 +239858,1540856490,705979157,1 +239859,1540856491,1540856492,0 +239860,1540856492,353246125,0 +239861,1540856493,1540856494,1 +239862,1540856494,705979263,1 +239863,1540856495,705979280,1 +239864,1540856496,705990368,1 +239865,1540856497,705990371,1 +239866,1540856498,360472071,1 +239867,1540856499,705990388,0 +239868,1540856500,360473428,0 +239869,1540856501,1540856502,0 +239870,1540856502,360727836,0 +239871,1540856503,353245113,1 +239872,1540856504,360728029,1 +239873,1540856505,353245525,1 +239874,1540856506,1540856507,1 +239875,1540856507,353245716,1 +239876,1540856508,1540856509,0 +239877,1540856509,360727918,0 +239878,1540856510,360727947,0 +239879,1540856511,1540856512,1 +239880,1540856512,360470318,1 +239881,1540856513,360470601,1 +239882,1540856514,1540856515,1 +239883,1540856515,706002947,1 +239884,1540856516,1540856517,1 +239885,1540856517,706821434,1 +239886,1540856518,360469447,1 +239887,1540856519,706821660,1 +239888,1540856520,1540856521,0 +239889,1540856521,360473619,0 +239890,1540856522,360469320,1 +239891,1540856523,1540856524,1 +239892,1540856524,1540856525,1 +239893,1540856525,272554693,1 +239894,1540856526,1540856527,0 +239895,1540856527,1285491909,0 +239897,1540856529,716888455,1 +239898,1540856530,716888478,1 +239899,1540856531,716888493,1 +239900,1540856532,429286588,1 +239901,1540856533,1540856534,1 +239902,1540856534,360206101,1 +239903,1540856535,716888615,1 +239904,1540856536,1540856537,1 +239905,1540856537,1540856538,1 +239906,1540856538,716888663,1 +239907,1540856539,1540856540,1 +239908,1540856540,1540856541,1 +239909,1540856541,1540856542,1 +239910,1540856542,716888709,1 +239911,1540856543,716888733,1 +239912,1540856544,1540856545,0 +239913,1540856545,429286578,0 +239914,1540856546,1540856547,0 +239915,1540856547,716888861,0 +239916,1540856548,1540856549,1 +239917,1540856549,1540856550,1 +239918,1540856550,1540856551,1 +239919,1540856551,1540856552,1 +239920,1540856552,1030329099,1 +239921,1540856553,429286592,1 +239922,1540856554,716888947,1 +239923,1540856555,429286590,1 +240115,1540856747,1540856748,1 +240116,1540856748,1540856749,1 +240117,1540856749,1540856750,1 +240118,1540856750,1540856751,1 +240119,1540856751,1540856752,1 +240120,1540856752,737307859,1 +240121,1540856753,736532468,1 +240122,1540856754,1540856755,1 +240123,1540856755,736532620,1 +240124,1540856756,1540856757,1 +240125,1540856757,1540856758,1 +240126,1540856758,1540856759,1 +240127,1540856759,1540856760,1 +240128,1540856760,1540856761,1 +240129,1540856761,1540856762,1 +240130,1540856762,1540856763,1 +240131,1540856763,1540856764,1 +240132,1540856764,1540856765,1 +240133,1540856765,1540856766,1 +240134,1540856766,736533381,1 +240135,1540856767,1540856768,1 +240136,1540856768,1540856769,1 +240137,1540856769,736537339,1 +240138,1540856770,737307548,1 +240139,1540856771,1540856772,1 +240140,1540856772,737307369,1 +240141,1540856773,736532729,1 +240142,1540856774,1540856775,1 +240143,1540856775,1540856776,1 +240144,1540856776,736532784,1 +240145,1540856777,736532791,1 +240146,1540856778,736532590,1 +240147,1540856779,1540856780,1 +240148,1540856780,736532807,1 +240149,1540856781,1540856782,1 +240150,1540856782,736532807,1 +240151,1540856783,736532596,1 +240152,1540856784,1540856785,1 +240153,1540856785,736533195,1 +240154,1540856786,736533220,1 +240155,1540856787,736533195,1 +240156,1540856788,1540856789,1 +240157,1540856789,736532784,1 +240158,1540856790,1540856791,1 +240159,1540856791,736532361,1 +240160,1540856792,1540856793,1 +240161,1540856793,1540856794,1 +240162,1540856794,736533042,1 +240163,1540856795,736533381,1 +240164,1540856796,1540856797,1 +240165,1540856797,736533576,1 +240166,1540856798,1540856799,1 +240167,1540856799,736533498,1 +240168,1540856800,736605128,1 +240169,1540856801,737260666,1 +240170,1540856802,736533638,1 +240171,1540856803,1540856804,1 +240172,1540856804,736605123,1 +240173,1540856805,1540856806,1 +240174,1540856806,736607251,1 +240175,1540856807,1540856808,1 +240176,1540856808,1540856809,1 +240177,1540856809,736604714,1 +240178,1540856810,736545306,1 +240179,1540856811,736546181,1 +240180,1540856812,737636351,1 +240181,1540856813,1540856814,1 +240182,1540856814,1540856815,1 +240183,1540856815,1540856816,1 +240184,1540856816,1540856817,1 +240185,1540856817,1540856818,1 +240186,1540856818,737636363,1 +240187,1540856819,736545306,1 +240188,1540856820,1540856821,1 +240189,1540856821,1540856822,1 +240190,1540856822,1540856823,1 +240191,1540856823,1540856824,1 +240192,1540856824,736605186,1 +240193,1540856825,1540856826,1 +240194,1540856826,736604714,1 +240195,1540856827,737636296,1 +240196,1540856828,1540856829,1 +240197,1540856829,1540856830,1 +240198,1540856830,736546855,1 +240199,1540856831,736604653,1 +240200,1540856832,1540856833,1 +240201,1540856833,1540856834,1 +240202,1540856834,1540856835,1 +240203,1540856835,736604701,1 +240204,1540856836,736607265,1 +240205,1540856837,1540856838,1 +240206,1540856838,736604722,1 +240207,1540856839,736607257,1 +240208,1540856840,736604989,1 +240209,1540856841,1540856842,1 +240210,1540856842,1540856843,1 +240211,1540856843,1540856844,1 +240212,1540856844,736607456,1 +240213,1540856845,736605088,1 +240214,1540856846,736605096,1 +240215,1540856847,736607242,1 +240216,1540856848,736607249,1 +240217,1540856849,1540856850,1 +240218,1540856850,736607456,1 +240219,1540856851,736605167,1 +240220,1540856852,1540856853,1 +240221,1540856853,1540856854,1 +240222,1540856854,736605159,1 +240223,1540856855,1540856856,1 +240224,1540856856,1540856857,1 +240225,1540856857,1540856858,1 +240226,1540856858,1540856859,1 +240227,1540856859,1540856860,1 +240228,1540856860,1540856861,1 +240229,1540856861,736605186,1 +240230,1540856862,736604772,1 +240231,1540856863,1540856864,1 +240232,1540856864,736604883,1 +240233,1540856865,1540856866,1 +240234,1540856866,736605116,1 +240235,1540856867,736607253,1 +240236,1540856868,1540856869,1 +240237,1540856869,736604701,1 +240238,1540856870,1540856871,1 +240239,1540856871,1540856872,1 +240240,1540856872,1540856873,1 +240241,1540856873,1540856874,1 +240242,1540856874,1540856875,1 +240243,1540856875,736605252,1 +240244,1540856876,737260685,1 +240245,1540856877,736607270,1 +240246,1540856878,1540856879,1 +240247,1540856879,736607278,1 +240248,1540856880,736607280,1 +240249,1540856881,736607175,1 +240250,1540856882,1540856883,0 +240251,1540856883,361196599,0 +240252,1540856884,736968721,1 +240253,1540856885,737307686,1 +240254,1540856886,1540856887,1 +240255,1540856887,736968948,1 +240256,1540856888,737253178,1 +240257,1540856889,1540856890,1 +240258,1540856890,1540856891,1 +240259,1540856891,1540856892,1 +240260,1540856892,737253235,1 +240261,1540856893,736968952,1 +240262,1540856894,736968954,1 +240263,1540856895,737253280,1 +240264,1540856896,1540856897,1 +240265,1540856897,737252881,1 +240266,1540856898,1540856899,1 +240267,1540856899,736968956,1 +240268,1540856900,1540856901,1 +240269,1540856901,737248946,1 +240270,1540856902,737253124,1 +240271,1540856903,737248920,1 +240272,1540856904,1540856905,1 +240273,1540856905,1540856906,1 +240274,1540856906,1540856907,1 +240275,1540856907,737248931,1 +240276,1540856908,737248936,1 +240277,1540856909,737252891,1 +240278,1540856910,736968937,1 +240279,1540856911,1540856912,1 +240280,1540856912,737248950,1 +240281,1540856913,1540856914,1 +240282,1540856914,737248953,1 +240283,1540856915,1540856916,1 +240284,1540856916,1540856917,1 +240285,1540856917,1540856918,1 +240286,1540856918,737248958,1 +240287,1540856919,737248947,1 +240288,1540856920,737248963,1 +240289,1540856921,1540856922,1 +240290,1540856922,737252846,1 +240291,1540856923,737253124,1 +240292,1540856924,736968956,1 +240293,1540856925,737252801,1 +240294,1540856926,737252805,1 +240295,1540856927,1540856928,1 +240296,1540856928,1540856929,1 +240297,1540856929,737252812,1 +240298,1540856930,1540856931,1 +240299,1540856931,737255488,1 +240300,1540856932,737252812,1 +240301,1540856933,737252891,1 +240302,1540856934,737252840,1 +240303,1540856935,1540856936,1 +240304,1540856936,737252852,1 +240305,1540856937,1540856938,1 +240306,1540856938,1540856939,1 +240307,1540856939,1540856940,1 +240308,1540856940,1540856941,1 +240309,1540856941,1540856942,1 +240310,1540856942,1540856943,1 +240311,1540856943,737252899,1 +240312,1540856944,737252933,1 +240313,1540856945,1540856946,1 +240314,1540856946,737252868,1 +240315,1540856947,1540856948,1 +240316,1540856948,1540856949,1 +240317,1540856949,1540856950,1 +240318,1540856950,737252904,1 +240319,1540856951,1540856952,1 +240320,1540856952,1540856953,1 +240321,1540856953,1540856954,1 +240322,1540856954,1540856955,1 +240323,1540856955,737253018,1 +240324,1540856956,737253252,1 +240325,1540856957,1540856958,1 +240326,1540856958,737255157,1 +240327,1540856959,1540856960,1 +240328,1540856960,737255171,1 +240329,1540856961,1540856962,1 +240330,1540856962,1540856963,1 +240331,1540856963,1540856964,1 +240332,1540856964,1540856965,1 +240333,1540856965,737255186,1 +240334,1540856966,737255211,1 +240335,1540856967,1540856968,1 +240336,1540856968,1540856969,1 +240337,1540856969,1540856970,1 +240338,1540856970,1540856971,1 +240339,1540856971,1540856972,1 +240340,1540856972,737255236,1 +240341,1540856973,737255497,1 +240342,1540856974,737252805,1 +240343,1540856975,736968950,1 +240344,1540856976,1540856977,1 +240345,1540856977,1540856978,1 +240346,1540856978,1540856979,1 +240347,1540856979,1540856980,1 +240348,1540856980,1540856981,1 +240349,1540856981,1540856982,1 +240350,1540856982,1540856983,1 +240351,1540856983,1540856984,1 +240352,1540856984,1540856985,1 +240353,1540856985,1540856986,1 +240354,1540856986,984772291,1 +240355,1540856987,1540856988,1 +240356,1540856988,365310995,1 +240357,1540856989,737258693,1 +240358,1540856990,737258700,1 +240359,1540856991,737258696,1 +240360,1540856992,1540856993,1 +240361,1540856993,737258709,1 +240362,1540856994,737258712,1 +240363,1540856995,1540856996,1 +240364,1540856996,1540856997,1 +240365,1540856997,1540856998,1 +240366,1540856998,1540856999,1 +240367,1540856999,1540857000,1 +240368,1540857000,737258722,1 +240369,1540857001,1540857002,1 +240370,1540857002,1540857003,1 +240371,1540857003,737255249,1 +240372,1540857004,1540857005,1 +240373,1540857005,1540857006,1 +240374,1540857006,737258746,1 +240375,1540857007,1540857008,1 +240376,1540857008,1540857009,1 +240377,1540857009,737258751,1 +240378,1540857010,1540857011,1 +240379,1540857011,737258690,1 +240380,1540857012,737258659,1 +240381,1540857013,737258704,1 +240382,1540857014,736546855,1 +240383,1540857015,737260624,1 +240384,1540857016,1540857017,1 +240385,1540857017,737300238,1 +240386,1540857018,737260632,1 +240387,1540857019,1540857020,1 +240388,1540857020,737300237,1 +240389,1540857021,737260636,1 +240390,1540857022,1540857023,1 +240391,1540857023,1540857024,1 +240392,1540857024,737260640,1 +240393,1540857025,737260647,1 +240394,1540857026,1540857027,1 +240395,1540857027,737260659,1 +240396,1540857028,737260661,1 +240397,1540857029,1540857030,1 +240398,1540857030,737260686,1 +240399,1540857031,737260656,1 +240400,1540857032,1540857033,1 +240401,1540857033,737300229,1 +240402,1540857034,1540857035,1 +240403,1540857035,737260615,1 +240404,1540857036,737260630,1 +240405,1540857037,737260651,1 +240406,1540857038,736533647,1 +240407,1540857039,1540857040,1 +240408,1540857040,737260613,1 +240409,1540857041,1540857042,1 +240410,1540857042,736968936,1 +240411,1540857043,1540857044,1 +240412,1540857044,737299108,1 +240413,1540857045,737299117,1 +240414,1540857046,1540857047,1 +240415,1540857047,736968935,1 +240416,1540857048,737300223,1 +240417,1540857049,737300226,1 +240418,1540857050,737300234,1 +240419,1540857051,1540857052,1 +240420,1540857052,737300250,1 +240421,1540857053,737300227,1 +240422,1540857054,984634320,1 +240423,1540857055,737307266,1 +240424,1540857056,737307269,1 +240425,1540857057,984634609,1 +240426,1540857058,985968690,1 +240427,1540857059,1540857060,1 +240428,1540857060,737307341,1 +240429,1540857061,1540857062,1 +240430,1540857062,984639834,1 +240431,1540857063,1540857064,1 +240432,1540857064,1540857065,1 +240433,1540857065,737307306,1 +240434,1540857066,737309586,1 +240435,1540857067,1540857068,1 +240436,1540857068,1540857069,1 +240437,1540857069,737307381,1 +240438,1540857070,737307384,1 +240439,1540857071,1540857072,1 +240440,1540857072,737635373,1 +240441,1540857073,1540857074,1 +240442,1540857074,737635177,1 +240443,1540857075,737307401,1 +240444,1540857076,1540857077,1 +240445,1540857077,1540857078,1 +240446,1540857078,1540857079,1 +240447,1540857079,737307433,1 +240448,1540857080,736533550,1 +240449,1540857081,737307549,1 +240450,1540857082,737307305,1 +240451,1540857083,737307358,1 +240452,1540857084,737307354,1 +240453,1540857085,737307282,1 +240454,1540857086,737307287,1 +240455,1540857087,1540857088,1 +240456,1540857088,1540857089,1 +240457,1540857089,737307325,1 +240458,1540857090,1540857091,1 +240459,1540857091,1540857092,1 +240460,1540857092,737307614,1 +240461,1540857093,1540857094,1 +240462,1540857094,1540857095,1 +240463,1540857095,984639812,1 +240464,1540857096,1540857097,1 +240465,1540857097,737307653,1 +240466,1540857098,737307733,1 +240467,1540857099,737307753,1 +240468,1540857100,737307762,1 +240469,1540857101,1540857102,1 +240470,1540857102,1540857103,1 +240471,1540857103,1540857104,1 +240472,1540857104,737307801,1 +240473,1540857105,737307836,1 +240474,1540857106,1540857107,1 +240475,1540857107,1540857108,1 +240476,1540857108,1540857109,1 +240477,1540857109,1540857110,1 +240478,1540857110,1540857111,1 +240479,1540857111,1540857112,1 +240480,1540857112,1540857113,1 +240481,1540857113,737307859,1 +240482,1540857114,1540857115,1 +240483,1540857115,1540857116,1 +240484,1540857116,737998498,1 +240485,1540857117,1540857118,1 +240486,1540857118,1540857119,1 +240487,1540857119,737307892,1 +240488,1540857120,1540857121,1 +240489,1540857121,1540857122,1 +240490,1540857122,737998501,1 +240491,1540857123,737307949,1 +240492,1540857124,737307955,1 +240493,1540857125,1540857126,1 +240494,1540857126,1540857127,1 +240495,1540857127,1540857128,1 +240496,1540857128,1540857129,1 +240497,1540857129,737307990,1 +240498,1540857130,1540857131,1 +240499,1540857131,1540857132,1 +240500,1540857132,737308026,1 +240501,1540857133,737307733,1 +240502,1540857134,1540857135,1 +240503,1540857135,737307695,1 +240504,1540857136,737307638,1 +240505,1540857137,1540857138,1 +240506,1540857138,737307365,1 +240507,1540857139,1540857140,1 +240508,1540857140,737307990,1 +240509,1540857141,1540857142,1 +240510,1540857142,1540857143,1 +240511,1540857143,1540857144,1 +240512,1540857144,1540857145,1 +240513,1540857145,1540857146,1 +240514,1540857146,1540857147,1 +240515,1540857147,1540857148,1 +240516,1540857148,1540857149,1 +240517,1540857149,736533346,1 +240518,1540857150,1540857151,1 +240519,1540857151,737308368,1 +240520,1540857152,1540857153,1 +240521,1540857153,1540857154,1 +240522,1540857154,1540857155,1 +240523,1540857155,1540857156,1 +240524,1540857156,737308371,1 +240525,1540857157,1540857158,1 +240526,1540857158,1540857159,1 +240527,1540857159,737308382,1 +240528,1540857160,737309573,1 +240529,1540857161,737307381,1 +240530,1540857162,737637986,1 +240531,1540857163,1540857164,1 +240532,1540857164,1540857165,1 +240533,1540857165,737309668,1 +240534,1540857166,737309682,1 +240535,1540857167,737308391,1 +240536,1540857168,600919194,1 +240537,1540857169,1540857170,1 +240538,1540857170,737308382,1 +240539,1540857171,1540857172,1 +240540,1540857172,737307360,1 +240541,1540857173,1540857174,1 +240542,1540857174,1540857175,1 +240543,1540857175,737307582,1 +240544,1540857176,1540857177,1 +240545,1540857177,600919210,1 +240546,1540857178,1540857179,1 +240547,1540857179,1540857180,1 +240548,1540857180,737309694,1 +240549,1540857181,984639809,1 +240550,1540857182,1540857183,1 +240551,1540857183,1540857184,1 +240552,1540857184,737634790,1 +240553,1540857185,737634858,1 +240554,1540857186,1540857187,1 +240555,1540857187,1540857188,1 +240556,1540857188,1540857189,1 +240557,1540857189,1540857190,1 +240558,1540857190,1540857191,1 +240559,1540857191,737634737,1 +240560,1540857192,1540857193,1 +240561,1540857193,1540857194,1 +240562,1540857194,737635177,1 +240563,1540857195,1540857196,1 +240564,1540857196,1540857197,1 +240565,1540857197,1540857198,1 +240566,1540857198,1540857199,1 +240567,1540857199,737635288,1 +240568,1540857200,1540857201,1 +240569,1540857201,1540857202,1 +240570,1540857202,737642023,1 +240571,1540857203,737642149,1 +240572,1540857204,523552914,1 +240573,1540857205,1540857206,1 +240574,1540857206,737635373,1 +240575,1540857207,1540857208,1 +240576,1540857208,737634823,1 +240577,1540857209,737634755,1 +240578,1540857210,737634737,1 +240579,1540857211,1540857212,1 +240580,1540857212,737635624,1 +240581,1540857213,1540857214,1 +240582,1540857214,737307444,1 +240583,1540857215,1540857216,1 +240584,1540857216,737635513,1 +240585,1540857217,1540857218,1 +240586,1540857218,1540857219,1 +240587,1540857219,1540857220,1 +240588,1540857220,1540857221,1 +240589,1540857221,737635918,1 +240590,1540857222,1540857223,1 +240591,1540857223,1540857224,1 +240592,1540857224,737635624,1 +240593,1540857225,1540857226,1 +240594,1540857226,1540857227,1 +240595,1540857227,737307401,1 +240596,1540857228,737636146,1 +240597,1540857229,1540857230,1 +240598,1540857230,737635641,1 +240599,1540857231,1540857232,1 +240600,1540857232,737636146,1 +240601,1540857233,1540857234,1 +240602,1540857234,737636260,1 +240603,1540857235,737636363,1 +240604,1540857236,737636390,1 +240605,1540857237,737642023,1 +240606,1540857238,737642149,1 +240607,1540857239,737642087,1 +240608,1540857240,1540857241,1 +240609,1540857241,737655406,1 +240610,1540857242,1540857243,1 +240611,1540857243,737655619,1 +240612,1540857244,1540857245,1 +240613,1540857245,1540857246,1 +240614,1540857246,1540857247,1 +240615,1540857247,1540857248,1 +240616,1540857248,1540857249,1 +240617,1540857249,1540857250,1 +240618,1540857250,1540857251,1 +240619,1540857251,1540857252,1 +240620,1540857252,1540857253,1 +240621,1540857253,1540857254,1 +240622,1540857254,1540857255,1 +240623,1540857255,1540857256,1 +240624,1540857256,1540857257,1 +240625,1540857257,737655447,1 +240626,1540857258,737655929,1 +240627,1540857259,737655474,1 +240628,1540857260,1540857261,1 +240629,1540857261,1540857262,1 +240630,1540857262,1540857263,1 +240631,1540857263,1540857264,1 +240632,1540857264,1540857265,1 +240633,1540857265,737655673,1 +240634,1540857266,1540857267,1 +240635,1540857267,1540857268,1 +240636,1540857268,1540857269,1 +240637,1540857269,1540857270,1 +240638,1540857270,1540857271,1 +240639,1540857271,737998257,1 +240640,1540857272,737998298,1 +240641,1540857273,1540857274,1 +240642,1540857274,1540857275,1 +240643,1540857275,1540857276,1 +240644,1540857276,1540857277,1 +240645,1540857277,1540857278,1 +240646,1540857278,1540857279,1 +240647,1540857279,1540857280,1 +240648,1540857280,1540857281,1 +240649,1540857281,1540857282,1 +240650,1540857282,1540857283,1 +240651,1540857283,1540857284,1 +240652,1540857284,1540857285,1 +240653,1540857285,1540857286,1 +240654,1540857286,1540857287,1 +240655,1540857287,1540857288,1 +240656,1540857288,1540857289,1 +240657,1540857289,1540857290,1 +240658,1540857290,1540857291,1 +240659,1540857291,737998334,1 +240660,1540857292,1540857293,1 +240661,1540857293,1540857294,1 +240662,1540857294,737998341,1 +240663,1540857295,1540857296,1 +240664,1540857296,1540857297,1 +240665,1540857297,737998367,1 +240666,1540857298,1540857299,1 +240667,1540857299,1540857300,1 +240668,1540857300,1540857301,1 +240669,1540857301,737998371,1 +240670,1540857302,737998430,1 +240671,1540857303,1540857304,1 +240672,1540857304,1540857305,1 +240673,1540857305,737998385,1 +240674,1540857306,1540857307,1 +240675,1540857307,985968802,1 +240676,1540857308,737998504,1 +240692,1540857324,360731340,1 +240693,1540857325,361193758,1 +240694,1540857326,559939153,1 +240695,1540857327,1540857328,1 +240696,1540857328,1540857329,1 +240697,1540857329,559940463,1 +240698,1540857330,1540857331,1 +240699,1540857331,559939150,1 +240700,1540857332,559939097,1 +240701,1540857333,559939033,1 +240702,1540857334,1540857335,1 +240703,1540857335,559939070,1 +240704,1540857336,1540857337,0 +240705,1540857337,1540857338,0 +240706,1540857338,559939186,0 +240707,1540857339,359998947,0 +240708,1540857340,359998809,0 +240709,1540857341,560582741,0 +240710,1540857342,1540857343,1 +240711,1540857343,581290413,1 +240712,1540857344,361196354,0 +240713,1540857345,559590883,1 +240714,1540857346,1540857347,1 +240715,1540857347,559590894,1 +240716,1540857348,559590878,1 +240717,1540857349,1540857350,1 +240718,1540857350,559590995,1 +240719,1540857351,559590925,1 +240720,1540857352,559591326,1 +240721,1540857353,1540857354,1 +240722,1540857354,559591165,1 +240723,1540857355,1540857356,1 +240724,1540857356,1540857357,1 +240725,1540857357,559591271,1 +240726,1540857358,1540857359,1 +240727,1540857359,1540857360,1 +240728,1540857360,428468066,1 +240729,1540857361,360476096,0 +240735,1540857367,793781656,1 +240736,1540857368,745090254,1 +240737,1540857369,745090261,1 +240738,1540857370,1540857371,1 +240739,1540857371,745090317,1 +240740,1540857372,745090323,1 +240741,1540857373,600926420,1 +240742,1540857374,793810060,1 +240743,1540857375,745090800,1 +240744,1540857376,1540857377,1 +240745,1540857377,745090272,1 +240746,1540857378,793799874,1 +240747,1540857379,745090699,1 +240748,1540857380,745090599,1 +240749,1540857381,793428358,1 +240750,1540857382,745090494,1 +240751,1540857383,793385639,1 +240752,1540857384,1540857385,1 +240753,1540857385,793428448,1 +240754,1540857386,1540857387,1 +240755,1540857387,793428432,1 +240756,1540857388,745091066,1 +240757,1540857389,745091077,1 +240758,1540857390,745090918,1 +240759,1540857391,745091099,1 +240760,1540857392,1540857393,1 +240761,1540857393,745091139,1 +240762,1540857394,1540857395,0 +240763,1540857395,1540857396,0 +240764,1540857396,1540857397,0 +240765,1540857397,745985508,0 +240766,1540857398,745988373,1 +240767,1540857399,745988376,1 +240768,1540857400,1540857401,0 +240769,1540857401,1540857402,0 +240770,1540857402,1540857403,0 +240771,1540857403,1540857404,0 +240772,1540857404,1540857405,0 +240773,1540857405,1540857406,0 +240774,1540857406,1540857407,0 +240775,1540857407,363860788,0 +240776,1540857408,745988385,1 +240777,1540857409,745988388,1 +240778,1540857410,1540857411,1 +240779,1540857411,1540857412,1 +240780,1540857412,745988394,1 +240781,1540857413,1540857414,1 +240782,1540857414,1540857415,1 +240783,1540857415,1540857416,1 +240784,1540857416,745988421,1 +240785,1540857417,1540857418,1 +240786,1540857418,1540857419,1 +240787,1540857419,745988425,1 +240788,1540857420,745988427,1 +240789,1540857421,745988402,1 +240790,1540857422,793479464,1 +240791,1540857423,793479401,1 +240792,1540857424,746691722,1 +240793,1540857425,1540857426,1 +240794,1540857426,745990594,1 +240795,1540857427,1540857428,1 +240796,1540857428,1540857429,1 +240797,1540857429,745990595,1 +240798,1540857430,1540857431,1 +240799,1540857431,745990605,1 +240800,1540857432,1540857433,1 +240801,1540857433,745990583,1 +240802,1540857434,1540857435,1 +240803,1540857435,745990606,1 +240804,1540857436,745990407,1 +240805,1540857437,746691602,1 +240806,1540857438,746691630,1 +240807,1540857439,746691671,1 +240808,1540857440,746691661,1 +240809,1540857441,746691469,1 +240861,1540857493,797375681,0 +241780,1540858412,559939104,0 +241785,1540858417,359998626,1 +241786,1540858418,359996135,1 +242141,1540858773,1540858774,1 +242142,1540858774,1540858775,1 +242143,1540858775,1540858776,1 +242144,1540858776,1540858777,1 +242145,1540858777,1540858778,1 +242146,1540858778,1540858779,1 +242147,1540858779,1540858780,1 +242148,1540858780,1540858781,1 +242149,1540858781,1540858782,1 +242150,1540858782,1540858783,1 +242151,1540858783,1540858784,1 +242152,1540858784,1540858785,1 +242153,1540858785,1540858786,1 +242154,1540858786,1540858787,1 +242155,1540858787,1540858788,1 +242156,1540858788,1540858789,1 +242157,1540858789,677948411,1 +242258,1540858890,1540858891,1 +242259,1540858891,775868324,1 +242260,1540858892,1540858893,1 +242261,1540858893,1540858894,1 +242262,1540858894,1540858895,1 +242263,1540858895,1540858896,1 +242264,1540858896,1540858897,1 +242265,1540858897,774084994,1 +242266,1540858898,1540858899,1 +242267,1540858899,1540858900,1 +242268,1540858900,774084999,1 +242269,1540858901,775868203,1 +242270,1540858902,1540858903,1 +242271,1540858903,774085003,1 +242272,1540858904,1540858905,1 +242273,1540858905,788841193,1 +242274,1540858906,1540858907,1 +242275,1540858907,1540858908,1 +242276,1540858908,1540858909,1 +242277,1540858909,1540858910,1 +242278,1540858910,1540858911,1 +242279,1540858911,774085012,1 +242280,1540858912,1540858913,1 +242281,1540858913,1540858914,1 +242282,1540858914,1540858915,1 +242283,1540858915,1540858916,1 +242284,1540858916,1540858917,1 +242285,1540858917,1540858918,1 +242286,1540858918,1540858919,1 +242287,1540858919,774085021,1 +242288,1540858920,774085040,1 +242289,1540858921,1540858922,1 +242290,1540858922,1540858923,1 +242291,1540858923,1540858924,1 +242292,1540858924,1540858925,1 +242293,1540858925,774085046,1 +242294,1540858926,1540858927,1 +242295,1540858927,1540858928,1 +242296,1540858928,774085052,1 +242297,1540858929,774085055,1 +242298,1540858930,1540858931,1 +242299,1540858931,774085058,1 +242300,1540858932,1540858933,1 +242301,1540858933,774085061,1 +242302,1540858934,1540858935,1 +242303,1540858935,774085048,1 +242304,1540858936,1540858937,1 +242305,1540858937,1540858938,1 +242306,1540858938,774085072,1 +242307,1540858939,774085074,1 +242308,1540858940,1540858941,1 +242309,1540858941,1540858942,1 +242310,1540858942,1540858943,1 +242311,1540858943,1540858944,1 +242312,1540858944,1540858945,1 +242313,1540858945,774085081,1 +242314,1540858946,1540858947,1 +242315,1540858947,1540858948,1 +242316,1540858948,1540858949,1 +242317,1540858949,1540858950,1 +242318,1540858950,1540858951,1 +242319,1540858951,1540858952,1 +242320,1540858952,1540858953,1 +242321,1540858953,1540858954,1 +242322,1540858954,1540858955,1 +242323,1540858955,1540858956,1 +242324,1540858956,1540858957,1 +242325,1540858957,1540858958,1 +242326,1540858958,1540858959,1 +242327,1540858959,1540858960,1 +242328,1540858960,1540858961,1 +242329,1540858961,1540858962,1 +242330,1540858962,1540858963,1 +242331,1540858963,1540858964,1 +242332,1540858964,1540858965,1 +242333,1540858965,1540858966,1 +242334,1540858966,1540858967,1 +242335,1540858967,1540858968,1 +242336,1540858968,1540858969,1 +242337,1540858969,1540858970,1 +242338,1540858970,774085162,1 +242339,1540858971,774085166,1 +242340,1540858972,788840838,1 +242341,1540858973,788851314,1 +242342,1540858974,677948378,1 +242343,1540858975,1540858976,1 +242344,1540858976,1540858977,1 +242345,1540858977,1540858978,1 +242346,1540858978,1540858979,1 +242347,1540858979,625912837,1 +242348,1540858980,1540858981,1 +242349,1540858981,788870786,1 +242350,1540858982,625904181,1 +242351,1540858983,1540858984,1 +242352,1540858984,1343088144,1 +242353,1540858985,1540858986,1 +242354,1540858986,625904201,1 +242355,1540858987,1540858988,1 +242356,1540858988,1540858989,1 +242357,1540858989,1540858990,1 +242358,1540858990,1540858991,1 +242359,1540858991,1540858992,1 +242360,1540858992,1540858993,1 +242361,1540858993,1343086030,1 +242362,1540858994,1540858995,1 +242363,1540858995,1540858996,1 +242364,1540858996,1540858997,1 +242365,1540858997,1540858998,1 +242366,1540858998,1540858999,1 +242367,1540858999,1540859000,1 +242368,1540859000,1540859001,1 +242369,1540859001,1540859002,1 +242370,1540859002,1375294972,1 +242371,1540859003,1343084389,1 +242372,1540859004,1540859005,1 +242373,1540859005,1540859006,1 +242374,1540859006,1540859007,1 +242375,1540859007,1540859008,1 +242376,1540859008,1540859009,1 +242377,1540859009,1540859010,1 +242378,1540859010,625904285,1 +242379,1540859011,1540859012,1 +242380,1540859012,1540859013,1 +242381,1540859013,796746781,1 +242382,1540859014,774085053,1 +242383,1540859015,1540859016,1 +242384,1540859016,774085067,1 +242385,1540859017,1540859018,1 +242386,1540859018,1540859019,1 +242387,1540859019,1540859020,1 +242388,1540859020,774085188,1 +242389,1540859021,1540859022,1 +242390,1540859022,1540859023,1 +242391,1540859023,1540859024,1 +242392,1540859024,774085193,1 +242393,1540859025,1540859026,1 +242394,1540859026,774084982,1 +242395,1540859027,775866179,1 +242396,1540859028,775866180,1 +242397,1540859029,1540859030,1 +242398,1540859030,775862953,1 +242399,1540859031,1540859032,1 +242400,1540859032,775862953,1 +242401,1540859033,1540859034,1 +242402,1540859034,775862965,1 +242403,1540859035,1540859036,1 +242404,1540859036,1540859037,1 +242405,1540859037,1540859038,1 +242406,1540859038,775862970,1 +242407,1540859039,1540859040,1 +242408,1540859040,775862974,1 +242409,1540859041,1540859042,1 +242410,1540859042,1540859043,1 +242411,1540859043,1540859044,1 +242412,1540859044,1540859045,1 +242413,1540859045,775862980,1 +242414,1540859046,775862965,1 +242415,1540859047,775862984,1 +242416,1540859048,1540859049,1 +242417,1540859049,1540859050,1 +242418,1540859050,1540859051,1 +242419,1540859051,1540859052,1 +242420,1540859052,1540859053,1 +242421,1540859053,1540859054,1 +242422,1540859054,1540859055,1 +242423,1540859055,1540859056,1 +242424,1540859056,1540859057,1 +242425,1540859057,1540859058,1 +242426,1540859058,1540859059,1 +242427,1540859059,775862997,1 +242428,1540859060,1540859061,1 +242429,1540859061,1540859062,1 +242430,1540859062,775863001,1 +242431,1540859063,1540859064,1 +242432,1540859064,1540859065,1 +242433,1540859065,1540859066,1 +242434,1540859066,1540859067,1 +242435,1540859067,1540859068,1 +242436,1540859068,1540859069,1 +242437,1540859069,1540859070,1 +242438,1540859070,1540859071,1 +242439,1540859071,1540859072,1 +242440,1540859072,1540859073,1 +242441,1540859073,1540859074,1 +242442,1540859074,1540859075,1 +242443,1540859075,1540859076,1 +242444,1540859076,1540859077,1 +242445,1540859077,1540859078,1 +242446,1540859078,1540859079,1 +242447,1540859079,1540859080,1 +242448,1540859080,1540859081,1 +242449,1540859081,1540859082,1 +242450,1540859082,775862965,1 +242451,1540859083,1540859084,1 +242452,1540859084,1540859085,1 +242453,1540859085,1540859086,1 +242454,1540859086,1540859087,1 +242455,1540859087,1540859088,1 +242456,1540859088,1540859089,1 +242457,1540859089,775862984,1 +242458,1540859090,775862959,1 +242459,1540859091,1540859092,1 +242460,1540859092,1540859093,1 +242461,1540859093,1540859094,1 +242462,1540859094,775862981,1 +242463,1540859095,1540859096,1 +242464,1540859096,1540859097,1 +242465,1540859097,1540859098,1 +242466,1540859098,1540859099,1 +242467,1540859099,1540859100,1 +242468,1540859100,1540859101,1 +242469,1540859101,1540859102,1 +242470,1540859102,1540859103,1 +242471,1540859103,775863001,1 +242472,1540859104,1540859105,1 +242473,1540859105,1540859106,1 +242474,1540859106,775863046,1 +242475,1540859107,775863048,1 +242476,1540859108,1540859109,1 +242477,1540859109,1540859110,1 +242478,1540859110,1540859111,1 +242479,1540859111,1540859112,1 +242480,1540859112,1540859113,1 +242481,1540859113,1540859114,1 +242482,1540859114,1540859115,1 +242483,1540859115,775863057,1 +242484,1540859116,774085164,1 +242485,1540859117,1540859118,1 +242486,1540859118,1540859119,1 +242487,1540859119,774085082,1 +242488,1540859120,1540859121,1 +242489,1540859121,1540859122,1 +242490,1540859122,1540859123,1 +242491,1540859123,1540859124,1 +242492,1540859124,1540859125,1 +242493,1540859125,1540859126,1 +242494,1540859126,1540859127,1 +242495,1540859127,775863072,1 +242496,1540859128,775862974,1 +242497,1540859129,1540859130,1 +242498,1540859130,1540859131,1 +242499,1540859131,1540859132,1 +242500,1540859132,1540859133,1 +242501,1540859133,1540859134,1 +242502,1540859134,775863081,1 +242503,1540859135,1540859136,1 +242504,1540859136,1540859137,1 +242505,1540859137,1540859138,1 +242506,1540859138,1540859139,1 +242507,1540859139,1540859140,1 +242508,1540859140,1540859141,1 +242509,1540859141,1540859142,1 +242510,1540859142,1540859143,1 +242511,1540859143,1540859144,1 +242512,1540859144,775863093,1 +242513,1540859145,1540859146,1 +242514,1540859146,1540859147,1 +242515,1540859147,775863098,1 +242516,1540859148,775863100,1 +242517,1540859149,1540859150,1 +242518,1540859150,1540859151,1 +242519,1540859151,1540859152,1 +242520,1540859152,1540859153,1 +242521,1540859153,775862970,1 +242522,1540859154,775862980,1 +242523,1540859155,1540859156,1 +242524,1540859156,1540859157,1 +242525,1540859157,775863111,1 +242526,1540859158,1540859159,1 +242527,1540859159,1540859160,1 +242528,1540859160,775863111,1 +242529,1540859161,775863107,1 +242530,1540859162,1540859163,1 +242531,1540859163,1540859164,1 +242532,1540859164,1540859165,1 +242533,1540859165,1540859166,1 +242534,1540859166,1540859167,1 +242535,1540859167,1540859168,1 +242536,1540859168,1540859169,1 +242537,1540859169,1540859170,1 +242538,1540859170,1540859171,1 +242539,1540859171,775863127,1 +242540,1540859172,1540859173,1 +242541,1540859173,1540859174,1 +242542,1540859174,1540859175,1 +242543,1540859175,1540859176,1 +242544,1540859176,1540859177,1 +242545,1540859177,775863129,1 +242546,1540859178,775863130,1 +242547,1540859179,1540859180,1 +242548,1540859180,1540859181,1 +242549,1540859181,1540859182,1 +242550,1540859182,1540859183,1 +242551,1540859183,1540859184,1 +242552,1540859184,1540859185,1 +242553,1540859185,775863112,1 +242554,1540859186,1540859187,1 +242555,1540859187,1540859188,1 +242556,1540859188,1540859189,1 +242557,1540859189,1540859190,1 +242558,1540859190,1540859191,1 +242559,1540859191,1540859192,1 +242560,1540859192,1540859193,1 +242561,1540859193,1540859194,1 +242562,1540859194,775863128,1 +242563,1540859195,1540859196,1 +242564,1540859196,1540859197,1 +242565,1540859197,1540859198,1 +242566,1540859198,1540859199,1 +242567,1540859199,1540859200,1 +242568,1540859200,775866076,1 +242569,1540859201,1540859202,1 +242570,1540859202,775866080,1 +242571,1540859203,1540859204,1 +242572,1540859204,1540859205,1 +242573,1540859205,1540859206,1 +242574,1540859206,1540859207,1 +242575,1540859207,1540859208,1 +242576,1540859208,1540859209,1 +242577,1540859209,1540859210,1 +242578,1540859210,1540859211,1 +242579,1540859211,775862981,1 +242580,1540859212,1540859213,1 +242581,1540859213,775866094,1 +242582,1540859214,1540859215,1 +242583,1540859215,1540859216,1 +242584,1540859216,1540859217,1 +242585,1540859217,775866099,1 +242586,1540859218,1540859219,1 +242587,1540859219,1540859220,1 +242588,1540859220,775866103,1 +242589,1540859221,1540859222,1 +242590,1540859222,788840856,1 +242591,1540859223,1540859224,1 +242592,1540859224,775866109,1 +242593,1540859225,1540859226,1 +242594,1540859226,1345207351,1 +242595,1540859227,1540859228,1 +242596,1540859228,1540859229,1 +242597,1540859229,775866119,1 +242598,1540859230,1540859231,1 +242599,1540859231,1540859232,1 +242600,1540859232,775866126,1 +242601,1540859233,775866129,1 +242602,1540859234,775866133,1 +242603,1540859235,775866136,1 +242604,1540859236,1540859237,1 +242605,1540859237,1540859238,1 +242606,1540859238,775866115,1 +242607,1540859239,775866113,1 +242608,1540859240,1540859241,1 +242609,1540859241,775866149,1 +242610,1540859242,1540859243,1 +242611,1540859243,1540859244,1 +242612,1540859244,1540859245,1 +242613,1540859245,775866154,1 +242614,1540859246,1540859247,1 +242615,1540859247,775866149,1 +242616,1540859248,1540859249,1 +242617,1540859249,775866126,1 +242618,1540859250,1540859251,1 +242619,1540859251,1540859252,1 +242620,1540859252,1540859253,1 +242621,1540859253,1540859254,1 +242622,1540859254,775866144,1 +242623,1540859255,1540859256,1 +242624,1540859256,775866166,1 +242625,1540859257,1540859258,1 +242626,1540859258,1540859259,1 +242627,1540859259,775866129,1 +242628,1540859260,775866133,1 +242629,1540859261,775866138,1 +242630,1540859262,1540859263,1 +242631,1540859263,1540859264,1 +242632,1540859264,775866166,1 +242633,1540859265,775866137,1 +242634,1540859266,775866081,1 +242635,1540859267,1540859268,1 +242636,1540859268,1540859269,1 +242637,1540859269,1540859270,1 +242638,1540859270,1540859271,1 +242639,1540859271,1540859272,1 +242640,1540859272,1540859273,1 +242641,1540859273,1540859274,1 +242642,1540859274,775866076,1 +242643,1540859275,775866178,1 +242644,1540859276,775866136,1 +242645,1540859277,1540859278,1 +242646,1540859278,1540859279,1 +242647,1540859279,1540859280,1 +242648,1540859280,775863048,1 +242649,1540859281,1540859282,1 +242650,1540859282,1540859283,1 +242651,1540859283,1540859284,1 +242652,1540859284,1540859285,1 +242653,1540859285,775866122,1 +242654,1540859286,1540859287,1 +242655,1540859287,1540859288,1 +242656,1540859288,1540859289,1 +242657,1540859289,775866069,1 +242658,1540859290,775866145,1 +242659,1540859291,1540859292,1 +242660,1540859292,1540859293,1 +242661,1540859293,775866127,1 +242662,1540859294,1540859295,1 +242663,1540859295,775866167,1 +242664,1540859296,1540859297,1 +242665,1540859297,775868198,1 +242666,1540859298,1540859299,1 +242667,1540859299,775868202,1 +242668,1540859300,775868206,1 +242669,1540859301,1540859302,1 +242670,1540859302,1540859303,1 +242671,1540859303,1540859304,1 +242672,1540859304,1540859305,1 +242673,1540859305,1540859306,1 +242674,1540859306,775868214,1 +242675,1540859307,1540859308,1 +242676,1540859308,1540859309,1 +242677,1540859309,1540859310,1 +242678,1540859310,1540859311,1 +242679,1540859311,1540859312,1 +242680,1540859312,1540859313,1 +242681,1540859313,1540859314,1 +242682,1540859314,1540859315,1 +242683,1540859315,774085196,1 +242684,1540859316,775868225,1 +242685,1540859317,1540859318,1 +242686,1540859318,1540859319,1 +242687,1540859319,1540859320,1 +242688,1540859320,1540859321,1 +242689,1540859321,1540859322,1 +242690,1540859322,1540859323,1 +242691,1540859323,1540859324,1 +242692,1540859324,1540859325,1 +242693,1540859325,775866109,1 +242694,1540859326,1540859327,1 +242695,1540859327,1540859328,1 +242696,1540859328,1540859329,1 +242697,1540859329,1540859330,1 +242698,1540859330,1540859331,1 +242699,1540859331,1540859332,1 +242700,1540859332,1540859333,1 +242701,1540859333,1540859334,1 +242702,1540859334,1540859335,1 +242703,1540859335,1540859336,1 +242704,1540859336,1540859337,1 +242705,1540859337,775868248,1 +242706,1540859338,775868251,1 +242707,1540859339,774085012,1 +242708,1540859340,1540859341,1 +242709,1540859341,1540859342,1 +242710,1540859342,775868256,1 +242711,1540859343,1540859344,1 +242712,1540859344,1540859345,1 +242713,1540859345,1540859346,1 +242714,1540859346,775868261,1 +242715,1540859347,1540859348,1 +242716,1540859348,1540859349,1 +242717,1540859349,775868265,1 +242718,1540859350,775868261,1 +242719,1540859351,1540859352,1 +242720,1540859352,1540859353,1 +242721,1540859353,1540859354,1 +242722,1540859354,775868273,1 +242723,1540859355,775868206,1 +242724,1540859356,1540859357,1 +242725,1540859357,1540859358,1 +242726,1540859358,1540859359,1 +242727,1540859359,1540859360,1 +242728,1540859360,775868225,1 +242734,1540859366,775868290,1 +242735,1540859367,1540859368,1 +242736,1540859368,1540859369,1 +242737,1540859369,1540859370,1 +242738,1540859370,1540859371,1 +242739,1540859371,1540859372,1 +242740,1540859372,1540859373,1 +242741,1540859373,1540859374,1 +242742,1540859374,1540859375,1 +242743,1540859375,1540859376,1 +242744,1540859376,1540859377,1 +242745,1540859377,1540859378,1 +242746,1540859378,1540859379,1 +242747,1540859379,1540859380,1 +242748,1540859380,1540859381,1 +242749,1540859381,1540859382,1 +242750,1540859382,775868307,1 +242751,1540859383,1540859384,1 +242752,1540859384,1540859385,1 +242753,1540859385,1540859386,1 +242754,1540859386,1540859387,1 +242755,1540859387,775868290,1 +242756,1540859388,1540859389,1 +242757,1540859389,775868316,1 +242761,1540859393,1540859394,1 +242762,1540859394,775868266,1 +242763,1540859395,775868268,1 +242764,1540859396,1540859397,1 +242765,1540859397,1540859398,1 +242766,1540859398,1540859399,1 +242767,1540859399,774084994,1 +242768,1540859400,1540859401,1 +242769,1540859401,1540859402,1 +242770,1540859402,1540859403,1 +242771,1540859403,1540859404,1 +242772,1540859404,1540859405,1 +242773,1540859405,1540859406,1 +242774,1540859406,1540859407,1 +242775,1540859407,1540859408,1 +242776,1540859408,775868535,1 +242777,1540859409,1540859410,1 +242778,1540859410,1345217966,1 +242779,1540859411,1540859412,1 +242780,1540859412,1540859413,1 +242781,1540859413,1540859414,1 +242782,1540859414,1540859415,1 +242783,1540859415,775866112,1 +242784,1540859416,1540859417,1 +242785,1540859417,1345212086,1 +242786,1540859418,1540859419,1 +242787,1540859419,775866099,1 +242788,1540859420,778677132,1 +242821,1540859453,1540859454,1 +242822,1540859454,788839513,1 +242823,1540859455,1540859456,1 +242824,1540859456,1540859457,1 +242825,1540859457,788839543,1 +242826,1540859458,1540859459,1 +242827,1540859459,1540859460,1 +242828,1540859460,1540859461,1 +242829,1540859461,1540859462,1 +242830,1540859462,1540859463,1 +242831,1540859463,788839572,1 +242832,1540859464,1540859465,1 +242833,1540859465,1540859466,1 +242834,1540859466,788839597,1 +242835,1540859467,1540859468,1 +242836,1540859468,1540859469,1 +242837,1540859469,1540859470,1 +242838,1540859470,1540859471,1 +242839,1540859471,1540859472,1 +242840,1540859472,1540859473,1 +242841,1540859473,1540859474,1 +242842,1540859474,1540859475,1 +242843,1540859475,1540859476,1 +242844,1540859476,1540859477,1 +242845,1540859477,1540859478,1 +242846,1540859478,1540859479,1 +242847,1540859479,788839545,1 +242848,1540859480,788839676,1 +242849,1540859481,1540859482,1 +242850,1540859482,1540859483,1 +242851,1540859483,1540859484,1 +242852,1540859484,1540859485,1 +242853,1540859485,1540859486,1 +242854,1540859486,1540859487,1 +242855,1540859487,788839720,1 +242856,1540859488,1540859489,1 +242857,1540859489,788839720,1 +242858,1540859490,1540859491,1 +242859,1540859491,1540859492,1 +242860,1540859492,1540859493,1 +242861,1540859493,788839768,1 +242862,1540859494,788839787,1 +242863,1540859495,1540859496,1 +242864,1540859496,1540859497,1 +242865,1540859497,1540859498,1 +242866,1540859498,1540859499,1 +242867,1540859499,1540859500,1 +242868,1540859500,1540859501,1 +242869,1540859501,1540859502,1 +242870,1540859502,1540859503,1 +242871,1540859503,788839582,1 +242872,1540859504,1540859505,1 +242873,1540859505,1540859506,1 +242874,1540859506,1540859507,1 +242875,1540859507,1540859508,1 +242876,1540859508,788839873,1 +242877,1540859509,1540859510,1 +242878,1540859510,1540859511,1 +242879,1540859511,1540859512,1 +242880,1540859512,788839768,1 +242881,1540859513,1540859514,1 +242882,1540859514,1540859515,1 +242883,1540859515,1540859516,1 +242884,1540859516,1540859517,1 +242885,1540859517,1540859518,1 +242886,1540859518,1540859519,1 +242887,1540859519,788839938,1 +242888,1540859520,1540859521,1 +242889,1540859521,1540859522,1 +242890,1540859522,1540859523,1 +242891,1540859523,1540859524,1 +242892,1540859524,1540859525,1 +242893,1540859525,788839873,1 +242894,1540859526,1540859527,1 +242895,1540859527,788839784,1 +242896,1540859528,788839837,1 +242897,1540859529,1540859530,1 +242898,1540859530,1540859531,1 +242899,1540859531,1540859532,1 +242900,1540859532,788839502,1 +242901,1540859533,1540859534,1 +242902,1540859534,1540859535,1 +242903,1540859535,788839938,1 +242904,1540859536,788839777,1 +242905,1540859537,1540859538,1 +242906,1540859538,1540859539,1 +242907,1540859539,1540859540,1 +242908,1540859540,1540859541,1 +242909,1540859541,1540859542,1 +242910,1540859542,788840274,1 +242911,1540859543,1540859544,1 +242912,1540859544,1540859545,1 +242913,1540859545,788840274,1 +242914,1540859546,1540859547,1 +242915,1540859547,1540859548,1 +242916,1540859548,788839851,1 +242917,1540859549,1540859550,1 +242918,1540859550,1540859551,1 +242919,1540859551,1540859552,1 +242920,1540859552,1540859553,1 +242921,1540859553,1540859554,1 +242922,1540859554,1540859555,1 +242923,1540859555,788840110,1 +242924,1540859556,1411219064,1 +242925,1540859557,788840060,1 +242926,1540859558,1540859559,1 +242927,1540859559,1540859560,1 +242928,1540859560,1540859561,1 +242929,1540859561,788840071,1 +242930,1540859562,1540859563,1 +242931,1540859563,788840110,1 +242932,1540859564,1540859565,1 +242933,1540859565,1540859566,1 +242934,1540859566,788840486,1 +242935,1540859567,1540859568,1 +242936,1540859568,788840077,1 +242937,1540859569,1540859570,1 +242938,1540859570,788840131,1 +242939,1540859571,1540859572,1 +242940,1540859572,788840631,1 +242941,1540859573,1540859574,1 +242942,1540859574,1540859575,1 +242943,1540859575,1540859576,1 +242944,1540859576,1540859577,1 +242945,1540859577,1540859578,1 +242946,1540859578,1540859579,1 +242947,1540859579,1540859580,1 +242948,1540859580,1540859581,1 +242949,1540859581,1540859582,1 +242950,1540859582,1540859583,1 +242951,1540859583,1540859584,1 +242952,1540859584,1540859585,1 +242953,1540859585,1540859586,1 +242954,1540859586,1540859587,1 +242955,1540859587,788840735,1 +242956,1540859588,1540859589,1 +242957,1540859589,1540859590,1 +242958,1540859590,1540859591,1 +242959,1540859591,1540859592,1 +242960,1540859592,1540859593,1 +242961,1540859593,788840822,1 +242962,1540859594,1540859595,1 +242963,1540859595,1540859596,1 +242964,1540859596,1540859597,1 +242965,1540859597,788840856,1 +242966,1540859598,1540859599,1 +242967,1540859599,1540859600,1 +242968,1540859600,1540859601,1 +242969,1540859601,1540859602,1 +242970,1540859602,1540859603,1 +242971,1540859603,788839676,1 +242972,1540859604,1540859605,1 +242973,1540859605,1540859606,1 +242974,1540859606,788840951,1 +242975,1540859607,1540859608,1 +242976,1540859608,788840960,1 +242977,1540859609,1540859610,1 +242978,1540859610,788840735,1 +242979,1540859611,1540859612,1 +242980,1540859612,788840631,1 +242981,1540859613,1540859614,1 +242982,1540859614,1540859615,1 +242983,1540859615,1540859616,1 +242984,1540859616,1540859617,1 +242985,1540859617,1540859618,1 +242986,1540859618,1540859619,1 +242987,1540859619,788841045,1 +242988,1540859620,1540859621,1 +242989,1540859621,788840930,1 +242990,1540859622,1540859623,1 +242991,1540859623,1540859624,1 +242992,1540859624,788841111,1 +242993,1540859625,1540859626,1 +242994,1540859626,788841120,1 +242995,1540859627,1540859628,1 +242996,1540859628,1540859629,1 +242997,1540859629,788841120,1 +242998,1540859630,788841141,1 +242999,1540859631,1540859632,1 +243000,1540859632,788841045,1 +243001,1540859633,788840910,1 +243002,1540859634,1540859635,1 +243003,1540859635,1540859636,1 +243004,1540859636,788841177,1 +243005,1540859637,788841141,1 +243006,1540859638,788841206,1 +243007,1540859639,1540859640,1 +243008,1540859640,788840926,1 +243009,1540859641,1540859642,1 +243010,1540859642,1540859643,1 +243011,1540859643,788841229,1 +243012,1540859644,788840822,1 +243013,1540859645,788840979,1 +243014,1540859646,1540859647,1 +243015,1540859647,788841177,1 +243016,1540859648,788841229,1 +243017,1540859649,1540859650,1 +243018,1540859650,1540859651,1 +243019,1540859651,1540859652,1 +243020,1540859652,788841372,1 +243021,1540859653,1540859654,1 +243022,1540859654,1540859655,1 +243023,1540859655,1540859656,1 +243024,1540859656,1540859657,1 +243025,1540859657,774085118,1 +243026,1540859658,788841416,1 +243027,1540859659,1540859660,1 +243028,1540859660,1540859661,1 +243029,1540859661,1540859662,1 +243030,1540859662,1540859663,1 +243031,1540859663,788841518,1 +243032,1540859664,788841378,1 +243033,1540859665,1540859666,1 +243034,1540859666,1540859667,1 +243035,1540859667,1540859668,1 +243036,1540859668,1540859669,1 +243037,1540859669,788841327,1 +243038,1540859670,1540859671,1 +243039,1540859671,1540859672,1 +243040,1540859672,1540859673,1 +243041,1540859673,1540859674,1 +243042,1540859674,788841355,1 +243043,1540859675,788851372,1 +243044,1540859676,1540859677,1 +243045,1540859677,788851410,1 +243046,1540859678,788870482,1 +243047,1540859679,788870484,1 +243048,1540859680,1085492692,1 +243049,1540859681,1540859682,1 +243050,1540859682,788870515,1 +243051,1540859683,788870517,1 +243052,1540859684,1540859685,1 +243053,1540859685,1307367458,1 +243054,1540859686,1540859687,1 +243055,1540859687,1307367263,1 +243056,1540859688,788870619,1 +243057,1540859689,1540859690,1 +243058,1540859690,1540859691,1 +243059,1540859691,1307354829,1 +243060,1540859692,1540859693,1 +243061,1540859693,1307367263,1 +243062,1540859694,1540859695,1 +243063,1540859695,1540859696,1 +243064,1540859696,1540859697,1 +243065,1540859697,1540859698,1 +243066,1540859698,1540859699,1 +243067,1540859699,1540859700,1 +243068,1540859700,1540859701,1 +243069,1540859701,1540859702,1 +243070,1540859702,625904164,1 +243071,1540859703,1540859704,1 +243072,1540859704,625904170,1 +243073,1540859705,788870767,1 +243074,1540859706,1540859707,1 +243075,1540859707,1540859708,1 +243076,1540859708,788870796,1 +243077,1540859709,1540859710,1 +243078,1540859710,788870794,1 +243079,1540859711,1343088144,1 +243080,1540859712,278009557,0 +243081,1540859713,789215922,1 +243082,1540859714,1371044076,1 +243083,1540859715,1540859716,1 +243084,1540859716,1540859717,1 +243085,1540859717,1540859718,1 +243086,1540859718,789215940,1 +243087,1540859719,789215944,1 +243088,1540859720,1540859721,1 +243089,1540859721,1371044029,1 +243090,1540859722,1540859723,1 +243091,1540859723,1540859724,1 +243092,1540859724,789215947,1 +243093,1540859725,1540859726,1 +243094,1540859726,1540859727,1 +243095,1540859727,1371043995,1 +243096,1540859728,1540859729,1 +243097,1540859729,1540859730,1 +243098,1540859730,1540859731,1 +243099,1540859731,789215957,1 +243100,1540859732,789215962,1 +243101,1540859733,1540859734,1 +243102,1540859734,789215833,1 +243103,1540859735,789215831,1 +243104,1540859736,789216026,1 +243105,1540859737,789216037,1 +243106,1540859738,1540859739,1 +243107,1540859739,1540859740,1 +243108,1540859740,1540859741,1 +243109,1540859741,789215972,1 +243110,1540859742,1038225098,1 +243111,1540859743,789216069,1 +243112,1540859744,789215947,1 +243113,1540859745,1371477972,1 +243114,1540859746,789215986,1 +243133,1540859765,1540859766,1 +243134,1540859766,1540859767,1 +243135,1540859767,1540859768,1 +243136,1540859768,1540859769,1 +243137,1540859769,152941465,1 +243138,1540859770,792045743,1 +243139,1540859771,792048334,1 +243140,1540859772,1540859773,1 +243141,1540859773,1540859774,1 +243142,1540859774,792048327,1 +243143,1540859775,792049841,1 +243144,1540859776,536579954,1 +243145,1540859777,528490482,1 +243146,1540859778,792054059,1 +243147,1540859779,792056424,1 +243148,1540859780,1540859781,1 +243149,1540859781,1540859782,1 +243150,1540859782,792056460,1 +243151,1540859783,792071803,1 +243152,1540859784,792056437,1 +243153,1540859785,1540859786,0 +243154,1540859786,1540859787,0 +243155,1540859787,1540859788,0 +243156,1540859788,1540859789,0 +243157,1540859789,1540859790,0 +243158,1540859790,792054066,0 +243159,1540859791,792056441,1 +243160,1540859792,792069982,1 +243161,1540859793,1540859794,1 +243162,1540859794,792069959,1 +243163,1540859795,1540859796,1 +243164,1540859796,1540859797,1 +243165,1540859797,1540859798,1 +243166,1540859798,1540859799,1 +243167,1540859799,1540859800,1 +243168,1540859800,1540859801,1 +243169,1540859801,1540859802,1 +243170,1540859802,792071810,1 +243171,1540859803,600205175,1 +243172,1540859804,792071829,1 +243173,1540859805,792071821,1 +243174,1540859806,1144323593,1 +243175,1540859807,792071792,1 +243176,1540859808,1540859809,1 +243177,1540859809,1540859810,1 +243178,1540859810,1540859811,1 +243179,1540859811,1540859812,1 +243180,1540859812,1540859813,1 +243181,1540859813,1540859814,1 +243182,1540859814,1540859815,1 +243183,1540859815,1540859816,1 +243184,1540859816,1540859817,1 +243185,1540859817,1540859818,1 +243186,1540859818,1540859819,1 +243187,1540859819,1540859820,1 +243188,1540859820,1540859821,1 +243189,1540859821,1540859822,1 +243190,1540859822,793240976,1 +243191,1540859823,1540859824,0 +243192,1540859824,793252666,0 +243193,1540859825,355929669,0 +243194,1540859826,1540859827,0 +243195,1540859827,1540859828,0 +243196,1540859828,1540859829,0 +243197,1540859829,1540859830,0 +243198,1540859830,1540859831,0 +243199,1540859831,1540859832,0 +243200,1540859832,1540859833,0 +243201,1540859833,1540859834,0 +243202,1540859834,36243712,0 +243203,1540859835,793279456,1 +243204,1540859836,793385629,1 +243205,1540859837,745091086,1 +243206,1540859838,793385717,1 +243207,1540859839,793279512,1 +243208,1540859840,745091002,1 +243209,1540859841,294243377,0 +243210,1540859842,793529678,0 +243211,1540859843,1540859844,1 +243212,1540859844,793385674,1 +243213,1540859845,793385616,1 +243214,1540859846,793385750,1 +243215,1540859847,793385741,1 +243216,1540859848,793428484,1 +243217,1540859849,1540859850,1 +243218,1540859850,1540859851,1 +243219,1540859851,1540859852,1 +243220,1540859852,793385639,1 +243221,1540859853,793385754,1 +243222,1540859854,745990622,1 +243223,1540859855,793385746,1 +243224,1540859856,793385711,1 +243225,1540859857,793385660,1 +243226,1540859858,1540859859,0 +243227,1540859859,294203944,0 +243228,1540859860,793385709,1 +243229,1540859861,1540859862,1 +243230,1540859862,793279479,1 +243231,1540859863,793279436,1 +243232,1540859864,793385674,1 +243233,1540859865,793428513,1 +243234,1540859866,793428429,1 +243235,1540859867,793428340,1 +243236,1540859868,793428336,1 +243237,1540859869,793428428,1 +243238,1540859870,793385746,1 +243239,1540859871,793428348,1 +243240,1540859872,1540859873,1 +243241,1540859873,793428399,1 +243242,1540859874,1540859875,1 +243243,1540859875,1540859876,1 +243244,1540859876,793428338,1 +243245,1540859877,1540859878,1 +243246,1540859878,793428500,1 +243247,1540859879,793428517,1 +243248,1540859880,793428370,1 +243249,1540859881,1540859882,1 +243250,1540859882,1540859883,1 +243251,1540859883,1540859884,1 +243252,1540859884,793385750,1 +243253,1540859885,1540859886,1 +243254,1540859886,793428344,1 +243255,1540859887,793428425,1 +243256,1540859888,1540859889,1 +243257,1540859889,1540859890,1 +243258,1540859890,1540859891,1 +243259,1540859891,1540859892,1 +243260,1540859892,1540859893,1 +243261,1540859893,1540859894,1 +243262,1540859894,1540859895,1 +243263,1540859895,1540859896,1 +243264,1540859896,793428451,1 +243265,1540859897,793428464,1 +243266,1540859898,793428380,1 +243267,1540859899,799917471,1 +243268,1540859900,793529865,1 +243269,1540859901,1540859902,1 +243270,1540859902,793479398,1 +243271,1540859903,705065806,1 +243272,1540859904,793529669,1 +243273,1540859905,793529846,1 +243274,1540859906,1540859907,1 +243275,1540859907,1540859908,1 +243276,1540859908,1540859909,1 +243277,1540859909,1540859910,1 +243278,1540859910,1540859911,1 +243279,1540859911,1540859912,1 +243280,1540859912,793529700,1 +243281,1540859913,793529751,1 +243282,1540859914,1540859915,1 +243283,1540859915,1540859916,1 +243284,1540859916,1540859917,1 +243285,1540859917,1540859918,1 +243286,1540859918,793529772,1 +243287,1540859919,705065809,1 +243288,1540859920,793529747,1 +243289,1540859921,1540859922,1 +243290,1540859922,793529836,1 +243291,1540859923,793771278,0 +243292,1540859924,581290410,0 +243293,1540859925,1540859926,0 +243294,1540859926,1540859927,0 +243295,1540859927,1540859928,0 +243296,1540859928,1540859929,0 +243297,1540859929,1540859930,0 +243298,1540859930,579794613,0 +243299,1540859931,1540859932,0 +243300,1540859932,1540859933,0 +243301,1540859933,793771274,0 +243302,1540859934,1540859935,0 +243303,1540859935,1540859936,0 +243304,1540859936,1540859937,0 +243305,1540859937,1540859938,0 +243306,1540859938,579794643,0 +243307,1540859939,1540859940,0 +243308,1540859940,1540859941,0 +243309,1540859941,793771331,0 +243310,1540859942,1540859943,0 +243311,1540859943,1540859944,0 +243312,1540859944,1540859945,0 +243313,1540859945,1540859946,0 +243314,1540859946,793771302,0 +243315,1540859947,1540859948,0 +243316,1540859948,1540859949,0 +243317,1540859949,1540859950,0 +243318,1540859950,792069982,0 +243319,1540859951,581290410,1 +243320,1540859952,793771278,0 +243321,1540859953,1540859954,0 +243322,1540859954,579794643,0 +243323,1540859955,793771274,0 +243324,1540859956,603753974,1 +243325,1540859957,793799988,1 +243326,1540859958,793781787,1 +243327,1540859959,793781731,1 +243328,1540859960,793781701,1 +243329,1540859961,793781717,1 +243330,1540859962,793781650,1 +243331,1540859963,793781750,1 +243332,1540859964,793781807,1 +243333,1540859965,361199839,1 +243334,1540859966,1540859967,1 +243335,1540859967,1540859968,1 +243336,1540859968,793781701,1 +243337,1540859969,793781839,1 +243338,1540859970,793799872,1 +243339,1540859971,1540859972,1 +243340,1540859972,793799897,1 +243341,1540859973,1540859974,1 +243342,1540859974,793799984,1 +243343,1540859975,793799968,1 +243344,1540859976,1540859977,1 +243345,1540859977,1540859978,1 +243346,1540859978,793799991,1 +243347,1540859979,603748694,1 +243348,1540859980,603748687,1 +243349,1540859981,1540859982,1 +243350,1540859982,793799885,1 +243351,1540859983,417276967,0 +243352,1540859984,361200013,0 +243353,1540859985,603748684,0 +243354,1540859986,603748694,0 +243355,1540859987,1540859988,1 +243356,1540859988,1540859989,1 +243357,1540859989,793810076,1 +243358,1540859990,1540859991,1 +243359,1540859991,1345658074,1 +243360,1540859992,1345660137,1 +243361,1540859993,1345659067,1 +243362,1540859994,600926427,1 +243363,1540859995,1540859996,1 +243364,1540859996,1540859997,1 +243365,1540859997,1540859998,1 +243366,1540859998,1540859999,1 +243367,1540859999,1540860000,1 +243368,1540860000,793810076,1 +243529,1540860161,536601223,1 +243530,1540860162,361406207,1 +243531,1540860163,795263012,1 +243532,1540860164,795263041,1 +243533,1540860165,575187178,1 +243534,1540860166,795263251,1 +243535,1540860167,795263243,1 +243536,1540860168,795263248,1 +243537,1540860169,528490581,1 +243538,1540860170,792045745,1 +243539,1540860171,795264083,1 +243540,1540860172,1540860173,1 +243541,1540860173,1113233830,1 +243542,1540860174,360015156,1 +244456,1540861088,1540861089,1 +244457,1540861089,1540861090,1 +244458,1540861090,797159608,1 +244478,1540861110,1540861111,1 +244479,1540861111,1540861112,1 +244480,1540861112,1540861113,1 +244481,1540861113,1540861114,1 +244482,1540861114,1540861115,1 +244483,1540861115,788839979,1 +244484,1540861116,1540861117,1 +244485,1540861117,1540861118,1 +244486,1540861118,1540861119,1 +244487,1540861119,1540861120,1 +244488,1540861120,1540861121,1 +244489,1540861121,774085085,1 +244490,1540861122,1540861123,1 +244491,1540861123,1540861124,1 +244492,1540861124,1540861125,1 +244493,1540861125,1540861126,1 +244494,1540861126,1540861127,1 +244495,1540861127,1540861128,1 +244496,1540861128,1540861129,1 +244497,1540861129,1540861130,1 +244498,1540861130,1540861131,1 +244499,1540861131,1540861132,1 +244500,1540861132,788840872,1 +244501,1540861133,1540861134,1 +244502,1540861134,1540861135,1 +244503,1540861135,1540861136,1 +244504,1540861136,1540861137,1 +244505,1540861137,1540861138,1 +244506,1540861138,1540861139,1 +244507,1540861139,1540861140,1 +244508,1540861140,1540861141,1 +244509,1540861141,1540861142,1 +244510,1540861142,1540861143,1 +244511,1540861143,788840290,1 +244512,1540861144,1540861145,1 +244513,1540861145,774085110,1 +244514,1540861146,1540861147,1 +244515,1540861147,1540861148,1 +244516,1540861148,1540861149,1 +244517,1540861149,788840459,1 +244518,1540861150,774085118,1 +244519,1540861151,1540861152,1 +244520,1540861152,774085052,1 +244521,1540861153,1540861154,1 +244522,1540861154,1540861155,1 +244523,1540861155,1540861156,1 +244524,1540861156,1540861157,1 +244525,1540861157,1540861158,1 +244526,1540861158,1540861159,1 +244527,1540861159,1540861160,1 +244528,1540861160,775868307,1 +244529,1540861161,1540861162,1 +244530,1540861162,1540861163,1 +244531,1540861163,775868274,1 +244532,1540861164,1540861165,1 +244533,1540861165,1540861166,1 +244534,1540861166,1540861167,1 +244535,1540861167,774085136,1 +244536,1540861168,1540861169,1 +244537,1540861169,1540861170,1 +244538,1540861170,796743717,1 +244539,1540861171,1540861172,1 +244540,1540861172,1540861173,1 +244541,1540861173,1540861174,1 +244542,1540861174,365311013,1 +244543,1540861175,796743692,1 +244544,1540861176,1540861177,1 +244545,1540861177,1540861178,1 +244546,1540861178,796743705,1 +244547,1540861179,1540861180,1 +244548,1540861180,1540861181,1 +244549,1540861181,797159587,1 +244550,1540861182,797159637,1 +244551,1540861183,796743724,1 +244552,1540861184,796743728,1 +244553,1540861185,625904285,1 +244554,1540861186,796746783,1 +244555,1540861187,797159533,1 +244556,1540861188,1540861189,1 +244557,1540861189,797159542,1 +244558,1540861190,1540861191,1 +244559,1540861191,797159560,1 +244560,1540861192,1540861193,1 +244561,1540861193,1540861194,1 +244562,1540861194,797159587,1 +244563,1540861195,797159601,1 +244564,1540861196,1540861197,1 +244565,1540861197,797159608,1 +244566,1540861198,1540861199,1 +244567,1540861199,1540861200,1 +244568,1540861200,797175370,1 +244569,1540861201,1540861202,1 +244570,1540861202,1343000036,1 +244571,1540861203,1540861204,1 +244572,1540861204,797175358,1 +244573,1540861205,1540861206,0 +244574,1540861206,365311007,0 +244575,1540861207,1540861208,1 +244576,1540861208,797175376,1 +244577,1540861209,797175363,1 +244578,1540861210,1540861211,1 +244579,1540861211,1540861212,1 +244580,1540861212,797175353,1 +244581,1540861213,1343000610,1 +244582,1540861214,1540861215,1 +244583,1540861215,1540861216,1 +244584,1540861216,1540861217,1 +244585,1540861217,1343000736,1 +244586,1540861218,1540861219,1 +244587,1540861219,1540861220,1 +244588,1540861220,1540861221,1 +244589,1540861221,1540861222,1 +244590,1540861222,1540861223,1 +244591,1540861223,1540861224,1 +244592,1540861224,1540861225,1 +244593,1540861225,1540861226,1 +244594,1540861226,984771834,1 +244595,1540861227,1540861228,1 +244596,1540861228,1540861229,1 +244597,1540861229,984772461,1 +244598,1540861230,797175507,1 +244599,1540861231,1540861232,1 +244600,1540861232,1540861233,1 +244601,1540861233,1540861234,1 +244602,1540861234,984772719,1 +244603,1540861235,1540861236,1 +244604,1540861236,1540861237,1 +244605,1540861237,1540861238,1 +244606,1540861238,1175924751,1 +244607,1540861239,1540861240,1 +244608,1540861240,797190040,1 +244609,1540861241,797190006,1 +244610,1540861242,1540861243,0 +244611,1540861243,797347639,0 +244612,1540861244,936853720,1 +244613,1540861245,1540861246,0 +244614,1540861246,1540861247,0 +244615,1540861247,797375658,0 +244616,1540861248,338485833,0 +244617,1540861249,1540861250,0 +244618,1540861250,1540861251,0 +244619,1540861251,1540861252,0 +244620,1540861252,797375787,0 +244621,1540861253,1540861254,1 +244622,1540861254,797375636,1 +244623,1540861255,797375800,1 +244624,1540861256,653281176,1 +244625,1540861257,1540861258,1 +244626,1540861258,1540861259,1 +244627,1540861259,797375707,1 +244628,1540861260,1540861261,1 +244629,1540861261,1540861262,1 +244630,1540861262,797375658,1 +244631,1540861263,1540861264,1 +244632,1540861264,1540861265,1 +244633,1540861265,1540861266,1 +244634,1540861266,797375685,1 +244635,1540861267,1540861268,1 +244636,1540861268,797375867,1 +244637,1540861269,803745201,0 +244638,1540861270,797375690,0 +244639,1540861271,1540861272,1 +244640,1540861272,1145611257,1 +244641,1540861273,361198931,1 +244642,1540861274,797375664,0 +244643,1540861275,797375778,1 +244644,1540861276,1540861277,1 +244645,1540861277,1540861278,1 +244646,1540861278,1540861279,1 +244647,1540861279,792054059,1 +244648,1540861280,294203208,1 +244649,1540861281,1540861282,1 +244650,1540861282,361199271,1 +244651,1540861283,797394756,1 +244652,1540861284,1540861285,1 +244653,1540861285,938143027,1 +244654,1540861286,797394753,1 +244655,1540861287,938143061,1 +244860,1540861492,1540861493,1 +244861,1540861493,365311016,1 +244862,1540861494,365377172,1 +244863,1540861495,365925014,1 +244864,1540861496,365311020,1 +244865,1540861497,365311016,1 +244866,1540861498,1540861499,0 +244867,1540861499,797175387,0 +244874,1540861506,1540861507,0 +244875,1540861507,1540861508,0 +244876,1540861508,1540861509,0 +244877,1540861509,1540861510,0 +244878,1540861510,1540861511,0 +244879,1540861511,360015820,0 +244880,1540861512,1291955682,1 +244881,1540861513,360004891,1 +244882,1540861514,1540861515,1 +244883,1540861515,1540861516,1 +244884,1540861516,801480051,1 +244885,1540861517,1540861518,0 +244886,1540861518,1540861519,0 +244887,1540861519,1540861520,0 +244888,1540861520,1540861521,0 +244889,1540861521,1540861522,0 +244890,1540861522,1540861523,0 +244891,1540861523,295775659,0 +244892,1540861524,1540861525,0 +244893,1540861525,1540861526,0 +244894,1540861526,361423237,0 +244895,1540861527,1540861528,0 +244896,1540861528,1540861529,0 +244897,1540861529,1540861530,0 +244898,1540861530,1540861531,0 +244899,1540861531,1540861532,0 +244900,1540861532,809948956,0 +244901,1540861533,1540861534,0 +244902,1540861534,1540861535,0 +244903,1540861535,1540861536,0 +244904,1540861536,1540861537,0 +244905,1540861537,35840949,0 +244906,1540861538,35840952,0 +244907,1540861539,1540861540,0 +244908,1540861540,1540861541,0 +244909,1540861541,1540861542,0 +244910,1540861542,1540861543,0 +244911,1540861543,359997700,0 +244912,1540861544,559564901,0 +244913,1540861545,1540861546,0 +244914,1540861546,1540861547,0 +244915,1540861547,1540861548,0 +244916,1540861548,1540861549,0 +244917,1540861549,1540861550,0 +244918,1540861550,1540861551,0 +244919,1540861551,360016036,0 +244920,1540861552,360016038,0 +244921,1540861553,1540861554,1 +244922,1540861554,800150235,1 +244923,1540861555,800150275,1 +244924,1540861556,1540861557,1 +244925,1540861557,1540861558,1 +244926,1540861558,800150242,1 +244927,1540861559,800150545,1 +244928,1540861560,1540861561,0 +244929,1540861561,1540861562,0 +244930,1540861562,800150609,0 +244931,1540861563,1540861564,0 +244932,1540861564,1540861565,0 +244933,1540861565,1540861566,0 +244934,1540861566,1540861567,0 +244935,1540861567,1540861568,0 +244936,1540861568,1540861569,0 +244937,1540861569,35840828,0 +244938,1540861570,800150217,1 +244939,1540861571,1540861572,1 +244940,1540861572,1540861573,1 +244941,1540861573,1540861574,1 +244942,1540861574,1540861575,1 +244943,1540861575,800150235,1 +244944,1540861576,800150442,1 +244945,1540861577,1540861578,1 +244946,1540861578,1540861579,1 +244947,1540861579,1540861580,1 +244948,1540861580,1540861581,1 +244949,1540861581,800150244,1 +244950,1540861582,152801591,1 +244951,1540861583,1540861584,1 +244952,1540861584,1540861585,1 +244953,1540861585,800150206,1 +244954,1540861586,1540861587,1 +244955,1540861587,1540861588,1 +244956,1540861588,1540861589,1 +244957,1540861589,1540861590,1 +244958,1540861590,1540861591,1 +244959,1540861591,1540861592,1 +244960,1540861592,1540861593,1 +244961,1540861593,800150395,1 +244962,1540861594,1540861595,0 +244963,1540861595,1540861596,0 +244964,1540861596,1540861597,0 +244965,1540861597,1540861598,0 +244966,1540861598,800150369,0 +244967,1540861599,800150244,0 +244968,1540861600,1540861601,0 +244969,1540861601,800150480,0 +244970,1540861602,1540861603,1 +244971,1540861603,800448962,1 +244972,1540861604,800448883,1 +244973,1540861605,1540861606,1 +244974,1540861606,800448609,1 +244975,1540861607,800448752,1 +244976,1540861608,800448662,1 +244977,1540861609,800448822,1 +244978,1540861610,800448808,1 +244979,1540861611,800448727,1 +244980,1540861612,800449059,1 +244981,1540861613,1540861614,1 +244982,1540861614,1540861615,1 +244983,1540861615,1540861616,1 +244984,1540861616,1540861617,1 +244985,1540861617,800448788,1 +244986,1540861618,800448704,1 +244987,1540861619,800448653,1 +244988,1540861620,1540861621,1 +244989,1540861621,1540861622,1 +244990,1540861622,800448924,1 +244991,1540861623,800448664,1 +244992,1540861624,1540861625,1 +244993,1540861625,800465918,1 +244994,1540861626,800448658,1 +244995,1540861627,1540861628,1 +244996,1540861628,1540861629,1 +244997,1540861629,1540861630,1 +244998,1540861630,800448603,1 +244999,1540861631,800448780,1 +245000,1540861632,1540861633,1 +245001,1540861633,1540861634,1 +245002,1540861634,1540861635,1 +245003,1540861635,1540861636,1 +245004,1540861636,1540861637,1 +245005,1540861637,1540861638,1 +245006,1540861638,800448924,1 +245007,1540861639,1540861640,1 +245010,1540861642,800448622,1 +245011,1540861643,1540861644,1 +245012,1540861644,800448734,1 +245013,1540861645,1540861646,1 +245014,1540861646,1540861647,1 +245015,1540861647,800448871,1 +245016,1540861648,800448612,1 +245017,1540861649,800448851,1 +245018,1540861650,800448788,1 +245019,1540861651,800448707,1 +245020,1540861652,800448944,1 +245021,1540861653,800448635,1 +245022,1540861654,800449014,1 +245023,1540861655,800448809,1 +245024,1540861656,1540861657,1 +245025,1540861657,800465892,1 +245043,1540861675,800465791,1 +245044,1540861676,800466267,1 +245050,1540861682,1540861683,1 +245051,1540861683,1540861684,1 +245052,1540861684,1540861685,1 +245053,1540861685,800466091,1 +245057,1540861689,1540861690,1 +245058,1540861690,1540861691,1 +245059,1540861691,800466353,1 +245067,1540861699,800466245,1 +245074,1540861706,800465977,1 +245075,1540861707,1540861708,1 +245076,1540861708,800466035,1 +245232,1540861864,1540861865,0 +245233,1540861865,272567305,0 +245234,1540861866,1540861867,0 +245235,1540861867,1540861868,0 +245236,1540861868,1540861869,0 +245237,1540861869,272567307,0 +245271,1540861903,1540861904,1 +245272,1540861904,801062884,1 +245274,1540861906,801062649,1 +245275,1540861907,801063215,1 +245278,1540861910,1540861911,1 +245279,1540861911,801062650,1 +245294,1540861926,801063215,1 +245298,1540861930,1540861931,1 +245299,1540861931,1540861932,1 +245300,1540861932,1540861933,1 +245301,1540861933,1540861934,1 +245302,1540861934,1540861935,1 +245303,1540861935,1540861936,1 +245304,1540861936,1540861937,1 +245305,1540861937,1540861938,1 +245306,1540861938,1540861939,1 +245307,1540861939,1540861940,1 +245308,1540861940,1540861941,1 +245309,1540861941,1540861942,1 +245310,1540861942,1540861943,1 +245311,1540861943,801062688,1 +245318,1540861950,1540861951,1 +245319,1540861951,1540861952,1 +245320,1540861952,1540861953,1 +245321,1540861953,1540861954,1 +245322,1540861954,801062778,1 +245323,1540861955,801063132,1 +245466,1540862098,1540862099,1 +245467,1540862099,801451957,1 +245476,1540862108,801451920,1 +245481,1540862113,1540862114,1 +245482,1540862114,1540862115,1 +245483,1540862115,1540862116,1 +245484,1540862116,633036602,1 +245485,1540862117,801467952,1 +245486,1540862118,800140515,1 +245487,1540862119,1540862120,1 +245488,1540862120,801467985,1 +245489,1540862121,1540862122,1 +245490,1540862122,361424117,1 +245491,1540862123,361424352,1 +245492,1540862124,792045729,1 +245493,1540862125,801467911,1 +245494,1540862126,1540862127,1 +245495,1540862127,801467949,1 +245496,1540862128,801468034,1 +245497,1540862129,800150395,1 +245498,1540862130,1540862131,1 +245499,1540862131,801467980,1 +245500,1540862132,801467926,1 +245501,1540862133,801467970,1 +245502,1540862134,801467952,1 +245503,1540862135,801467948,1 +245504,1540862136,1540862137,1 +245505,1540862137,1540862138,1 +245506,1540862138,1540862139,1 +245507,1540862139,801467983,1 +245508,1540862140,1540862141,0 +245509,1540862141,1540862142,0 +245510,1540862142,1540862143,0 +245511,1540862143,801467995,0 +245512,1540862144,801480050,1 +245513,1540862145,1540862146,1 +245514,1540862146,1540862147,1 +245515,1540862147,1540862148,1 +245516,1540862148,801480037,1 +245517,1540862149,801480026,1 +245518,1540862150,360004890,1 +245519,1540862151,1540862152,1 +245520,1540862152,801479955,1 +245521,1540862153,1540862154,1 +245522,1540862154,1540862155,1 +245523,1540862155,633036268,1 +245524,1540862156,801480019,1 +245525,1540862157,1540862158,1 +245526,1540862158,801484168,1 +245527,1540862159,1540862160,1 +245528,1540862160,360015403,1 +245529,1540862161,1540862162,1 +245530,1540862162,1540862163,1 +245531,1540862163,1540862164,1 +245532,1540862164,536579471,1 +245688,1540862320,1141011977,1 +245689,1540862321,803745148,0 +245690,1540862322,1141011964,0 +245691,1540862323,1540862324,0 +245692,1540862324,803745184,0 +245693,1540862325,803745016,1 +245694,1540862326,803745115,1 +245695,1540862327,1540862328,1 +245696,1540862328,803745027,1 +245697,1540862329,1540862330,0 +245698,1540862330,803745073,0 +245699,1540862331,938502011,1 +245700,1540862332,803745105,1 +245701,1540862333,803745208,0 +245702,1540862334,803745164,0 +245703,1540862335,803745117,1 +245704,1540862336,803745018,1 +245705,1540862337,1540862338,0 +245706,1540862338,803745239,0 +245707,1540862339,803745080,1 +245947,1540862579,1540862580,1 +245948,1540862580,1540862581,1 +245949,1540862581,683298011,1 +246023,1540862655,1540862656,0 +246024,1540862656,1540862657,0 +246025,1540862657,1540862658,0 +246026,1540862658,800140499,0 +246102,1540862734,789215962,1 +246103,1540862735,810716453,1 +246104,1540862736,810716450,1 +246105,1540862737,789215874,1 +246106,1540862738,789215878,1 +246107,1540862739,1371125567,1 +246159,1540862791,1540862792,1 +246160,1540862792,813097939,1 +246161,1540862793,813097784,1 +246162,1540862794,813097914,1 +246163,1540862795,1540862796,1 +246164,1540862796,1540862797,1 +246165,1540862797,1540862798,1 +246166,1540862798,1540862799,1 +246167,1540862799,1540862800,1 +246168,1540862800,1540862801,1 +246170,1540862802,1540862803,1 +246171,1540862803,1540862804,1 +246172,1540862804,1540862805,1 +246173,1540862805,1540862806,1 +246174,1540862806,1540862807,1 +246175,1540862807,1540862808,1 +246176,1540862808,1540862809,1 +246177,1540862809,1540862810,1 +246178,1540862810,813097946,1 +246179,1540862811,1540862812,1 +246180,1540862812,1540862813,1 +246181,1540862813,813097905,1 +246182,1540862814,813097816,1 +246189,1540862821,813097847,1 +246190,1540862822,1540862823,1 +246191,1540862823,813097962,1 +246195,1540862827,1540862828,1 +246196,1540862828,1540862829,1 +246197,1540862829,813097975,1 +246198,1540862830,1540862831,1 +246199,1540862831,1540862832,1 +246200,1540862832,1540862833,1 +246201,1540862833,1540862834,1 +246202,1540862834,1540862835,1 +246203,1540862835,1540862836,1 +246204,1540862836,1540862837,1 +246205,1540862837,1540862838,1 +246206,1540862838,1540862839,1 +246207,1540862839,1540862840,1 +246221,1540862853,813097975,1 +246222,1540862854,813098010,1 +246223,1540862855,801451952,1 +246229,1540862861,1540862862,1 +246230,1540862862,813097808,1 +246281,1540862913,286541740,1 +246282,1540862914,745988421,1 +246283,1540862915,745988376,1 +247801,1540864433,561406946,0 +247802,1540864434,561406920,0 +247803,1540864435,1540864436,1 +247804,1540864436,560576537,1 +247805,1540864437,365970187,1 +247806,1540864438,365120907,1 +247807,1540864439,561407251,1 +247808,1540864440,365970093,0 +247809,1540864441,832461845,1 +249407,1540866039,272499528,0 +249408,1540866040,272499526,0 +249414,1540866046,272499530,1 +249577,1540866209,795263231,1 +249578,1540866210,536601254,1 +249579,1540866211,1540866212,0 +249580,1540866212,1540866213,0 +249581,1540866213,1540866214,0 +249582,1540866214,361442902,0 +249583,1540866215,889471538,0 +249584,1540866216,581288214,0 +249585,1540866217,1540866218,0 +249586,1540866218,1540866219,0 +249587,1540866219,360728582,0 +249588,1540866220,1540866221,0 +249589,1540866221,361434511,0 +249590,1540866222,361434510,0 +249591,1540866223,361434733,0 +249592,1540866224,891524045,1 +249593,1540866225,1540866226,1 +249594,1540866226,1540866227,1 +249595,1540866227,1540866228,1 +249596,1540866228,932361968,1 +249597,1540866229,1540866230,1 +249598,1540866230,1540866231,1 +249599,1540866231,1540866232,1 +249600,1540866232,891523971,1 +249601,1540866233,1540866234,1 +249602,1540866234,1178850760,1 +249603,1540866235,985968748,1 +249604,1540866236,891523995,1 +249605,1540866237,891524000,1 +249606,1540866238,1411198429,1 +249731,1540866363,1540866364,0 +249732,1540866364,360221447,0 +249733,1540866365,1540866366,1 +249734,1540866366,360217342,1 +249735,1540866367,1540866368,1 +249736,1540866368,912014337,1 +249737,1540866369,1540866370,1 +249738,1540866370,1540866371,1 +249739,1540866371,1540866372,1 +249740,1540866372,912014321,1 +249741,1540866373,1540866374,1 +249742,1540866374,912014337,1 +249743,1540866375,418771213,1 +249744,1540866376,418771212,1 +249745,1540866377,1540866378,1 +249746,1540866378,360189871,1 +249747,1540866379,1540866380,1 +249748,1540866380,1540866381,1 +249749,1540866381,1540866382,1 +249750,1540866382,1540866383,1 +249751,1540866383,1540866384,1 +249752,1540866384,1540866385,1 +249753,1540866385,1540866386,1 +249754,1540866386,1540866387,1 +249755,1540866387,1540866388,1 +249756,1540866388,1540866389,1 +249757,1540866389,1540866390,1 +249758,1540866390,1540866391,1 +249759,1540866391,1540866392,1 +249760,1540866392,1540866393,1 +249761,1540866393,1540866394,1 +249762,1540866394,1540866395,1 +249763,1540866395,1540866396,1 +249764,1540866396,1540866397,1 +249765,1540866397,1540866398,1 +249766,1540866398,1540866399,1 +249767,1540866399,1540866400,1 +249768,1540866400,1540866401,1 +249769,1540866401,1540866402,1 +249770,1540866402,1540866403,1 +249771,1540866403,1540866404,1 +249772,1540866404,1540866405,1 +250756,1540867388,536578831,1 +250757,1540867389,536578839,1 +251107,1540867739,1540867740,1 +251108,1540867740,1345643912,1 +251124,1540867756,1540867757,1 +251125,1540867757,1540867758,1 +251126,1540867758,1540867759,1 +251127,1540867759,1540867760,1 +251128,1540867760,1540867761,1 +251129,1540867761,1540867762,1 +251130,1540867762,1540867763,1 +251131,1540867763,935854875,1 +251132,1540867764,1540867765,1 +251133,1540867765,1540867766,1 +251134,1540867766,1540867767,1 +251135,1540867767,1540867768,1 +251136,1540867768,1540867769,1 +251137,1540867769,1540867770,1 +251138,1540867770,1540867771,1 +251139,1540867771,1540867772,1 +251140,1540867772,1540867773,1 +251141,1540867773,1540867774,1 +251142,1540867774,1540867775,1 +251143,1540867775,1540867776,1 +251144,1540867776,1540867777,1 +251145,1540867777,1540867778,1 +251146,1540867778,1540867779,1 +251147,1540867779,1540867780,1 +251148,1540867780,1540867781,1 +251149,1540867781,1540867782,1 +251150,1540867782,1540867783,1 +251151,1540867783,1540867784,1 +251152,1540867784,1540867785,1 +251153,1540867785,1540867786,1 +251154,1540867786,1540867787,1 +251155,1540867787,1540867788,1 +251156,1540867788,1345652044,1 +251157,1540867789,1540867790,1 +251158,1540867790,1540867791,1 +251159,1540867791,1540867792,1 +251160,1540867792,1345651540,1 +251161,1540867793,1540867794,1 +251162,1540867794,1540867795,1 +251163,1540867795,1540867796,1 +251164,1540867796,1540867797,1 +251165,1540867797,1345651509,1 +251166,1540867798,1540867799,0 +251167,1540867799,935855851,0 +251168,1540867800,935855403,1 +251169,1540867801,1540867802,1 +251170,1540867802,1540867803,1 +251171,1540867803,1540867804,1 +251172,1540867804,1540867805,1 +251173,1540867805,1540867806,1 +251174,1540867806,935854739,1 +251175,1540867807,935855427,1 +251182,1540867814,935855599,1 +251183,1540867815,935855738,1 +251233,1540867865,935855613,1 +251328,1540867960,935855029,1 +251329,1540867961,1540867962,1 +251330,1540867962,1540867963,1 +251331,1540867963,935854559,1 +251332,1540867964,935855283,1 +251333,1540867965,1307354809,1 +251334,1540867966,1345645494,1 +251335,1540867967,1540867968,1 +251336,1540867968,1540867969,1 +251337,1540867969,1540867970,1 +251338,1540867970,1540867971,1 +251339,1540867971,1540867972,1 +251340,1540867972,1540867973,1 +251341,1540867973,1540867974,1 +251342,1540867974,1540867975,1 +251343,1540867975,1540867976,1 +251344,1540867976,1540867977,1 +251345,1540867977,1540867978,1 +251346,1540867978,1540867979,1 +251347,1540867979,1540867980,1 +251348,1540867980,1540867981,1 +251349,1540867981,1540867982,1 +251350,1540867982,1540867983,1 +251351,1540867983,1540867984,1 +251352,1540867984,1540867985,1 +251353,1540867985,1540867986,1 +251354,1540867986,1540867987,1 +251355,1540867987,1540867988,1 +251356,1540867988,1540867989,1 +251357,1540867989,1540867990,1 +251358,1540867990,1540867991,1 +251359,1540867991,1540867992,1 +251360,1540867992,1345233480,1 +251361,1540867993,1540867994,1 +251362,1540867994,1540867995,1 +251363,1540867995,1540867996,1 +251364,1540867996,1540867997,1 +251365,1540867997,1540867998,1 +251366,1540867998,1540867999,1 +251367,1540867999,1540868000,1 +251368,1540868000,1540868001,1 +251369,1540868001,1540868002,1 +251370,1540868002,1307354585,1 +251371,1540868003,1540868004,1 +251372,1540868004,1540868005,1 +251373,1540868005,1540868006,1 +251374,1540868006,1540868007,1 +251375,1540868007,1540868008,1 +251376,1540868008,1540868009,1 +251377,1540868009,1540868010,1 +251378,1540868010,1540868011,1 +251379,1540868011,1540868012,1 +251380,1540868012,1540868013,1 +251381,1540868013,1540868014,1 +251382,1540868014,1540868015,1 +251383,1540868015,1540868016,1 +251384,1540868016,1540868017,1 +251385,1540868017,1540868018,1 +251386,1540868018,1540868019,1 +251387,1540868019,1540868020,1 +251388,1540868020,1345205746,1 +251389,1540868021,1540868022,1 +251390,1540868022,935854664,1 +251395,1540868027,1540868028,1 +251396,1540868028,935855686,1 +251397,1540868029,1540868030,1 +251398,1540868030,935855700,1 +251399,1540868031,1540868032,1 +251400,1540868032,935855677,1 +251469,1540868101,935854880,1 +251470,1540868102,935855555,1 +251476,1540868108,1540868109,1 +251477,1540868109,1540868110,1 +251478,1540868110,1307354700,1 +251479,1540868111,1307354651,1 +251480,1540868112,1540868113,1 +251481,1540868113,1307354781,1 +251482,1540868114,1307354727,1 +251483,1540868115,1540868116,1 +251484,1540868116,1540868117,1 +251485,1540868117,1307354374,1 +251486,1540868118,1307354679,1 +251487,1540868119,1307354628,1 +251488,1540868120,1540868121,1 +251489,1540868121,1540868122,1 +251490,1540868122,1540868123,1 +251491,1540868123,935855227,1 +251492,1540868124,1540868125,1 +251493,1540868125,1540868126,1 +251494,1540868126,1540868127,1 +251495,1540868127,1540868128,1 +251496,1540868128,1540868129,1 +251497,1540868129,1540868130,1 +251498,1540868130,1540868131,1 +251499,1540868131,1540868132,1 +251500,1540868132,1540868133,1 +251501,1540868133,1540868134,1 +251502,1540868134,1540868135,1 +251503,1540868135,1540868136,1 +251504,1540868136,1540868137,1 +251505,1540868137,1540868138,1 +251506,1540868138,1540868139,1 +251507,1540868139,1540868140,1 +251508,1540868140,1540868141,1 +251509,1540868141,1540868142,1 +251510,1540868142,1540868143,1 +251511,1540868143,1540868144,1 +251512,1540868144,1540868145,1 +251513,1540868145,1540868146,1 +251514,1540868146,935855677,1 +251515,1540868147,1540868148,1 +251516,1540868148,1540868149,1 +251517,1540868149,935854584,1 +251518,1540868150,935854691,1 +251843,1540868475,1540868476,1 +251844,1540868476,1540868477,1 +251845,1540868477,1540868478,1 +251846,1540868478,1540868479,1 +251847,1540868479,936804192,1 +251848,1540868480,360476537,0 +251849,1540868481,1540868482,0 +251850,1540868482,1540868483,0 +251851,1540868483,1540868484,0 +251852,1540868484,1540868485,0 +251853,1540868485,1540868486,0 +251854,1540868486,936853855,0 +251855,1540868487,938502215,1 +251856,1540868488,360476914,1 +251857,1540868489,360476926,1 +251858,1540868490,1540868491,1 +251859,1540868491,360476991,1 +251860,1540868492,1540868493,1 +251861,1540868493,360477041,1 +251862,1540868494,360476537,1 +251863,1540868495,938140812,1 +251864,1540868496,938140781,1 +251865,1540868497,937216375,1 +251866,1540868498,937216436,1 +251867,1540868499,1540868500,1 +251868,1540868500,937216167,1 +251869,1540868501,937216421,1 +251870,1540868502,937216035,1 +251871,1540868503,937216608,1 +251872,1540868504,937216542,1 +251873,1540868505,937216270,1 +251874,1540868506,1540868507,1 +251875,1540868507,1540868508,1 +251876,1540868508,937216277,1 +251877,1540868509,1540868510,1 +251878,1540868510,1540868511,1 +251879,1540868511,937216425,1 +251880,1540868512,1540868513,1 +251881,1540868513,1540868514,1 +251882,1540868514,937216246,1 +251883,1540868515,1540868516,1 +251884,1540868516,1540868517,1 +251885,1540868517,937216123,1 +251886,1540868518,1540868519,1 +251887,1540868519,937216354,1 +251888,1540868520,937216482,1 +251889,1540868521,937216248,1 +251890,1540868522,937216612,1 +251891,1540868523,937216351,1 +251892,1540868524,937216161,1 +251893,1540868525,937216333,1 +251894,1540868526,937216455,1 +251895,1540868527,937216259,1 +251896,1540868528,937216018,1 +251897,1540868529,1540868530,1 +251898,1540868530,1540868531,1 +251899,1540868531,1540868532,1 +251900,1540868532,600926437,1 +251901,1540868533,937216014,1 +251902,1540868534,1540868535,1 +251903,1540868535,1540868536,1 +251904,1540868536,937216175,1 +251905,1540868537,938140760,1 +251906,1540868538,938140785,1 +251907,1540868539,1540868540,1 +251908,1540868540,937216220,1 +251909,1540868541,1540868542,1 +251910,1540868542,937216492,1 +251911,1540868543,937216099,1 +251912,1540868544,937216039,1 +251913,1540868545,937216010,1 +251914,1540868546,1540868547,1 +251915,1540868547,937216173,1 +251916,1540868548,937216236,1 +251917,1540868549,1540868550,1 +251918,1540868550,1540868551,1 +251919,1540868551,937216067,1 +251920,1540868552,361199750,1 +251921,1540868553,937216564,1 +251922,1540868554,937216413,1 +251923,1540868555,1540868556,1 +251924,1540868556,1540868557,1 +251925,1540868557,1540868558,1 +251926,1540868558,938140789,1 +251927,1540868559,938140780,1 +251928,1540868560,361199380,1 +251929,1540868561,797394761,1 +251930,1540868562,937365605,1 +251931,1540868563,937365437,1 +251932,1540868564,1540868565,1 +251933,1540868565,1540868566,1 +251934,1540868566,937216067,1 +251935,1540868567,937216598,1 +251936,1540868568,1540868569,1 +251937,1540868569,937216599,1 +251938,1540868570,937365446,1 +251939,1540868571,1540868572,1 +251940,1540868572,1540868573,1 +251941,1540868573,937365502,1 +251942,1540868574,937216207,1 +251943,1540868575,152803983,1 +251944,1540868576,1540868577,1 +251945,1540868577,1540868578,1 +251946,1540868578,937216001,1 +251947,1540868579,1540868580,1 +251948,1540868580,1540868581,1 +251949,1540868581,937365411,1 +251950,1540868582,937365628,1 +251951,1540868583,938140787,1 +251952,1540868584,937365446,1 +251953,1540868585,361199487,1 +251954,1540868586,938140783,1 +251955,1540868587,937365630,1 +251956,1540868588,1540868589,1 +251957,1540868589,1540868590,1 +251958,1540868590,937365547,1 +251959,1540868591,937365529,1 +251960,1540868592,937365639,1 +251961,1540868593,937365388,1 +251962,1540868594,937365490,1 +251963,1540868595,1540868596,1 +251964,1540868596,937216507,1 +251965,1540868597,1540868598,0 +251966,1540868598,1540868599,0 +251967,1540868599,1540868600,0 +251968,1540868600,1540868601,0 +251969,1540868601,1540868602,0 +251970,1540868602,1540868603,0 +251971,1540868603,1540868604,0 +251972,1540868604,1540868605,0 +251973,1540868605,1540868606,0 +251974,1540868606,1540868607,0 +251975,1540868607,1540868608,0 +251976,1540868608,1540868609,0 +251977,1540868609,1540868610,0 +251978,1540868610,1540868611,0 +251979,1540868611,1540868612,0 +251980,1540868612,1540868613,0 +251981,1540868613,1540868614,0 +251982,1540868614,1540868615,0 +251983,1540868615,1540868616,0 +251984,1540868616,1540868617,0 +251985,1540868617,1540868618,0 +251986,1540868618,445393431,0 +251987,1540868619,1540868620,0 +251988,1540868620,1540868621,0 +251989,1540868621,1540868622,0 +251990,1540868622,1540868623,0 +251991,1540868623,1540868624,0 +251992,1540868624,1540868625,0 +251993,1540868625,1540868626,0 +251994,1540868626,1540868627,0 +251995,1540868627,445393429,0 +252002,1540868634,1540868635,1 +252003,1540868635,1540868636,1 +252004,1540868636,1540868637,1 +252005,1540868637,1540868638,1 +252006,1540868638,1540868639,1 +252007,1540868639,937378209,1 +252011,1540868643,1540868644,0 +252012,1540868644,1540868645,0 +252013,1540868645,1540868646,0 +252014,1540868646,445393429,0 +252015,1540868647,1540868648,0 +252016,1540868648,1540868649,0 +252017,1540868649,1540868650,0 +252018,1540868650,1540868651,0 +252019,1540868651,1540868652,0 +252020,1540868652,1540868653,0 +252021,1540868653,1540868654,0 +252022,1540868654,1540868655,0 +252023,1540868655,1540868656,0 +252024,1540868656,84568354,0 +252025,1540868657,1540868658,0 +252026,1540868658,1540868659,0 +252027,1540868659,1540868660,0 +252028,1540868660,130197784,0 +252029,1540868661,1540868662,1 +252030,1540868662,1540868663,1 +252031,1540868663,1540868664,1 +252032,1540868664,1540868665,1 +252033,1540868665,1540868666,1 +252034,1540868666,1540868667,1 +252035,1540868667,1540868668,1 +252036,1540868668,1540868669,1 +252037,1540868669,1540868670,1 +252038,1540868670,1540868671,1 +252039,1540868671,1540868672,1 +252040,1540868672,1540868673,1 +252041,1540868673,1540868674,1 +252042,1540868674,152805030,1 +252043,1540868675,1540868676,1 +252044,1540868676,1540868677,1 +252045,1540868677,1540868678,1 +252046,1540868678,1540868679,1 +252047,1540868679,1540868680,1 +252048,1540868680,1540868681,1 +252049,1540868681,1540868682,1 +252050,1540868682,1540868683,1 +252051,1540868683,1540868684,1 +252052,1540868684,1540868685,1 +252053,1540868685,1540868686,1 +252054,1540868686,1540868687,1 +252055,1540868687,1540868688,1 +252056,1540868688,1540868689,1 +252057,1540868689,1540868690,1 +252058,1540868690,1540868691,1 +252059,1540868691,937378231,1 +252256,1540868888,1540868889,1 +252257,1540868889,1540868890,1 +252258,1540868890,361199625,1 +252259,1540868891,938143080,1 +252260,1540868892,1540868893,1 +252261,1540868893,1540868894,1 +252262,1540868894,1540868895,1 +252263,1540868895,1540868896,1 +252264,1540868896,361199627,1 +252265,1540868897,1540868898,1 +252266,1540868898,1540868899,1 +252267,1540868899,1540868900,1 +252268,1540868900,1540868901,1 +252269,1540868901,1343063215,1 +252270,1540868902,1343052619,1 +252271,1540868903,1343052621,1 +252272,1540868904,1343052623,1 +252273,1540868905,938142809,1 +252274,1540868906,938140744,1 +252275,1540868907,938140812,1 +252276,1540868908,361199745,1 +252277,1540868909,1540868910,1 +252278,1540868910,937216065,1 +252279,1540868911,938140743,1 +252280,1540868912,600927586,1 +252281,1540868913,1540868914,1 +252282,1540868914,938140746,1 +252283,1540868915,938140791,1 +252284,1540868916,938140781,1 +252285,1540868917,938140760,1 +252286,1540868918,1540868919,1 +252287,1540868919,938140742,1 +252288,1540868920,1540868921,1 +252289,1540868921,938143006,1 +252290,1540868922,938142962,1 +252291,1540868923,938142986,1 +252292,1540868924,1540868925,1 +252293,1540868925,938143115,1 +252294,1540868926,1540868927,1 +252295,1540868927,938142858,1 +252296,1540868928,938143155,1 +252297,1540868929,1540868930,1 +252298,1540868930,1540868931,1 +252299,1540868931,938143066,1 +252300,1540868932,938143004,1 +252301,1540868933,938143052,1 +252302,1540868934,1540868935,1 +252303,1540868935,938142964,1 +252304,1540868936,938142912,1 +252305,1540868937,1540868938,1 +252306,1540868938,938142985,1 +252307,1540868939,938143125,1 +252308,1540868940,1343071761,1 +252309,1540868941,294203215,1 +252310,1540868942,1540868943,1 +252311,1540868943,1540868944,1 +252312,1540868944,938143024,1 +252313,1540868945,938142903,1 +252314,1540868946,938142811,1 +252315,1540868947,938143155,1 +252316,1540868948,938142841,1 +252317,1540868949,1540868950,1 +252318,1540868950,938142803,1 +252319,1540868951,938143112,1 +252320,1540868952,938143045,1 +252321,1540868953,938143017,1 +252322,1540868954,938142946,1 +252323,1540868955,938142989,1 +252324,1540868956,294203215,1 +252325,1540868957,938142964,1 +252326,1540868958,938142945,1 +252327,1540868959,1540868960,1 +252328,1540868960,1540868961,1 +252329,1540868961,1540868962,1 +252330,1540868962,938142869,1 +252331,1540868963,1540868964,1 +252332,1540868964,1540868965,1 +252333,1540868965,938142858,1 +252334,1540868966,938142984,1 +252335,1540868967,938143042,1 +252336,1540868968,1540868969,1 +252337,1540868969,938143013,1 +252338,1540868970,938142809,1 +252339,1540868971,1540868972,1 +252340,1540868972,938142984,1 +252341,1540868973,938142962,1 +252342,1540868974,1540868975,1 +252343,1540868975,938142867,1 +252344,1540868976,938142832,1 +252345,1540868977,1540868978,1 +252346,1540868978,938149077,1 +252347,1540868979,938149186,1 +252348,1540868980,938149113,1 +252349,1540868981,1540868982,1 +252350,1540868982,938149096,1 +252354,1540868986,1540868987,1 +252355,1540868987,1540868988,1 +252356,1540868988,938501939,1 +252357,1540868989,938501997,1 +252358,1540868990,294162342,0 +252359,1540868991,1144431652,1 +252360,1540868992,938502401,1 +252361,1540868993,1540868994,1 +252362,1540868994,1540868995,1 +252363,1540868995,1540868996,1 +252364,1540868996,938502124,1 +252365,1540868997,938502135,1 +252366,1540868998,1540868999,1 +252367,1540868999,1540869000,1 +252368,1540869000,938502398,1 +252369,1540869001,1540869002,1 +252370,1540869002,1540869003,1 +252371,1540869003,1540869004,1 +252372,1540869004,1540869005,1 +252373,1540869005,938502343,1 +252374,1540869006,1540869007,1 +252375,1540869007,938502181,1 +252376,1540869008,938502038,0 +252377,1540869009,938501948,1 +252378,1540869010,1540869011,1 +252379,1540869011,938502197,1 +252380,1540869012,1540869013,1 +252381,1540869013,1540869014,1 +252382,1540869014,1540869015,1 +252383,1540869015,938502284,1 +252384,1540869016,1540869017,1 +252385,1540869017,1540869018,1 +252386,1540869018,938502181,1 +252387,1540869019,938502209,1 +252388,1540869020,938502386,1 +252389,1540869021,1540869022,1 +252390,1540869022,1141083892,1 +252391,1540869023,1540869024,1 +252392,1540869024,1141083851,1 +252393,1540869025,1540869026,1 +252394,1540869026,1540869027,1 +252395,1540869027,1132701122,1 +252396,1540869028,938502259,1 +252397,1540869029,667221929,0 +252398,1540869030,938502353,0 +252399,1540869031,938501993,1 +252400,1540869032,938502278,1 +252401,1540869033,1540869034,1 +252402,1540869034,1540869035,1 +252403,1540869035,1540869036,1 +252404,1540869036,1540869037,1 +252405,1540869037,938502222,1 +252406,1540869038,1540869039,1 +252407,1540869039,1540869040,1 +252408,1540869040,1540869041,1 +252409,1540869041,938502331,1 +252410,1540869042,1140966212,1 +252411,1540869043,1540869044,1 +252412,1540869044,938501996,1 +252413,1540869045,938502237,1 +252414,1540869046,1540869047,1 +252415,1540869047,938502134,1 +252416,1540869048,1540869049,1 +252417,1540869049,938501961,1 +252418,1540869050,667221930,0 +252419,1540869051,938501996,0 +252420,1540869052,1343037492,1 +252421,1540869053,1540869054,1 +252422,1540869054,1540869055,1 +252423,1540869055,1540869056,1 +252424,1540869056,1540869057,1 +252425,1540869057,938502080,1 +252426,1540869058,1540869059,1 +252427,1540869059,938502278,1 +252428,1540869060,1119992514,1 +252429,1540869061,938501966,1 +252430,1540869062,653316959,1 +252431,1540869063,938502324,1 +252432,1540869064,653316956,1 +252768,1540869400,1540869401,0 +252769,1540869401,1540869402,0 +252770,1540869402,1540869403,0 +252771,1540869403,660490311,0 +252772,1540869404,1540869405,1 +252773,1540869405,1540869406,1 +252774,1540869406,360015812,1 +252775,1540869407,1540869408,1 +252776,1540869408,1540869409,1 +252777,1540869409,792045747,1 +252778,1540869410,1540869411,0 +252779,1540869411,1540869412,0 +252780,1540869412,1540869413,0 +252781,1540869413,1540869414,0 +252782,1540869414,1540869415,0 +252783,1540869415,939594136,0 +252784,1540869416,939593956,0 +252785,1540869417,939593933,0 +252786,1540869418,939594028,0 +252787,1540869419,1540869420,0 +252788,1540869420,1540869421,0 +252789,1540869421,1540869422,0 +252790,1540869422,1540869423,0 +252791,1540869423,1540869424,0 +252792,1540869424,939594027,0 +252793,1540869425,1540869426,0 +252794,1540869426,1540869427,0 +252795,1540869427,1540869428,0 +252796,1540869428,1540869429,0 +252797,1540869429,1540869430,0 +252798,1540869430,1540869431,0 +252799,1540869431,1015274267,0 +252800,1540869432,1540869433,1 +252801,1540869433,1540869434,1 +252802,1540869434,1540869435,1 +252803,1540869435,1540869436,1 +252804,1540869436,1540869437,1 +252805,1540869437,1540869438,1 +252806,1540869438,360015837,1 +252807,1540869439,1540869440,0 +252808,1540869440,939593999,0 +252809,1540869441,1540869442,0 +252810,1540869442,1540869443,0 +252811,1540869443,1540869444,0 +252812,1540869444,1540869445,0 +252813,1540869445,360015818,0 +252814,1540869446,939594028,0 +252815,1540869447,939593999,0 +252816,1540869448,1540869449,0 +252817,1540869449,1015274267,0 +252818,1540869450,1540869451,0 +252819,1540869451,1540869452,0 +252820,1540869452,1540869453,0 +252821,1540869453,939594062,0 +252913,1540869545,940611007,1 +252914,1540869546,1540869547,1 +252915,1540869547,1540869548,1 +252916,1540869548,1540869549,1 +252917,1540869549,966314842,1 +252918,1540869550,1540869551,1 +252919,1540869551,536600486,1 +252920,1540869552,1540869553,1 +252921,1540869553,940611005,1 +252922,1540869554,363986997,1 +252923,1540869555,940610999,1 +252924,1540869556,536600481,1 +253019,1540869651,1540869652,1 +253020,1540869652,952161231,1 +253021,1540869653,952161319,1 +253022,1540869654,1540869655,1 +253023,1540869655,952161852,1 +253024,1540869656,952161857,1 +253025,1540869657,1030975484,1 +253026,1540869658,1540869659,1 +253027,1540869659,952161850,1 +253028,1540869660,1540869661,1 +253029,1540869661,1540869662,1 +253030,1540869662,952161739,1 +253031,1540869663,1030689913,0 +253032,1540869664,1540869665,0 +253033,1540869665,1540869666,0 +253034,1540869666,1540869667,0 +253035,1540869667,1540869668,0 +253036,1540869668,952161298,0 +253037,1540869669,1540869670,0 +253038,1540869670,1540869671,0 +253039,1540869671,1540869672,0 +253040,1540869672,1540869673,0 +253041,1540869673,952161846,0 +253042,1540869674,1540869675,0 +253043,1540869675,1540869676,0 +253044,1540869676,1540869677,0 +253045,1540869677,1540869678,0 +253046,1540869678,1030689248,0 +253047,1540869679,1540869680,0 +253048,1540869680,1540869681,0 +253049,1540869681,1540869682,0 +253050,1540869682,1030688812,0 +253051,1540869683,1540869684,0 +253052,1540869684,1540869685,0 +253053,1540869685,1030689788,0 +253054,1540869686,1540869687,0 +253055,1540869687,1540869688,0 +253056,1540869688,1540869689,0 +253057,1540869689,1540869690,0 +253058,1540869690,1540869691,0 +253059,1540869691,1540869692,0 +253060,1540869692,1540869693,0 +253061,1540869693,1540869694,0 +253062,1540869694,1540869695,0 +253063,1540869695,1540869696,0 +253064,1540869696,1030689974,0 +253065,1540869697,1540869698,0 +253066,1540869698,1036415661,0 +253067,1540869699,1540869700,0 +253068,1540869700,1540869701,0 +253069,1540869701,1540869702,0 +253070,1540869702,1540869703,0 +253071,1540869703,1036415436,0 +253072,1540869704,1540869705,0 +253073,1540869705,952161584,0 +253074,1540869706,952161109,0 +253075,1540869707,952161559,0 +253076,1540869708,1540869709,0 +253077,1540869709,952161425,0 +253078,1540869710,1540869711,0 +253079,1540869711,952161259,0 +253080,1540869712,952161690,0 +253081,1540869713,1030975289,1 +253082,1540869714,1540869715,0 +253083,1540869715,1036415877,0 +253084,1540869716,1540869717,0 +253085,1540869717,1540869718,0 +253086,1540869718,1540869719,0 +253087,1540869719,1540869720,0 +253088,1540869720,1030689225,0 +253089,1540869721,1540869722,0 +253090,1540869722,1540869723,0 +253091,1540869723,1540869724,0 +253092,1540869724,1540869725,0 +253093,1540869725,1540869726,0 +253094,1540869726,1540869727,0 +253095,1540869727,1540869728,0 +253096,1540869728,1540869729,0 +253097,1540869729,1540869730,0 +253098,1540869730,1030689645,0 +253099,1540869731,1540869732,0 +253100,1540869732,1540869733,0 +253101,1540869733,1540869734,0 +253102,1540869734,1540869735,0 +253103,1540869735,1540869736,0 +253104,1540869736,1030689358,0 +253105,1540869737,1540869738,0 +253106,1540869738,1540869739,0 +253107,1540869739,1540869740,0 +253108,1540869740,1540869741,0 +253109,1540869741,952161779,0 +253110,1540869742,1540869743,0 +253111,1540869743,1540869744,0 +253112,1540869744,1540869745,0 +253113,1540869745,952161299,0 +253114,1540869746,952160960,0 +253115,1540869747,1540869748,0 +253116,1540869748,1540869749,0 +253117,1540869749,1540869750,0 +253118,1540869750,1540869751,0 +253119,1540869751,952161183,0 +253120,1540869752,1030690067,0 +253121,1540869753,1540869754,0 +253122,1540869754,952161554,0 +253123,1540869755,952161739,0 +253124,1540869756,952161163,0 +253125,1540869757,1540869758,0 +253126,1540869758,952161076,0 +253127,1540869759,952161806,0 +253210,1540869842,1540869843,1 +253211,1540869843,1540869844,1 +253212,1540869844,956789170,1 +253451,1540870083,1540870084,1 +253452,1540870084,1540870085,1 +253453,1540870085,961664584,1 +253454,1540870086,961664603,1 +253455,1540870087,1540870088,1 +253456,1540870088,1540870089,1 +253457,1540870089,1540870090,1 +253458,1540870090,528475264,1 +253459,1540870091,1540870092,1 +253460,1540870092,939593944,1 +253461,1540870093,956787101,1 +253462,1540870094,1540870095,1 +253463,1540870095,1540870096,1 +253464,1540870096,359998484,1 +253465,1540870097,1540870098,1 +253466,1540870098,1540870099,1 +253467,1540870099,1540870100,1 +253468,1540870100,1540870101,1 +253469,1540870101,961664561,1 +253470,1540870102,961664425,1 +253471,1540870103,1540870104,1 +253472,1540870104,956789170,1 +253473,1540870105,1540870106,1 +253474,1540870106,1540870107,1 +253475,1540870107,792048327,1 +253476,1540870108,961664697,1 +253477,1540870109,961664738,1 +253478,1540870110,360000369,1 +253479,1540870111,360000540,1 +253480,1540870112,1540870113,1 +253481,1540870113,1540870114,1 +253482,1540870114,1540870115,1 +253483,1540870115,360000523,1 +253484,1540870116,1540870117,1 +253485,1540870117,961664439,1 +253486,1540870118,961683622,1 +253718,1540870350,1540870351,0 +253719,1540870351,1540870352,0 +253720,1540870352,1540870353,0 +253721,1540870353,963987494,0 +253722,1540870354,1540870355,1 +253723,1540870355,1540870356,1 +253724,1540870356,360221447,1 +253730,1540870362,965013869,1 +253731,1540870363,965013872,1 +253732,1540870364,1333878370,1 +253733,1540870365,1540870366,1 +253734,1540870366,1196620819,1 +253735,1540870367,1540870368,1 +253736,1540870368,1333877875,1 +253737,1540870369,1333878172,1 +253738,1540870370,1540870371,1 +253739,1540870371,1540870372,1 +253740,1540870372,1540870373,1 +253741,1540870373,1540870374,1 +253742,1540870374,1540870375,1 +253743,1540870375,1540870376,1 +253744,1540870376,1333878189,1 +253745,1540870377,1540870378,1 +253746,1540870378,1333878133,1 +253747,1540870379,1540870380,1 +253748,1540870380,1540870381,1 +253749,1540870381,965013909,1 +253907,1540870539,1540870540,1 +253908,1540870540,965140641,1 +253926,1540870558,1540870559,1 +253927,1540870559,965140463,1 +253928,1540870560,1540870561,1 +253929,1540870561,1540870562,1 +253930,1540870562,1540870563,1 +253931,1540870563,1540870564,1 +253932,1540870564,1540870565,1 +253933,1540870565,1540870566,1 +253934,1540870566,1540870567,1 +253935,1540870567,1540870568,1 +253936,1540870568,1540870569,1 +253937,1540870569,1540870570,1 +253938,1540870570,1540870571,1 +253939,1540870571,1540870572,1 +253940,1540870572,1540870573,1 +253941,1540870573,1540870574,1 +253942,1540870574,1540870575,1 +253943,1540870575,1540870576,1 +253944,1540870576,1540870577,1 +253945,1540870577,1540870578,1 +253946,1540870578,1540870579,1 +253947,1540870579,1540870580,1 +253948,1540870580,1179200509,1 +253973,1540870605,1540870606,1 +253974,1540870606,1540870607,1 +253975,1540870607,1540870608,1 +253976,1540870608,1540870609,1 +253977,1540870609,1540870610,1 +253978,1540870610,1540870611,1 +253979,1540870611,1540870612,1 +253980,1540870612,1540870613,1 +253981,1540870613,1540870614,1 +253982,1540870614,1540870615,1 +253983,1540870615,1540870616,1 +253984,1540870616,1540870617,1 +253985,1540870617,1540870618,1 +253986,1540870618,1540870619,1 +253987,1540870619,1540870620,1 +253988,1540870620,1540870621,1 +253989,1540870621,1540870622,1 +253990,1540870622,1540870623,1 +253991,1540870623,1540870624,1 +253992,1540870624,1179200499,1 +253993,1540870625,1540870626,1 +253994,1540870626,965140505,1 +254180,1540870812,965324248,1 +254181,1540870813,1540870814,1 +254182,1540870814,1540870815,1 +254183,1540870815,966153823,1 +254184,1540870816,1540870817,1 +254185,1540870817,1540870818,1 +254186,1540870818,1540870819,1 +254187,1540870819,1540870820,1 +254188,1540870820,965324220,1 +254189,1540870821,1540870822,1 +254190,1540870822,363986466,1 +254281,1540870913,1540870914,1 +254282,1540870914,965332085,1 +254287,1540870919,965332081,1 +254288,1540870920,1540870921,1 +254289,1540870921,965332005,1 +254359,1540870991,966154032,1 +254383,1540871015,1540871016,1 +254384,1540871016,1540871017,1 +254385,1540871017,965332005,1 +254390,1540871022,1540871023,1 +254391,1540871023,966153998,1 +254392,1540871024,966154120,1 +254395,1540871027,966154044,1 +254396,1540871028,966154079,1 +254397,1540871029,1540871030,1 +254398,1540871030,1540871031,1 +254399,1540871031,965323843,1 +254401,1540871033,966315323,1 +254402,1540871034,966314683,1 +254403,1540871035,363986467,1 +254404,1540871036,966154033,1 +254405,1540871037,1540871038,1 +254406,1540871038,363986469,1 +254407,1540871039,966314894,1 +254426,1540871058,1540871059,1 +254427,1540871059,1540871060,1 +254428,1540871060,966153998,1 +254451,1540871083,363984889,1 +254452,1540871084,1540871085,1 +254453,1540871085,1540871086,1 +254454,1540871086,363986457,1 +254455,1540871087,363986460,1 +254456,1540871088,1540871089,1 +254457,1540871089,1540871090,1 +254458,1540871090,1540871091,1 +254459,1540871091,966294252,1 +254460,1540871092,966154088,1 +254461,1540871093,1540871094,1 +254462,1540871094,1540871095,1 +254463,1540871095,363986473,1 +254464,1540871096,1540871097,1 +254465,1540871097,1540871098,1 +254466,1540871098,966303953,1 +254467,1540871099,1540871100,1 +254468,1540871100,1540871101,1 +254469,1540871101,966303886,1 +254470,1540871102,1540871103,1 +254471,1540871103,1540871104,1 +254472,1540871104,583435261,1 +254480,1540871112,967199382,1 +254481,1540871113,967199511,1 +254496,1540871128,1540871129,1 +254497,1540871129,967199365,1 +254506,1540871138,1540871139,1 +254507,1540871139,1540871140,1 +254508,1540871140,1540871141,1 +254509,1540871141,1540871142,1 +254510,1540871142,1540871143,1 +254511,1540871143,1540871144,1 +254512,1540871144,1540871145,1 +254513,1540871145,966303953,1 +254514,1540871146,966315162,1 +254515,1540871147,966314744,1 +254516,1540871148,1540871149,1 +254517,1540871149,966314710,1 +254518,1540871150,1540871151,1 +254519,1540871151,1540871152,1 +254520,1540871152,1540871153,1 +254521,1540871153,966315140,1 +254522,1540871154,966315487,1 +254523,1540871155,967241378,1 +254524,1540871156,966314812,1 +254525,1540871157,966314878,1 +254526,1540871158,966314760,1 +254527,1540871159,1540871160,1 +254528,1540871160,966314733,1 +254529,1540871161,1540871162,1 +254530,1540871162,1540871163,1 +254531,1540871163,1540871164,1 +254532,1540871164,536600492,1 +254533,1540871165,966314861,1 +254534,1540871166,940611003,1 +254535,1540871167,966315447,1 +254536,1540871168,966315509,1 +254537,1540871169,966314859,1 +254538,1540871170,1540871171,1 +254539,1540871171,1540871172,1 +254540,1540871172,966314733,1 +254541,1540871173,528489829,1 +254542,1540871174,1540871175,1 +254543,1540871175,966315275,1 +254544,1540871176,1540871177,1 +254545,1540871177,966315072,1 +254546,1540871178,1540871179,1 +254547,1540871179,966314880,1 +254548,1540871180,966315125,1 +254549,1540871181,966314880,1 +254550,1540871182,966314660,1 +254551,1540871183,1540871184,1 +254552,1540871184,966314681,1 +254553,1540871185,966314788,1 +254554,1540871186,1540871187,1 +254555,1540871187,966315404,1 +254556,1540871188,1540871189,1 +254557,1540871189,966314671,1 +254558,1540871190,1540871191,1 +254559,1540871191,536600470,1 +254560,1540871192,1540871193,1 +254561,1540871193,966314820,1 +254562,1540871194,1540871195,1 +254563,1540871195,1540871196,1 +254564,1540871196,966315125,1 +254565,1540871197,536600490,1 +254566,1540871198,1540871199,1 +254567,1540871199,1540871200,1 +254568,1540871200,966314786,1 +254569,1540871201,1540871202,1 +254570,1540871202,1540871203,1 +254571,1540871203,966314740,1 +254572,1540871204,1540871205,1 +254573,1540871205,1540871206,1 +254574,1540871206,528489811,1 +254575,1540871207,536600462,1 +254576,1540871208,966314986,1 +254577,1540871209,966314757,1 +254578,1540871210,1540871211,1 +254579,1540871211,536600473,1 +254580,1540871212,1540871213,1 +254581,1540871213,966314911,1 +254582,1540871214,1540871215,1 +254583,1540871215,966315215,1 +254584,1540871216,966315129,1 +254585,1540871217,528489802,1 +254586,1540871218,1540871219,1 +254587,1540871219,966315123,1 +254588,1540871220,966315443,1 +254589,1540871221,1540871222,1 +254590,1540871222,536600489,1 +254591,1540871223,966315381,1 +254592,1540871224,966315509,1 +254593,1540871225,1540871226,1 +254594,1540871226,966314820,1 +254595,1540871227,966315207,1 +254596,1540871228,966315263,1 +254597,1540871229,966315217,1 +254598,1540871230,1540871231,1 +254599,1540871231,966315167,1 +254600,1540871232,1540871233,1 +254601,1540871233,1540871234,1 +254602,1540871234,536600465,1 +254603,1540871235,1540871236,1 +254604,1540871236,1540871237,1 +254605,1540871237,583435303,1 +254606,1540871238,966315100,1 +254607,1540871239,1540871240,1 +254608,1540871240,1540871241,1 +254609,1540871241,966315059,1 +254610,1540871242,966315458,1 +254611,1540871243,940611024,1 +254612,1540871244,1540871245,1 +254613,1540871245,966314776,1 +254614,1540871246,966314850,1 +254615,1540871247,1540871248,1 +254616,1540871248,1540871249,1 +254617,1540871249,1540871250,1 +254618,1540871250,966314702,1 +254619,1540871251,966639718,1 +254620,1540871252,966639979,1 +254621,1540871253,1540871254,1 +254622,1540871254,360008371,1 +254623,1540871255,599532941,0 +254624,1540871256,966666289,1 +254625,1540871257,1540871258,1 +254626,1540871258,1540871259,1 +254627,1540871259,966666266,1 +254628,1540871260,1540871261,1 +254629,1540871261,1540871262,1 +254630,1540871262,966666274,1 +254631,1540871263,966666258,1 +254634,1540871266,967199704,1 +254635,1540871267,1540871268,1 +254636,1540871268,1540871269,1 +254637,1540871269,967240633,1 +254638,1540871270,1540871271,1 +254639,1540871271,1540871272,1 +254640,1540871272,1540871273,1 +254641,1540871273,1540871274,1 +254642,1540871274,967199339,1 +254643,1540871275,967199460,1 +254644,1540871276,1540871277,1 +254645,1540871277,1540871278,1 +254646,1540871278,1540871279,1 +254647,1540871279,1540871280,1 +254648,1540871280,967199588,1 +254649,1540871281,967199724,1 +254650,1540871282,967199619,1 +254651,1540871283,1540871284,1 +254652,1540871284,967199551,1 +254653,1540871285,363984903,1 +254654,1540871286,1540871287,1 +254655,1540871287,1540871288,1 +254656,1540871288,1540871289,1 +254657,1540871289,1540871290,1 +254658,1540871290,967199482,1 +254659,1540871291,1540871292,1 +254660,1540871292,361406194,1 +254661,1540871293,967199588,1 +254662,1540871294,967199509,1 +254663,1540871295,360019719,1 +254664,1540871296,1540871297,1 +254665,1540871297,1540871298,1 +254666,1540871298,966314812,1 +254667,1540871299,967199576,1 +254668,1540871300,360019433,1 +254669,1540871301,1540871302,1 +254670,1540871302,1540871303,1 +254671,1540871303,360019972,1 +254672,1540871304,967241392,0 +254673,1540871305,1540871306,0 +254674,1540871306,1540871307,0 +254675,1540871307,795263003,0 +254676,1540871308,967199365,1 +254677,1540871309,1540871310,0 +254678,1540871310,1540871311,0 +254679,1540871311,967241392,0 +254680,1540871312,1540871313,0 +254681,1540871313,1540871314,0 +254682,1540871314,549560806,0 +254683,1540871315,967240642,0 +254684,1540871316,967240558,0 +254685,1540871317,1540871318,1 +254686,1540871318,967241285,1 +254687,1540871319,967240788,1 +254688,1540871320,967241292,0 +254689,1540871321,1540871322,0 +254690,1540871322,1540871323,0 +254691,1540871323,967240676,0 +254692,1540871324,1540871325,0 +254693,1540871325,967241207,0 +254694,1540871326,361406194,0 +254695,1540871327,1540871328,1 +254696,1540871328,1540871329,1 +254697,1540871329,1540871330,1 +254698,1540871330,1540871331,1 +254699,1540871331,967199486,1 +254700,1540871332,967241171,1 +254701,1540871333,967240645,0 +254702,1540871334,361406197,0 +254703,1540871335,967241052,1 +254704,1540871336,1540871337,0 +254705,1540871337,1540871338,0 +254706,1540871338,967240601,0 +254707,1540871339,1540871340,1 +254708,1540871340,967240673,1 +254709,1540871341,1540871342,1 +254710,1540871342,1540871343,1 +254711,1540871343,967241333,1 +254712,1540871344,966279430,1 +254713,1540871345,967199757,1 +254714,1540871346,1540871347,1 +254715,1540871347,967240585,1 +254716,1540871348,795263236,1 +254717,1540871349,1540871350,1 +254718,1540871350,1540871351,1 +254719,1540871351,967241333,1 +254720,1540871352,1540871353,1 +254721,1540871353,1540871354,1 +254722,1540871354,1540871355,1 +254723,1540871355,1540871356,1 +254724,1540871356,1540871357,1 +254725,1540871357,360019427,1 +254726,1540871358,360019759,1 +254727,1540871359,360019438,1 +254728,1540871360,1540871361,1 +254729,1540871361,967331728,1 +254730,1540871362,1540871363,1 +254731,1540871363,536600619,1 +254732,1540871364,1540871365,1 +254733,1540871365,1540871366,1 +254734,1540871366,1540871367,1 +254735,1540871367,1540871368,1 +254736,1540871368,1540871369,1 +254737,1540871369,967331611,1 +254738,1540871370,1540871371,1 +254739,1540871371,1540871372,1 +254740,1540871372,967331615,1 +254741,1540871373,967331634,1 +254742,1540871374,1540871375,1 +254743,1540871375,1540871376,1 +254744,1540871376,967331634,1 +254745,1540871377,1540871378,1 +254746,1540871378,1540871379,1 +254747,1540871379,360019881,1 +254748,1540871380,1540871381,1 +254749,1540871381,1540871382,1 +254750,1540871382,1540871383,1 +254751,1540871383,1540871384,1 +254752,1540871384,360019884,1 +254753,1540871385,967331666,1 +254816,1540871448,968962598,1 +254817,1540871449,1015275358,1 +254818,1540871450,363972537,1 +254819,1540871451,968962577,1 +254820,1540871452,1540871453,1 +254821,1540871453,1540871454,1 +254822,1540871454,1540871455,1 +254823,1540871455,974030515,1 +254824,1540871456,968962590,1 +254825,1540871457,968962592,1 +254826,1540871458,968962586,1 +254827,1540871459,968962584,1 +254828,1540871460,1540871461,1 +254829,1540871461,968962587,1 +255464,1540872096,972315919,1 +255465,1540872097,972315703,1 +255466,1540872098,972315168,1 +255467,1540872099,966315458,1 +255468,1540872100,972315731,1 +255469,1540872101,972315304,1 +255470,1540872102,1540872103,1 +255471,1540872103,1540872104,1 +255472,1540872104,972315882,1 +255473,1540872105,583433305,1 +255474,1540872106,972315346,1 +255475,1540872107,583433308,1 +255476,1540872108,972315234,1 +255477,1540872109,360012348,1 +255478,1540872110,1540872111,1 +255479,1540872111,1540872112,1 +255480,1540872112,1540872113,1 +255481,1540872113,1540872114,1 +255482,1540872114,1540872115,1 +255483,1540872115,1540872116,1 +255484,1540872116,1540872117,1 +255485,1540872117,972315168,1 +255486,1540872118,1540872119,1 +255487,1540872119,1540872120,1 +255488,1540872120,1540872121,1 +255489,1540872121,1540872122,1 +255490,1540872122,972316045,1 +255491,1540872123,1540872124,1 +255492,1540872124,1540872125,1 +255493,1540872125,360010649,1 +255494,1540872126,1540872127,1 +255495,1540872127,1540872128,1 +255496,1540872128,360010541,1 +255497,1540872129,1540872130,1 +255498,1540872130,1540872131,1 +255499,1540872131,973982977,1 +255500,1540872132,1540872133,1 +255501,1540872133,1540872134,1 +255502,1540872134,966653557,1 +255503,1540872135,566679103,1 +255504,1540872136,972315170,1 +255505,1540872137,1540872138,1 +255506,1540872138,972316210,1 +255507,1540872139,1540872140,1 +255508,1540872140,1540872141,1 +255509,1540872141,972316162,1 +255510,1540872142,1540872143,1 +255511,1540872143,1540872144,1 +255512,1540872144,1540872145,1 +255513,1540872145,966315059,1 +255514,1540872146,1540872147,1 +255515,1540872147,1015275655,1 +255516,1540872148,1540872149,1 +255517,1540872149,972315978,1 +255518,1540872150,1540872151,1 +255519,1540872151,1540872152,1 +255520,1540872152,1540872153,1 +255521,1540872153,1540872154,1 +255522,1540872154,972316162,1 +255523,1540872155,1540872156,1 +255524,1540872156,1540872157,1 +255525,1540872157,972316033,1 +255526,1540872158,1540872159,1 +255527,1540872159,972315764,1 +255528,1540872160,1540872161,1 +255529,1540872161,972315738,1 +255530,1540872162,972315472,1 +255531,1540872163,972316190,1 +255532,1540872164,1540872165,1 +255533,1540872165,972315346,1 +255534,1540872166,972316151,1 +255535,1540872167,972315613,1 +255536,1540872168,1540872169,1 +255537,1540872169,1540872170,1 +255538,1540872170,972315285,1 +255539,1540872171,972315764,1 +255540,1540872172,1540872173,1 +255541,1540872173,972315178,1 +255542,1540872174,972316171,1 +255543,1540872175,1540872176,1 +255544,1540872176,972316095,1 +255545,1540872177,583433308,1 +255546,1540872178,972315173,1 +255547,1540872179,1540872180,1 +255548,1540872180,418771182,1 +255549,1540872181,1540872182,1 +255550,1540872182,1540872183,1 +255551,1540872183,1540872184,1 +255552,1540872184,1540872185,1 +255553,1540872185,1540872186,1 +255554,1540872186,972315878,1 +255555,1540872187,972316154,1 +255556,1540872188,1540872189,1 +255557,1540872189,966314820,1 +255558,1540872190,1540872191,1 +255559,1540872191,972315191,1 +255560,1540872192,972315731,1 +255561,1540872193,972316026,1 +255562,1540872194,972315699,1 +255563,1540872195,418771204,1 +255564,1540872196,418771181,1 +255565,1540872197,1540872198,1 +255566,1540872198,966639753,1 +255567,1540872199,583433337,1 +255568,1540872200,972316190,1 +255569,1540872201,1540872202,1 +255570,1540872202,972315768,1 +255571,1540872203,1540872204,1 +255572,1540872204,1540872205,1 +255573,1540872205,1540872206,1 +255574,1540872206,1540872207,1 +255575,1540872207,1540872208,1 +255576,1540872208,972315364,1 +255577,1540872209,1540872210,1 +255578,1540872210,973983024,1 +255579,1540872211,1540872212,1 +255580,1540872212,363973310,1 +255581,1540872213,972315801,1 +255582,1540872214,360205869,1 +255583,1540872215,972481953,1 +255584,1540872216,1540872217,1 +255585,1540872217,1540872218,1 +255586,1540872218,1540872219,1 +255587,1540872219,972481812,1 +255588,1540872220,1540872221,0 +255589,1540872221,1540872222,0 +255590,1540872222,1540872223,0 +255591,1540872223,1540872224,0 +255592,1540872224,360205519,0 +255593,1540872225,1540872226,1 +255594,1540872226,1540872227,1 +255595,1540872227,1540872228,1 +255596,1540872228,1540872229,1 +255597,1540872229,1540872230,1 +255598,1540872230,1540872231,1 +255599,1540872231,1540872232,1 +255600,1540872232,972481820,1 +255601,1540872233,1540872234,1 +255602,1540872234,1540872235,1 +255603,1540872235,1540872236,1 +255604,1540872236,1540872237,1 +255605,1540872237,1540872238,1 +255606,1540872238,1540872239,1 +255607,1540872239,1540872240,1 +255608,1540872240,972481966,1 +255609,1540872241,1540872242,1 +255610,1540872242,1540872243,1 +255611,1540872243,1540872244,1 +255612,1540872244,1540872245,1 +255613,1540872245,1540872246,1 +255614,1540872246,972481963,1 +255615,1540872247,1540872248,1 +255616,1540872248,600396283,1 +255617,1540872249,972481790,1 +255618,1540872250,1540872251,1 +255619,1540872251,1540872252,1 +255620,1540872252,972481760,1 +255621,1540872253,1540872254,1 +255622,1540872254,1540872255,1 +255623,1540872255,972481665,1 +255624,1540872256,1540872257,1 +255625,1540872257,279591451,1 +255626,1540872258,1540872259,1 +255627,1540872259,1540872260,1 +255628,1540872260,1540872261,1 +255629,1540872261,1540872262,1 +255630,1540872262,1540872263,1 +255631,1540872263,1540872264,1 +255632,1540872264,1540872265,1 +255633,1540872265,360206039,1 +255634,1540872266,1540872267,1 +255635,1540872267,1540872268,1 +255636,1540872268,1540872269,1 +255637,1540872269,972481981,1 +255638,1540872270,360194055,1 +255639,1540872271,972481801,0 +255640,1540872272,972481605,0 +255641,1540872273,972481725,0 +255642,1540872274,972481734,0 +255643,1540872275,972481839,0 +255644,1540872276,972481759,0 +255645,1540872277,360194109,1 +255646,1540872278,1540872279,1 +255647,1540872279,1540872280,1 +255648,1540872280,1540872281,1 +255649,1540872281,1540872282,1 +255650,1540872282,1540872283,1 +255651,1540872283,1540872284,1 +255652,1540872284,972481861,1 +255653,1540872285,1540872286,1 +255654,1540872286,972481813,1 +255655,1540872287,1540872288,1 +255656,1540872288,1540872289,1 +255657,1540872289,1540872290,1 +255658,1540872290,972481679,1 +255659,1540872291,1540872292,1 +255660,1540872292,1540872293,1 +255661,1540872293,972481830,1 +255662,1540872294,1540872295,1 +255663,1540872295,360190929,1 +255664,1540872296,1540872297,1 +255665,1540872297,1540872298,1 +255666,1540872298,972481609,1 +255667,1540872299,972481633,1 +255668,1540872300,360194251,1 +255669,1540872301,972481813,0 +255670,1540872302,972481730,0 +255671,1540872303,1540872304,1 +255672,1540872304,1540872305,1 +255673,1540872305,1540872306,1 +255674,1540872306,1540872307,1 +255675,1540872307,972481905,1 +255676,1540872308,1540872309,1 +255677,1540872309,972481647,1 +255678,1540872310,1540872311,1 +255679,1540872311,1540872312,1 +255680,1540872312,972481752,1 +255681,1540872313,576508569,1 +255682,1540872314,583433365,1 +255683,1540872315,1540872316,1 +255684,1540872316,1540872317,1 +255685,1540872317,1540872318,1 +255686,1540872318,1540872319,1 +255687,1540872319,1540872320,1 +255688,1540872320,1540872321,1 +255689,1540872321,1540872322,1 +255690,1540872322,360224599,1 +255691,1540872323,1540872324,1 +255692,1540872324,1540872325,1 +255693,1540872325,1540872326,1 +255694,1540872326,1540872327,1 +255695,1540872327,1540872328,1 +255696,1540872328,1540872329,1 +255697,1540872329,1540872330,1 +255698,1540872330,1540872331,1 +255699,1540872331,549791399,1 +255700,1540872332,549787380,1 +255701,1540872333,1540872334,0 +255702,1540872334,279591667,0 +255703,1540872335,360191195,0 +255704,1540872336,1540872337,0 +255705,1540872337,279591661,0 +255706,1540872338,972481984,0 +255707,1540872339,972481914,1 +255708,1540872340,1540872341,1 +255709,1540872341,1540872342,1 +255710,1540872342,1540872343,1 +255711,1540872343,1540872344,1 +255712,1540872344,1540872345,1 +255713,1540872345,972481797,1 +255762,1540872394,1041566605,1 +255823,1540872455,1540872456,0 +255824,1540872456,1540872457,0 +255825,1540872457,1540872458,0 +255826,1540872458,1540872459,0 +255827,1540872459,1540872460,0 +255828,1540872460,1540872461,0 +255829,1540872461,1540872462,0 +255830,1540872462,973017196,0 +255835,1540872467,1540872468,0 +255836,1540872468,1540872469,0 +255837,1540872469,1540872470,0 +255838,1540872470,1540872471,0 +255839,1540872471,1540872472,0 +255840,1540872472,1540872473,0 +255841,1540872473,1540872474,0 +255842,1540872474,1540872475,0 +255843,1540872475,35487995,0 +255844,1540872476,360226000,0 +255877,1540872509,1540872510,0 +255878,1540872510,1540872511,0 +255879,1540872511,1540872512,0 +255880,1540872512,1540872513,0 +255881,1540872513,1540872514,0 +255882,1540872514,1540872515,0 +255883,1540872515,1540872516,0 +255884,1540872516,360227483,0 +255945,1540872577,1540872578,0 +255946,1540872578,1540872579,0 +255947,1540872579,1540872580,0 +255948,1540872580,1540872581,0 +255949,1540872581,1540872582,0 +255950,1540872582,1540872583,0 +255951,1540872583,973017371,0 +255955,1540872587,1540872588,0 +255956,1540872588,1540872589,0 +255957,1540872589,1540872590,0 +255958,1540872590,1540872591,0 +255959,1540872591,1540872592,0 +255960,1540872592,1540872593,0 +255961,1540872593,1540872594,0 +255962,1540872594,973037250,0 +255963,1540872595,1540872596,0 +255964,1540872596,1540872597,0 +255965,1540872597,600629166,0 +255966,1540872598,360195555,1 +255967,1540872599,1540872600,1 +255968,1540872600,360195552,1 +255969,1540872601,1540872602,1 +255970,1540872602,973053968,1 +255971,1540872603,973777017,1 +255994,1540872626,1540872627,0 +255995,1540872627,1540872628,0 +255996,1540872628,1540872629,0 +255997,1540872629,1540872630,0 +255998,1540872630,1540872631,0 +256092,1540872724,972315768,1 +256093,1540872725,974030615,0 +256094,1540872726,1540872727,0 +256095,1540872727,1540872728,0 +256096,1540872728,1540872729,0 +256097,1540872729,363974816,0 +256098,1540872730,279591116,0 +256099,1540872731,1540872732,1 +256100,1540872732,1540872733,1 +256101,1540872733,973983241,1 +256102,1540872734,1540872735,1 +256103,1540872735,1540872736,1 +256104,1540872736,1540872737,1 +256105,1540872737,1540872738,1 +256106,1540872738,1540872739,1 +256107,1540872739,1540872740,1 +256108,1540872740,1540872741,1 +256109,1540872741,1540872742,1 +256110,1540872742,973983685,1 +256111,1540872743,973983247,1 +256112,1540872744,1540872745,1 +256113,1540872745,1540872746,1 +256114,1540872746,973983043,1 +256115,1540872747,973983407,1 +256116,1540872748,973983507,1 +256117,1540872749,1540872750,1 +256118,1540872750,973983116,1 +256119,1540872751,279591134,1 +256120,1540872752,1540872753,1 +256121,1540872753,1540872754,1 +256122,1540872754,279591275,1 +256123,1540872755,1540872756,1 +256124,1540872756,1540872757,1 +256125,1540872757,1540872758,1 +256126,1540872758,1540872759,1 +256127,1540872759,1540872760,1 +256128,1540872760,1540872761,1 +256129,1540872761,1540872762,1 +256130,1540872762,1540872763,1 +256131,1540872763,1540872764,1 +256132,1540872764,1540872765,1 +256133,1540872765,974030929,1 +256134,1540872766,973983208,1 +256135,1540872767,972315864,1 +256136,1540872768,1540872769,1 +256137,1540872769,973983485,1 +256138,1540872770,1540872771,1 +256139,1540872771,1540872772,1 +256140,1540872772,1540872773,1 +256141,1540872773,363973302,1 +256142,1540872774,973983698,1 +256143,1540872775,973983161,1 +256144,1540872776,1540872777,1 +256145,1540872777,973983334,1 +256146,1540872778,973983017,1 +256147,1540872779,973983479,1 +256148,1540872780,360012718,1 +256149,1540872781,973983087,1 +256150,1540872782,1540872783,1 +256151,1540872783,1540872784,1 +256152,1540872784,1540872785,1 +256153,1540872785,973983396,1 +256154,1540872786,418771192,1 +256155,1540872787,973983113,1 +256156,1540872788,1540872789,1 +256157,1540872789,1540872790,1 +256158,1540872790,1540872791,1 +256159,1540872791,1540872792,1 +256160,1540872792,973983265,1 +256161,1540872793,1540872794,1 +256162,1540872794,1540872795,1 +256163,1540872795,1540872796,1 +256164,1540872796,1540872797,1 +256165,1540872797,1540872798,1 +256166,1540872798,974030526,1 +256167,1540872799,1540872800,1 +256168,1540872800,1540872801,1 +256169,1540872801,974031041,1 +256170,1540872802,279591459,1 +256171,1540872803,1540872804,1 +256172,1540872804,974030524,1 +256173,1540872805,279590131,1 +256174,1540872806,974030790,1 +256175,1540872807,1540872808,1 +256176,1540872808,974030784,1 +256177,1540872809,1540872810,1 +256178,1540872810,974030491,1 +256179,1540872811,1540872812,1 +256180,1540872812,1540872813,1 +256181,1540872813,1540872814,1 +256182,1540872814,1540872815,1 +256183,1540872815,974031214,1 +256184,1540872816,1540872817,1 +256185,1540872817,974030884,1 +256186,1540872818,1540872819,0 +256187,1540872819,974030576,0 +256188,1540872820,1540872821,0 +256189,1540872821,1540872822,0 +256190,1540872822,1540872823,0 +256191,1540872823,1540872824,0 +256192,1540872824,974030619,0 +256193,1540872825,1540872826,0 +256194,1540872826,1540872827,0 +256195,1540872827,974031110,0 +256196,1540872828,1540872829,1 +256197,1540872829,1540872830,1 +256198,1540872830,974030802,1 +256199,1540872831,1540872832,1 +256200,1540872832,974030615,1 +256201,1540872833,1540872834,1 +256202,1540872834,1540872835,1 +256203,1540872835,1540872836,1 +256204,1540872836,1540872837,1 +256205,1540872837,1540872838,1 +256206,1540872838,974031208,1 +256207,1540872839,974030524,1 +256208,1540872840,974030929,1 +256209,1540872841,974066386,0 +256210,1540872842,1540872843,0 +256211,1540872843,1540872844,0 +256212,1540872844,974067523,0 +256213,1540872845,1540872846,0 +256214,1540872846,1540872847,0 +256215,1540872847,974066797,0 +256216,1540872848,1030328438,0 +256217,1540872849,974066566,0 +256218,1540872850,1540872851,1 +256219,1540872851,1540872852,1 +256220,1540872852,1540872853,1 +256221,1540872853,1540872854,1 +256222,1540872854,974066190,1 +256223,1540872855,1540872856,1 +256224,1540872856,1540872857,1 +256225,1540872857,1540872858,1 +256226,1540872858,1540872859,1 +256227,1540872859,974066940,1 +256228,1540872860,1540872861,1 +256229,1540872861,1540872862,1 +256230,1540872862,1540872863,1 +256231,1540872863,1540872864,1 +256232,1540872864,1540872865,1 +256233,1540872865,1540872866,1 +256234,1540872866,974066787,1 +256235,1540872867,1540872868,1 +256236,1540872868,974066348,1 +256237,1540872869,1540872870,1 +256238,1540872870,974067117,1 +256239,1540872871,360206030,1 +256240,1540872872,1540872873,1 +256241,1540872873,360210340,1 +256242,1540872874,974066794,1 +256243,1540872875,974067378,1 +256244,1540872876,974067107,1 +256245,1540872877,974066472,1 +256246,1540872878,1540872879,1 +256247,1540872879,1540872880,1 +256248,1540872880,360206871,1 +256249,1540872881,1540872882,1 +256250,1540872882,974067410,1 +256251,1540872883,974067502,1 +256252,1540872884,1540872885,1 +256253,1540872885,974066401,1 +256254,1540872886,1540872887,1 +256255,1540872887,1540872888,1 +256256,1540872888,1540872889,1 +256257,1540872889,1540872890,1 +256258,1540872890,974067413,1 +256259,1540872891,974066712,1 +256260,1540872892,1540872893,1 +256261,1540872893,1540872894,1 +256262,1540872894,1540872895,1 +256263,1540872895,1540872896,1 +256264,1540872896,1540872897,1 +256265,1540872897,1540872898,1 +256266,1540872898,974066353,1 +256267,1540872899,1540872900,1 +256268,1540872900,1540872901,1 +256269,1540872901,1540872902,1 +256270,1540872902,974066733,1 +256271,1540872903,1540872904,1 +256272,1540872904,1540872905,1 +256273,1540872905,1163936685,1 +256274,1540872906,360207178,1 +256275,1540872907,1540872908,1 +256276,1540872908,1540872909,1 +256277,1540872909,1540872910,1 +256278,1540872910,974066611,1 +256279,1540872911,1540872912,1 +256280,1540872912,1540872913,1 +256281,1540872913,1540872914,1 +256282,1540872914,1540872915,1 +256283,1540872915,974067199,1 +256284,1540872916,1540872917,1 +256285,1540872917,1540872918,1 +256286,1540872918,974066233,1 +256287,1540872919,1540872920,1 +256288,1540872920,1540872921,1 +256289,1540872921,1540872922,1 +256290,1540872922,1540872923,1 +256291,1540872923,1540872924,1 +256292,1540872924,1540872925,1 +256293,1540872925,1540872926,1 +256294,1540872926,1540872927,1 +256295,1540872927,1540872928,1 +256296,1540872928,1540872929,1 +256297,1540872929,974067137,1 +256298,1540872930,1540872931,1 +256299,1540872931,1540872932,1 +256300,1540872932,1540872933,1 +256301,1540872933,1540872934,1 +256302,1540872934,974067296,1 +256303,1540872935,1540872936,1 +256304,1540872936,1540872937,1 +256305,1540872937,974066197,1 +256306,1540872938,1540872939,1 +256307,1540872939,1540872940,1 +256308,1540872940,974066673,1 +256309,1540872941,974066712,1 +256310,1540872942,974066626,1 +256311,1540872943,974066558,1 +256312,1540872944,974066944,1 +256313,1540872945,1540872946,0 +256314,1540872946,1540872947,0 +256315,1540872947,974066787,0 +256316,1540872948,1540872949,0 +256317,1540872949,1540872950,0 +256318,1540872950,1540872951,0 +256319,1540872951,974067304,0 +256320,1540872952,974066963,1 +256321,1540872953,1540872954,1 +256322,1540872954,1540872955,1 +256323,1540872955,1540872956,1 +256324,1540872956,1540872957,1 +256325,1540872957,1540872958,1 +256326,1540872958,1540872959,1 +256327,1540872959,1540872960,1 +256328,1540872960,1540872961,1 +256329,1540872961,1540872962,1 +256330,1540872962,1540872963,1 +256331,1540872963,974067268,1 +256332,1540872964,974066193,1 +256333,1540872965,1540872966,1 +256334,1540872966,1540872967,1 +256335,1540872967,1540872968,1 +256336,1540872968,1540872969,1 +256337,1540872969,974066233,1 +256338,1540872970,1540872971,1 +256339,1540872971,1540872972,1 +256340,1540872972,1540872973,1 +256341,1540872973,1540872974,1 +256342,1540872974,1540872975,1 +256343,1540872975,1540872976,1 +256344,1540872976,1540872977,1 +256345,1540872977,1540872978,1 +256346,1540872978,1540872979,1 +256347,1540872979,974067171,1 +256348,1540872980,1540872981,1 +256349,1540872981,1540872982,1 +256350,1540872982,974066403,1 +256351,1540872983,1540872984,1 +256352,1540872984,974066229,1 +256353,1540872985,974067304,1 +256354,1540872986,1540872987,0 +256355,1540872987,1540872988,0 +256356,1540872988,1540872989,0 +256357,1540872989,1540872990,0 +256358,1540872990,1540872991,0 +256359,1540872991,1540872992,0 +256360,1540872992,974066523,0 +256361,1540872993,1540872994,1 +256362,1540872994,974066538,1 +256363,1540872995,1540872996,1 +256364,1540872996,1540872997,1 +256365,1540872997,1540872998,1 +256366,1540872998,974066566,1 +256367,1540872999,1540873000,1 +256368,1540873000,1540873001,1 +256369,1540873001,1540873002,1 +256370,1540873002,1540873003,1 +256371,1540873003,1540873004,1 +256372,1540873004,1540873005,1 +256373,1540873005,974066151,1 +256374,1540873006,1540873007,1 +256375,1540873007,1540873008,1 +256376,1540873008,1540873009,1 +256377,1540873009,1540873010,1 +256378,1540873010,1540873011,1 +256379,1540873011,1540873012,1 +256380,1540873012,1540873013,1 +256381,1540873013,1540873014,1 +256382,1540873014,1172477536,1 +256383,1540873015,1540873016,1 +256384,1540873016,1540873017,1 +256385,1540873017,1540873018,1 +256386,1540873018,1540873019,1 +256387,1540873019,1540873020,1 +256388,1540873020,1540873021,1 +256389,1540873021,1540873022,1 +256390,1540873022,1172477476,1 +256391,1540873023,1540873024,1 +256392,1540873024,1540873025,1 +256393,1540873025,1540873026,1 +256394,1540873026,1540873027,1 +256395,1540873027,974066280,1 +256396,1540873028,974066323,1 +256397,1540873029,974066733,1 +256398,1540873030,1540873031,1 +256399,1540873031,1540873032,1 +256400,1540873032,974067107,1 +256401,1540873033,1540873034,1 +256402,1540873034,1540873035,1 +256403,1540873035,1540873036,1 +256404,1540873036,1540873037,1 +256405,1540873037,974067567,1 +257306,1540873938,981693544,1 +257307,1540873939,981693527,1 +257313,1540873945,1540873946,1 +257314,1540873946,1540873947,1 +257315,1540873947,982077268,1 +257316,1540873948,1540873949,1 +257317,1540873949,982077259,1 +257318,1540873950,1540873951,1 +257319,1540873951,1540873952,1 +257320,1540873952,1540873953,1 +257321,1540873953,1540873954,1 +257322,1540873954,982077240,1 +257323,1540873955,982077224,1 +257625,1540874257,1540874258,1 +257626,1540874258,1540874259,1 +257627,1540874259,1540874260,1 +257628,1540874260,1540874261,1 +257629,1540874261,1540874262,1 +257630,1540874262,1540874263,1 +257631,1540874263,1540874264,1 +257632,1540874264,1540874265,1 +257633,1540874265,984332675,1 +257634,1540874266,1540874267,1 +257635,1540874267,1540874268,1 +257636,1540874268,1540874269,1 +257637,1540874269,1540874270,1 +257638,1540874270,1540874271,1 +257639,1540874271,1540874272,1 +257640,1540874272,1540874273,1 +257641,1540874273,1540874274,1 +257642,1540874274,984332318,1 +257643,1540874275,1540874276,1 +257644,1540874276,1540874277,1 +257645,1540874277,1540874278,1 +257646,1540874278,984332496,1 +257647,1540874279,1540874280,1 +257648,1540874280,984332687,1 +257649,1540874281,1540874282,1 +257650,1540874282,1540874283,1 +257651,1540874283,984332675,1 +257652,1540874284,1540874285,1 +257653,1540874285,1540874286,1 +257654,1540874286,1540874287,1 +257655,1540874287,1540874288,1 +257656,1540874288,1540874289,1 +257657,1540874289,1540874290,1 +257658,1540874290,1540874291,1 +257659,1540874291,984332185,1 +257660,1540874292,1540874293,1 +257661,1540874293,1540874294,1 +257662,1540874294,984332648,1 +257663,1540874295,1540874296,1 +257664,1540874296,1540874297,1 +257665,1540874297,1540874298,1 +257666,1540874298,984332503,1 +257667,1540874299,1540874300,1 +257668,1540874300,1540874301,1 +257669,1540874301,294144924,1 +257670,1540874302,1540874303,0 +257671,1540874303,1540874304,0 +257672,1540874304,1540874305,0 +257673,1540874305,984332456,0 +257674,1540874306,1540874307,1 +257675,1540874307,523552917,1 +257676,1540874308,1540874309,1 +257677,1540874309,1540874310,1 +257678,1540874310,737655474,1 +257679,1540874311,1540874312,1 +257680,1540874312,1540874313,1 +257681,1540874313,1540874314,1 +257682,1540874314,1540874315,1 +257683,1540874315,1540874316,1 +257684,1540874316,1540874317,1 +257685,1540874317,1540874318,1 +257686,1540874318,1540874319,1 +257687,1540874319,984332536,1 +257688,1540874320,1540874321,1 +257689,1540874321,1540874322,1 +257690,1540874322,984332648,1 +257691,1540874323,984332534,0 +257692,1540874324,1540874325,1 +257693,1540874325,1540874326,1 +257694,1540874326,1540874327,1 +257695,1540874327,984332496,1 +257696,1540874328,984332645,1 +257697,1540874329,1540874330,1 +257698,1540874330,1540874331,1 +257699,1540874331,984332306,1 +257700,1540874332,1540874333,1 +257701,1540874333,984332698,1 +257702,1540874334,1540874335,1 +257703,1540874335,1540874336,1 +257704,1540874336,984332687,1 +257705,1540874337,984332361,1 +257706,1540874338,1540874339,1 +257707,1540874339,984332500,1 +257708,1540874340,984332317,1 +257709,1540874341,1540874342,1 +257710,1540874342,1540874343,1 +257711,1540874343,984332386,1 +257712,1540874344,1540874345,1 +257713,1540874345,1540874346,1 +257714,1540874346,1540874347,1 +257715,1540874347,1540874348,1 +257716,1540874348,1540874349,1 +257717,1540874349,1540874350,1 +257718,1540874350,984332590,1 +257719,1540874351,1540874352,1 +257720,1540874352,984332318,1 +257721,1540874353,984332675,1 +257722,1540874354,523552921,1 +257723,1540874355,523552922,1 +257724,1540874356,984332626,1 +257725,1540874357,1540874358,1 +257726,1540874358,1540874359,1 +257727,1540874359,1540874360,1 +257728,1540874360,1540874361,1 +257729,1540874361,984332247,1 +257730,1540874362,984332297,1 +257731,1540874363,1540874364,1 +257732,1540874364,1540874365,1 +257733,1540874365,984364293,1 +257734,1540874366,1540874367,1 +257735,1540874367,1540874368,1 +257736,1540874368,984364670,1 +257737,1540874369,1540874370,1 +257738,1540874370,984364621,1 +257739,1540874371,984364855,1 +257740,1540874372,984364208,1 +257741,1540874373,1540874374,1 +257742,1540874374,984364556,1 +257743,1540874375,1540874376,1 +257744,1540874376,1540874377,1 +257745,1540874377,1540874378,1 +257746,1540874378,984364617,1 +257747,1540874379,1540874380,1 +257748,1540874380,984364376,1 +257749,1540874381,984364130,1 +257750,1540874382,984364531,1 +257751,1540874383,1540874384,1 +257752,1540874384,984364846,1 +257753,1540874385,1540874386,1 +257754,1540874386,1540874387,1 +257755,1540874387,984364277,1 +257756,1540874388,1540874389,1 +257757,1540874389,984364895,1 +257758,1540874390,984364320,1 +257759,1540874391,1540874392,1 +257760,1540874392,984364876,1 +257761,1540874393,984364567,1 +257762,1540874394,1540874395,1 +257763,1540874395,984364322,1 +257764,1540874396,984364325,1 +257765,1540874397,1540874398,0 +257766,1540874398,984364272,0 +257767,1540874399,984364605,0 +257768,1540874400,984364590,1 +257769,1540874401,1540874402,1 +257770,1540874402,1540874403,1 +257771,1540874403,1540874404,1 +257772,1540874404,1540874405,1 +257773,1540874405,984364670,1 +257774,1540874406,1540874407,1 +257775,1540874407,984364594,1 +257776,1540874408,1540874409,1 +257777,1540874409,1540874410,1 +257778,1540874410,984364513,1 +257779,1540874411,984364293,1 +257780,1540874412,984415685,1 +257781,1540874413,1540874414,1 +257782,1540874414,1540874415,1 +257783,1540874415,1540874416,1 +257784,1540874416,1540874417,1 +257785,1540874417,1129262188,1 +257810,1540874442,984606880,1 +257811,1540874443,1540874444,1 +257812,1540874444,1540874445,1 +257813,1540874445,984606856,1 +257814,1540874446,984607072,1 +257815,1540874447,984607094,1 +257816,1540874448,1540874449,1 +257817,1540874449,1540874450,1 +257818,1540874450,984606856,1 +257819,1540874451,984607094,1 +257820,1540874452,1540874453,1 +257821,1540874453,981693546,1 +257822,1540874454,1540874455,1 +257823,1540874455,1540874456,1 +257824,1540874456,1540874457,1 +257825,1540874457,1540874458,1 +257826,1540874458,1540874459,1 +257827,1540874459,1540874460,1 +257828,1540874460,1540874461,1 +257829,1540874461,1540874462,1 +257830,1540874462,1540874463,1 +257831,1540874463,1540874464,1 +257832,1540874464,984606766,1 +257833,1540874465,984415638,1 +257834,1540874466,984606564,1 +257835,1540874467,1540874468,1 +257836,1540874468,1540874469,1 +257837,1540874469,1540874470,1 +257838,1540874470,1540874471,1 +257839,1540874471,984606655,1 +257840,1540874472,1540874473,1 +257841,1540874473,1540874474,1 +257842,1540874474,1540874475,1 +257843,1540874475,1540874476,1 +257844,1540874476,984606939,1 +257845,1540874477,737307331,1 +257846,1540874478,984634033,0 +257847,1540874479,984634084,0 +257848,1540874480,1540874481,1 +257849,1540874481,984634525,1 +257850,1540874482,984634172,1 +257851,1540874483,294114443,1 +257852,1540874484,1540874485,1 +257853,1540874485,984634383,1 +257854,1540874486,1540874487,1 +257855,1540874487,1540874488,1 +257856,1540874488,984634086,1 +257857,1540874489,1540874490,1 +257858,1540874490,984633979,1 +257859,1540874491,737307341,1 +257860,1540874492,984639830,1 +257861,1540874493,1540874494,1 +257862,1540874494,1540874495,1 +257863,1540874495,938502196,1 +257864,1540874496,1540874497,1 +257865,1540874497,737307336,1 +257866,1540874498,984634629,0 +257867,1540874499,1540874500,0 +257868,1540874500,984634330,0 +257869,1540874501,1540874502,1 +257870,1540874502,1540874503,1 +257871,1540874503,984634411,1 +257872,1540874504,1540874505,1 +257873,1540874505,984633916,1 +257874,1540874506,984634602,1 +257875,1540874507,1540874508,1 +257876,1540874508,1540874509,1 +257877,1540874509,1540874510,1 +257878,1540874510,1540874511,1 +257879,1540874511,1540874512,1 +257880,1540874512,1540874513,1 +257881,1540874513,1540874514,1 +257882,1540874514,984634470,1 +257883,1540874515,1540874516,1 +257884,1540874516,984634450,1 +257885,1540874517,1540874518,0 +257886,1540874518,984639834,0 +257887,1540874519,984639869,0 +257888,1540874520,1540874521,1 +257889,1540874521,984639848,1 +257890,1540874522,984639838,0 +257891,1540874523,1540874524,0 +257892,1540874524,1540874525,0 +257893,1540874525,984634285,0 +257894,1540874526,1540874527,0 +257895,1540874527,984639854,0 +257896,1540874528,1540874529,0 +257897,1540874529,1113561564,0 +257898,1540874530,984639888,0 +257899,1540874531,1540874532,1 +257900,1540874532,984639754,1 +257901,1540874533,1540874534,1 +257902,1540874534,1540874535,1 +257903,1540874535,1540874536,1 +257904,1540874536,1540874537,1 +257905,1540874537,1540874538,1 +257906,1540874538,984639912,1 +257907,1540874539,1540874540,1 +257908,1540874540,1540874541,1 +257909,1540874541,1540874542,1 +257910,1540874542,1540874543,1 +257911,1540874543,1540874544,1 +257912,1540874544,1411198305,1 +257913,1540874545,1540874546,1 +257914,1540874546,1411198293,1 +257915,1540874547,1540874548,1 +257916,1540874548,1540874549,1 +257917,1540874549,1540874550,1 +257918,1540874550,1540874551,1 +257919,1540874551,984634435,1 +257920,1540874552,294114688,1 +257921,1540874553,294113938,1 +257922,1540874554,1540874555,1 +257923,1540874555,1540874556,1 +257924,1540874556,984726051,1 +257925,1540874557,984725716,1 +257926,1540874558,152802874,1 +257927,1540874559,1540874560,1 +257928,1540874560,1540874561,1 +257929,1540874561,1540874562,1 +257930,1540874562,984725791,1 +257931,1540874563,984726105,1 +257932,1540874564,984726119,1 +257933,1540874565,1540874566,1 +257934,1540874566,984726086,1 +257935,1540874567,1540874568,1 +257936,1540874568,1540874569,1 +257937,1540874569,984726016,1 +257938,1540874570,984726104,1 +257939,1540874571,984725984,1 +257940,1540874572,1540874573,1 +257941,1540874573,1540874574,1 +257942,1540874574,984752781,1 +257943,1540874575,1540874576,1 +257944,1540874576,1540874577,1 +257945,1540874577,984752911,1 +257946,1540874578,984752770,1 +257947,1540874579,1540874580,1 +257948,1540874580,984772683,1 +257949,1540874581,1540874582,1 +257950,1540874582,1540874583,1 +257951,1540874583,1540874584,1 +257952,1540874584,1540874585,1 +257953,1540874585,1540874586,1 +257954,1540874586,1540874587,1 +257955,1540874587,1540874588,1 +257956,1540874588,1540874589,1 +257957,1540874589,1540874590,1 +257958,1540874590,1540874591,1 +257959,1540874591,1540874592,1 +257960,1540874592,984771875,1 +257961,1540874593,984771845,1 +257962,1540874594,984771845,1 +257963,1540874595,1540874596,1 +257964,1540874596,984772262,1 +257965,1540874597,1540874598,1 +257966,1540874598,1540874599,1 +257967,1540874599,1540874600,1 +257968,1540874600,1540874601,1 +257969,1540874601,1540874602,1 +257970,1540874602,1540874603,1 +257971,1540874603,1540874604,1 +257972,1540874604,1540874605,1 +257973,1540874605,1540874606,1 +257974,1540874606,1540874607,1 +257975,1540874607,1540874608,1 +257976,1540874608,1540874609,1 +257977,1540874609,1540874610,1 +257978,1540874610,1540874611,1 +257979,1540874611,1540874612,1 +257980,1540874612,984772488,1 +257981,1540874613,1540874614,1 +257982,1540874614,984771610,1 +257983,1540874615,1540874616,1 +257984,1540874616,1540874617,1 +257985,1540874617,1540874618,1 +257986,1540874618,1540874619,1 +257987,1540874619,1540874620,1 +257988,1540874620,1540874621,1 +257989,1540874621,1540874622,1 +257990,1540874622,1540874623,1 +257991,1540874623,1540874624,1 +257992,1540874624,1540874625,1 +257993,1540874625,984772380,1 +257994,1540874626,1540874627,1 +257995,1540874627,1540874628,1 +257996,1540874628,1540874629,1 +257997,1540874629,984771615,1 +257998,1540874630,1540874631,1 +257999,1540874631,1540874632,1 +258000,1540874632,1540874633,1 +258001,1540874633,1540874634,1 +258002,1540874634,1540874635,1 +258003,1540874635,984772579,1 +258004,1540874636,1540874637,1 +258005,1540874637,1540874638,1 +258006,1540874638,1540874639,1 +258007,1540874639,1540874640,1 +258008,1540874640,1540874641,1 +258009,1540874641,1540874642,1 +258010,1540874642,1540874643,1 +258011,1540874643,1540874644,1 +258012,1540874644,1540874645,1 +258013,1540874645,1540874646,1 +258014,1540874646,1540874647,1 +258015,1540874647,1540874648,1 +258016,1540874648,1540874649,1 +258017,1540874649,1540874650,1 +258018,1540874650,1540874651,1 +258019,1540874651,984771549,1 +258020,1540874652,1540874653,1 +258021,1540874653,1540874654,1 +258022,1540874654,1540874655,1 +258023,1540874655,1540874656,1 +258024,1540874656,1540874657,1 +258025,1540874657,1540874658,1 +258026,1540874658,1540874659,1 +258027,1540874659,1540874660,1 +258028,1540874660,1540874661,1 +258029,1540874661,984772377,1 +258030,1540874662,1540874663,1 +258031,1540874663,1540874664,1 +258032,1540874664,1540874665,1 +258033,1540874665,1540874666,1 +258034,1540874666,1540874667,1 +258035,1540874667,1540874668,1 +258036,1540874668,984771451,1 +258037,1540874669,1540874670,1 +258038,1540874670,1540874671,1 +258039,1540874671,1540874672,1 +258040,1540874672,984772276,1 +258041,1540874673,984771747,1 +258042,1540874674,1540874675,1 +258043,1540874675,1540874676,1 +258044,1540874676,1540874677,1 +258045,1540874677,984772103,1 +258046,1540874678,1540874679,1 +258047,1540874679,1540874680,1 +258048,1540874680,1540874681,1 +258049,1540874681,1540874682,1 +258050,1540874682,1540874683,1 +258051,1540874683,984771420,1 +258052,1540874684,984772128,1 +258053,1540874685,1540874686,1 +258054,1540874686,984771399,1 +258055,1540874687,1540874688,1 +258056,1540874688,984772066,1 +258057,1540874689,1540874690,1 +258058,1540874690,1540874691,1 +258059,1540874691,1540874692,1 +258060,1540874692,1540874693,1 +258061,1540874693,1540874694,1 +258062,1540874694,1540874695,1 +258063,1540874695,1540874696,1 +258064,1540874696,984771572,1 +258065,1540874697,1540874698,1 +258066,1540874698,1540874699,1 +258067,1540874699,984771420,1 +258068,1540874700,1540874701,1 +258069,1540874701,984772469,1 +258070,1540874702,1540874703,1 +258071,1540874703,984771632,1 +258072,1540874704,1540874705,1 +258073,1540874705,1540874706,1 +258074,1540874706,984771827,1 +258075,1540874707,1540874708,1 +258076,1540874708,1540874709,1 +258077,1540874709,1540874710,1 +258078,1540874710,1540874711,1 +258079,1540874711,1540874712,1 +258080,1540874712,984772780,1 +258081,1540874713,1540874714,1 +258082,1540874714,984771549,1 +258083,1540874715,984772024,1 +258084,1540874716,1540874717,1 +258085,1540874717,1540874718,1 +258086,1540874718,1540874719,1 +258087,1540874719,1540874720,1 +258088,1540874720,984772336,1 +258089,1540874721,1540874722,1 +258090,1540874722,1540874723,1 +258091,1540874723,1540874724,1 +258092,1540874724,1540874725,1 +258093,1540874725,984771596,1 +258094,1540874726,984772719,1 +258095,1540874727,984771387,1 +258096,1540874728,1540874729,1 +258097,1540874729,1540874730,1 +258098,1540874730,1540874731,1 +258099,1540874731,1540874732,1 +258100,1540874732,1540874733,1 +258101,1540874733,1540874734,1 +258102,1540874734,1540874735,1 +258103,1540874735,1540874736,1 +258104,1540874736,984771405,1 +258105,1540874737,1540874738,1 +258106,1540874738,1540874739,1 +258107,1540874739,1540874740,1 +258108,1540874740,1540874741,1 +258109,1540874741,1540874742,1 +258110,1540874742,1540874743,1 +258111,1540874743,1540874744,1 +258112,1540874744,984772410,1 +258116,1540874748,1540874749,1 +258117,1540874749,985285723,1 +258118,1540874750,985286132,1 +258119,1540874751,1540874752,1 +258120,1540874752,985285642,1 +258121,1540874753,985286052,1 +258122,1540874754,1540874755,1 +258123,1540874755,985285903,1 +258124,1540874756,985285639,1 +258125,1540874757,985286169,1 +258126,1540874758,1540874759,1 +258127,1540874759,985285557,1 +258128,1540874760,1540874761,1 +258129,1540874761,984364376,1 +258130,1540874762,985285590,1 +258131,1540874763,1540874764,1 +258132,1540874764,985286132,1 +258133,1540874765,985286049,1 +258134,1540874766,1540874767,1 +258135,1540874767,985286241,1 +258136,1540874768,985921425,1 +258137,1540874769,1540874770,1 +258138,1540874770,1540874771,1 +258139,1540874771,1540874772,1 +258140,1540874772,1540874773,1 +258141,1540874773,1540874774,1 +258142,1540874774,985946029,1 +258143,1540874775,1540874776,1 +258144,1540874776,1540874777,1 +258145,1540874777,1540874778,1 +258146,1540874778,1540874779,1 +258147,1540874779,985946361,1 +258148,1540874780,1540874781,1 +258149,1540874781,985945981,1 +258150,1540874782,1540874783,1 +258151,1540874783,985946318,1 +258152,1540874784,1540874785,0 +258153,1540874785,985945881,0 +258154,1540874786,1540874787,1 +258155,1540874787,985946343,1 +258156,1540874788,1540874789,1 +258157,1540874789,1540874790,1 +258158,1540874790,1540874791,1 +258159,1540874791,1540874792,1 +258160,1540874792,1540874793,1 +258161,1540874793,1540874794,1 +258162,1540874794,985946390,1 +258163,1540874795,1540874796,1 +258164,1540874796,1540874797,1 +258165,1540874797,1540874798,1 +258166,1540874798,360008750,1 +258167,1540874799,1540874800,1 +258168,1540874800,295865926,1 +258169,1540874801,1540874802,0 +258170,1540874802,985945999,0 +258171,1540874803,1540874804,1 +258172,1540874804,1540874805,1 +258173,1540874805,1540874806,1 +258174,1540874806,1540874807,1 +258175,1540874807,1540874808,1 +258176,1540874808,985946280,1 +258177,1540874809,985945871,0 +258178,1540874810,1540874811,1 +258179,1540874811,1540874812,1 +258180,1540874812,985968895,1 +258181,1540874813,1540874814,1 +258182,1540874814,891524000,1 +258183,1540874815,1540874816,1 +258184,1540874816,1540874817,1 +258185,1540874817,737311464,1 +258186,1540874818,1540874819,1 +258187,1540874819,1540874820,1 +258188,1540874820,1540874821,1 +258189,1540874821,1540874822,1 +258190,1540874822,1540874823,1 +258191,1540874823,1540874824,1 +258192,1540874824,1540874825,1 +258193,1540874825,1540874826,1 +258194,1540874826,1540874827,1 +258195,1540874827,1540874828,1 +258196,1540874828,985968875,1 +258197,1540874829,985968800,1 +258198,1540874830,1540874831,1 +258199,1540874831,985968852,1 +258200,1540874832,1540874833,1 +258201,1540874833,985968823,1 +258202,1540874834,985968904,1 +258203,1540874835,737307686,1 +258204,1540874836,1540874837,1 +258205,1540874837,1540874838,1 +258206,1540874838,1540874839,1 +258207,1540874839,1540874840,1 +258208,1540874840,1540874841,1 +258209,1540874841,985968907,1 +258210,1540874842,1540874843,1 +258211,1540874843,985968638,1 +258212,1540874844,1540874845,1 +258213,1540874845,985968879,1 +258214,1540874846,1540874847,1 +258215,1540874847,1540874848,1 +258216,1540874848,985968748,1 +258217,1540874849,1540874850,0 +258218,1540874850,1540874851,0 +258219,1540874851,985968635,0 +258220,1540874852,985968667,0 +258221,1540874853,1540874854,1 +258222,1540874854,1540874855,1 +258223,1540874855,985968887,1 +258224,1540874856,1540874857,1 +258225,1540874857,1540874858,1 +258226,1540874858,985968883,1 +258227,1540874859,891524001,1 +258228,1540874860,1540874861,1 +258229,1540874861,1540874862,1 +258230,1540874862,1540874863,1 +258231,1540874863,1540874864,1 +258232,1540874864,1540874865,1 +258233,1540874865,985968802,1 +258234,1540874866,985968668,1 +258235,1540874867,1540874868,1 +258236,1540874868,985968649,1 +259698,1540876330,360002692,0 +259699,1540876331,559938888,0 +259700,1540876332,1540876333,0 +259701,1540876333,1540876334,0 +259702,1540876334,1540876335,0 +259703,1540876335,1013434005,0 +259704,1540876336,1540876337,0 +259705,1540876337,1013433863,0 +259706,1540876338,1540876339,0 +259707,1540876339,559939046,0 +259708,1540876340,559940333,0 +259709,1540876341,1540876342,0 +259710,1540876342,1033229521,0 +259711,1540876343,1540876344,0 +259712,1540876344,1540876345,0 +259713,1540876345,1540876346,0 +259714,1540876346,1540876347,0 +259715,1540876347,1540876348,0 +259716,1540876348,1033229536,0 +259717,1540876349,1033229521,0 +259718,1540876350,1540876351,0 +259719,1540876351,1540876352,0 +259720,1540876352,1540876353,0 +259721,1540876353,1540876354,0 +259722,1540876354,559597237,0 +259723,1540876355,1540876356,0 +259724,1540876356,1013433973,0 +259725,1540876357,559939114,0 +259726,1540876358,1540876359,0 +259727,1540876359,1540876360,0 +259728,1540876360,1540876361,0 +259729,1540876361,559939044,0 +259730,1540876362,1540876363,0 +259731,1540876363,1540876364,0 +259732,1540876364,1540876365,0 +259733,1540876365,360002862,0 +259734,1540876366,1540876367,0 +259735,1540876367,360002721,0 +259736,1540876368,1540876369,0 +259737,1540876369,360000521,0 +259738,1540876370,1540876371,0 +259739,1540876371,1540876372,0 +259740,1540876372,559939216,0 +259741,1540876373,1540876374,0 +259742,1540876374,1540876375,0 +259743,1540876375,1540876376,0 +259744,1540876376,1540876377,0 +259745,1540876377,559938648,0 +259746,1540876378,1540876379,0 +259747,1540876379,1540876380,0 +259748,1540876380,1540876381,0 +259749,1540876381,559940379,0 +259750,1540876382,1540876383,0 +259751,1540876383,559938648,0 +259752,1540876384,1540876385,1 +259753,1540876385,1540876386,1 +259754,1540876386,936804293,1 +259868,1540876500,1540876501,0 +259869,1540876501,1540876502,0 +259870,1540876502,1015274279,0 +259871,1540876503,1540876504,0 +259872,1540876504,1540876505,0 +259873,1540876505,1540876506,0 +259874,1540876506,1540876507,0 +259875,1540876507,1540876508,0 +259876,1540876508,1015274270,0 +260391,1540877023,1540877024,1 +260392,1540877024,1540877025,1 +260393,1540877025,1019989420,1 +260394,1540877026,1540877027,1 +260395,1540877027,1540877028,1 +260396,1540877028,1540877029,1 +260397,1540877029,1540877030,1 +260398,1540877030,1540877031,1 +260399,1540877031,1540877032,1 +260400,1540877032,1540877033,1 +260401,1540877033,1540877034,1 +260402,1540877034,1540877035,1 +260403,1540877035,1540877036,1 +260404,1540877036,1540877037,1 +260405,1540877037,1540877038,1 +260406,1540877038,1540877039,1 +260407,1540877039,1540877040,1 +260408,1540877040,1540877041,1 +260409,1540877041,1540877042,1 +260410,1540877042,1540877043,1 +260411,1540877043,1019989686,1 +260412,1540877044,1540877045,1 +260413,1540877045,1540877046,1 +260414,1540877046,1540877047,1 +260415,1540877047,1540877048,1 +260416,1540877048,1540877049,1 +260417,1540877049,1540877050,1 +260418,1540877050,1540877051,1 +260419,1540877051,1540877052,1 +260420,1540877052,1540877053,1 +260421,1540877053,1540877054,1 +260422,1540877054,1540877055,1 +260423,1540877055,1540877056,1 +260424,1540877056,1540877057,1 +260425,1540877057,1540877058,1 +260426,1540877058,1540877059,1 +260427,1540877059,1540877060,1 +260428,1540877060,1540877061,1 +260429,1540877061,1019990282,1 +260430,1540877062,1540877063,1 +260431,1540877063,1019990225,1 +260432,1540877064,1540877065,1 +260433,1540877065,1540877066,1 +260434,1540877066,1540877067,1 +260435,1540877067,1540877068,1 +260436,1540877068,1540877069,1 +260437,1540877069,1540877070,1 +260438,1540877070,1540877071,1 +260439,1540877071,1540877072,1 +260440,1540877072,1540877073,1 +260441,1540877073,1540877074,1 +260442,1540877074,1540877075,1 +260443,1540877075,1540877076,1 +260444,1540877076,1540877077,1 +260445,1540877077,1540877078,1 +260446,1540877078,1540877079,1 +260447,1540877079,1540877080,1 +260448,1540877080,1540877081,1 +260449,1540877081,1540877082,1 +260450,1540877082,1540877083,1 +260451,1540877083,1540877084,1 +260452,1540877084,1540877085,1 +260453,1540877085,1540877086,1 +260454,1540877086,1019989821,1 +260455,1540877087,1540877088,1 +260456,1540877088,1540877089,1 +260457,1540877089,1540877090,1 +260458,1540877090,1019989863,1 +260459,1540877091,1019990327,1 +260460,1540877092,1540877093,1 +260461,1540877093,1019990290,1 +260462,1540877094,1019990178,1 +260463,1540877095,1540877096,1 +260464,1540877096,1540877097,1 +260465,1540877097,1540877098,1 +260466,1540877098,1540877099,1 +260467,1540877099,1540877100,1 +260468,1540877100,1540877101,1 +260469,1540877101,1540877102,1 +260470,1540877102,1540877103,1 +260471,1540877103,1540877104,1 +260472,1540877104,1540877105,1 +260473,1540877105,1540877106,1 +260474,1540877106,1540877107,1 +260475,1540877107,1019989686,1 +260476,1540877108,1540877109,1 +260477,1540877109,1019989595,1 +260478,1540877110,1540877111,1 +260479,1540877111,1540877112,1 +260480,1540877112,1019990247,1 +260882,1540877514,360009519,1 +260883,1540877515,1540877516,1 +260884,1540877516,1540877517,1 +260885,1540877517,1025767720,1 +260886,1540877518,1540877519,1 +260887,1540877519,1540877520,1 +260888,1540877520,1540877521,1 +260889,1540877521,1025767709,1 +260890,1540877522,1540877523,1 +260891,1540877523,1540877524,1 +260892,1540877524,1025767703,1 +261357,1540877989,1540877990,1 +261358,1540877990,761371857,1 +261359,1540877991,1540877992,1 +261360,1540877992,1540877993,1 +261361,1540877993,1030300201,1 +261362,1540877994,1540877995,1 +261363,1540877995,1540877996,1 +261364,1540877996,973983301,1 +261365,1540877997,360012508,1 +261366,1540877998,360012743,1 +261367,1540877999,1540878000,1 +261368,1540878000,1030313163,1 +261369,1540878001,1030313287,1 +261370,1540878002,1540878003,0 +261371,1540878003,1540878004,0 +261372,1540878004,1540878005,0 +261373,1540878005,1540878006,0 +261374,1540878006,1030313258,0 +261375,1540878007,1540878008,0 +261376,1540878008,1540878009,0 +261377,1540878009,1540878010,0 +261378,1540878010,1030313253,0 +261379,1540878011,1540878012,0 +261380,1540878012,1030313096,0 +261381,1540878013,1030313118,0 +261382,1540878014,1540878015,0 +261383,1540878015,716888865,0 +261384,1540878016,1540878017,1 +261385,1540878017,1540878018,1 +261386,1540878018,1030313077,1 +261387,1540878019,1540878020,1 +261388,1540878020,1030313142,1 +261389,1540878021,1030313271,1 +261390,1540878022,1540878023,0 +261391,1540878023,1540878024,0 +261392,1540878024,1540878025,0 +261393,1540878025,1030323807,0 +261394,1540878026,360193613,0 +261395,1540878027,1540878028,0 +261396,1540878028,1030323779,0 +261397,1540878029,1030323786,0 +261398,1540878030,1030323707,1 +261399,1540878031,716888947,1 +261400,1540878032,1030313271,1 +261401,1540878033,1030313219,0 +261402,1540878034,1540878035,0 +261403,1540878035,1540878036,0 +261404,1540878036,1030313166,0 +261405,1540878037,1540878038,0 +261406,1540878038,1540878039,0 +261407,1540878039,1540878040,0 +261408,1540878040,1030313148,0 +261409,1540878041,1540878042,0 +261410,1540878042,1030313102,0 +261411,1540878043,1540878044,0 +261412,1540878044,1540878045,0 +261413,1540878045,1030313214,0 +261414,1540878046,1540878047,0 +261415,1540878047,1030313245,0 +261416,1540878048,1540878049,0 +261417,1540878049,1540878050,0 +261418,1540878050,1540878051,0 +261419,1540878051,1540878052,0 +261420,1540878052,1030313153,0 +261421,1540878053,1540878054,0 +261422,1540878054,1030313144,0 +261423,1540878055,1030323863,1 +261424,1540878056,1540878057,1 +261425,1540878057,1030323723,1 +261426,1540878058,1540878059,1 +261427,1540878059,1030323724,1 +261428,1540878060,1540878061,1 +261429,1540878061,1540878062,1 +261430,1540878062,1540878063,1 +261431,1540878063,1030323720,1 +261432,1540878064,1540878065,1 +261433,1540878065,1030323783,1 +261434,1540878066,360191658,1 +261435,1540878067,1030323800,1 +261436,1540878068,1540878069,1 +261437,1540878069,1030323812,1 +261438,1540878070,1540878071,1 +261439,1540878071,1540878072,1 +261440,1540878072,360201944,1 +261441,1540878073,1030323802,1 +261442,1540878074,1030323823,1 +261443,1540878075,1540878076,1 +261444,1540878076,360204341,1 +261445,1540878077,1540878078,0 +261446,1540878078,1030323743,0 +261447,1540878079,1540878080,0 +261448,1540878080,1030323848,0 +261449,1540878081,1030323712,0 +261450,1540878082,1540878083,0 +261451,1540878083,1030313266,0 +261452,1540878084,1060029297,1 +261453,1540878085,1030329073,1 +261454,1540878086,1030329114,1 +261455,1540878087,1540878088,1 +261456,1540878088,1030329177,1 +261457,1540878089,1540878090,1 +261458,1540878090,1030328450,1 +261459,1540878091,1540878092,1 +261460,1540878092,1540878093,1 +261461,1540878093,1540878094,1 +261462,1540878094,1030328616,1 +261463,1540878095,1540878096,1 +261464,1540878096,1540878097,1 +261465,1540878097,1540878098,1 +261466,1540878098,1540878099,1 +261467,1540878099,1030328461,1 +261468,1540878100,1030328465,1 +261469,1540878101,1540878102,1 +261470,1540878102,1540878103,1 +261471,1540878103,1030328717,1 +261472,1540878104,1540878105,1 +261473,1540878105,1540878106,1 +261474,1540878106,1540878107,1 +261475,1540878107,1540878108,1 +261476,1540878108,1030328922,1 +261477,1540878109,1540878110,1 +261478,1540878110,1540878111,1 +261479,1540878111,1030328580,1 +261480,1540878112,1030328511,0 +261481,1540878113,1540878114,0 +261482,1540878114,1540878115,0 +261483,1540878115,1540878116,0 +261484,1540878116,1540878117,0 +261485,1540878117,1540878118,0 +261486,1540878118,1030329073,0 +261487,1540878119,1540878120,0 +261488,1540878120,1030329048,0 +261489,1540878121,1540878122,0 +261490,1540878122,1540878123,0 +261491,1540878123,1540878124,0 +261492,1540878124,1030328924,0 +261493,1540878125,1540878126,0 +261494,1540878126,1540878127,0 +261495,1540878127,1540878128,0 +261496,1540878128,1540878129,0 +261497,1540878129,1030329094,0 +261498,1540878130,1540878131,0 +261499,1540878131,1540878132,0 +261500,1540878132,1540878133,0 +261501,1540878133,1540878134,0 +261502,1540878134,1540878135,0 +261503,1540878135,1540878136,0 +261504,1540878136,1540878137,0 +261505,1540878137,1540878138,0 +261506,1540878138,1030328624,0 +261507,1540878139,1030328487,0 +261508,1540878140,1540878141,0 +261509,1540878141,1030328979,0 +261510,1540878142,1030329157,0 +261511,1540878143,1540878144,0 +261512,1540878144,1030328430,0 +261513,1540878145,1540878146,1 +261514,1540878146,1540878147,1 +261515,1540878147,1540878148,1 +261516,1540878148,1540878149,1 +261517,1540878149,1540878150,1 +261518,1540878150,1540878151,1 +261519,1540878151,1540878152,1 +261520,1540878152,1540878153,1 +261521,1540878153,1540878154,1 +261522,1540878154,1030328693,1 +261523,1540878155,1540878156,1 +261524,1540878156,1540878157,1 +261525,1540878157,1540878158,1 +261526,1540878158,1540878159,1 +261527,1540878159,1030328502,1 +261528,1540878160,1540878161,1 +261529,1540878161,1540878162,1 +261530,1540878162,1540878163,1 +261531,1540878163,1540878164,1 +261532,1540878164,1540878165,1 +261533,1540878165,1540878166,1 +261534,1540878166,1030334547,1 +261535,1540878167,1030334560,1 +261536,1540878168,1540878169,1 +261537,1540878169,1540878170,1 +261538,1540878170,1030328824,1 +261539,1540878171,1540878172,1 +261540,1540878172,1030328502,1 +261541,1540878173,1030328505,1 +261542,1540878174,1540878175,1 +261543,1540878175,1540878176,1 +261544,1540878176,1540878177,1 +261545,1540878177,1030328741,1 +261546,1540878178,1540878179,1 +261547,1540878179,1030328500,1 +261548,1540878180,1540878181,1 +261549,1540878181,1540878182,1 +261550,1540878182,1540878183,1 +261551,1540878183,1540878184,1 +261552,1540878184,1540878185,1 +261553,1540878185,1030328805,1 +261554,1540878186,1030328656,1 +261555,1540878187,1540878188,1 +261556,1540878188,1540878189,1 +261557,1540878189,1540878190,1 +261558,1540878190,1540878191,1 +261559,1540878191,1540878192,1 +261560,1540878192,1540878193,1 +261561,1540878193,1540878194,1 +261562,1540878194,1540878195,1 +261563,1540878195,1030334595,1 +261564,1540878196,1030334711,1 +261565,1540878197,1030328543,1 +261566,1540878198,1030328976,1 +261567,1540878199,1030334689,1 +261568,1540878200,1030328616,1 +261569,1540878201,1030328558,1 +261570,1540878202,1030328463,1 +261571,1540878203,1540878204,1 +261572,1540878204,1540878205,1 +261573,1540878205,1540878206,1 +261574,1540878206,1540878207,1 +261575,1540878207,1540878208,1 +261576,1540878208,1540878209,1 +261577,1540878209,1540878210,1 +261578,1540878210,1540878211,1 +261579,1540878211,1540878212,1 +261580,1540878212,1540878213,1 +261581,1540878213,1540878214,1 +261582,1540878214,1540878215,1 +261583,1540878215,1030328858,1 +261584,1540878216,1540878217,1 +261585,1540878217,1540878218,1 +261586,1540878218,1540878219,1 +261587,1540878219,1030328465,1 +261588,1540878220,1540878221,0 +261589,1540878221,1030328697,0 +261590,1540878222,1540878223,1 +261591,1540878223,1540878224,1 +261592,1540878224,1540878225,1 +261593,1540878225,1540878226,1 +261594,1540878226,1030329080,1 +261595,1540878227,1540878228,1 +261596,1540878228,1540878229,1 +261597,1540878229,1540878230,1 +261598,1540878230,1540878231,1 +261599,1540878231,1540878232,1 +261600,1540878232,1540878233,1 +261601,1540878233,1030328498,1 +261602,1540878234,1540878235,1 +261603,1540878235,1540878236,1 +261604,1540878236,1540878237,1 +261605,1540878237,716888422,1 +261606,1540878238,1540878239,1 +261607,1540878239,1540878240,1 +261608,1540878240,1540878241,1 +261609,1540878241,1540878242,1 +261610,1540878242,1540878243,1 +261611,1540878243,1030329157,1 +261612,1540878244,1540878245,1 +261613,1540878245,1540878246,1 +261614,1540878246,1540878247,1 +261615,1540878247,1540878248,1 +261616,1540878248,1540878249,1 +261617,1540878249,1540878250,1 +261618,1540878250,1540878251,1 +261619,1540878251,1030328585,1 +261620,1540878252,1030329007,1 +261621,1540878253,1540878254,1 +261622,1540878254,1540878255,1 +261623,1540878255,1540878256,1 +261624,1540878256,1030328979,1 +261625,1540878257,1540878258,0 +261626,1540878258,1540878259,0 +261627,1540878259,1540878260,0 +261628,1540878260,1540878261,0 +261629,1540878261,1540878262,0 +261630,1540878262,1030328872,0 +261631,1540878263,1540878264,0 +261632,1540878264,1540878265,0 +261633,1540878265,1030328511,0 +261634,1540878266,1540878267,0 +261635,1540878267,1540878268,0 +261636,1540878268,1540878269,0 +261637,1540878269,1540878270,0 +261638,1540878270,1540878271,0 +261639,1540878271,1540878272,0 +261640,1540878272,1030328950,0 +261641,1540878273,1540878274,0 +261642,1540878274,1540878275,0 +261643,1540878275,1030328445,0 +261644,1540878276,1540878277,0 +261645,1540878277,1540878278,0 +261646,1540878278,1540878279,0 +261647,1540878279,1540878280,0 +261648,1540878280,1540878281,0 +261649,1540878281,1030329155,0 +261650,1540878282,974066435,1 +261651,1540878283,1540878284,0 +261652,1540878284,1540878285,0 +261653,1540878285,1540878286,0 +261654,1540878286,974066797,0 +261655,1540878287,1540878288,0 +261656,1540878288,1540878289,0 +261657,1540878289,1540878290,0 +261658,1540878290,1540878291,0 +261659,1540878291,1030328807,0 +261660,1540878292,1540878293,0 +261661,1540878293,1540878294,0 +261662,1540878294,1030328471,0 +261663,1540878295,1540878296,0 +261664,1540878296,1030329097,0 +261665,1540878297,1540878298,0 +261666,1540878298,1540878299,0 +261667,1540878299,1540878300,0 +261668,1540878300,1540878301,0 +261669,1540878301,1540878302,0 +261670,1540878302,1030328829,0 +261671,1540878303,1540878304,0 +261672,1540878304,1540878305,0 +261673,1540878305,1540878306,0 +261674,1540878306,1030329188,0 +261675,1540878307,1540878308,0 +261676,1540878308,1030328578,0 +261677,1540878309,1540878310,0 +261678,1540878310,1030328733,0 +261679,1540878311,1540878312,1 +261680,1540878312,1540878313,1 +261681,1540878313,1030328558,1 +261682,1540878314,1540878315,0 +261683,1540878315,1030313181,0 +261684,1540878316,1540878317,1 +261685,1540878317,1540878318,1 +261686,1540878318,1540878319,1 +261687,1540878319,1540878320,1 +261688,1540878320,1540878321,1 +261689,1540878321,1540878322,1 +261690,1540878322,1030328785,1 +261691,1540878323,1540878324,1 +261692,1540878324,1540878325,1 +261693,1540878325,1540878326,1 +261694,1540878326,1030334689,1 +261695,1540878327,1540878328,1 +261696,1540878328,1540878329,1 +261697,1540878329,1540878330,1 +261698,1540878330,1540878331,1 +261699,1540878331,1540878332,1 +261700,1540878332,1540878333,1 +261701,1540878333,1540878334,1 +261702,1540878334,1540878335,1 +261703,1540878335,1540878336,1 +261704,1540878336,1540878337,1 +261705,1540878337,1540878338,1 +261706,1540878338,1030334670,1 +261707,1540878339,1540878340,1 +261708,1540878340,1540878341,1 +261709,1540878341,1540878342,1 +261710,1540878342,1030334741,1 +261711,1540878343,1540878344,1 +261712,1540878344,1540878345,1 +261713,1540878345,1030334738,1 +261714,1540878346,1540878347,1 +261715,1540878347,1030334687,1 +261716,1540878348,1030334557,1 +261717,1540878349,1540878350,1 +261718,1540878350,1540878351,1 +261719,1540878351,1030334568,1 +261720,1540878352,1540878353,1 +261721,1540878353,1540878354,1 +261722,1540878354,1540878355,1 +261723,1540878355,1540878356,1 +261724,1540878356,1540878357,1 +261725,1540878357,1540878358,1 +261726,1540878358,1540878359,1 +261727,1540878359,1540878360,1 +261728,1540878360,1030334572,1 +261729,1540878361,1540878362,1 +261730,1540878362,1540878363,1 +261731,1540878363,1540878364,1 +261732,1540878364,1540878365,1 +261733,1540878365,1540878366,1 +261734,1540878366,1540878367,1 +261735,1540878367,1540878368,1 +261736,1540878368,1030334585,1 +261737,1540878369,1540878370,1 +261738,1540878370,1540878371,1 +261739,1540878371,1540878372,1 +261740,1540878372,1540878373,1 +261741,1540878373,1540878374,1 +261742,1540878374,1540878375,1 +261743,1540878375,1540878376,1 +261744,1540878376,1540878377,1 +261745,1540878377,1540878378,1 +261746,1540878378,1030328500,1 +261747,1540878379,1540878380,1 +261748,1540878380,1540878381,1 +261749,1540878381,1030334675,1 +261750,1540878382,1540878383,1 +261751,1540878383,1540878384,1 +261752,1540878384,1030334736,1 +261753,1540878385,1540878386,1 +261754,1540878386,1540878387,1 +261755,1540878387,1030334711,1 +261756,1540878388,1540878389,1 +261757,1540878389,1540878390,1 +261758,1540878390,1540878391,1 +261759,1540878391,1030334626,1 +261760,1540878392,1540878393,1 +261761,1540878393,1030334568,1 +261762,1540878394,1540878395,1 +261763,1540878395,1540878396,1 +261764,1540878396,1540878397,1 +261765,1540878397,1030334548,1 +261766,1540878398,1540878399,1 +261767,1540878399,1540878400,1 +261768,1540878400,1540878401,1 +261769,1540878401,1540878402,1 +261770,1540878402,1540878403,1 +261771,1540878403,1540878404,1 +261772,1540878404,1540878405,1 +261773,1540878405,1540878406,1 +261774,1540878406,1540878407,1 +261775,1540878407,1540878408,1 +261776,1540878408,1540878409,1 +261777,1540878409,1030334613,1 +261778,1540878410,1540878411,1 +261779,1540878411,1540878412,1 +261780,1540878412,1540878413,1 +261781,1540878413,1030334694,1 +261782,1540878414,1030328805,1 +261783,1540878415,1030334604,1 +261784,1540878416,1540878417,1 +261785,1540878417,1540878418,1 +261786,1540878418,1540878419,1 +261787,1540878419,1540878420,1 +261788,1540878420,1540878421,1 +261789,1540878421,1540878422,1 +261790,1540878422,1540878423,1 +261791,1540878423,1030334636,1 +261792,1540878424,1540878425,1 +261793,1540878425,1540878426,1 +261794,1540878426,1540878427,1 +261795,1540878427,1540878428,1 +261796,1540878428,1540878429,1 +261797,1540878429,1030334700,1 +261798,1540878430,1540878431,1 +261799,1540878431,1030334589,1 +261800,1540878432,1030334575,1 +261801,1540878433,1540878434,1 +261802,1540878434,1540878435,1 +261803,1540878435,1540878436,1 +261804,1540878436,1540878437,1 +261805,1540878437,1540878438,1 +261806,1540878438,1030334630,1 +261807,1540878439,1540878440,1 +261808,1540878440,1540878441,1 +261809,1540878441,1540878442,1 +261810,1540878442,1540878443,1 +261811,1540878443,1030334604,1 +261812,1540878444,1540878445,1 +261813,1540878445,1540878446,1 +261814,1540878446,1540878447,1 +261815,1540878447,1030329177,1 +261816,1540878448,1540878449,1 +261817,1540878449,1540878450,1 +261818,1540878450,1540878451,1 +261819,1540878451,1540878452,1 +261820,1540878452,1540878453,1 +261821,1540878453,1030334559,1 +261822,1540878454,1540878455,1 +261823,1540878455,1030334729,1 +261824,1540878456,1540878457,1 +261825,1540878457,1030334624,1 +261826,1540878458,1540878459,1 +261827,1540878459,1540878460,1 +261828,1540878460,1540878461,1 +261829,1540878461,1540878462,1 +261830,1540878462,1540878463,1 +261831,1540878463,1540878464,1 +261832,1540878464,1540878465,1 +261833,1540878465,1030328501,1 +261834,1540878466,1540878467,1 +261835,1540878467,1540878468,1 +261836,1540878468,1540878469,1 +261837,1540878469,1540878470,1 +261838,1540878470,1030328622,1 +261841,1540878473,1030688862,0 +261842,1540878474,1540878475,1 +261843,1540878475,1030689925,1 +261844,1540878476,1540878477,1 +261845,1540878477,1540878478,1 +261846,1540878478,1540878479,1 +261847,1540878479,1030689805,1 +261848,1540878480,1030689131,0 +261849,1540878481,1540878482,1 +261850,1540878482,1540878483,1 +261851,1540878483,1540878484,1 +261852,1540878484,1540878485,1 +261853,1540878485,1540878486,1 +261854,1540878486,1540878487,1 +261855,1540878487,1540878488,1 +261856,1540878488,1540878489,1 +261857,1540878489,1540878490,1 +261858,1540878490,1540878491,1 +261859,1540878491,1540878492,1 +261860,1540878492,1540878493,1 +261861,1540878493,1540878494,1 +261862,1540878494,1540878495,1 +261863,1540878495,1030689131,1 +261864,1540878496,1030688913,1 +261865,1540878497,1030689412,1 +261866,1540878498,1030688975,1 +261867,1540878499,1540878500,1 +261868,1540878500,1540878501,1 +261869,1540878501,1540878502,1 +261870,1540878502,1540878503,1 +261871,1540878503,1540878504,1 +261872,1540878504,1540878505,1 +261873,1540878505,1540878506,1 +261874,1540878506,1540878507,1 +261875,1540878507,1540878508,1 +261876,1540878508,1540878509,1 +261877,1540878509,1030688971,1 +261878,1540878510,1540878511,1 +261879,1540878511,1540878512,1 +261880,1540878512,1540878513,1 +261881,1540878513,1540878514,1 +261882,1540878514,1540878515,1 +261883,1540878515,1540878516,1 +261884,1540878516,1540878517,1 +261885,1540878517,1540878518,1 +261886,1540878518,1540878519,1 +261887,1540878519,1030689131,1 +261888,1540878520,1030689127,1 +261889,1540878521,1030690039,1 +261890,1540878522,1540878523,0 +261891,1540878523,1030689518,0 +261892,1540878524,1540878525,0 +261893,1540878525,1540878526,0 +261894,1540878526,1540878527,0 +261895,1540878527,1030689096,0 +261896,1540878528,1540878529,0 +261897,1540878529,1540878530,0 +261898,1540878530,1030689653,0 +261899,1540878531,1540878532,0 +261900,1540878532,1030689563,0 +261901,1540878533,1540878534,0 +261902,1540878534,1540878535,0 +261903,1540878535,1540878536,0 +261904,1540878536,1030689784,0 +261905,1540878537,1540878538,1 +261906,1540878538,1540878539,1 +261907,1540878539,1540878540,1 +261908,1540878540,1030689176,1 +261909,1540878541,1030689640,1 +261910,1540878542,1030688837,1 +261911,1540878543,1540878544,1 +261912,1540878544,1540878545,1 +261913,1540878545,1030688861,1 +261914,1540878546,1030689686,1 +261915,1540878547,1030689122,1 +261916,1540878548,1540878549,1 +261917,1540878549,1540878550,1 +261918,1540878550,1540878551,1 +261919,1540878551,1540878552,1 +261920,1540878552,1030689166,1 +261921,1540878553,1540878554,1 +261922,1540878554,1540878555,1 +261923,1540878555,1540878556,1 +261924,1540878556,1030689755,1 +261925,1540878557,1030689470,1 +261926,1540878558,1540878559,0 +261927,1540878559,1540878560,0 +261928,1540878560,1540878561,0 +261929,1540878561,1030690034,0 +261930,1540878562,1540878563,0 +261931,1540878563,1030689750,0 +261932,1540878564,1540878565,0 +261933,1540878565,1540878566,0 +261934,1540878566,1030689148,0 +261935,1540878567,1540878568,0 +261936,1540878568,1030689442,0 +261937,1540878569,1540878570,0 +261938,1540878570,1540878571,0 +261939,1540878571,1030689113,0 +261940,1540878572,1540878573,1 +261941,1540878573,1030689736,1 +261942,1540878574,1540878575,1 +261943,1540878575,1030688929,1 +261944,1540878576,1540878577,1 +261945,1540878577,1030688896,1 +261946,1540878578,1030689653,1 +261947,1540878579,1540878580,1 +261948,1540878580,1030688975,1 +261949,1540878581,1540878582,1 +261950,1540878582,1540878583,1 +261951,1540878583,1030689402,1 +261952,1540878584,1540878585,1 +261953,1540878585,1030689060,1 +261954,1540878586,1030689974,1 +261955,1540878587,1030689798,1 +261956,1540878588,1030690039,1 +261957,1540878589,1030689805,1 +261958,1540878590,1540878591,1 +261959,1540878591,1540878592,1 +261960,1540878592,1540878593,1 +261961,1540878593,1540878594,1 +261962,1540878594,1540878595,1 +261963,1540878595,1030689414,1 +261964,1540878596,1540878597,1 +261965,1540878597,1540878598,1 +261966,1540878598,1030689961,1 +261967,1540878599,1540878600,1 +261968,1540878600,1540878601,1 +261969,1540878601,1030334705,1 +261970,1540878602,1540878603,1 +261971,1540878603,1030688937,1 +261972,1540878604,952161319,1 +261973,1540878605,1540878606,1 +261974,1540878606,1030689298,1 +261975,1540878607,1030689686,1 +261976,1540878608,1540878609,1 +261977,1540878609,1540878610,1 +261978,1540878610,1030689731,1 +261979,1540878611,1540878612,0 +261980,1540878612,1540878613,0 +261981,1540878613,1030689565,0 +261982,1540878614,1540878615,0 +261983,1540878615,1030689533,0 +261984,1540878616,1540878617,0 +261985,1540878617,1540878618,0 +261986,1540878618,1030689755,0 +261987,1540878619,1540878620,0 +261988,1540878620,1540878621,0 +261989,1540878621,1540878622,0 +261990,1540878622,1540878623,0 +261991,1540878623,1540878624,0 +261992,1540878624,1540878625,0 +261993,1540878625,1540878626,0 +261994,1540878626,1030689268,0 +261995,1540878627,1540878628,0 +261996,1540878628,1540878629,0 +261997,1540878629,1030689019,0 +261998,1540878630,952161857,1 +261999,1540878631,1540878632,1 +262000,1540878632,1540878633,1 +262001,1540878633,1540878634,1 +262002,1540878634,1030689046,1 +262003,1540878635,1540878636,1 +262004,1540878636,1540878637,1 +262005,1540878637,1030689896,1 +262006,1540878638,1540878639,1 +262007,1540878639,1540878640,1 +262008,1540878640,1540878641,1 +262009,1540878641,1540878642,1 +262010,1540878642,1540878643,1 +262011,1540878643,1540878644,1 +262012,1540878644,1030688989,1 +262013,1540878645,1540878646,1 +262014,1540878646,1030688896,1 +262015,1540878647,1030689557,1 +262016,1540878648,1540878649,1 +262017,1540878649,1030689592,1 +262018,1540878650,1540878651,1 +262019,1540878651,1540878652,1 +262020,1540878652,1540878653,1 +262021,1540878653,1540878654,1 +262022,1540878654,1540878655,1 +262023,1540878655,1030689833,1 +262024,1540878656,1540878657,1 +262025,1540878657,1540878658,1 +262026,1540878658,1540878659,1 +262027,1540878659,1540878660,1 +262028,1540878660,1540878661,1 +262029,1540878661,1540878662,1 +262030,1540878662,1540878663,1 +262031,1540878663,1540878664,1 +262032,1540878664,1540878665,1 +262033,1540878665,1540878666,1 +262034,1540878666,1540878667,1 +262035,1540878667,1540878668,1 +262036,1540878668,1540878669,1 +262037,1540878669,1540878670,1 +262038,1540878670,1540878671,1 +262039,1540878671,1540878672,1 +262040,1540878672,1540878673,1 +262041,1540878673,1540878674,1 +262042,1540878674,1540878675,1 +262043,1540878675,1540878676,1 +262044,1540878676,1030688806,1 +262045,1540878677,1540878678,1 +262046,1540878678,1540878679,1 +262047,1540878679,1540878680,1 +262048,1540878680,1030688971,1 +262049,1540878681,1540878682,1 +262050,1540878682,1030689076,1 +262051,1540878683,1540878684,1 +262052,1540878684,1030334581,1 +262053,1540878685,1540878686,1 +262054,1540878686,1030334639,1 +262055,1540878687,1540878688,1 +262056,1540878688,1030689230,1 +262057,1540878689,1540878690,1 +262058,1540878690,1540878691,1 +262059,1540878691,1540878692,1 +262060,1540878692,1540878693,1 +262061,1540878693,1540878694,1 +262062,1540878694,1540878695,1 +262063,1540878695,1540878696,1 +262064,1540878696,1540878697,1 +262065,1540878697,1540878698,1 +262066,1540878698,1540878699,1 +262067,1540878699,1540878700,1 +262068,1540878700,1540878701,1 +262069,1540878701,1540878702,1 +262070,1540878702,1540878703,1 +262071,1540878703,1540878704,1 +262072,1540878704,1540878705,1 +262073,1540878705,1540878706,1 +262074,1540878706,1540878707,1 +262075,1540878707,1030689833,1 +262076,1540878708,1540878709,1 +262077,1540878709,1030690106,1 +262078,1540878710,1030689202,1 +262079,1540878711,1540878712,1 +262080,1540878712,1540878713,1 +262081,1540878713,1540878714,1 +262082,1540878714,1540878715,1 +262083,1540878715,1540878716,1 +262084,1540878716,1030334548,1 +262085,1540878717,1540878718,1 +262086,1540878718,1540878719,1 +262087,1540878719,1030334636,1 +262088,1540878720,1540878721,1 +262089,1540878721,1540878722,1 +262090,1540878722,1540878723,1 +262091,1540878723,1540878724,1 +262092,1540878724,1540878725,1 +262093,1540878725,1030334559,1 +262094,1540878726,1540878727,1 +262095,1540878727,1540878728,1 +262096,1540878728,1540878729,1 +262097,1540878729,1540878730,1 +262098,1540878730,1030689253,1 +262099,1540878731,1540878732,1 +262100,1540878732,1540878733,1 +262101,1540878733,1030689788,1 +262102,1540878734,1540878735,1 +262103,1540878735,1540878736,1 +262104,1540878736,1036415401,1 +262105,1540878737,1540878738,1 +262106,1540878738,1540878739,1 +262107,1540878739,1030689068,1 +262108,1540878740,1540878741,1 +262109,1540878741,1030688988,1 +262110,1540878742,1540878743,1 +262111,1540878743,1540878744,1 +262112,1540878744,1540878745,1 +262113,1540878745,1030688837,1 +262114,1540878746,1540878747,1 +262115,1540878747,1030690069,1 +262116,1540878748,1540878749,1 +262117,1540878749,1540878750,1 +262118,1540878750,1030689672,1 +262119,1540878751,1030689515,1 +262120,1540878752,1540878753,1 +262121,1540878753,1540878754,1 +262122,1540878754,1540878755,1 +262123,1540878755,1540878756,1 +262124,1540878756,1030688814,1 +262125,1540878757,1540878758,1 +262126,1540878758,1540878759,1 +262127,1540878759,1540878760,1 +262128,1540878760,1540878761,1 +262129,1540878761,1540878762,1 +262130,1540878762,1540878763,1 +262131,1540878763,1540878764,1 +262132,1540878764,1540878765,1 +262133,1540878765,1540878766,1 +262134,1540878766,1540878767,1 +262135,1540878767,1540878768,1 +262136,1540878768,1540878769,1 +262137,1540878769,1030689131,1 +262138,1540878770,1030689046,1 +262139,1540878771,1540878772,1 +262140,1540878772,1030689393,1 +262141,1540878773,952161298,1 +262142,1540878774,1030688835,0 +262143,1540878775,952161785,1 +262144,1540878776,1540878777,1 +262145,1540878777,1540878778,1 +262146,1540878778,1540878779,1 +262147,1540878779,1540878780,1 +262148,1540878780,1540878781,1 +262149,1540878781,1540878782,1 +262150,1540878782,1540878783,1 +262151,1540878783,1540878784,1 +262152,1540878784,1540878785,1 +262153,1540878785,1540878786,1 +262154,1540878786,1540878787,1 +262155,1540878787,1540878788,1 +262156,1540878788,1030689462,1 +262157,1540878789,1030689784,1 +262158,1540878790,1540878791,1 +262159,1540878791,1540878792,1 +262160,1540878792,1030689736,1 +262161,1540878793,1540878794,1 +262162,1540878794,1030689835,1 +262163,1540878795,1540878796,1 +262164,1540878796,1030689076,1 +262165,1540878797,1540878798,1 +262166,1540878798,1540878799,1 +262167,1540878799,1540878800,1 +262168,1540878800,1540878801,1 +262169,1540878801,1540878802,1 +262170,1540878802,1540878803,1 +262171,1540878803,1540878804,1 +262172,1540878804,1540878805,1 +262173,1540878805,1540878806,1 +262174,1540878806,1540878807,1 +262175,1540878807,1540878808,1 +262176,1540878808,1540878809,1 +262177,1540878809,1540878810,1 +262178,1540878810,1540878811,1 +262179,1540878811,1030689920,1 +262180,1540878812,1540878813,1 +262181,1540878813,1540878814,1 +262182,1540878814,1540878815,1 +262183,1540878815,1540878816,1 +262184,1540878816,1540878817,1 +262185,1540878817,1540878818,1 +262186,1540878818,1540878819,1 +262187,1540878819,1540878820,1 +262188,1540878820,1540878821,1 +262189,1540878821,1540878822,1 +262190,1540878822,1540878823,1 +262191,1540878823,1030689672,1 +262192,1540878824,1540878825,1 +262193,1540878825,1540878826,1 +262194,1540878826,1540878827,1 +262195,1540878827,1540878828,1 +262196,1540878828,1540878829,1 +262197,1540878829,1540878830,1 +262198,1540878830,1540878831,1 +262199,1540878831,1540878832,1 +262200,1540878832,1540878833,1 +262201,1540878833,1540878834,1 +262202,1540878834,1540878835,1 +262203,1540878835,1540878836,1 +262204,1540878836,1030689439,1 +262205,1540878837,1540878838,1 +262206,1540878838,1540878839,1 +262207,1540878839,1540878840,1 +262208,1540878840,1540878841,1 +262209,1540878841,1540878842,1 +262210,1540878842,1540878843,1 +262211,1540878843,1030689260,1 +262212,1540878844,1540878845,1 +262213,1540878845,1030334594,1 +262214,1540878846,1030975149,1 +262215,1540878847,1030974861,1 +262216,1540878848,1540878849,1 +262217,1540878849,1030975224,1 +262218,1540878850,1540878851,0 +262219,1540878851,1030975075,0 +262220,1540878852,1030975401,1 +262221,1540878853,360235270,1 +262222,1540878854,1030974698,1 +262223,1540878855,1030974806,1 +262224,1540878856,1540878857,1 +262225,1540878857,360203051,1 +262226,1540878858,1540878859,1 +262227,1540878859,1030975075,1 +262228,1540878860,1540878861,1 +262229,1540878861,1540878862,1 +262230,1540878862,1030975227,1 +262231,1540878863,1030974662,1 +262232,1540878864,1030975035,1 +262233,1540878865,1030974501,1 +262234,1540878866,1030975084,1 +262235,1540878867,1030974609,1 +262236,1540878868,1030974564,1 +262237,1540878869,1540878870,1 +262238,1540878870,1540878871,1 +262239,1540878871,1540878872,1 +262240,1540878872,1030974762,1 +262241,1540878873,1030975075,0 +262242,1540878874,1540878875,1 +262243,1540878875,1540878876,1 +262244,1540878876,560946143,1 +262245,1540878877,560946147,1 +262246,1540878878,1540878879,1 +262247,1540878879,1540878880,1 +262248,1540878880,1540878881,1 +262249,1540878881,1540878882,1 +262250,1540878882,1540878883,1 +262251,1540878883,1540878884,1 +262252,1540878884,1540878885,1 +262253,1540878885,560945077,1 +262254,1540878886,1540878887,1 +262255,1540878887,1540878888,1 +262256,1540878888,1540878889,1 +262257,1540878889,1540878890,1 +262258,1540878890,1540878891,1 +262259,1540878891,560944982,1 +262260,1540878892,560944924,1 +262261,1540878893,1540878894,1 +262262,1540878894,1540878895,1 +262263,1540878895,1540878896,1 +262264,1540878896,1540878897,1 +262265,1540878897,560944966,1 +262266,1540878898,1540878899,1 +262267,1540878899,952161842,1 +262268,1540878900,1540878901,1 +262269,1540878901,1540878902,1 +262270,1540878902,1540878903,1 +262271,1540878903,1030974448,1 +262272,1540878904,1030974818,1 +262273,1540878905,1030974633,1 +262274,1540878906,1540878907,1 +262275,1540878907,1540878908,1 +262276,1540878908,1540878909,1 +262277,1540878909,1030975571,1 +262278,1540878910,1030975171,1 +262279,1540878911,1030975081,1 +262280,1540878912,1030975623,1 +262281,1540878913,1540878914,1 +262282,1540878914,1030975552,1 +262283,1540878915,1540878916,1 +262284,1540878916,1540878917,1 +262285,1540878917,1030975145,1 +262286,1540878918,1030974758,1 +262287,1540878919,1540878920,1 +262288,1540878920,1540878921,1 +262289,1540878921,1540878922,1 +262290,1540878922,278009641,1 +262291,1540878923,1540878924,1 +262292,1540878924,1030974704,1 +262293,1540878925,1540878926,1 +262294,1540878926,1030975176,1 +262295,1540878927,1540878928,1 +262296,1540878928,1540878929,1 +262297,1540878929,1540878930,1 +262298,1540878930,1030975434,1 +262299,1540878931,1030975140,1 +262633,1540879265,1033229521,0 +262634,1540879266,1013434005,0 +262635,1540879267,1540879268,0 +262636,1540879268,559939186,0 +262637,1540879269,559939191,1 +262638,1540879270,1540879271,0 +262639,1540879271,559939005,0 +262640,1540879272,559938648,0 +262656,1540879288,1540879289,1 +262657,1540879289,1036415732,1 +262658,1540879290,1540879291,1 +262659,1540879291,1540879292,1 +262660,1540879292,1540879293,1 +262661,1540879293,1540879294,1 +262662,1540879294,1540879295,1 +262663,1540879295,1540879296,1 +262664,1540879296,1540879297,1 +262665,1540879297,1540879298,1 +262666,1540879298,1540879299,1 +262667,1540879299,1540879300,1 +262668,1540879300,1540879301,1 +262669,1540879301,1540879302,1 +262670,1540879302,1540879303,1 +262671,1540879303,1540879304,1 +262672,1540879304,560728681,1 +262673,1540879305,1540879306,1 +262674,1540879306,1540879307,1 +262675,1540879307,1540879308,1 +262676,1540879308,1036415821,1 +262677,1540879309,1036415781,1 +262678,1540879310,1540879311,1 +262679,1540879311,1036415641,1 +262680,1540879312,1540879313,1 +262681,1540879313,1036415786,1 +262682,1540879314,1540879315,1 +262683,1540879315,1540879316,1 +262684,1540879316,1540879317,1 +262685,1540879317,1036415348,1 +262686,1540879318,1540879319,1 +262687,1540879319,1540879320,1 +262688,1540879320,1036415566,1 +262689,1540879321,1036415792,1 +262690,1540879322,1540879323,1 +262691,1540879323,1540879324,1 +262692,1540879324,1540879325,1 +262693,1540879325,1036415651,1 +262694,1540879326,1540879327,1 +262695,1540879327,1540879328,1 +262696,1540879328,1540879329,1 +262697,1540879329,1540879330,1 +262698,1540879330,1540879331,1 +262699,1540879331,1036415372,1 +262700,1540879332,1540879333,0 +262701,1540879333,1036415654,0 +262702,1540879334,1036415809,0 +262703,1540879335,1036415635,0 +262704,1540879336,1036415797,0 +262705,1540879337,1036415620,0 +262706,1540879338,1540879339,0 +262707,1540879339,1036415592,0 +262708,1540879340,1540879341,0 +262709,1540879341,1540879342,0 +262710,1540879342,1540879343,0 +262711,1540879343,1540879344,0 +262712,1540879344,1036415833,0 +262713,1540879345,1540879346,1 +262714,1540879346,1036415570,1 +262715,1540879347,1036415534,0 +262716,1540879348,1540879349,0 +262717,1540879349,1036415463,0 +262718,1540879350,1036415651,0 +262719,1540879351,1540879352,0 +262720,1540879352,1540879353,0 +262721,1540879353,1540879354,0 +262722,1540879354,1540879355,0 +262723,1540879355,1540879356,0 +262724,1540879356,1540879357,0 +262725,1540879357,1540879358,0 +262726,1540879358,1540879359,0 +262727,1540879359,1036415654,0 +262728,1540879360,1540879361,1 +262729,1540879361,1540879362,1 +262730,1540879362,1540879363,1 +262731,1540879363,1540879364,1 +262732,1540879364,1036415357,1 +262733,1540879365,1036415641,1 +262734,1540879366,1540879367,1 +262735,1540879367,1540879368,1 +262736,1540879368,1036415557,1 +262737,1540879369,1540879370,1 +262738,1540879370,1036415657,1 +262739,1540879371,1036415710,1 +262740,1540879372,1540879373,1 +262741,1540879373,1540879374,1 +262742,1540879374,1036415588,1 +262743,1540879375,1036415421,1 +262744,1540879376,1540879377,1 +262745,1540879377,1036415744,1 +262746,1540879378,1030689402,1 +262747,1540879379,1036415693,1 +262748,1540879380,1540879381,1 +262749,1540879381,1540879382,1 +262750,1540879382,1036415568,1 +262751,1540879383,1540879384,1 +262752,1540879384,1036415718,1 +262753,1540879385,1540879386,1 +262754,1540879386,1540879387,1 +262755,1540879387,1540879388,1 +262756,1540879388,1036415722,1 +262757,1540879389,1540879390,1 +262758,1540879390,1540879391,1 +262759,1540879391,1540879392,1 +262760,1540879392,1540879393,1 +262761,1540879393,1540879394,1 +262762,1540879394,1036415792,1 +262763,1540879395,1540879396,1 +262764,1540879396,1540879397,1 +262765,1540879397,1036415466,1 +262766,1540879398,1540879399,1 +262767,1540879399,1540879400,1 +262768,1540879400,1540879401,1 +262769,1540879401,1036415878,1 +262770,1540879402,1540879403,1 +262771,1540879403,1540879404,1 +262772,1540879404,1540879405,1 +262773,1540879405,1540879406,1 +262774,1540879406,1540879407,1 +262775,1540879407,1540879408,1 +262776,1540879408,1540879409,1 +262777,1540879409,1540879410,1 +262778,1540879410,1540879411,1 +262779,1540879411,1540879412,1 +262780,1540879412,1540879413,1 +262781,1540879413,1540879414,1 +262782,1540879414,1540879415,1 +262783,1540879415,1036415445,1 +262784,1540879416,1036415511,1 +262785,1540879417,1540879418,1 +262786,1540879418,1036415322,1 +262787,1540879419,1036415465,1 +262788,1540879420,1540879421,1 +262789,1540879421,1540879422,1 +262790,1540879422,1540879423,1 +262791,1540879423,1540879424,1 +262792,1540879424,1540879425,1 +262793,1540879425,1540879426,1 +262794,1540879426,1036415810,1 +262795,1540879427,1036415466,1 +262796,1540879428,1540879429,0 +262797,1540879429,1036415442,0 +262798,1540879430,1540879431,0 +262799,1540879431,1540879432,0 +262800,1540879432,1036415567,0 +262801,1540879433,1540879434,1 +262802,1540879434,1540879435,1 +262803,1540879435,1540879436,1 +262804,1540879436,1036415633,1 +262805,1540879437,1540879438,1 +262806,1540879438,1036415680,1 +262807,1540879439,1036415888,1 +262808,1540879440,1540879441,1 +262809,1540879441,1036415822,1 +262810,1540879442,1036415446,1 +262811,1540879443,1540879444,1 +262812,1540879444,1540879445,1 +262813,1540879445,1540879446,1 +262814,1540879446,1540879447,1 +262815,1540879447,1540879448,1 +262816,1540879448,1540879449,1 +262817,1540879449,1540879450,1 +262818,1540879450,1036415320,1 +262819,1540879451,1036415744,1 +262820,1540879452,1540879453,1 +262821,1540879453,1540879454,1 +262822,1540879454,1036415720,1 +262823,1540879455,1540879456,1 +262824,1540879456,1540879457,1 +262825,1540879457,1540879458,1 +262826,1540879458,1540879459,1 +262827,1540879459,1540879460,1 +262828,1540879460,1540879461,1 +262829,1540879461,1030688929,1 +262830,1540879462,1540879463,1 +262831,1540879463,1540879464,1 +262832,1540879464,1540879465,1 +262833,1540879465,1036415491,1 +262834,1540879466,1036415795,1 +262835,1540879467,1540879468,1 +262836,1540879468,1036415446,1 +262837,1540879469,1540879470,1 +262838,1540879470,1540879471,1 +262839,1540879471,1036415566,1 +262840,1540879472,1540879473,1 +262841,1540879473,1036415718,1 +262842,1540879474,1540879475,1 +262843,1540879475,1540879476,1 +262844,1540879476,1540879477,1 +262845,1540879477,1540879478,1 +262846,1540879478,1036415795,1 +262847,1540879479,1540879480,1 +262848,1540879480,1540879481,1 +262849,1540879481,1540879482,1 +262850,1540879482,1540879483,1 +262851,1540879483,1540879484,1 +262852,1540879484,1540879485,1 +262853,1540879485,1540879486,1 +262854,1540879486,1540879487,1 +262855,1540879487,1540879488,1 +262856,1540879488,1540879489,1 +262857,1540879489,1540879490,1 +262858,1540879490,1036415797,1 +262859,1540879491,1036415418,1 +262860,1540879492,1540879493,0 +262861,1540879493,1036415499,0 +262862,1540879494,1540879495,0 +262863,1540879495,1540879496,0 +262864,1540879496,1540879497,0 +262865,1540879497,1540879498,0 +262866,1540879498,1540879499,0 +262867,1540879499,1540879500,0 +262868,1540879500,1540879501,0 +262869,1540879501,1540879502,0 +262870,1540879502,1540879503,0 +262871,1540879503,1036415892,0 +262872,1540879504,1540879505,0 +262873,1540879505,1036415557,0 +262874,1540879506,1540879507,0 +262875,1540879507,1540879508,0 +262876,1540879508,1540879509,0 +262877,1540879509,1036628089,0 +262878,1540879510,1036415464,1 +262879,1540879511,1540879512,0 +262880,1540879512,1036415730,0 +262881,1540879513,1036415822,0 +262882,1540879514,1036415401,0 +262883,1540879515,1540879516,0 +262884,1540879516,1036415788,0 +262885,1540879517,1540879518,0 +262886,1540879518,1540879519,0 +262887,1540879519,1036415695,0 +262888,1540879520,1540879521,0 +262889,1540879521,1036415570,0 +262890,1540879522,1036415823,1 +262891,1540879523,1036628208,1 +262892,1540879524,1540879525,1 +262893,1540879525,1540879526,1 +262894,1540879526,1540879527,1 +262895,1540879527,1540879528,1 +262896,1540879528,1540879529,1 +262897,1540879529,1036628268,1 +262898,1540879530,1540879531,1 +262899,1540879531,1540879532,1 +262900,1540879532,1540879533,1 +262901,1540879533,1540879534,1 +262902,1540879534,1540879535,1 +262903,1540879535,1036628019,1 +262904,1540879536,1540879537,0 +262905,1540879537,1540879538,0 +262906,1540879538,1540879539,0 +262907,1540879539,1036628165,0 +262908,1540879540,1540879541,1 +262909,1540879541,1036628039,1 +262910,1540879542,1540879543,0 +262911,1540879543,1036628275,0 +262912,1540879544,1540879545,0 +262913,1540879545,1540879546,0 +262914,1540879546,1540879547,0 +262915,1540879547,1036628253,0 +262916,1540879548,1540879549,0 +262917,1540879549,1540879550,0 +262918,1540879550,1036628104,0 +262919,1540879551,1036627969,0 +262920,1540879552,1036628233,0 +262921,1540879553,1540879554,0 +262922,1540879554,1540879555,0 +262923,1540879555,1036628089,0 +262924,1540879556,1540879557,1 +262925,1540879557,1036628102,1 +262926,1540879558,1540879559,1 +262927,1540879559,1036627936,1 +262928,1540879560,1540879561,0 +262929,1540879561,1540879562,0 +262930,1540879562,1540879563,0 +262931,1540879563,1540879564,0 +262932,1540879564,1540879565,0 +262933,1540879565,1036628101,0 +262934,1540879566,1540879567,0 +262935,1540879567,1540879568,0 +262936,1540879568,1540879569,0 +262937,1540879569,1036628066,0 +262938,1540879570,365388314,0 +262939,1540879571,1540879572,1 +262940,1540879572,1540879573,1 +262941,1540879573,1540879574,1 +262942,1540879574,1036627847,1 +262943,1540879575,1540879576,1 +262944,1540879576,1540879577,1 +262945,1540879577,1540879578,1 +262946,1540879578,1540879579,1 +262947,1540879579,1036627833,1 +262948,1540879580,1540879581,1 +262949,1540879581,1540879582,1 +262950,1540879582,1540879583,1 +262951,1540879583,1540879584,1 +262952,1540879584,1540879585,1 +262953,1540879585,1540879586,1 +262954,1540879586,1540879587,1 +262955,1540879587,1540879588,1 +262956,1540879588,1540879589,1 +262957,1540879589,1036627896,1 +262958,1540879590,1540879591,0 +262959,1540879591,1540879592,0 +262960,1540879592,1036627871,0 +262961,1540879593,1540879594,1 +262962,1540879594,1036627841,1 +262963,1540879595,1540879596,1 +262964,1540879596,365388304,1 +262965,1540879597,1540879598,1 +262966,1540879598,1540879599,1 +262967,1540879599,1540879600,1 +262968,1540879600,1540879601,1 +262969,1540879601,1036627847,1 +262970,1540879602,1036628260,1 +262971,1540879603,1540879604,1 +262972,1540879604,1036627952,1 +262973,1540879605,1540879606,0 +262974,1540879606,1540879607,0 +262975,1540879607,1036628165,0 +262976,1540879608,1036628278,0 +262977,1540879609,1540879610,1 +262978,1540879610,1036627883,1 +262979,1540879611,1540879612,1 +262980,1540879612,1540879613,1 +262981,1540879613,1540879614,1 +262982,1540879614,1036628012,1 +262983,1540879615,1540879616,0 +262984,1540879616,1540879617,0 +262985,1540879617,1540879618,0 +262986,1540879618,1036628232,0 +262987,1540879619,1540879620,1 +262988,1540879620,1540879621,1 +262989,1540879621,1036628232,1 +262990,1540879622,1540879623,1 +262991,1540879623,1540879624,1 +262992,1540879624,1036628035,1 +262993,1540879625,1540879626,0 +262994,1540879626,1540879627,0 +262995,1540879627,1540879628,0 +262996,1540879628,278009601,0 +262997,1540879629,1540879630,1 +262998,1540879630,1036628101,1 +262999,1540879631,1540879632,1 +263000,1540879632,1540879633,1 +263001,1540879633,1540879634,1 +263002,1540879634,1540879635,1 +263003,1540879635,1540879636,1 +263004,1540879636,1540879637,1 +263005,1540879637,1540879638,1 +263006,1540879638,1540879639,1 +263007,1540879639,1540879640,1 +263008,1540879640,1540879641,1 +263009,1540879641,1540879642,1 +263010,1540879642,1540879643,1 +263011,1540879643,1540879644,1 +263012,1540879644,1036415374,1 +263013,1540879645,1540879646,1 +263014,1540879646,1540879647,1 +263015,1540879647,1540879648,1 +263016,1540879648,1540879649,1 +263017,1540879649,1540879650,1 +263018,1540879650,1540879651,1 +263019,1540879651,1036628094,1 +263020,1540879652,1036415699,1 +263021,1540879653,716879736,1 +263022,1540879654,1540879655,1 +263023,1540879655,1540879656,1 +263024,1540879656,1540879657,1 +263025,1540879657,1540879658,1 +263026,1540879658,1036627861,1 +263027,1540879659,1540879660,1 +263028,1540879660,1540879661,1 +263029,1540879661,1036415731,1 +263030,1540879662,1037130865,1 +263031,1540879663,1037130890,1 +263032,1540879664,1540879665,1 +263033,1540879665,1037131027,1 +263034,1540879666,1036627940,1 +263035,1540879667,1540879668,1 +263036,1540879668,1540879669,1 +263037,1540879669,1036627916,1 +263038,1540879670,1540879671,1 +263039,1540879671,1540879672,1 +263040,1540879672,1540879673,1 +263041,1540879673,1036627897,1 +263042,1540879674,1540879675,1 +263043,1540879675,1540879676,1 +263044,1540879676,1036627841,1 +263045,1540879677,1540879678,1 +263046,1540879678,1540879679,1 +263047,1540879679,1540879680,1 +263048,1540879680,1540879681,1 +263049,1540879681,1036627984,1 +263050,1540879682,1540879683,0 +263051,1540879683,1540879684,0 +263052,1540879684,1540879685,0 +263053,1540879685,1036628260,0 +263054,1540879686,1036628038,1 +263055,1540879687,1540879688,1 +263056,1540879688,1036628116,1 +263057,1540879689,278009594,1 +263058,1540879690,1036628181,1 +263059,1540879691,1036628132,1 +263060,1540879692,1540879693,1 +263061,1540879693,1540879694,1 +263062,1540879694,1540879695,1 +263063,1540879695,1540879696,1 +263064,1540879696,1036628043,1 +263065,1540879697,1036627872,1 +263066,1540879698,1036627954,1 +263067,1540879699,1540879700,1 +263068,1540879700,1036627974,1 +263069,1540879701,1540879702,0 +263070,1540879702,1540879703,0 +263071,1540879703,1540879704,0 +263072,1540879704,1540879705,0 +263073,1540879705,1540879706,0 +263074,1540879706,1540879707,0 +263075,1540879707,1036415652,0 +263076,1540879708,1371044002,1 +263077,1540879709,1540879710,1 +263078,1540879710,1540879711,1 +263079,1540879711,1540879712,1 +263080,1540879712,1540879713,1 +263081,1540879713,1037131247,1 +263082,1540879714,1540879715,1 +263083,1540879715,1540879716,1 +263084,1540879716,1540879717,1 +263085,1540879717,1540879718,1 +263086,1540879718,1037131138,1 +263087,1540879719,1540879720,1 +263088,1540879720,1540879721,1 +263089,1540879721,1540879722,1 +263090,1540879722,278009580,1 +263091,1540879723,1540879724,1 +263092,1540879724,1540879725,1 +263093,1540879725,1540879726,1 +263094,1540879726,1540879727,1 +263095,1540879727,1540879728,1 +263096,1540879728,1037131244,1 +263097,1540879729,1540879730,1 +263098,1540879730,1540879731,1 +263099,1540879731,1540879732,1 +263100,1540879732,1037131226,1 +263101,1540879733,1037131141,1 +263102,1540879734,1540879735,1 +263103,1540879735,1037211891,1 +263104,1540879736,1037211860,1 +263105,1540879737,1540879738,0 +263106,1540879738,1540879739,0 +263107,1540879739,1540879740,0 +263108,1540879740,1540879741,0 +263109,1540879741,1540879742,0 +263110,1540879742,1540879743,0 +263111,1540879743,1037131186,0 +263112,1540879744,1540879745,0 +263113,1540879745,1540879746,0 +263114,1540879746,1540879747,0 +263115,1540879747,1540879748,0 +263116,1540879748,1540879749,0 +263117,1540879749,1037130954,0 +263118,1540879750,1540879751,0 +263119,1540879751,1540879752,0 +263120,1540879752,1540879753,0 +263121,1540879753,1037131233,0 +263122,1540879754,1037130961,1 +263123,1540879755,1540879756,1 +263124,1540879756,1540879757,1 +263125,1540879757,1037130866,1 +263126,1540879758,1540879759,1 +263127,1540879759,1037131133,1 +263128,1540879760,1540879761,1 +263129,1540879761,1540879762,1 +263130,1540879762,1037131230,1 +263131,1540879763,1540879764,1 +263132,1540879764,1540879765,1 +263133,1540879765,1037130951,1 +263134,1540879766,1540879767,1 +263135,1540879767,1037131209,1 +263136,1540879768,1037131174,1 +263137,1540879769,1540879770,1 +263138,1540879770,1540879771,1 +263139,1540879771,1540879772,1 +263140,1540879772,1540879773,1 +263141,1540879773,1540879774,1 +263142,1540879774,1540879775,1 +263143,1540879775,1540879776,1 +263144,1540879776,1540879777,1 +263145,1540879777,1037131138,1 +263146,1540879778,1037131125,1 +263147,1540879779,1037131245,1 +263148,1540879780,1037131193,1 +263149,1540879781,1540879782,1 +263150,1540879782,1037130885,1 +263151,1540879783,1037130972,1 +263152,1540879784,1037130925,1 +263153,1540879785,1037361916,1 +263154,1540879786,1540879787,1 +263155,1540879787,1540879788,1 +263156,1540879788,1037131141,1 +263157,1540879789,1540879790,1 +263158,1540879790,1037131150,1 +263159,1540879791,1540879792,1 +263160,1540879792,1540879793,1 +263161,1540879793,1540879794,1 +263162,1540879794,1037131063,1 +263163,1540879795,1540879796,1 +263164,1540879796,1037131031,1 +263165,1540879797,1037130890,1 +263166,1540879798,1540879799,1 +263167,1540879799,1540879800,1 +263168,1540879800,1037131125,1 +263169,1540879801,1540879802,1 +263170,1540879802,1037131016,1 +263171,1540879803,1540879804,0 +263172,1540879804,1540879805,0 +263173,1540879805,1540879806,0 +263174,1540879806,1037131046,0 +263175,1540879807,1540879808,0 +263176,1540879808,1037131244,0 +263177,1540879809,1540879810,0 +263178,1540879810,1540879811,0 +263179,1540879811,1540879812,0 +263180,1540879812,1037130997,0 +263181,1540879813,1540879814,0 +263182,1540879814,1540879815,0 +263183,1540879815,1037130876,0 +263184,1540879816,278009577,1 +263185,1540879817,1540879818,0 +263186,1540879818,1037130928,0 +263187,1540879819,1540879820,0 +263188,1540879820,1540879821,0 +263189,1540879821,1540879822,0 +263190,1540879822,1037131074,0 +263191,1540879823,1540879824,0 +263192,1540879824,1037131090,0 +263193,1540879825,1540879826,0 +263194,1540879826,1037131224,0 +263195,1540879827,1540879828,0 +263196,1540879828,1037131043,0 +263197,1540879829,1037131022,0 +263198,1540879830,1540879831,1 +263199,1540879831,1540879832,1 +263200,1540879832,1540879833,1 +263201,1540879833,1540879834,1 +263202,1540879834,1540879835,1 +263203,1540879835,1540879836,1 +263204,1540879836,1540879837,1 +263205,1540879837,1540879838,1 +263206,1540879838,1540879839,1 +263207,1540879839,1037131021,1 +263208,1540879840,1540879841,1 +263209,1540879841,1540879842,1 +263210,1540879842,1037131249,1 +263211,1540879843,1037131150,1 +263212,1540879844,1540879845,1 +263213,1540879845,1540879846,1 +263214,1540879846,1037211919,1 +263215,1540879847,1037211909,1 +263216,1540879848,1037211869,1 +263217,1540879849,1540879850,1 +263218,1540879850,1540879851,1 +263219,1540879851,1540879852,1 +263220,1540879852,1037211908,1 +263221,1540879853,1540879854,1 +263222,1540879854,1540879855,1 +263223,1540879855,1540879856,1 +263224,1540879856,1037211869,1 +263225,1540879857,1540879858,1 +263226,1540879858,1540879859,1 +263227,1540879859,1037211856,1 +263228,1540879860,1540879861,1 +263229,1540879861,1037211875,1 +263230,1540879862,1540879863,1 +263231,1540879863,1540879864,1 +263232,1540879864,1540879865,1 +263233,1540879865,1540879866,1 +263234,1540879866,1540879867,1 +263235,1540879867,1540879868,1 +263236,1540879868,1540879869,1 +263237,1540879869,1540879870,1 +263238,1540879870,1540879871,1 +263239,1540879871,1037211891,1 +263240,1540879872,1540879873,1 +263241,1540879873,1540879874,1 +263242,1540879874,1174599841,1 +263243,1540879875,1037131082,1 +263244,1540879876,1540879877,1 +263245,1540879877,1540879878,1 +263246,1540879878,1540879879,1 +263247,1540879879,1037130992,1 +263248,1540879880,1540879881,1 +263249,1540879881,1540879882,1 +263250,1540879882,1540879883,1 +263251,1540879883,1037361906,1 +263252,1540879884,1037361975,1 +263253,1540879885,1540879886,1 +263254,1540879886,1540879887,1 +263255,1540879887,1540879888,1 +263256,1540879888,1037361615,1 +263257,1540879889,1540879890,1 +263258,1540879890,1037361710,1 +263259,1540879891,1540879892,1 +263260,1540879892,1540879893,1 +263261,1540879893,1540879894,1 +263262,1540879894,1540879895,1 +263263,1540879895,365388287,1 +263264,1540879896,1540879897,1 +263265,1540879897,1038782689,1 +263266,1540879898,1038782761,1 +263267,1540879899,1540879900,1 +263268,1540879900,1540879901,1 +263269,1540879901,1540879902,1 +263270,1540879902,1540879903,1 +263271,1540879903,1540879904,1 +263272,1540879904,1540879905,1 +263273,1540879905,1540879906,1 +263274,1540879906,1540879907,1 +263275,1540879907,1540879908,1 +263276,1540879908,1540879909,1 +263277,1540879909,1540879910,1 +263278,1540879910,1038782708,1 +263279,1540879911,1540879912,1 +263280,1540879912,1540879913,1 +263281,1540879913,1037361552,1 +263282,1540879914,1540879915,1 +263283,1540879915,789216061,1 +263284,1540879916,1540879917,1 +263285,1540879917,365388286,1 +263286,1540879918,1037361846,1 +263287,1540879919,1037361566,1 +263288,1540879920,1037361674,1 +263289,1540879921,1037361855,0 +263290,1540879922,789216016,0 +263291,1540879923,1540879924,0 +263292,1540879924,789216033,0 +263293,1540879925,1540879926,0 +263294,1540879926,1371044092,0 +263295,1540879927,1037361741,0 +263296,1540879928,1037361793,1 +263297,1540879929,1037362000,1 +263298,1540879930,1037362007,1 +263299,1540879931,1540879932,1 +263300,1540879932,1540879933,1 +263301,1540879933,1540879934,1 +263302,1540879934,1540879935,1 +263303,1540879935,1037361591,1 +263304,1540879936,1037361674,1 +263305,1540879937,1540879938,1 +263306,1540879938,1037361915,1 +263307,1540879939,1540879940,1 +263308,1540879940,1037361831,1 +263309,1540879941,1540879942,1 +263310,1540879942,1037361849,1 +263311,1540879943,1037361955,1 +263312,1540879944,1037361932,1 +263313,1540879945,1037361530,1 +263314,1540879946,1540879947,1 +263315,1540879947,1540879948,1 +263316,1540879948,1038225151,1 +263317,1540879949,1037361919,1 +263318,1540879950,1540879951,1 +263319,1540879951,1037361961,1 +263320,1540879952,1540879953,1 +263321,1540879953,1037361530,1 +263322,1540879954,1540879955,1 +263323,1540879955,1037361831,1 +263324,1540879956,1540879957,1 +263325,1540879957,1037361979,1 +263326,1540879958,1037361589,1 +263327,1540879959,1298242187,1 +263328,1540879960,1037361546,1 +263329,1540879961,1037361911,1 +263330,1540879962,1037361951,1 +263331,1540879963,1038225010,1 +263332,1540879964,1540879965,1 +263333,1540879965,1038225221,1 +263334,1540879966,1037361929,1 +263335,1540879967,1037361890,1 +263336,1540879968,1540879969,1 +263337,1540879969,1037131193,1 +263338,1540879970,1037361715,1 +263339,1540879971,1540879972,1 +263340,1540879972,1540879973,1 +263341,1540879973,1037361975,1 +263342,1540879974,1540879975,1 +263343,1540879975,1540879976,1 +263344,1540879976,1540879977,1 +263345,1540879977,1037361875,1 +263346,1540879978,1037131026,1 +263347,1540879979,1037361811,1 +263348,1540879980,1037361859,1 +263349,1540879981,1037361611,1 +263350,1540879982,1037361970,1 +263351,1540879983,1540879984,1 +263352,1540879984,1037361861,1 +263353,1540879985,1540879986,1 +263354,1540879986,1037361979,1 +263355,1540879987,1037362000,1 +263356,1540879988,1540879989,1 +263357,1540879989,1540879990,1 +263358,1540879990,1037361564,1 +263359,1540879991,1371044034,1 +263360,1540879992,1371044030,1 +263361,1540879993,1540879994,1 +263362,1540879994,1371044026,1 +263363,1540879995,1540879996,1 +263364,1540879996,1540879997,1 +263365,1540879997,1037361906,1 +263366,1540879998,1540879999,1 +263367,1540879999,1037361940,1 +263368,1540880000,1037361709,1 +263369,1540880001,1540880002,1 +263370,1540880002,1037361710,1 +263371,1540880003,1540880004,1 +263372,1540880004,1540880005,1 +263373,1540880005,1540880006,1 +263374,1540880006,1037361793,1 +263377,1540880009,1540880010,0 +263378,1540880010,1540880011,0 +263379,1540880011,1540880012,0 +263380,1540880012,1540880013,0 +263381,1540880013,1540880014,0 +263382,1540880014,279592740,0 +263435,1540880067,1540880068,1 +263436,1540880068,1038782555,1 +263437,1540880069,1540880070,1 +263438,1540880070,1540880071,1 +263439,1540880071,1540880072,1 +263440,1540880072,1540880073,1 +263441,1540880073,1038782617,1 +263442,1540880074,1540880075,1 +263443,1540880075,1540880076,1 +263444,1540880076,1540880077,1 +263445,1540880077,1540880078,1 +263446,1540880078,1540880079,1 +263447,1540880079,1540880080,1 +263448,1540880080,1540880081,1 +263449,1540880081,1038225147,1 +263450,1540880082,1038225086,1 +263451,1540880083,1038225219,1 +263452,1540880084,1038225210,1 +263453,1540880085,1540880086,1 +263454,1540880086,1540880087,1 +263455,1540880087,1540880088,1 +263456,1540880088,1540880089,1 +263457,1540880089,1540880090,1 +263458,1540880090,1540880091,1 +263459,1540880091,1540880092,1 +263460,1540880092,1540880093,1 +263461,1540880093,1540880094,1 +263462,1540880094,1540880095,1 +263463,1540880095,1540880096,1 +263464,1540880096,1037805158,1 +263465,1540880097,1038253639,1 +263466,1540880098,1540880099,1 +263467,1540880099,1540880100,1 +263468,1540880100,1540880101,1 +263469,1540880101,1540880102,1 +263470,1540880102,1037804979,1 +263504,1540880136,1540880137,1 +263505,1540880137,1540880138,1 +263506,1540880138,1540880139,1 +263507,1540880139,1540880140,1 +263508,1540880140,1540880141,1 +263509,1540880141,1540880142,1 +263510,1540880142,1037804977,1 +263511,1540880143,1540880144,1 +263512,1540880144,1540880145,1 +263513,1540880145,1037805010,1 +263519,1540880151,1037805164,1 +263536,1540880168,1540880169,1 +263537,1540880169,1540880170,1 +263538,1540880170,1540880171,1 +263539,1540880171,1540880172,1 +263540,1540880172,365388273,1 +263544,1540880176,1037805234,1 +263545,1540880177,1038225207,1 +263553,1540880185,1540880186,1 +263554,1540880186,1037804973,1 +263555,1540880187,1540880188,1 +263556,1540880188,1037805031,1 +263557,1540880189,1540880190,1 +263558,1540880190,1037805040,1 +263565,1540880197,1540880198,1 +263566,1540880198,1540880199,1 +263567,1540880199,1540880200,1 +263568,1540880200,1540880201,1 +263569,1540880201,1540880202,1 +263570,1540880202,1540880203,1 +263571,1540880203,1540880204,1 +263572,1540880204,1540880205,1 +263573,1540880205,1540880206,1 +263574,1540880206,1540880207,1 +263575,1540880207,1540880208,1 +263576,1540880208,1540880209,1 +263577,1540880209,1540880210,1 +263578,1540880210,1540880211,1 +263579,1540880211,1540880212,1 +263580,1540880212,1540880213,1 +263581,1540880213,1540880214,1 +263582,1540880214,1540880215,1 +263583,1540880215,1540880216,1 +263584,1540880216,1540880217,1 +263585,1540880217,1540880218,1 +263586,1540880218,1540880219,1 +263587,1540880219,1540880220,1 +263588,1540880220,1540880221,1 +263589,1540880221,1540880222,1 +263590,1540880222,1540880223,1 +263591,1540880223,1540880224,1 +263592,1540880224,1540880225,1 +263593,1540880225,1540880226,1 +263594,1540880226,1540880227,1 +263595,1540880227,1540880228,1 +263596,1540880228,1540880229,1 +263597,1540880229,1540880230,1 +263598,1540880230,1540880231,1 +263599,1540880231,1540880232,1 +263600,1540880232,1540880233,1 +263601,1540880233,1540880234,1 +263602,1540880234,1540880235,1 +263603,1540880235,1540880236,1 +263604,1540880236,1540880237,1 +263605,1540880237,1540880238,1 +263606,1540880238,1387911917,1 +263770,1540880402,1038225203,1 +263814,1540880446,1540880447,1 +263815,1540880447,1037361951,1 +263816,1540880448,1038225039,1 +263817,1540880449,1038225245,1 +263818,1540880450,1038225078,1 +263819,1540880451,1038225005,1 +263820,1540880452,1038225055,1 +263821,1540880453,1540880454,1 +263822,1540880454,1038225221,1 +263823,1540880455,1540880456,1 +263824,1540880456,1038225228,1 +263825,1540880457,1037805162,1 +263826,1540880458,1540880459,1 +263827,1540880459,1540880460,1 +263828,1540880460,1540880461,1 +263829,1540880461,1038225107,1 +263830,1540880462,1540880463,1 +263831,1540880463,1038225111,1 +263832,1540880464,1540880465,1 +263833,1540880465,1540880466,1 +263834,1540880466,1540880467,1 +263835,1540880467,1038225184,1 +263836,1540880468,1540880469,1 +263837,1540880469,1540880470,1 +263838,1540880470,1038225168,1 +263839,1540880471,1038225045,1 +263840,1540880472,1540880473,1 +263841,1540880473,1540880474,1 +263842,1540880474,1540880475,1 +263843,1540880475,1540880476,1 +263844,1540880476,1540880477,1 +263845,1540880477,1038225170,1 +263846,1540880478,1037804879,1 +263847,1540880479,1540880480,1 +263848,1540880480,1038225201,1 +263849,1540880481,1540880482,1 +263850,1540880482,1038225157,1 +263851,1540880483,1540880484,1 +263852,1540880484,1540880485,1 +263853,1540880485,1038225228,1 +263854,1540880486,1540880487,1 +263855,1540880487,1038225095,1 +263856,1540880488,1540880489,1 +263857,1540880489,1038225168,1 +263858,1540880490,1540880491,1 +263859,1540880491,1540880492,1 +263860,1540880492,1540880493,1 +263861,1540880493,1540880494,1 +263862,1540880494,1540880495,1 +263863,1540880495,1038225206,1 +263864,1540880496,1540880497,1 +263865,1540880497,1540880498,1 +263866,1540880498,1540880499,1 +263867,1540880499,1038225095,1 +263868,1540880500,1038225075,1 +263869,1540880501,1540880502,1 +263870,1540880502,1038225134,1 +263871,1540880503,1540880504,1 +263872,1540880504,1540880505,1 +263873,1540880505,1038225064,1 +263874,1540880506,1540880507,1 +263875,1540880507,1540880508,1 +263876,1540880508,1540880509,1 +263877,1540880509,1540880510,1 +263878,1540880510,1038225210,1 +263879,1540880511,1038783082,1 +263880,1540880512,1540880513,1 +263881,1540880513,1540880514,1 +263882,1540880514,1540880515,1 +263883,1540880515,1540880516,1 +263884,1540880516,1038225094,1 +263885,1540880517,1540880518,1 +263886,1540880518,1540880519,1 +263887,1540880519,1540880520,1 +263888,1540880520,1540880521,1 +263889,1540880521,1540880522,1 +263890,1540880522,1540880523,1 +263891,1540880523,1540880524,1 +263892,1540880524,1038225072,1 +263893,1540880525,1540880526,1 +263894,1540880526,1038225069,1 +263895,1540880527,1038225218,1 +263896,1540880528,1540880529,1 +263897,1540880529,1540880530,1 +263898,1540880530,1540880531,1 +263899,1540880531,1038225107,1 +263900,1540880532,1540880533,1 +263901,1540880533,1038225063,1 +263902,1540880534,1038225151,1 +263903,1540880535,1540880536,1 +263904,1540880536,1038225174,1 +263905,1540880537,1540880538,1 +263906,1540880538,1540880539,1 +263907,1540880539,1540880540,1 +263908,1540880540,1038225025,1 +263909,1540880541,1540880542,1 +263910,1540880542,1540880543,1 +263911,1540880543,1037805170,1 +263912,1540880544,1037805179,1 +263913,1540880545,1540880546,1 +263914,1540880546,1540880547,1 +263915,1540880547,1540880548,1 +263916,1540880548,1038225056,1 +263917,1540880549,1540880550,1 +263918,1540880550,1540880551,1 +263919,1540880551,1038253611,1 +263957,1540880589,1038782659,1 +263958,1540880590,1038782743,1 +263959,1540880591,1540880592,1 +263960,1540880592,1540880593,1 +263961,1540880593,1038782472,1 +263973,1540880605,1540880606,1 +263974,1540880606,1540880607,1 +263975,1540880607,1540880608,1 +263976,1540880608,1540880609,1 +263977,1540880609,1540880610,1 +263978,1540880610,1540880611,1 +263979,1540880611,1540880612,1 +263980,1540880612,1540880613,1 +263981,1540880613,1540880614,1 +263982,1540880614,1540880615,1 +263983,1540880615,1540880616,1 +263984,1540880616,1038782920,1 +263985,1540880617,1540880618,1 +263986,1540880618,1038782903,1 +263987,1540880619,1540880620,1 +263988,1540880620,1038783070,1 +263989,1540880621,1540880622,1 +263990,1540880622,1540880623,1 +263991,1540880623,1540880624,1 +263992,1540880624,1540880625,1 +263993,1540880625,1540880626,1 +263994,1540880626,1540880627,1 +263995,1540880627,1540880628,1 +263996,1540880628,1540880629,1 +263997,1540880629,1540880630,1 +263998,1540880630,1038782904,1 +263999,1540880631,1540880632,1 +264000,1540880632,1540880633,1 +264033,1540880665,1038782752,1 +264034,1540880666,1540880667,1 +264035,1540880667,1540880668,1 +264036,1540880668,1038783160,1 +264037,1540880669,1540880670,1 +264038,1540880670,1038782359,1 +264039,1540880671,1038782642,1 +264040,1540880672,1540880673,1 +264041,1540880673,1038782279,1 +264042,1540880674,1038782969,1 +264043,1540880675,1540880676,1 +264044,1540880676,1540880677,1 +264045,1540880677,1540880678,1 +264046,1540880678,1540880679,1 +264047,1540880679,1540880680,1 +264048,1540880680,1540880681,1 +264049,1540880681,1540880682,1 +264050,1540880682,1540880683,1 +264051,1540880683,1540880684,1 +264052,1540880684,1540880685,1 +264053,1540880685,1540880686,1 +264054,1540880686,1540880687,1 +264055,1540880687,1038782617,1 +264056,1540880688,1038782339,0 +264057,1540880689,1540880690,0 +264058,1540880690,1038782876,0 +264059,1540880691,1038782985,0 +264060,1540880692,1540880693,0 +264061,1540880693,1540880694,0 +264062,1540880694,1038782283,0 +264063,1540880695,1540880696,0 +264064,1540880696,1540880697,0 +264065,1540880697,1038783148,0 +264066,1540880698,1540880699,0 +264067,1540880699,1540880700,0 +264068,1540880700,1038782530,0 +264069,1540880701,1038782479,1 +264070,1540880702,1540880703,1 +264071,1540880703,1540880704,1 +264072,1540880704,1540880705,1 +264073,1540880705,1540880706,1 +264074,1540880706,1038782597,1 +264075,1540880707,1540880708,1 +264076,1540880708,1540880709,1 +264077,1540880709,1540880710,1 +264078,1540880710,1540880711,1 +264079,1540880711,1540880712,1 +264080,1540880712,1540880713,1 +264081,1540880713,1540880714,1 +264082,1540880714,1038782522,1 +264083,1540880715,1540880716,1 +264090,1540880722,1540880723,1 +264091,1540880723,1540880724,1 +264092,1540880724,1540880725,1 +264093,1540880725,1038782528,1 +264099,1540880731,1540880732,1 +264100,1540880732,1540880733,1 +264101,1540880733,1038782254,1 +264102,1540880734,1540880735,1 +264103,1540880735,1038782375,1 +264104,1540880736,1540880737,1 +264105,1540880737,1038782320,1 +264115,1540880747,1540880748,1 +264116,1540880748,1038782821,1 +264117,1540880749,1540880750,1 +264118,1540880750,1540880751,1 +264119,1540880751,1540880752,1 +264120,1540880752,1540880753,1 +264121,1540880753,1540880754,1 +264122,1540880754,1038782915,1 +264123,1540880755,1540880756,1 +264124,1540880756,1540880757,1 +264125,1540880757,1540880758,1 +264126,1540880758,1540880759,1 +264127,1540880759,1540880760,1 +264128,1540880760,1540880761,1 +264129,1540880761,1540880762,1 +264130,1540880762,1540880763,1 +264131,1540880763,1540880764,1 +264132,1540880764,1540880765,1 +264133,1540880765,1540880766,1 +264134,1540880766,1540880767,1 +264135,1540880767,1540880768,1 +264136,1540880768,1540880769,1 +264137,1540880769,1540880770,1 +264138,1540880770,1540880771,1 +264139,1540880771,1540880772,1 +264140,1540880772,1540880773,1 +264141,1540880773,1540880774,1 +264142,1540880774,1540880775,1 +264143,1540880775,1540880776,1 +264144,1540880776,1038782817,1 +264145,1540880777,1038782755,1 +264146,1540880778,1038782522,1 +264147,1540880779,1540880780,1 +264148,1540880780,1540880781,1 +264149,1540880781,1540880782,1 +264150,1540880782,1540880783,1 +264151,1540880783,1038783030,1 +264152,1540880784,1540880785,1 +264153,1540880785,1540880786,1 +264154,1540880786,1540880787,1 +264155,1540880787,1540880788,1 +264156,1540880788,1540880789,1 +264157,1540880789,1540880790,1 +264158,1540880790,1540880791,1 +264159,1540880791,1540880792,1 +264160,1540880792,1540880793,1 +264161,1540880793,1540880794,1 +264162,1540880794,1540880795,1 +264163,1540880795,1540880796,1 +264164,1540880796,1540880797,1 +264165,1540880797,1540880798,1 +264166,1540880798,1540880799,1 +264167,1540880799,1540880800,1 +264168,1540880800,1540880801,1 +264169,1540880801,1540880802,1 +264170,1540880802,1540880803,1 +264171,1540880803,1540880804,1 +264172,1540880804,1038782590,1 +264173,1540880805,1038782320,1 +264174,1540880806,1038783003,1 +264175,1540880807,1540880808,1 +264176,1540880808,1540880809,1 +264177,1540880809,1540880810,1 +264178,1540880810,1540880811,1 +264179,1540880811,1540880812,1 +264180,1540880812,1540880813,1 +264181,1540880813,1540880814,1 +264182,1540880814,1540880815,1 +264183,1540880815,1540880816,1 +264184,1540880816,1540880817,1 +264185,1540880817,1540880818,1 +264186,1540880818,1038783030,1 +264187,1540880819,1540880820,1 +264188,1540880820,1540880821,1 +264189,1540880821,1540880822,1 +264190,1540880822,1540880823,1 +264191,1540880823,1540880824,1 +264192,1540880824,1038782821,1 +264193,1540880825,1540880826,1 +264194,1540880826,1540880827,1 +264195,1540880827,1038782893,1 +264196,1540880828,1540880829,1 +264197,1540880829,1038782570,1 +264198,1540880830,1540880831,1 +264199,1540880831,1540880832,1 +264200,1540880832,1540880833,1 +264201,1540880833,1540880834,1 +264202,1540880834,1038782862,1 +264203,1540880835,1540880836,1 +264204,1540880836,1540880837,1 +264205,1540880837,1540880838,1 +264206,1540880838,1038782359,1 +264207,1540880839,1038782254,1 +264208,1540880840,1540880841,1 +264209,1540880841,1540880842,1 +264210,1540880842,1038782854,1 +264211,1540880843,1540880844,1 +264212,1540880844,1038782371,1 +264213,1540880845,1540880846,1 +264214,1540880846,1540880847,1 +264215,1540880847,1038783070,1 +264216,1540880848,1540880849,1 +264217,1540880849,1540880850,1 +264218,1540880850,1540880851,1 +264219,1540880851,1038783005,1 +264220,1540880852,1540880853,1 +264221,1540880853,1540880854,1 +264222,1540880854,1540880855,1 +264223,1540880855,1540880856,1 +264224,1540880856,1540880857,1 +264225,1540880857,1038782893,1 +264226,1540880858,1540880859,1 +264227,1540880859,1540880860,1 +264253,1540880885,1540880886,1 +264254,1540880886,1540880887,1 +264255,1540880887,1540880888,1 +264256,1540880888,1540880889,1 +264257,1540880889,1038782528,1 +264747,1540881379,1540881380,1 +264748,1540881380,1041566605,1 +264749,1540881381,1540881382,1 +264750,1540881382,1540881383,1 +264751,1540881383,1540881384,1 +264752,1540881384,1540881385,1 +264753,1540881385,1540881386,1 +264754,1540881386,1540881387,1 +264755,1540881387,1540881388,1 +264756,1540881388,1540881389,1 +264757,1540881389,1540881390,1 +264758,1540881390,1540881391,1 +264759,1540881391,1540881392,1 +264760,1540881392,1540881393,1 +264761,1540881393,1540881394,1 +264762,1540881394,1540881395,1 +264763,1540881395,1540881396,1 +264764,1540881396,1540881397,1 +264765,1540881397,1041566398,1 +265218,1540881850,278009644,1 +265219,1540881851,1030329097,1 +265220,1540881852,1540881853,0 +265221,1540881853,1540881854,0 +265222,1540881854,35487978,0 +265223,1540881855,1540881856,0 +265224,1540881856,1540881857,0 +265225,1540881857,1540881858,0 +265226,1540881858,1540881859,0 +265227,1540881859,1540881860,0 +265228,1540881860,1540881861,0 +265229,1540881861,1540881862,0 +265230,1540881862,600400244,0 +265231,1540881863,1540881864,0 +265232,1540881864,1540881865,0 +265233,1540881865,1540881866,0 +265234,1540881866,1540881867,0 +265235,1540881867,1540881868,0 +265236,1540881868,1540881869,0 +265237,1540881869,1540881870,0 +265238,1540881870,35487981,0 +266027,1540882659,360730004,0 +266028,1540882660,361434733,0 +266029,1540882661,361434463,0 +266263,1540882895,360466723,1 +267289,1540883921,1540883922,1 +267290,1540883922,1540883923,1 +267291,1540883923,360012420,1 +267292,1540883924,966653591,1 +267293,1540883925,966653561,1 +267294,1540883926,360012820,1 +267295,1540883927,360012649,0 +267296,1540883928,1540883929,0 +267297,1540883929,360011311,0 +267298,1540883930,360012479,1 +267299,1540883931,1540883932,1 +267300,1540883932,966639979,1 +267301,1540883933,1540883934,1 +267302,1540883934,972316179,1 +267303,1540883935,966639960,1 +267304,1540883936,972315974,1 +267305,1540883937,972315753,1 +267306,1540883938,1540883939,1 +267307,1540883939,418771174,1 +267308,1540883940,1540883941,1 +267309,1540883941,360011585,1 +267310,1540883942,360011588,1 +267311,1540883943,536600652,1 +267312,1540883944,536600658,1 +267313,1540883945,795264077,1 +267314,1540883946,528489628,1 +267315,1540883947,1113233822,1 +267316,1540883948,528489609,1 +267317,1540883949,1540883950,1 +267318,1540883950,528489623,1 +267319,1540883951,795264066,1 +267320,1540883952,528489612,1 +267321,1540883953,795263252,1 +267322,1540883954,1540883955,1 +267323,1540883955,536579491,1 +267324,1540883956,536579471,1 +267325,1540883957,536580250,1 +267326,1540883958,1540883959,1 +267327,1540883959,558986653,1 +267328,1540883960,1540883961,1 +267329,1540883961,509819404,1 +267330,1540883962,1540883963,1 +267331,1540883963,1540883964,1 +267332,1540883964,1540883965,1 +267333,1540883965,559940463,1 +267334,1540883966,1540883967,1 +267335,1540883967,1540883968,1 +267336,1540883968,558986191,1 +267337,1540883969,1540883970,1 +267338,1540883970,1540883971,1 +267339,1540883971,536580276,1 +267340,1540883972,558986179,1 +267341,1540883973,558986031,1 +267342,1540883974,1493090224,0 +267343,1540883975,1540883976,1 +267344,1540883976,984364895,1 +267345,1540883977,1540883978,1 +267346,1540883978,984639912,1 +267347,1540883979,984634389,1 +267348,1540883980,1540883981,1 +267349,1540883981,984634086,1 +267350,1540883982,1540883983,1 +267351,1540883983,1540883984,1 +267352,1540883984,984634261,1 +267353,1540883985,1540883986,1 +267354,1540883986,1540883987,1 +267355,1540883987,1540883988,1 +267356,1540883988,1540883989,1 +267357,1540883989,984634525,1 +267386,1540884018,509781936,1 +267387,1540884019,558986063,1 +267432,1540884064,793529637,1 +267433,1540884065,793529788,1 +267434,1540884066,353243344,1 +267435,1540884067,793529775,1 +267436,1540884068,793529686,1 +267437,1540884069,793529652,1 +267438,1540884070,793529803,1 +267439,1540884071,793529733,1 +267440,1540884072,793479467,1 +267441,1540884073,936853887,1 +267442,1540884074,360476336,1 +267443,1540884075,1540884076,1 +267444,1540884076,803745149,1 +267445,1540884077,1540884078,0 +267446,1540884078,1540884079,0 +267447,1540884079,803745108,0 +267448,1540884080,803745157,0 +267449,1540884081,1540884082,1 +267450,1540884082,803745207,1 +267451,1540884083,1540884084,1 +267452,1540884084,1540884085,1 +267453,1540884085,1540884086,1 +267454,1540884086,803745027,1 +267780,1540884412,1540884413,1 +267781,1540884413,1540884414,1 +267782,1540884414,1540884415,1 +267783,1540884415,347780520,1 +267785,1540884417,1540884418,1 +267786,1540884418,1540884419,1 +267787,1540884419,1540884420,1 +267788,1540884420,1540884421,1 +267789,1540884421,347780192,1 +267807,1540884439,1540884440,1 +267808,1540884440,1540884441,1 +267809,1540884441,1540884442,1 +267810,1540884442,1132701153,1 +267811,1540884443,938502165,1 +267812,1540884444,1540884445,1 +267813,1540884445,600918108,1 +267814,1540884446,1540884447,1 +267815,1540884447,656190111,1 +267816,1540884448,1540884449,1 +267817,1540884449,365310995,1 +267818,1540884450,1540884451,1 +267819,1540884451,365310996,1 +267820,1540884452,1540884453,1 +267821,1540884453,1540884454,1 +267822,1540884454,1540884455,1 +267823,1540884455,1540884456,1 +267824,1540884456,984771985,1 +267825,1540884457,1540884458,1 +267826,1540884458,1540884459,1 +267827,1540884459,1540884460,1 +267828,1540884460,1540884461,1 +267829,1540884461,1540884462,1 +267830,1540884462,1540884463,1 +267831,1540884463,1540884464,1 +267832,1540884464,1540884465,1 +267833,1540884465,365311002,1 +267834,1540884466,1540884467,1 +267835,1540884467,365311005,1 +267836,1540884468,365311007,1 +267837,1540884469,1540884470,1 +267838,1540884470,1540884471,1 +267839,1540884471,1540884472,1 +267840,1540884472,1540884473,1 +267841,1540884473,1540884474,1 +267842,1540884474,1540884475,1 +267843,1540884475,1540884476,1 +267844,1540884476,1540884477,1 +267845,1540884477,1540884478,1 +267846,1540884478,1540884479,1 +267847,1540884479,1540884480,1 +267848,1540884480,1132701095,1 +268333,1540884965,361198220,1 +268334,1540884966,1540884967,1 +268335,1540884967,792056419,1 +268336,1540884968,1540884969,1 +268337,1540884969,1540884970,1 +268338,1540884970,1540884971,1 +268339,1540884971,1540884972,1 +268340,1540884972,360476934,1 +268341,1540884973,1540884974,1 +268342,1540884974,984752708,1 +268343,1540884975,1139689432,0 +268344,1540884976,1540884977,0 +268345,1540884977,938502387,0 +268346,1540884978,938501957,1 +268347,1540884979,1140945511,1 +268348,1540884980,1540884981,1 +268349,1540884981,1540884982,1 +268350,1540884982,803745218,1 +268351,1540884983,803745172,1 +268352,1540884984,1540884985,0 +268353,1540884985,361198998,0 +268354,1540884986,1140945511,1 +268355,1540884987,1241999147,1 +268356,1540884988,803745047,0 +268357,1540884989,803745135,1 +268358,1540884990,653317016,0 +268359,1540884991,653317019,0 +268360,1540884992,1540884993,1 +268361,1540884993,1540884994,1 +268362,1540884994,1540884995,1 +268363,1540884995,1540884996,1 +268364,1540884996,1540884997,1 +268365,1540884997,653316931,1 +268366,1540884998,653316945,1 +268367,1540884999,1141083911,0 +268368,1540885000,653316945,0 +268369,1540885001,653316946,0 +268370,1540885002,1540885003,1 +268371,1540885003,1540885004,1 +268372,1540885004,653316968,1 +268373,1540885005,1540885006,1 +268374,1540885006,653316958,1 +268375,1540885007,1540885008,1 +268376,1540885008,1540885009,1 +268377,1540885009,1540885010,1 +268378,1540885010,1540885011,1 +268379,1540885011,1540885012,1 +268380,1540885012,1540885013,1 +268381,1540885013,1141083936,1 +268382,1540885014,1540885015,1 +268383,1540885015,1540885016,1 +268384,1540885016,1540885017,1 +268385,1540885017,1540885018,1 +268386,1540885018,1540885019,1 +268387,1540885019,1540885020,1 +268388,1540885020,1540885021,1 +268389,1540885021,1540885022,1 +268390,1540885022,653316979,1 +268391,1540885023,653316955,0 +268392,1540885024,1540885025,1 +268393,1540885025,1540885026,1 +268394,1540885026,1540885027,1 +268395,1540885027,1540885028,1 +268396,1540885028,1540885029,1 +268397,1540885029,1141083967,1 +268398,1540885030,1540885031,1 +268399,1540885031,1540885032,1 +268400,1540885032,1540885033,1 +268401,1540885033,1141083936,1 +268402,1540885034,653316956,1 +268403,1540885035,1540885036,1 +268404,1540885036,653316923,1 +268405,1540885037,1540885038,1 +268406,1540885038,1540885039,1 +268407,1540885039,1540885040,1 +268408,1540885040,1540885041,1 +268409,1540885041,1141083892,1 +268410,1540885042,1540885043,1 +268411,1540885043,1540885044,1 +268412,1540885044,1540885045,1 +268413,1540885045,1540885046,1 +268414,1540885046,1141083967,1 +268415,1540885047,1540885048,1 +268416,1540885048,1540885049,1 +268417,1540885049,1540885050,1 +268418,1540885050,1540885051,1 +268419,1540885051,1540885052,1 +268420,1540885052,1141084014,1 +268421,1540885053,1540885054,1 +268422,1540885054,1540885055,1 +268423,1540885055,1540885056,1 +268424,1540885056,1540885057,1 +268425,1540885057,1540885058,1 +268426,1540885058,1540885059,1 +268427,1540885059,1540885060,1 +268428,1540885060,938502237,1 +268429,1540885061,338484169,0 +268430,1540885062,360473790,1 +268431,1540885063,1540885064,1 +268432,1540885064,353244385,1 +268433,1540885065,353244388,1 +268438,1540885070,1540885071,0 +268439,1540885071,1141269201,0 +268440,1540885072,1141269207,1 +268441,1540885073,1141269255,0 +268442,1540885074,360470377,0 +268443,1540885075,360470595,0 +268444,1540885076,1540885077,0 +268445,1540885077,1540885078,0 +268446,1540885078,705971082,0 +268447,1540885079,1540885080,1 +268448,1540885080,360728846,1 +268449,1540885081,1540885082,1 +268450,1540885082,1540885083,1 +268451,1540885083,1540885084,1 +268452,1540885084,1540885085,1 +268453,1540885085,705971035,1 +268496,1540885128,353245362,0 +268497,1540885129,353245364,0 +268498,1540885130,360474616,0 +268499,1540885131,360729958,0 +268500,1540885132,705073957,1 +268501,1540885133,1142507858,1 +268502,1540885134,1540885135,1 +268503,1540885135,360730598,1 +268504,1540885136,360729906,1 +268505,1540885137,1540885138,1 +268506,1540885138,1540885139,1 +268507,1540885139,1540885140,1 +268508,1540885140,705073941,1 +268509,1540885141,1540885142,1 +268510,1540885142,360729193,1 +268511,1540885143,705073953,1 +268512,1540885144,1540885145,1 +268513,1540885145,1540885146,1 +268514,1540885146,1540885147,1 +268515,1540885147,1540885148,1 +268516,1540885148,1142507845,1 +268517,1540885149,1540885150,1 +268518,1540885150,683301577,1 +268519,1540885151,338485291,0 +268520,1540885152,338484489,0 +268521,1540885153,353246790,0 +268522,1540885154,360475936,0 +268523,1540885155,1540885156,1 +268524,1540885156,683301671,1 +268525,1540885157,678158820,1 +268526,1540885158,360475785,0 +268527,1540885159,1540885160,0 +268528,1540885160,694770235,0 +268529,1540885161,678158752,1 +268530,1540885162,1540885163,1 +268531,1540885163,360475567,1 +268532,1540885164,694789286,1 +268533,1540885165,1540885166,0 +268534,1540885166,360474613,0 +268535,1540885167,365122254,1 +268536,1540885168,1540885169,0 +268537,1540885169,365122620,0 +268540,1540885172,1540885173,0 +268541,1540885173,360475371,0 +268542,1540885174,1540885175,0 +268543,1540885175,1540885176,0 +268544,1540885176,360475399,0 +268545,1540885177,365120060,0 +268546,1540885178,1540885179,0 +268547,1540885179,365118952,0 +268548,1540885180,1540885181,0 +268549,1540885181,1540885182,0 +268550,1540885182,1144045155,0 +268551,1540885183,365970002,0 +268552,1540885184,365120940,0 +268553,1540885185,365120938,0 +268554,1540885186,1540885187,0 +268555,1540885187,562865746,0 +268556,1540885188,1540885189,0 +268557,1540885189,1540885190,0 +268558,1540885190,1540885191,0 +268559,1540885191,360000058,0 +268560,1540885192,1540885193,0 +268561,1540885193,1540885194,0 +268562,1540885194,1540885195,0 +268563,1540885195,1540885196,0 +268564,1540885196,1540885197,0 +268565,1540885197,1540885198,0 +268566,1540885198,1540885199,0 +268567,1540885199,1540885200,0 +268568,1540885200,1540885201,0 +268569,1540885201,1540885202,0 +268570,1540885202,1540885203,0 +268571,1540885203,1540885204,0 +268572,1540885204,1540885205,0 +268573,1540885205,1540885206,0 +268574,1540885206,1540885207,0 +268575,1540885207,1540885208,0 +268576,1540885208,1540885209,0 +268577,1540885209,1540885210,0 +268578,1540885210,1540885211,0 +268579,1540885211,361217711,0 +268580,1540885212,1540885213,0 +268581,1540885213,1540885214,0 +268582,1540885214,559494652,0 +268583,1540885215,361217718,0 +268584,1540885216,512543960,0 +268587,1540885219,360000002,0 +268588,1540885220,1540885221,0 +268589,1540885221,1013433983,0 +268590,1540885222,365970500,0 +268593,1540885225,793529693,1 +268594,1540885226,1540885227,0 +268595,1540885227,1540885228,0 +268596,1540885228,579794593,0 +268597,1540885229,797394792,1 +268598,1540885230,797394851,1 +268599,1540885231,1540885232,1 +268600,1540885232,361199271,1 +268601,1540885233,938143038,1 +268602,1540885234,600205087,1 +268603,1540885235,1540885236,1 +268604,1540885236,938149108,1 +268605,1540885237,1540885238,1 +268606,1540885238,938502261,1 +268607,1540885239,361198981,1 +268608,1540885240,1343011715,1 +268609,1540885241,1343029774,1 +268610,1540885242,1540885243,1 +268611,1540885243,1540885244,1 +268612,1540885244,1540885245,1 +268613,1540885245,1343029643,1 +268614,1540885246,1343029630,1 +268615,1540885247,1343011215,1 +268616,1540885248,1343029892,1 +268617,1540885249,1540885250,1 +268618,1540885250,1144431870,1 +268619,1540885251,1144431812,1 +268620,1540885252,1540885253,1 +268621,1540885253,1144431660,1 +268622,1540885254,1540885255,1 +268623,1540885255,1540885256,1 +268624,1540885256,1540885257,1 +268625,1540885257,1145611281,1 +268626,1540885258,1145577400,1 +268627,1540885259,1145611274,1 +268628,1540885260,1145611265,1 +268629,1540885261,1540885262,1 +268630,1540885262,938502300,1 +269900,1540886532,527804587,1 +269901,1540886533,1540886534,1 +269902,1540886534,527804423,1 +269903,1540886535,1540886536,1 +269904,1540886536,527804630,1 +269905,1540886537,527804647,1 +269906,1540886538,1540886539,1 +269907,1540886539,1540886540,1 +269908,1540886540,560712671,1 +269909,1540886541,560712728,1 +269910,1540886542,1540886543,0 +269911,1540886543,1540886544,0 +269912,1540886544,1540886545,0 +269913,1540886545,352724965,0 +269914,1540886546,1540886547,0 +269915,1540886547,1540886548,0 +269916,1540886548,1540886549,0 +269917,1540886549,352724970,0 +269918,1540886550,1540886551,0 +269919,1540886551,1540886552,0 +269920,1540886552,1540886553,0 +269921,1540886553,352724978,0 +269922,1540886554,1540886555,1 +269923,1540886555,527804418,1 +269924,1540886556,527804703,1 +269979,1540886611,1540886612,1 +269980,1540886612,1540886613,1 +269981,1540886613,1540886614,1 +269982,1540886614,1540886615,1 +269983,1540886615,1540886616,1 +269984,1540886616,1163936359,1 +269985,1540886617,1540886618,1 +269986,1540886618,1540886619,1 +269987,1540886619,1540886620,1 +269988,1540886620,1540886621,1 +269989,1540886621,1540886622,1 +269990,1540886622,1540886623,1 +269991,1540886623,1540886624,1 +269992,1540886624,1540886625,1 +269993,1540886625,1172498098,1 +269994,1540886626,1540886627,1 +269995,1540886627,1540886628,1 +269996,1540886628,1540886629,1 +269997,1540886629,1540886630,1 +269998,1540886630,1163936425,1 +272957,1540889589,1540889590,1 +272958,1540889590,1540889591,1 +272959,1540889591,1540889592,1 +272960,1540889592,1540889593,1 +272961,1540889593,1540889594,1 +272962,1540889594,1540889595,1 +272963,1540889595,1540889596,1 +272964,1540889596,1540889597,1 +272965,1540889597,1172380434,1 +272966,1540889598,1172380461,1 +272967,1540889599,1540889600,1 +272968,1540889600,1540889601,1 +272969,1540889601,1540889602,1 +272970,1540889602,1540889603,1 +272971,1540889603,1540889604,1 +272972,1540889604,1540889605,1 +272973,1540889605,1172380351,1 +272974,1540889606,1540889607,1 +272975,1540889607,1540889608,1 +272976,1540889608,1172380560,1 +272977,1540889609,1540889610,1 +272978,1540889610,1540889611,1 +272979,1540889611,1540889612,1 +272980,1540889612,1540889613,1 +272981,1540889613,1540889614,1 +272982,1540889614,1540889615,1 +272983,1540889615,1540889616,1 +272984,1540889616,1540889617,1 +272985,1540889617,1540889618,1 +272986,1540889618,1540889619,1 +272987,1540889619,1540889620,1 +272988,1540889620,1540889621,1 +272989,1540889621,1540889622,1 +272990,1540889622,1540889623,1 +272991,1540889623,1172380410,1 +272992,1540889624,1540889625,1 +272993,1540889625,1540889626,1 +272994,1540889626,1540889627,1 +272995,1540889627,1172380434,1 +272996,1540889628,1540889629,1 +272997,1540889629,1540889630,1 +272998,1540889630,1540889631,1 +272999,1540889631,1172389463,1 +273000,1540889632,1172388091,1 +273001,1540889633,1172607796,1 +273002,1540889634,1540889635,1 +273003,1540889635,1540889636,1 +273004,1540889636,1540889637,1 +273005,1540889637,1540889638,1 +273006,1540889638,1540889639,1 +273007,1540889639,1540889640,1 +273008,1540889640,1540889641,1 +273009,1540889641,1540889642,1 +273010,1540889642,1540889643,1 +273011,1540889643,1540889644,1 +273012,1540889644,1540889645,1 +273013,1540889645,1540889646,1 +273014,1540889646,1540889647,1 +273015,1540889647,1540889648,1 +273016,1540889648,1540889649,1 +273017,1540889649,1540889650,1 +273018,1540889650,1540889651,1 +273019,1540889651,1540889652,1 +273020,1540889652,1540889653,1 +273021,1540889653,1540889654,1 +273022,1540889654,1540889655,1 +273023,1540889655,1540889656,1 +273024,1540889656,1540889657,1 +273025,1540889657,1540889658,1 +273026,1540889658,1540889659,1 +273027,1540889659,1540889660,1 +273028,1540889660,1540889661,1 +273029,1540889661,1540889662,1 +273030,1540889662,1540889663,1 +273031,1540889663,1540889664,1 +273032,1540889664,1540889665,1 +273033,1540889665,1540889666,1 +273034,1540889666,1540889667,1 +273035,1540889667,1540889668,1 +273036,1540889668,1540889669,1 +273037,1540889669,1540889670,1 +273038,1540889670,1540889671,1 +273039,1540889671,1540889672,1 +273040,1540889672,1540889673,1 +273041,1540889673,1540889674,1 +273042,1540889674,1540889675,1 +273043,1540889675,1172388610,1 +273044,1540889676,1540889677,1 +273045,1540889677,1540889678,1 +273046,1540889678,1540889679,1 +273047,1540889679,1540889680,1 +273048,1540889680,1540889681,1 +273049,1540889681,1540889682,1 +273050,1540889682,1540889683,1 +273051,1540889683,1540889684,1 +273052,1540889684,1540889685,1 +273053,1540889685,1540889686,1 +273054,1540889686,1540889687,1 +273055,1540889687,1540889688,1 +273056,1540889688,1540889689,1 +273057,1540889689,1540889690,1 +273058,1540889690,1540889691,1 +273059,1540889691,1540889692,1 +273060,1540889692,1540889693,1 +273061,1540889693,1540889694,1 +273062,1540889694,1540889695,1 +273063,1540889695,1172388681,1 +273064,1540889696,1540889697,1 +273065,1540889697,1540889698,1 +273066,1540889698,1540889699,1 +273067,1540889699,1540889700,1 +273068,1540889700,1540889701,1 +273069,1540889701,1540889702,1 +273070,1540889702,1540889703,1 +273071,1540889703,1540889704,1 +273072,1540889704,1540889705,1 +273073,1540889705,1540889706,1 +273074,1540889706,1540889707,1 +273075,1540889707,1540889708,1 +273076,1540889708,1540889709,1 +273077,1540889709,1540889710,1 +273078,1540889710,1540889711,1 +273079,1540889711,1540889712,1 +273080,1540889712,1540889713,1 +273081,1540889713,1540889714,1 +273082,1540889714,1540889715,1 +273083,1540889715,1540889716,1 +273084,1540889716,1540889717,1 +273085,1540889717,1540889718,1 +273086,1540889718,1540889719,1 +273087,1540889719,1540889720,1 +273088,1540889720,1540889721,1 +273089,1540889721,1540889722,1 +273090,1540889722,1540889723,1 +273091,1540889723,1540889724,1 +273092,1540889724,1540889725,1 +273093,1540889725,1540889726,1 +273094,1540889726,1540889727,1 +273095,1540889727,1540889728,1 +273096,1540889728,1540889729,1 +273097,1540889729,1540889730,1 +273098,1540889730,1540889731,1 +273099,1540889731,1540889732,1 +273100,1540889732,1540889733,1 +273101,1540889733,1540889734,1 +273102,1540889734,1540889735,1 +273103,1540889735,1540889736,1 +273104,1540889736,1540889737,1 +273105,1540889737,1540889738,1 +273106,1540889738,1540889739,1 +273107,1540889739,1540889740,1 +273108,1540889740,1540889741,1 +273109,1540889741,1540889742,1 +273110,1540889742,1540889743,1 +273111,1540889743,1172388231,1 +273112,1540889744,1540889745,1 +273113,1540889745,1540889746,1 +273114,1540889746,1540889747,1 +273115,1540889747,1540889748,1 +273116,1540889748,1540889749,1 +273117,1540889749,1540889750,1 +273118,1540889750,1540889751,1 +273119,1540889751,1540889752,1 +273120,1540889752,1540889753,1 +273121,1540889753,1540889754,1 +273122,1540889754,1540889755,1 +273123,1540889755,1540889756,1 +273124,1540889756,1540889757,1 +273125,1540889757,1540889758,1 +273126,1540889758,1540889759,1 +273127,1540889759,1540889760,1 +273128,1540889760,1540889761,1 +273129,1540889761,1540889762,1 +273130,1540889762,1540889763,1 +273131,1540889763,1540889764,1 +273132,1540889764,1540889765,1 +273133,1540889765,1540889766,1 +273134,1540889766,1540889767,1 +273135,1540889767,1540889768,1 +273136,1540889768,1540889769,1 +273137,1540889769,1540889770,1 +273138,1540889770,1540889771,1 +273139,1540889771,1540889772,1 +273140,1540889772,1540889773,1 +273141,1540889773,1540889774,1 +273142,1540889774,1172388419,1 +273143,1540889775,1172388222,1 +273144,1540889776,1540889777,1 +273145,1540889777,1540889778,1 +273146,1540889778,1540889779,1 +273147,1540889779,1540889780,1 +273148,1540889780,1540889781,1 +273149,1540889781,1540889782,1 +273150,1540889782,1540889783,1 +273151,1540889783,1540889784,1 +273152,1540889784,1540889785,1 +273153,1540889785,1540889786,1 +273154,1540889786,1540889787,1 +273155,1540889787,1540889788,1 +273156,1540889788,1540889789,1 +273157,1540889789,1540889790,1 +273158,1540889790,1540889791,1 +273159,1540889791,1540889792,1 +273160,1540889792,1540889793,1 +273161,1540889793,1540889794,1 +273162,1540889794,1540889795,1 +273163,1540889795,1540889796,1 +273164,1540889796,1540889797,1 +273165,1540889797,1540889798,1 +273166,1540889798,1540889799,1 +273167,1540889799,1540889800,1 +273168,1540889800,1540889801,1 +273169,1540889801,1540889802,1 +273170,1540889802,1540889803,1 +273171,1540889803,1540889804,1 +273172,1540889804,1540889805,1 +273173,1540889805,1540889806,1 +273174,1540889806,1540889807,1 +273175,1540889807,1540889808,1 +273176,1540889808,1540889809,1 +273177,1540889809,1540889810,1 +273178,1540889810,1540889811,1 +273179,1540889811,1540889812,1 +273180,1540889812,1540889813,1 +273181,1540889813,1540889814,1 +273182,1540889814,1540889815,1 +273183,1540889815,1540889816,1 +273184,1540889816,1540889817,1 +273185,1540889817,1540889818,1 +273186,1540889818,1540889819,1 +273187,1540889819,1172388404,1 +273188,1540889820,1540889821,1 +273189,1540889821,1540889822,1 +273190,1540889822,1540889823,1 +273191,1540889823,1540889824,1 +273192,1540889824,1540889825,1 +273193,1540889825,1540889826,1 +273194,1540889826,1540889827,1 +273195,1540889827,1540889828,1 +273196,1540889828,1540889829,1 +273197,1540889829,1540889830,1 +273198,1540889830,1540889831,1 +273199,1540889831,1540889832,1 +273200,1540889832,1540889833,1 +273201,1540889833,1540889834,1 +273202,1540889834,1540889835,1 +273203,1540889835,1540889836,1 +273204,1540889836,1540889837,1 +273205,1540889837,1540889838,1 +273206,1540889838,1540889839,1 +273207,1540889839,1540889840,1 +273208,1540889840,1540889841,1 +273209,1540889841,1540889842,1 +273210,1540889842,1540889843,1 +273211,1540889843,1172380410,1 +273212,1540889844,1540889845,1 +273213,1540889845,1540889846,1 +273214,1540889846,1540889847,1 +273215,1540889847,1172389463,1 +273216,1540889848,1540889849,1 +273217,1540889849,1172477536,1 +273218,1540889850,1540889851,1 +273219,1540889851,1540889852,1 +273220,1540889852,1540889853,1 +273221,1540889853,1540889854,1 +273222,1540889854,1540889855,1 +273223,1540889855,1540889856,1 +273224,1540889856,1540889857,1 +273225,1540889857,360206868,1 +273226,1540889858,1540889859,1 +273227,1540889859,1540889860,1 +273228,1540889860,1540889861,1 +273229,1540889861,1540889862,1 +273230,1540889862,1540889863,1 +273231,1540889863,1540889864,1 +273232,1540889864,1540889865,1 +273233,1540889865,1540889866,1 +273234,1540889866,1540889867,1 +273235,1540889867,1540889868,1 +273236,1540889868,1540889869,1 +273237,1540889869,1540889870,1 +273238,1540889870,1540889871,1 +273239,1540889871,1540889872,1 +273240,1540889872,1540889873,1 +273241,1540889873,1540889874,1 +273242,1540889874,1540889875,1 +273243,1540889875,1540889876,1 +273244,1540889876,1540889877,1 +273245,1540889877,1540889878,1 +273246,1540889878,1540889879,1 +273247,1540889879,1540889880,1 +273248,1540889880,1540889881,1 +273249,1540889881,1540889882,1 +273250,1540889882,1540889883,1 +273251,1540889883,1540889884,1 +273252,1540889884,1540889885,1 +273253,1540889885,1540889886,1 +273254,1540889886,1540889887,1 +273255,1540889887,1540889888,1 +273256,1540889888,1540889889,1 +273257,1540889889,1540889890,1 +273258,1540889890,1540889891,1 +273259,1540889891,1540889892,1 +273260,1540889892,1172573445,1 +273262,1540889894,1540889895,1 +273263,1540889895,1172609445,1 +273264,1540889896,1540889897,1 +273265,1540889897,1540889898,1 +273266,1540889898,1540889899,1 +273267,1540889899,1540889900,1 +273268,1540889900,1540889901,1 +273269,1540889901,1540889902,1 +273270,1540889902,1540889903,1 +273271,1540889903,1540889904,1 +273272,1540889904,1172601416,1 +273273,1540889905,1540889906,1 +273274,1540889906,1540889907,1 +273275,1540889907,1540889908,1 +273276,1540889908,1540889909,1 +273277,1540889909,1172607796,1 +273278,1540889910,1172612127,1 +273279,1540889911,1540889912,1 +273280,1540889912,1540889913,1 +273281,1540889913,1540889914,1 +273282,1540889914,1540889915,1 +273283,1540889915,1540889916,1 +273284,1540889916,1172607848,1 +273285,1540889917,1172607819,1 +273286,1540889918,1540889919,1 +273287,1540889919,1540889920,1 +273288,1540889920,1172612127,1 +273289,1540889921,1172609440,1 +273290,1540889922,1540889923,1 +273291,1540889923,1172609445,1 +273292,1540889924,1540889925,1 +273293,1540889925,1172609434,1 +273294,1540889926,1540889927,1 +273295,1540889927,1540889928,1 +273296,1540889928,1540889929,1 +273297,1540889929,1540889930,1 +273298,1540889930,1540889931,1 +273299,1540889931,1540889932,1 +273300,1540889932,1172609440,1 +273301,1540889933,1540889934,1 +273302,1540889934,1540889935,1 +273303,1540889935,1540889936,1 +273304,1540889936,1540889937,1 +273305,1540889937,1540889938,1 +273306,1540889938,1540889939,1 +273307,1540889939,1540889940,1 +273308,1540889940,1540889941,1 +273309,1540889941,1540889942,1 +273310,1540889942,1540889943,1 +273311,1540889943,1540889944,1 +273312,1540889944,1540889945,1 +273313,1540889945,365378211,1 +273314,1540889946,1540889947,1 +273315,1540889947,1540889948,1 +273316,1540889948,1172609434,1 +273317,1540889949,1172612126,1 +273318,1540889950,1540889951,1 +273319,1540889951,1540889952,1 +273320,1540889952,1540889953,1 +273321,1540889953,1540889954,1 +273322,1540889954,1172615090,1 +273323,1540889955,1540889956,1 +273324,1540889956,1540889957,1 +273325,1540889957,1540889958,1 +273326,1540889958,278010568,1 +273327,1540889959,1540889960,1 +273328,1540889960,1540889961,1 +273329,1540889961,1540889962,1 +273330,1540889962,278011402,1 +273331,1540889963,1540889964,1 +273332,1540889964,1540889965,1 +273333,1540889965,1540889966,1 +273334,1540889966,1172655426,1 +273335,1540889967,1540889968,1 +273336,1540889968,1424068577,1 +273337,1540889969,1540889970,1 +273338,1540889970,1540889971,1 +273339,1540889971,1540889972,1 +273340,1540889972,1540889973,1 +273341,1540889973,1540889974,1 +273342,1540889974,1172528348,1 +273476,1540890108,1540890109,1 +273477,1540890109,1540890110,1 +273478,1540890110,1540890111,1 +273479,1540890111,1540890112,1 +273480,1540890112,1540890113,1 +273481,1540890113,1540890114,1 +273482,1540890114,1540890115,1 +273483,1540890115,1540890116,1 +273484,1540890116,1540890117,1 +273485,1540890117,1540890118,1 +273486,1540890118,1540890119,1 +273487,1540890119,1540890120,1 +273488,1540890120,1540890121,1 +273489,1540890121,1540890122,1 +273490,1540890122,1540890123,1 +273491,1540890123,1540890124,1 +273492,1540890124,1540890125,1 +273493,1540890125,1540890126,1 +273494,1540890126,1540890127,1 +273495,1540890127,1540890128,1 +273501,1540890133,1540890134,1 +273502,1540890134,1540890135,1 +273503,1540890135,1540890136,1 +273504,1540890136,1540890137,1 +273505,1540890137,1540890138,1 +273506,1540890138,1174782357,1 +273876,1540890508,1540890509,1 +273877,1540890509,1178859363,1 +273878,1540890510,1540890511,1 +273879,1540890511,1178893677,1 +273880,1540890512,1178859410,1 +273881,1540890513,1178859389,1 +273882,1540890514,1178893711,1 +273883,1540890515,1540890516,1 +273884,1540890516,1540890517,1 +273885,1540890517,1540890518,1 +273886,1540890518,1540890519,1 +273887,1540890519,1540890520,1 +273888,1540890520,1540890521,1 +273889,1540890521,1178859421,1 +273890,1540890522,1540890523,1 +273891,1540890523,1178859407,1 +273892,1540890524,1178859395,1 +273893,1540890525,1540890526,1 +273894,1540890526,1540890527,1 +273895,1540890527,1178859363,1 +273896,1540890528,1540890529,1 +273897,1540890529,1540890530,1 +273898,1540890530,1178880780,1 +273899,1540890531,1540890532,1 +273900,1540890532,1178859508,1 +273901,1540890533,1540890534,1 +273902,1540890534,1540890535,1 +273903,1540890535,1540890536,1 +273904,1540890536,1540890537,1 +273905,1540890537,1178859500,1 +273906,1540890538,1178859496,1 +273907,1540890539,1540890540,1 +273908,1540890540,1178859387,1 +273909,1540890541,1178909424,1 +273910,1540890542,1540890543,1 +273911,1540890543,1540890544,1 +273912,1540890544,1540890545,1 +273913,1540890545,1540890546,1 +273914,1540890546,1178859518,1 +273915,1540890547,1178859414,1 +273916,1540890548,1540890549,1 +273917,1540890549,1540890550,1 +273918,1540890550,1178859896,1 +273919,1540890551,1540890552,1 +273920,1540890552,1178909143,1 +273921,1540890553,1540890554,1 +273922,1540890554,1178859395,1 +273923,1540890555,1178881593,1 +273924,1540890556,1540890557,1 +273925,1540890557,1178881590,1 +273926,1540890558,1540890559,1 +273927,1540890559,1540890560,1 +273928,1540890560,1540890561,1 +273929,1540890561,1540890562,1 +273930,1540890562,1540890563,1 +273931,1540890563,1540890564,1 +273932,1540890564,1178860136,1 +273933,1540890565,1540890566,1 +273934,1540890566,1540890567,1 +273935,1540890567,1540890568,1 +273936,1540890568,1540890569,1 +273937,1540890569,1540890570,1 +273938,1540890570,1540890571,1 +273939,1540890571,1540890572,1 +273940,1540890572,1178859407,1 +274094,1540890726,1540890727,1 +274095,1540890727,1540890728,1 +274275,1540890907,1540890908,1 +274276,1540890908,1540890909,1 +274277,1540890909,1540890910,1 +274278,1540890910,1540890911,1 +274279,1540890911,1540890912,1 +274280,1540890912,1540890913,1 +274281,1540890913,1179200509,1 +277816,1540894448,1540894449,0 +277817,1540894449,360716311,0 +277818,1540894450,1540894451,0 +277819,1540894451,1540894452,0 +277820,1540894452,745984371,0 +277821,1540894453,1540894454,1 +277822,1540894454,360716816,1 +277823,1540894455,360714804,1 +277824,1540894456,360714807,1 +277827,1540894459,1540894460,1 +277828,1540894460,360719963,1 +277829,1540894461,745986936,1 +277830,1540894462,1540894463,1 +277831,1540894463,294250794,1 +277832,1540894464,1540894465,1 +277833,1540894465,1540894466,1 +277834,1540894466,1540894467,1 +277835,1540894467,1540894468,1 +277836,1540894468,1540894469,1 +277837,1540894469,1540894470,1 +277838,1540894470,1540894471,1 +277839,1540894471,1540894472,1 +277840,1540894472,1540894473,1 +277841,1540894473,1540894474,1 +277842,1540894474,1540894475,1 +277843,1540894475,1540894476,1 +277844,1540894476,1540894477,1 +277845,1540894477,1540894478,1 +277846,1540894478,1540894479,1 +277847,1540894479,1540894480,1 +277848,1540894480,1540894481,1 +277849,1540894481,1540894482,1 +277850,1540894482,1540894483,1 +277851,1540894483,1540894484,1 +277852,1540894484,1540894485,1 +277853,1540894485,1540894486,1 +277854,1540894486,1540894487,1 +277855,1540894487,1540894488,1 +277856,1540894488,1540894489,1 +277857,1540894489,1182463055,1 +277858,1540894490,1540894491,1 +277859,1540894491,1540894492,1 +277860,1540894492,1540894493,1 +277861,1540894493,1540894494,1 +277862,1540894494,1540894495,1 +277863,1540894495,1540894496,1 +277864,1540894496,1540894497,1 +277865,1540894497,1540894498,1 +277866,1540894498,1540894499,1 +277867,1540894499,1540894500,1 +277868,1540894500,1540894501,1 +277869,1540894501,1540894502,1 +277870,1540894502,1540894503,1 +277871,1540894503,1540894504,1 +277872,1540894504,1540894505,1 +277873,1540894505,1540894506,1 +277874,1540894506,1540894507,1 +277875,1540894507,1540894508,1 +277876,1540894508,1540894509,1 +277877,1540894509,1540894510,1 +277878,1540894510,1540894511,1 +277879,1540894511,1540894512,1 +277880,1540894512,1540894513,1 +277881,1540894513,1540894514,1 +277882,1540894514,1540894515,1 +277883,1540894515,1540894516,1 +277884,1540894516,1184179151,1 +277885,1540894517,1540894518,1 +277886,1540894518,1540894519,1 +277887,1540894519,1184179155,1 +277888,1540894520,1540894521,1 +277889,1540894521,1540894522,1 +277890,1540894522,1540894523,1 +277891,1540894523,1540894524,1 +277892,1540894524,1540894525,1 +277893,1540894525,1540894526,1 +277894,1540894526,1540894527,1 +277895,1540894527,1540894528,1 +277896,1540894528,1184179165,1 +277898,1540894530,1540894531,1 +277899,1540894531,1540894532,1 +277900,1540894532,1540894533,1 +277901,1540894533,1540894534,1 +277902,1540894534,1540894535,1 +277903,1540894535,1540894536,1 +277904,1540894536,1540894537,1 +277905,1540894537,1540894538,1 +277906,1540894538,1540894539,1 +277907,1540894539,1540894540,1 +277908,1540894540,1540894541,1 +277909,1540894541,1540894542,1 +277910,1540894542,1540894543,1 +277911,1540894543,1540894544,1 +277912,1540894544,1540894545,1 +277913,1540894545,1540894546,1 +277914,1540894546,1540894547,1 +277915,1540894547,1540894548,1 +277916,1540894548,1540894549,1 +277917,1540894549,1540894550,1 +277918,1540894550,1540894551,1 +277919,1540894551,1540894552,1 +277920,1540894552,1184175914,1 +277921,1540894553,1540894554,1 +277922,1540894554,1540894555,1 +277923,1540894555,1540894556,1 +277924,1540894556,1540894557,1 +277925,1540894557,1540894558,1 +277926,1540894558,1540894559,1 +277927,1540894559,1540894560,1 +277928,1540894560,1540894561,1 +277929,1540894561,1540894562,1 +277930,1540894562,1540894563,1 +277931,1540894563,1540894564,1 +277932,1540894564,1540894565,1 +277933,1540894565,1540894566,1 +277953,1540894585,1540894586,1 +277954,1540894586,1540894587,1 +277955,1540894587,1540894588,1 +277956,1540894588,1540894589,1 +277957,1540894589,1540894590,1 +277958,1540894590,1540894591,1 +277959,1540894591,1540894592,1 +277960,1540894592,1540894593,1 +277961,1540894593,1540894594,1 +277962,1540894594,1540894595,1 +277963,1540894595,1540894596,1 +277964,1540894596,1540894597,1 +277965,1540894597,1540894598,1 +277966,1540894598,1540894599,1 +277967,1540894599,1540894600,1 +277968,1540894600,1540894601,1 +277969,1540894601,1540894602,1 +277970,1540894602,1540894603,1 +277971,1540894603,1540894604,1 +277972,1540894604,1540894605,1 +277973,1540894605,1540894606,1 +277974,1540894606,1540894607,1 +277975,1540894607,1540894608,1 +277976,1540894608,1540894609,1 +277977,1540894609,1540894610,1 +277978,1540894610,1540894611,1 +277979,1540894611,1540894612,1 +277980,1540894612,1184179155,1 +277981,1540894613,1540894614,1 +277982,1540894614,1540894615,1 +277983,1540894615,1540894616,1 +277984,1540894616,1540894617,1 +277985,1540894617,1540894618,1 +277986,1540894618,1540894619,1 +277987,1540894619,1540894620,1 +277988,1540894620,1540894621,1 +277989,1540894621,1540894622,1 +277990,1540894622,1540894623,1 +277991,1540894623,1540894624,1 +277992,1540894624,1540894625,1 +277993,1540894625,1540894626,1 +277994,1540894626,1540894627,1 +277995,1540894627,1540894628,1 +277996,1540894628,1540894629,1 +277997,1540894629,1540894630,1 +277998,1540894630,1540894631,1 +277999,1540894631,1540894632,1 +278000,1540894632,1540894633,1 +278001,1540894633,1540894634,1 +278002,1540894634,1540894635,1 +278003,1540894635,1540894636,1 +278004,1540894636,1540894637,1 +278005,1540894637,1540894638,1 +278006,1540894638,1540894639,1 +278007,1540894639,1540894640,1 +278008,1540894640,1540894641,1 +278009,1540894641,1540894642,1 +278010,1540894642,1540894643,1 +278011,1540894643,1540894644,1 +278012,1540894644,1540894645,1 +278013,1540894645,1540894646,1 +278014,1540894646,1184181057,1 +278015,1540894647,1540894648,1 +278016,1540894648,1540894649,1 +278017,1540894649,1540894650,1 +278018,1540894650,1540894651,1 +278019,1540894651,1540894652,1 +278020,1540894652,1540894653,1 +278021,1540894653,1540894654,1 +278022,1540894654,1540894655,1 +278023,1540894655,1184182825,1 +278024,1540894656,1540894657,1 +278025,1540894657,1540894658,1 +278026,1540894658,1540894659,1 +278027,1540894659,1540894660,1 +278028,1540894660,1540894661,1 +278029,1540894661,1540894662,1 +278030,1540894662,1540894663,1 +278031,1540894663,1540894664,1 +278032,1540894664,1540894665,1 +278033,1540894665,1540894666,1 +278034,1540894666,1540894667,1 +278035,1540894667,1540894668,1 +278036,1540894668,1540894669,1 +278037,1540894669,1540894670,1 +278038,1540894670,1540894671,1 +278039,1540894671,1540894672,1 +278040,1540894672,1540894673,1 +278041,1540894673,1540894674,1 +278042,1540894674,1540894675,1 +278043,1540894675,1540894676,1 +278044,1540894676,1540894677,1 +278045,1540894677,1540894678,1 +278046,1540894678,1540894679,1 +278047,1540894679,1540894680,1 +278048,1540894680,1540894681,1 +278049,1540894681,1540894682,1 +278050,1540894682,1540894683,1 +278051,1540894683,1540894684,1 +278052,1540894684,1540894685,1 +278053,1540894685,1540894686,1 +278054,1540894686,1540894687,1 +278055,1540894687,1184179151,1 +278056,1540894688,1540894689,1 +278057,1540894689,1540894690,1 +278058,1540894690,1540894691,1 +278059,1540894691,1540894692,1 +278060,1540894692,1540894693,1 +278061,1540894693,1540894694,1 +278062,1540894694,1540894695,1 +278063,1540894695,1540894696,1 +278064,1540894696,1540894697,1 +278065,1540894697,1540894698,1 +278066,1540894698,1540894699,1 +278067,1540894699,1540894700,1 +278068,1540894700,1540894701,1 +278069,1540894701,1540894702,1 +278070,1540894702,1540894703,1 +278071,1540894703,1540894704,1 +278072,1540894704,1540894705,1 +278073,1540894705,1540894706,1 +278074,1540894706,1540894707,1 +278075,1540894707,1540894708,1 +278076,1540894708,1540894709,1 +278077,1540894709,1540894710,1 +278078,1540894710,1540894711,1 +278079,1540894711,1540894712,1 +278080,1540894712,1540894713,1 +278081,1540894713,1540894714,1 +278082,1540894714,1540894715,1 +278083,1540894715,1540894716,1 +278084,1540894716,1540894717,1 +278085,1540894717,1540894718,1 +278086,1540894718,1540894719,1 +278087,1540894719,1540894720,1 +278088,1540894720,1540894721,1 +278089,1540894721,1540894722,1 +278090,1540894722,1540894723,1 +278091,1540894723,1540894724,1 +278092,1540894724,1540894725,1 +278093,1540894725,1540894726,1 +278094,1540894726,1540894727,1 +278095,1540894727,1540894728,1 +278096,1540894728,1540894729,1 +278097,1540894729,1540894730,1 +278098,1540894730,1540894731,1 +278099,1540894731,1540894732,1 +278100,1540894732,1184187525,1 +278101,1540894733,1540894734,1 +278102,1540894734,1540894735,1 +278103,1540894735,1184179165,1 +278844,1540895476,1540895477,1 +278845,1540895477,1540895478,1 +278846,1540895478,1540895479,1 +278847,1540895479,1540895480,1 +278848,1540895480,1540895481,1 +278849,1540895481,1540895482,1 +278850,1540895482,1540895483,1 +278851,1540895483,1540895484,1 +278852,1540895484,1540895485,1 +278853,1540895485,1540895486,1 +278854,1540895486,1540895487,1 +278855,1540895487,1540895488,1 +278856,1540895488,1540895489,1 +278857,1540895489,1540895490,1 +278858,1540895490,1540895491,1 +278859,1540895491,1540895492,1 +278860,1540895492,1540895493,1 +278861,1540895493,1540895494,1 +278862,1540895494,1540895495,1 +278863,1540895495,1540895496,1 +278864,1540895496,1540895497,1 +278865,1540895497,1540895498,1 +278866,1540895498,1184187437,1 +278867,1540895499,1540895500,1 +278868,1540895500,1540895501,1 +278869,1540895501,1540895502,1 +278870,1540895502,1540895503,1 +278871,1540895503,1540895504,1 +278872,1540895504,1540895505,1 +278873,1540895505,1540895506,1 +278874,1540895506,1540895507,1 +278875,1540895507,1540895508,1 +278876,1540895508,1540895509,1 +278877,1540895509,1540895510,1 +278878,1540895510,1540895511,1 +278879,1540895511,1540895512,1 +278880,1540895512,1540895513,1 +278881,1540895513,1540895514,1 +278882,1540895514,1540895515,1 +278883,1540895515,1540895516,1 +278884,1540895516,1540895517,1 +278885,1540895517,1540895518,1 +278886,1540895518,1540895519,1 +278887,1540895519,1540895520,1 +278888,1540895520,1540895521,1 +278889,1540895521,1540895522,1 +278890,1540895522,1540895523,1 +278891,1540895523,1540895524,1 +278892,1540895524,1540895525,1 +278893,1540895525,1540895526,1 +278894,1540895526,1540895527,1 +278895,1540895527,1540895528,1 +278896,1540895528,1540895529,1 +278897,1540895529,1540895530,1 +278898,1540895530,1540895531,1 +278899,1540895531,1540895532,1 +278900,1540895532,1540895533,1 +278901,1540895533,1540895534,1 +278902,1540895534,1540895535,1 +278903,1540895535,1540895536,1 +278904,1540895536,1540895537,1 +278905,1540895537,1540895538,1 +278906,1540895538,1540895539,1 +278907,1540895539,1540895540,1 +278908,1540895540,1540895541,1 +278909,1540895541,1540895542,1 +278910,1540895542,1540895543,1 +278911,1540895543,1540895544,1 +278912,1540895544,1540895545,1 +278913,1540895545,1540895546,1 +278914,1540895546,1540895547,1 +278915,1540895547,1540895548,1 +278916,1540895548,1540895549,1 +278917,1540895549,1540895550,1 +278918,1540895550,1540895551,1 +278919,1540895551,1540895552,1 +278920,1540895552,1540895553,1 +278921,1540895553,1540895554,1 +278922,1540895554,1184257675,1 +278923,1540895555,1540895556,1 +278924,1540895556,1540895557,1 +278925,1540895557,1540895558,1 +278926,1540895558,1540895559,1 +278927,1540895559,1540895560,1 +278928,1540895560,1540895561,1 +278929,1540895561,1540895562,1 +278930,1540895562,1540895563,1 +278931,1540895563,1540895564,1 +278932,1540895564,1540895565,1 +278933,1540895565,1540895566,1 +278934,1540895566,1540895567,1 +278935,1540895567,1540895568,1 +278936,1540895568,1540895569,1 +278937,1540895569,1540895570,1 +278938,1540895570,1540895571,1 +278939,1540895571,1540895572,1 +278940,1540895572,1540895573,1 +278941,1540895573,1184259750,1 +278942,1540895574,1540895575,1 +278943,1540895575,1540895576,1 +278944,1540895576,1540895577,1 +278945,1540895577,1540895578,1 +278946,1540895578,1540895579,1 +278947,1540895579,1540895580,1 +278948,1540895580,1540895581,1 +278949,1540895581,1540895582,1 +278950,1540895582,1540895583,1 +278951,1540895583,1540895584,1 +278952,1540895584,1540895585,1 +278953,1540895585,1540895586,1 +278954,1540895586,1540895587,1 +278955,1540895587,1540895588,1 +278956,1540895588,1540895589,1 +278957,1540895589,1540895590,1 +278958,1540895590,1540895591,1 +278959,1540895591,1540895592,1 +278960,1540895592,1184259745,1 +278961,1540895593,1540895594,1 +278962,1540895594,1540895595,1 +278963,1540895595,1540895596,1 +278964,1540895596,1540895597,1 +278965,1540895597,1184260710,1 +278966,1540895598,1540895599,1 +278967,1540895599,1540895600,1 +278968,1540895600,1540895601,1 +278969,1540895601,1184260710,1 +278970,1540895602,1540895603,1 +278971,1540895603,1540895604,1 +278972,1540895604,1371125536,1 +278973,1540895605,1540895606,1 +278974,1540895606,1540895607,1 +278975,1540895607,1540895608,1 +278976,1540895608,1371125449,1 +278977,1540895609,704804636,1 +278978,1540895610,1424068459,1 +278979,1540895611,1540895612,1 +278980,1540895612,1540895613,1 +278981,1540895613,1540895614,1 +278982,1540895614,1540895615,1 +278983,1540895615,1540895616,1 +278984,1540895616,1540895617,1 +278985,1540895617,1540895618,1 +278986,1540895618,1540895619,1 +278987,1540895619,1540895620,1 +278988,1540895620,1540895621,1 +278989,1540895621,1540895622,1 +278990,1540895622,1540895623,1 +278991,1540895623,1540895624,1 +278992,1540895624,1184257540,1 +279064,1540895696,793529835,1 +279065,1540895697,294203310,1 +280298,1540896930,1540896931,0 +280299,1540896931,597692699,0 +280300,1540896932,365118578,0 +280301,1540896933,1540896934,0 +280302,1540896934,1540896935,0 +280303,1540896935,1540896936,0 +280304,1540896936,560576458,0 +280305,1540896937,1540896938,0 +280306,1540896938,560576461,0 +280307,1540896939,360475201,1 +281454,1540898086,1540898087,1 +281455,1540898087,279590132,1 +288292,1540904924,360475454,1 +288293,1540904925,1540904926,0 +288294,1540904926,360475454,0 +288295,1540904927,338485292,0 +288296,1540904928,246588554,0 +288297,1540904929,581291049,1 +288298,1540904930,360476174,1 +288299,1540904931,360475935,0 +288300,1540904932,577419403,1 +288301,1540904933,360476329,1 +288505,1540905137,360730598,1 +288506,1540905138,705073941,1 +288507,1540905139,360729197,1 +288508,1540905140,361194477,1 +288509,1540905141,361196118,1 +288510,1540905142,353244893,1 +288511,1540905143,353244898,1 +288512,1540905144,1540905145,0 +288513,1540905145,1540905146,0 +288514,1540905146,365120166,0 +288515,1540905147,694770163,0 +288516,1540905148,1540905149,0 +288517,1540905149,365119552,0 +288518,1540905150,559939139,1 +288519,1540905151,428468067,1 +288520,1540905152,1540905153,0 +288521,1540905153,360476027,0 +288522,1540905154,360728743,1 +288523,1540905155,1540905156,1 +288524,1540905156,1540905157,1 +288525,1540905157,1540905158,1 +288526,1540905158,360728170,1 +288527,1540905159,360728174,1 +288528,1540905160,360470321,1 +288529,1540905161,360470594,1 +288530,1540905162,1540905163,1 +288531,1540905163,1540905164,1 +288532,1540905164,360471442,1 +288533,1540905165,360472241,1 +288534,1540905166,705979164,0 +288535,1540905167,353245029,0 +288536,1540905168,1540905169,0 +288537,1540905169,353245877,0 +288538,1540905170,1540905171,0 +288539,1540905171,1540905172,0 +288540,1540905172,1540905173,0 +288541,1540905173,353245634,0 +288542,1540905174,365308200,1 +288543,1540905175,1540905176,1 +288544,1540905176,360467988,1 +288545,1540905177,360473559,1 +288546,1540905178,1540905179,1 +288547,1540905179,360468326,1 +288548,1540905180,597692580,0 +288851,1540905483,360467621,0 +288860,1540905492,1540905493,0 +288861,1540905493,1540905494,0 +288862,1540905494,1285491853,0 +288863,1540905495,1540905496,0 +288864,1540905496,1540905497,0 +288865,1540905497,1540905498,0 +288866,1540905498,272554684,0 +288867,1540905499,1540905500,0 +288868,1540905500,1540905501,0 +288869,1540905501,272554680,0 +288870,1540905502,1285491856,0 +288871,1540905503,1540905504,0 +288872,1540905504,1540905505,0 +288873,1540905505,1285491905,0 +288876,1540905508,1540905509,1 +288877,1540905509,272554420,1 +288932,1540905564,360476071,0 +288933,1540905565,792056477,1 +288934,1540905566,797375713,0 +288935,1540905567,985968898,1 +288936,1540905568,360208495,1 +288937,1540905569,737998288,1 +288938,1540905570,1540905571,1 +288939,1540905571,279590321,1 +288940,1540905572,279590323,1 +288941,1540905573,279590306,1 +288942,1540905574,279590303,0 +288943,1540905575,279590300,0 +288944,1540905576,279589959,0 +288953,1540905585,363975098,0 +288954,1540905586,972481961,0 +288955,1540905587,1540905588,0 +288956,1540905588,1540905589,0 +288957,1540905589,972481712,0 +288958,1540905590,1540905591,0 +288959,1540905591,1540905592,0 +288960,1540905592,1540905593,0 +288961,1540905593,1030688861,0 +288962,1540905594,1540905595,0 +288963,1540905595,1030689874,0 +288964,1540905596,1540905597,0 +288965,1540905597,1030688899,0 +288966,1540905598,1030689019,1 +288967,1540905599,1540905600,0 +288968,1540905600,1036415436,0 +288969,1540905601,1036415461,0 +288970,1540905602,1540905603,0 +288971,1540905603,1036415417,0 +288972,1540905604,360235270,1 +288973,1540905605,360201708,1 +288974,1540905606,1030323737,0 +288975,1540905607,1540905608,1 +288976,1540905608,1540905609,1 +288977,1540905609,1030313183,1 +288978,1540905610,1540905611,0 +288979,1540905611,716888879,0 +288980,1540905612,716888818,0 +288981,1540905613,360191657,1 +288982,1540905614,360191658,1 +288983,1540905615,1030313181,1 +288984,1540905616,705062339,0 +292445,1540909077,1285491827,0 +292446,1540909078,1540909079,0 +292447,1540909079,1285491906,0 +292452,1540909084,706854252,0 +292453,1540909085,1540909086,0 +292454,1540909086,1540909087,0 +292455,1540909087,1540909088,0 +292456,1540909088,1285491906,0 +292457,1540909089,1540909090,1 +292458,1540909090,1540909091,1 +292459,1540909091,1285491942,1 +292460,1540909092,1540909093,0 +292461,1540909093,1540909094,0 +292462,1540909094,1540909095,0 +292463,1540909095,1285491869,0 +292464,1540909096,1540909097,0 +292465,1540909097,1540909098,0 +292466,1540909098,1285491841,0 +292472,1540909104,1285491868,0 +292473,1540909105,1540909106,0 +292474,1540909106,1285491898,0 +292475,1540909107,1540909108,0 +292476,1540909108,1540909109,0 +292477,1540909109,1285491827,0 +292478,1540909110,1540909111,0 +292479,1540909111,1285491853,0 +292480,1540909112,1540909113,0 +292492,1540909124,1540909125,0 +292493,1540909125,1540909126,0 +292494,1540909126,1540909127,0 +292495,1540909127,1540909128,0 +292496,1540909128,1540909129,0 +292497,1540909129,1285491836,0 +292498,1540909130,1540909131,0 +292499,1540909131,1285491927,0 +292500,1540909132,1540909133,0 +292501,1540909133,272554421,0 +292502,1540909134,1285491855,0 +292503,1540909135,1285491868,0 +292505,1540909137,1540909138,0 +292506,1540909138,1540909139,0 +292507,1540909139,1540909140,0 +292508,1540909140,1540909141,0 +292509,1540909141,706854268,0 +292510,1540909142,1285491932,0 +292511,1540909143,566803328,0 +292512,1540909144,1285491943,0 +292513,1540909145,1285491866,0 +292514,1540909146,1540909147,0 +292515,1540909147,566803346,0 +292516,1540909148,566803347,0 +292517,1540909149,597693485,0 +292521,1540909153,1540909154,0 +292522,1540909154,1285491813,0 +292523,1540909155,1285491892,0 +292524,1540909156,1540909157,0 +292525,1540909157,1285491828,0 +292604,1540909236,1540909237,1 +292605,1540909237,1291955686,1 +292606,1540909238,1540909239,1 +292607,1540909239,1540909240,1 +292608,1540909240,1291955701,1 +292609,1540909241,1540909242,1 +292610,1540909242,1291955687,1 +292611,1540909243,1540909244,1 +292612,1540909244,1540909245,1 +292613,1540909245,1540909246,1 +292614,1540909246,1540909247,1 +292615,1540909247,974066614,1 +292616,1540909248,1540909249,0 +292617,1540909249,1540909250,0 +292618,1540909250,1540909251,0 +292619,1540909251,360215100,0 +292620,1540909252,1540909253,0 +292621,1540909253,360221715,0 +292622,1540909254,360221716,0 +303639,1540920271,1540920272,0 +303640,1540920272,1540920273,0 +303641,1540920273,36645010,0 +303642,1540920274,1540920275,0 +303643,1540920275,801467980,0 +303644,1540920276,1540920277,0 +303645,1540920277,936804451,0 +303646,1540920278,1540920279,0 +303647,1540920279,1540920280,0 +303648,1540920280,1540920281,0 +303649,1540920281,1540920282,0 +303650,1540920282,1540920283,0 +303651,1540920283,1540920284,0 +303652,1540920284,1540920285,0 +303653,1540920285,559939055,0 +303654,1540920286,1540920287,0 +303655,1540920287,347776878,0 +303656,1540920288,1540920289,0 +303657,1540920289,597693501,0 +303658,1540920290,1540920291,0 +303659,1540920291,1285491928,0 +303660,1540920292,1540920293,0 +303661,1540920293,1540920294,0 +303662,1540920294,1540920295,0 +303663,1540920295,1540920296,0 +303664,1540920296,1285491817,0 +303665,1540920297,1540920298,0 +303666,1540920298,1540920299,0 +303667,1540920299,1540920300,0 +303668,1540920300,1540920301,0 +303669,1540920301,559938656,0 +303670,1540920302,1540920303,0 +303671,1540920303,1540920304,0 +303672,1540920304,352706645,0 +303673,1540920305,36643968,0 +303674,1540920306,1540920307,0 +303675,1540920307,1540920308,0 +303676,1540920308,1540920309,0 +303677,1540920309,1540920310,0 +303678,1540920310,1540920311,0 +303679,1540920311,1540920312,0 +303680,1540920312,583229701,0 +303681,1540920313,1540920314,0 +303682,1540920314,597692598,0 +303683,1540920315,1540920316,0 +303684,1540920316,1540920317,0 +303685,1540920317,597692667,0 +303686,1540920318,1540920319,0 +303687,1540920319,1540920320,0 +303688,1540920320,1540920321,0 +303689,1540920321,1013433823,0 +303690,1540920322,1305716359,1 +305877,1540922509,1540922510,1 +305878,1540922510,1540922511,1 +305879,1540922511,1307354394,1 +305880,1540922512,1307354678,1 +305881,1540922513,1307354343,1 +305882,1540922514,1540922515,1 +305883,1540922515,1307354443,1 +305884,1540922516,1307354796,1 +305885,1540922517,1307354358,1 +305886,1540922518,1307354617,1 +305887,1540922519,1540922520,1 +305888,1540922520,1540922521,1 +305889,1540922521,1540922522,1 +305890,1540922522,1540922523,1 +305891,1540922523,1540922524,1 +305892,1540922524,1540922525,1 +305893,1540922525,1307354693,1 +305894,1540922526,1345223597,1 +305895,1540922527,1307354335,1 +305896,1540922528,1307354506,1 +305897,1540922529,1307354469,1 +305898,1540922530,1540922531,1 +305899,1540922531,1307354648,1 +305900,1540922532,1540922533,1 +305901,1540922533,1307354648,1 +305902,1540922534,1307354469,1 +305903,1540922535,1540922536,1 +305904,1540922536,1307354831,1 +305905,1540922537,1307354740,1 +305906,1540922538,1307354869,1 +305907,1540922539,1540922540,1 +305908,1540922540,1540922541,1 +305909,1540922541,1307354431,1 +305910,1540922542,1307354343,1 +305911,1540922543,1540922544,1 +305912,1540922544,1307354783,1 +305913,1540922545,1307354615,1 +305914,1540922546,1307354740,1 +305915,1540922547,1307354842,1 +305916,1540922548,1540922549,1 +305917,1540922549,1540922550,1 +305918,1540922550,1307354826,1 +305919,1540922551,1540922552,1 +305920,1540922552,1540922553,1 +305921,1540922553,1345222622,1 +305922,1540922554,1540922555,1 +305923,1540922555,1307354563,1 +305924,1540922556,1540922557,1 +305925,1540922557,1307354762,1 +305926,1540922558,1307354692,1 +305927,1540922559,1540922560,1 +305928,1540922560,1540922561,1 +305929,1540922561,1540922562,1 +305930,1540922562,1307354813,1 +305931,1540922563,1307354424,1 +305932,1540922564,1307354660,1 +305933,1540922565,372787085,1 +305934,1540922566,1540922567,1 +305935,1540922567,1307354625,1 +305936,1540922568,1307354858,1 +305937,1540922569,1540922570,1 +305938,1540922570,1540922571,1 +305939,1540922571,1540922572,1 +305940,1540922572,1540922573,1 +305941,1540922573,1307354820,1 +305942,1540922574,1307354871,1 +305943,1540922575,1307354761,1 +305944,1540922576,1540922577,1 +305945,1540922577,1540922578,1 +305946,1540922578,1540922579,1 +305947,1540922579,1540922580,1 +305948,1540922580,1540922581,1 +305949,1540922581,1540922582,1 +305950,1540922582,1540922583,1 +305951,1540922583,1540922584,1 +305952,1540922584,1540922585,1 +305953,1540922585,1540922586,1 +305954,1540922586,1540922587,1 +305955,1540922587,1540922588,1 +305956,1540922588,1307354602,1 +305957,1540922589,1540922590,1 +305958,1540922590,1540922591,1 +305959,1540922591,1307354829,1 +305960,1540922592,1307354579,1 +305961,1540922593,1540922594,1 +305962,1540922594,1307354624,1 +305963,1540922595,1540922596,1 +305964,1540922596,1540922597,1 +305965,1540922597,1540922598,1 +305966,1540922598,1540922599,1 +305967,1540922599,1307354641,1 +305968,1540922600,1307354694,1 +305969,1540922601,1307354836,1 +305970,1540922602,1540922603,1 +305971,1540922603,1540922604,1 +305972,1540922604,1307354694,1 +305973,1540922605,1540922606,1 +305974,1540922606,1540922607,1 +305975,1540922607,1540922608,1 +305976,1540922608,1540922609,1 +305977,1540922609,1307354617,1 +305978,1540922610,1540922611,1 +305979,1540922611,1540922612,1 +305980,1540922612,1540922613,1 +305981,1540922613,1540922614,1 +305982,1540922614,1540922615,1 +305983,1540922615,1540922616,1 +305984,1540922616,1540922617,1 +305985,1540922617,1540922618,1 +305986,1540922618,1540922619,1 +305987,1540922619,1540922620,1 +305988,1540922620,1540922621,1 +305989,1540922621,1540922622,1 +305990,1540922622,1540922623,1 +305991,1540922623,1540922624,1 +305992,1540922624,1540922625,1 +305993,1540922625,1307354715,1 +305994,1540922626,1540922627,1 +305995,1540922627,1540922628,1 +305996,1540922628,1307354824,1 +305997,1540922629,1307354331,1 +305998,1540922630,1307354744,1 +305999,1540922631,1540922632,1 +306000,1540922632,1307354775,1 +306001,1540922633,1307354606,1 +306002,1540922634,1307354658,1 +306003,1540922635,1540922636,1 +306004,1540922636,1307354360,1 +306005,1540922637,1307354743,1 +306006,1540922638,1307354427,1 +306007,1540922639,1540922640,1 +306008,1540922640,1307354831,1 +306009,1540922641,1540922642,1 +306010,1540922642,1307354689,1 +306011,1540922643,1540922644,1 +306012,1540922644,1540922645,1 +306013,1540922645,1307354338,1 +306014,1540922646,1540922647,1 +306015,1540922647,1540922648,1 +306016,1540922648,1540922649,1 +306017,1540922649,1307354464,1 +306018,1540922650,1540922651,1 +306019,1540922651,1307354773,1 +306020,1540922652,1307354833,1 +306021,1540922653,1540922654,1 +306022,1540922654,1307354399,1 +306023,1540922655,1307354717,1 +306024,1540922656,1540922657,1 +306025,1540922657,1540922658,1 +306026,1540922658,1540922659,1 +306027,1540922659,1307354363,1 +306028,1540922660,1540922661,1 +306029,1540922661,1307354444,1 +306030,1540922662,1307354683,1 +306031,1540922663,1345217922,1 +306032,1540922664,1307367407,1 +306033,1540922665,1540922666,1 +306034,1540922666,1307367449,1 +306035,1540922667,1540922668,1 +306036,1540922668,1540922669,1 +306037,1540922669,1540922670,1 +306038,1540922670,1307367285,1 +306039,1540922671,1307367420,1 +306040,1540922672,1307367439,1 +306041,1540922673,1307367406,1 +306042,1540922674,1540922675,1 +306043,1540922675,1307367237,1 +306044,1540922676,1540922677,1 +306045,1540922677,1540922678,1 +306046,1540922678,1540922679,1 +306047,1540922679,788870479,1 +306048,1540922680,1540922681,1 +306049,1540922681,1540922682,1 +306050,1540922682,1540922683,1 +306051,1540922683,1540922684,1 +306052,1540922684,1540922685,1 +306053,1540922685,1540922686,1 +306054,1540922686,1540922687,1 +306055,1540922687,1540922688,1 +306056,1540922688,1540922689,1 +306057,1540922689,1540922690,1 +306058,1540922690,1540922691,1 +306059,1540922691,1307367294,1 +306060,1540922692,1540922693,1 +306061,1540922693,1307367256,1 +306062,1540922694,1540922695,1 +306063,1540922695,1307367466,1 +306064,1540922696,1307367416,1 +306065,1540922697,1307367284,1 +306066,1540922698,1307367203,1 +306067,1540922699,1540922700,1 +306068,1540922700,1540922701,1 +306069,1540922701,1540922702,1 +306070,1540922702,1307367470,1 +306071,1540922703,1307367195,1 +306072,1540922704,1307367312,1 +306073,1540922705,1307367428,1 +306074,1540922706,1307367464,1 +306075,1540922707,1540922708,1 +306076,1540922708,1307367349,1 +306077,1540922709,1540922710,1 +306078,1540922710,1307367383,1 +306079,1540922711,1540922712,1 +306080,1540922712,1540922713,1 +306081,1540922713,1540922714,1 +306082,1540922714,1540922715,1 +306083,1540922715,1307367280,1 +306084,1540922716,1540922717,1 +306085,1540922717,1540922718,1 +306086,1540922718,1540922719,1 +306087,1540922719,1540922720,1 +306088,1540922720,1307367208,1 +306089,1540922721,1540922722,1 +306090,1540922722,1540922723,1 +306091,1540922723,1307367187,1 +306092,1540922724,1540922725,1 +306093,1540922725,1540922726,1 +306094,1540922726,1540922727,1 +306095,1540922727,1540922728,1 +306096,1540922728,1540922729,1 +306097,1540922729,1307367455,1 +306098,1540922730,1307367314,1 +306099,1540922731,1307367443,1 +306100,1540922732,1307367256,1 +306101,1540922733,1540922734,1 +306102,1540922734,1540922735,1 +306103,1540922735,1307367384,1 +306104,1540922736,1540922737,1 +306105,1540922737,1540922738,1 +306106,1540922738,1540922739,1 +306107,1540922739,1540922740,1 +306108,1540922740,1540922741,1 +306109,1540922741,1307367266,1 +306110,1540922742,788870476,1 +306111,1540922743,1307367315,1 +306112,1540922744,1307367467,1 +306113,1540922745,1307367225,1 +306114,1540922746,1540922747,1 +306115,1540922747,1540922748,1 +306116,1540922748,1540922749,1 +306117,1540922749,1540922750,1 +306118,1540922750,1540922751,1 +306119,1540922751,1540922752,1 +306120,1540922752,1540922753,1 +306121,1540922753,1540922754,1 +306122,1540922754,1540922755,1 +306123,1540922755,1540922756,1 +306124,1540922756,1540922757,1 +306125,1540922757,1540922758,1 +306126,1540922758,1540922759,1 +306127,1540922759,1540922760,1 +306128,1540922760,1540922761,1 +306129,1540922761,1307367186,1 +306130,1540922762,1307367345,1 +306131,1540922763,1307367469,1 +306132,1540922764,1307367233,1 +306133,1540922765,1307367417,1 +306134,1540922766,1540922767,1 +306135,1540922767,1307367348,1 +306136,1540922768,1540922769,1 +306137,1540922769,1307367357,1 +306138,1540922770,1307367198,1 +306139,1540922771,1307367360,1 +306140,1540922772,1540922773,1 +306141,1540922773,1540922774,1 +306142,1540922774,1540922775,1 +306143,1540922775,1540922776,1 +306144,1540922776,1540922777,1 +306145,1540922777,1345657435,1 +306146,1540922778,1307367413,1 +306147,1540922779,1540922780,1 +306148,1540922780,1540922781,1 +306149,1540922781,1540922782,1 +306150,1540922782,625912020,1 +306151,1540922783,1540922784,1 +306152,1540922784,1540922785,1 +306153,1540922785,1540922786,1 +306154,1540922786,625912025,1 +306155,1540922787,625912030,1 +306156,1540922788,625912041,1 +306157,1540922789,1307367422,1 +306158,1540922790,1540922791,1 +306159,1540922791,1540922792,1 +306160,1540922792,1307367198,1 +306161,1540922793,1540922794,1 +306162,1540922794,1540922795,1 +306163,1540922795,1540922796,1 +306164,1540922796,1307367473,1 +306165,1540922797,1307367341,1 +306166,1540922798,1540922799,1 +306167,1540922799,625912058,1 +306168,1540922800,372786481,1 +306169,1540922801,1307367426,1 +306170,1540922802,1343085694,1 +306171,1540922803,1540922804,1 +306172,1540922804,1540922805,1 +306173,1540922805,1540922806,1 +306174,1540922806,1540922807,1 +306175,1540922807,1540922808,1 +306176,1540922808,625912020,1 +306177,1540922809,1540922810,1 +306178,1540922810,1540922811,1 +306179,1540922811,1307367444,1 +306888,1540923520,365970667,1 +306889,1540923521,1540923522,1 +306890,1540923522,365970492,1 +306891,1540923523,1540923524,0 +306892,1540923524,1307601639,0 +307341,1540923973,937378209,1 +307360,1540923992,1308321628,1 +307363,1540923995,1308321617,1 +307366,1540923998,1540923999,1 +307367,1540923999,1308321628,1 +307368,1540924000,1540924001,1 +307369,1540924001,1308321617,1 +311895,1540928527,1333798922,1 +311896,1540928528,1333798996,1 +311897,1540928529,1540928530,1 +311898,1540928530,1540928531,1 +311899,1540928531,1540928532,1 +311900,1540928532,1333799038,1 +311901,1540928533,1540928534,1 +311902,1540928534,1540928535,1 +311903,1540928535,1540928536,1 +311904,1540928536,1540928537,1 +311905,1540928537,1333799040,1 +311906,1540928538,1540928539,1 +311907,1540928539,1333798935,1 +311946,1540928578,1540928579,1 +311947,1540928579,1540928580,1 +311948,1540928580,1540928581,1 +311949,1540928581,774085174,1 +311976,1540928608,1333810242,1 +311977,1540928609,1333810001,1 +311978,1540928610,1333810083,1 +311979,1540928611,1540928612,1 +311980,1540928612,1333810075,1 +311981,1540928613,1333810005,1 +311982,1540928614,1540928615,1 +311983,1540928615,1540928616,1 +311984,1540928616,1540928617,1 +311985,1540928617,1540928618,1 +311986,1540928618,1540928619,1 +311987,1540928619,1540928620,1 +311988,1540928620,1540928621,1 +311989,1540928621,1333810280,1 +312022,1540928654,774085175,1 +312023,1540928655,1333810171,1 +312024,1540928656,1333799040,1 +312049,1540928681,1333810242,1 +312050,1540928682,1540928683,1 +312051,1540928683,1333798935,1 +312053,1540928685,1333810075,1 +312054,1540928686,1333810274,1 +312100,1540928732,1333799046,1 +312661,1540929293,1540929294,1 +312662,1540929294,1540929295,1 +312663,1540929295,1540929296,1 +312664,1540929296,1540929297,1 +312665,1540929297,1333878522,1 +312666,1540929298,1540929299,1 +312667,1540929299,1333878425,1 +312668,1540929300,1333877969,1 +312669,1540929301,1540929302,1 +312677,1540929309,1540929310,1 +312678,1540929310,1540929311,1 +312679,1540929311,1540929312,1 +312680,1540929312,1333878225,1 +312681,1540929313,1540929314,1 +312682,1540929314,1540929315,1 +312683,1540929315,1333878537,1 +312684,1540929316,1540929317,1 +312685,1540929317,1540929318,1 +312686,1540929318,1333878262,1 +312687,1540929319,1333878262,1 +312688,1540929320,965013913,1 +312689,1540929321,1540929322,1 +312690,1540929322,1540929323,1 +312691,1540929323,1540929324,1 +312692,1540929324,1333877903,1 +312693,1540929325,1540929326,1 +312694,1540929326,1540929327,1 +312695,1540929327,1540929328,1 +312696,1540929328,1333878640,1 +312756,1540929388,1333878341,1 +312757,1540929389,1540929390,1 +312758,1540929390,1540929391,1 +312759,1540929391,1540929392,1 +312760,1540929392,1540929393,1 +312761,1540929393,1540929394,1 +312762,1540929394,1540929395,1 +312763,1540929395,1540929396,1 +312764,1540929396,1540929397,1 +312765,1540929397,1333878746,1 +312766,1540929398,1333878539,1 +312767,1540929399,1540929400,1 +312768,1540929400,1333878591,1 +312769,1540929401,1333878522,1 +312770,1540929402,1540929403,1 +312771,1540929403,1540929404,1 +312772,1540929404,1540929405,1 +312773,1540929405,1540929406,1 +312774,1540929406,1540929407,1 +312775,1540929407,1540929408,1 +312776,1540929408,1540929409,1 +312777,1540929409,1540929410,1 +312778,1540929410,1540929411,1 +312779,1540929411,1333878341,1 +312780,1540929412,1540929413,1 +312781,1540929413,1540929414,1 +312782,1540929414,1540929415,1 +312783,1540929415,1333878736,1 +312784,1540929416,1540929417,1 +312785,1540929417,1540929418,1 +312786,1540929418,1333877956,1 +312787,1540929419,1540929420,1 +312788,1540929420,1374266416,1 +312789,1540929421,1540929422,1 +312790,1540929422,1333878315,1 +312791,1540929423,1540929424,1 +312792,1540929424,1333878542,1 +312793,1540929425,1540929426,1 +312794,1540929426,1540929427,1 +312795,1540929427,1540929428,1 +312796,1540929428,1333878003,1 +312797,1540929429,1333877887,1 +312798,1540929430,1540929431,1 +312799,1540929431,1540929432,1 +312800,1540929432,1540929433,1 +312801,1540929433,1333878278,1 +312802,1540929434,1333878731,1 +312803,1540929435,1333877820,1 +312804,1540929436,1540929437,1 +312805,1540929437,1540929438,1 +312806,1540929438,1196620820,1 +312807,1540929439,1540929440,1 +312808,1540929440,1540929441,1 +312809,1540929441,1540929442,1 +312810,1540929442,1540929443,1 +312811,1540929443,1540929444,1 +312816,1540929448,1333878701,1 +312817,1540929449,1333878028,1 +312818,1540929450,1333878746,1 +312819,1540929451,1540929452,1 +312820,1540929452,1540929453,1 +312821,1540929453,1540929454,1 +312822,1540929454,1540929455,1 +312823,1540929455,1540929456,1 +312824,1540929456,1540929457,1 +312825,1540929457,1540929458,1 +312826,1540929458,1540929459,1 +312827,1540929459,1540929460,1 +312828,1540929460,1540929461,1 +312829,1540929461,1333878043,1 +312830,1540929462,1540929463,1 +312831,1540929463,1333877840,1 +312832,1540929464,1540929465,1 +312833,1540929465,1540929466,1 +312834,1540929466,1540929467,1 +312835,1540929467,1540929468,1 +312836,1540929468,1333878425,1 +312837,1540929469,1540929470,1 +312838,1540929470,1540929471,1 +312839,1540929471,1540929472,1 +312852,1540929484,1540929485,1 +312853,1540929485,1540929486,1 +312854,1540929486,1540929487,1 +312855,1540929487,1333878539,1 +312856,1540929488,1540929489,1 +312857,1540929489,1540929490,1 +312858,1540929490,1540929491,1 +312859,1540929491,1540929492,1 +312860,1540929492,1540929493,1 +312861,1540929493,1333878189,1 +312862,1540929494,1333878313,1 +312875,1540929507,1333878003,1 +312876,1540929508,1333878508,1 +312877,1540929509,1540929510,1 +312878,1540929510,1333877887,1 +312879,1540929511,1540929512,1 +312880,1540929512,1333878701,1 +313046,1540929678,1540929679,1 +313047,1540929679,1333810013,1 +313048,1540929680,1333810001,1 +313068,1540929700,1540929701,1 +313069,1540929701,1540929702,1 +313070,1540929702,1540929703,1 +313118,1540929750,1540929751,1 +313119,1540929751,1333799038,1 +313126,1540929758,1540929759,1 +313127,1540929759,1540929760,1 +313128,1540929760,1540929761,1 +313129,1540929761,1540929762,1 +313130,1540929762,1540929763,1 +313131,1540929763,1540929764,1 +313132,1540929764,1540929765,1 +313133,1540929765,1540929766,1 +313134,1540929766,1540929767,1 +313135,1540929767,1540929768,1 +313136,1540929768,1540929769,1 +313137,1540929769,1540929770,1 +313138,1540929770,1540929771,1 +313139,1540929771,1540929772,1 +313140,1540929772,1540929773,1 +313141,1540929773,1540929774,1 +313142,1540929774,1540929775,1 +313143,1540929775,1334277131,1 +313144,1540929776,1540929777,1 +313145,1540929777,1540929778,1 +313146,1540929778,1540929779,1 +313147,1540929779,1540929780,1 +313148,1540929780,1540929781,1 +313149,1540929781,1540929782,1 +313150,1540929782,1540929783,1 +313151,1540929783,1540929784,1 +313152,1540929784,1540929785,1 +313153,1540929785,1334277223,1 +313154,1540929786,1540929787,1 +313155,1540929787,1540929788,1 +313156,1540929788,1540929789,1 +313157,1540929789,1540929790,1 +313158,1540929790,1345686502,1 +313159,1540929791,1540929792,1 +313160,1540929792,1540929793,1 +313161,1540929793,1540929794,1 +313162,1540929794,1540929795,1 +313163,1540929795,1334277203,1 +313164,1540929796,1540929797,1 +313165,1540929797,1540929798,1 +313166,1540929798,1540929799,1 +313167,1540929799,1345228064,1 +313168,1540929800,1540929801,1 +313169,1540929801,1334277198,1 +313170,1540929802,1540929803,1 +313171,1540929803,1334277194,1 +313172,1540929804,1540929805,1 +313173,1540929805,1540929806,1 +313174,1540929806,1345642872,1 +313175,1540929807,1540929808,1 +313176,1540929808,1540929809,1 +313177,1540929809,1334277195,1 +313178,1540929810,1540929811,1 +313179,1540929811,1540929812,1 +313180,1540929812,1540929813,1 +313181,1540929813,1540929814,1 +313182,1540929814,1540929815,1 +313183,1540929815,1334277158,1 +313184,1540929816,1345646386,1 +313186,1540929818,1540929819,1 +313187,1540929819,1540929820,1 +313188,1540929820,1540929821,1 +313189,1540929821,1540929822,1 +313190,1540929822,1540929823,1 +313191,1540929823,1540929824,1 +313192,1540929824,1540929825,1 +313193,1540929825,1540929826,1 +313194,1540929826,1540929827,1 +313195,1540929827,1334277194,1 +313196,1540929828,1540929829,1 +313197,1540929829,1540929830,1 +313198,1540929830,1540929831,1 +313199,1540929831,1540929832,1 +313200,1540929832,1540929833,1 +313201,1540929833,1540929834,1 +313202,1540929834,1540929835,1 +313203,1540929835,1540929836,1 +313204,1540929836,1540929837,1 +313205,1540929837,1540929838,1 +313206,1540929838,1540929839,1 +313207,1540929839,1540929840,1 +313208,1540929840,1540929841,1 +313209,1540929841,1540929842,1 +313210,1540929842,1540929843,1 +313211,1540929843,1540929844,1 +313212,1540929844,1540929845,1 +313213,1540929845,1540929846,1 +313214,1540929846,1540929847,1 +313215,1540929847,1540929848,1 +313216,1540929848,277535693,1 +313660,1540930292,1540930293,1 +313661,1540930293,1540930294,1 +313662,1540930294,1540930295,1 +313663,1540930295,1540930296,1 +313664,1540930296,1540930297,1 +313665,1540930297,1540930298,1 +313666,1540930298,1540930299,1 +313667,1540930299,1540930300,1 +313668,1540930300,1540930301,1 +313669,1540930301,1540930302,1 +313670,1540930302,1540930303,1 +313671,1540930303,1540930304,1 +313672,1540930304,1540930305,1 +313673,1540930305,1540930306,1 +313674,1540930306,788840131,1 +318070,1540934702,1540934703,1 +318071,1540934703,974067296,1 +318072,1540934704,360207867,1 +318073,1540934705,974067160,1 +318074,1540934706,974067154,1 +318075,1540934707,974066794,1 +318076,1540934708,360205039,1 +318077,1540934709,1030689697,1 +318078,1540934710,278009641,1 +318079,1540934711,1540934712,1 +318080,1540934712,1540934713,1 +318081,1540934713,1540934714,1 +318082,1540934714,278009643,1 +318083,1540934715,1030313169,1 +318084,1540934716,1030313199,1 +318085,1540934717,1540934718,1 +318086,1540934718,1030313138,1 +318087,1540934719,278009648,1 +318088,1540934720,1540934721,1 +318089,1540934721,278009650,1 +318090,1540934722,1540934723,1 +318091,1540934723,1540934724,1 +318092,1540934724,278009654,1 +318093,1540934725,1540934726,1 +318094,1540934726,1540934727,1 +318095,1540934727,278009537,1 +318096,1540934728,1540934729,1 +318097,1540934729,1540934730,1 +318098,1540934730,1540934731,1 +318099,1540934731,1540934732,1 +318100,1540934732,1037361867,1 +318101,1540934733,1540934734,1 +318102,1540934734,1540934735,1 +318103,1540934735,365388298,1 +318104,1540934736,716879736,1 +318105,1540934737,1540934738,1 +318106,1540934738,1540934739,1 +318107,1540934739,1540934740,1 +318108,1540934740,1036627871,1 +318109,1540934741,365388314,1 +318110,1540934742,278009603,1 +318111,1540934743,1540934744,1 +318112,1540934744,1540934745,1 +318113,1540934745,1540934746,1 +318114,1540934746,1036628266,1 +318115,1540934747,1540934748,1 +318116,1540934748,1540934749,1 +318117,1540934749,1540934750,1 +318118,1540934750,1540934751,1 +318119,1540934751,1540934752,1 +318120,1540934752,278009609,1 +318121,1540934753,1036628123,1 +318122,1540934754,1540934755,1 +318123,1540934755,1036415720,1 +318124,1540934756,1036415810,1 +318125,1540934757,1540934758,1 +318126,1540934758,1540934759,1 +318127,1540934759,1540934760,1 +318128,1540934760,278009614,1 +318129,1540934761,278009617,1 +318130,1540934762,1540934763,1 +318131,1540934763,278009618,1 +318132,1540934764,278009619,1 +318133,1540934765,278009620,1 +318134,1540934766,952161384,1 +318135,1540934767,1540934768,1 +318136,1540934768,278009624,1 +318137,1540934769,1540934770,1 +318138,1540934770,278009627,1 +318139,1540934771,278009629,1 +318140,1540934772,952161852,1 +318141,1540934773,1540934774,1 +318142,1540934774,1030688859,1 +318280,1540934912,1540934913,1 +318281,1540934913,1540934914,1 +318282,1540934914,1540934915,1 +318283,1540934915,1540934916,1 +318284,1540934916,1540934917,1 +318285,1540934917,1540934918,1 +318286,1540934918,1540934919,1 +318287,1540934919,1540934920,1 +318288,1540934920,1540934921,1 +318289,1540934921,1540934922,1 +318290,1540934922,1540934923,1 +318291,1540934923,1540934924,1 +318292,1540934924,1540934925,1 +318293,1540934925,1540934926,1 +318294,1540934926,1342036793,1 +318295,1540934927,1540934928,1 +318296,1540934928,1540934929,1 +318297,1540934929,1540934930,1 +318298,1540934930,1540934931,1 +318299,1540934931,1540934932,1 +318300,1540934932,1540934933,1 +318301,1540934933,1540934934,1 +318302,1540934934,1540934935,1 +318303,1540934935,1540934936,1 +318304,1540934936,1540934937,1 +318305,1540934937,1540934938,1 +318306,1540934938,1540934939,1 +318307,1540934939,1540934940,1 +318308,1540934940,1540934941,1 +318309,1540934941,1540934942,1 +318310,1540934942,1540934943,1 +318311,1540934943,1540934944,1 +318312,1540934944,1540934945,1 +318313,1540934945,1540934946,1 +318314,1540934946,1540934947,1 +318315,1540934947,1342036678,1 +318316,1540934948,1540934949,1 +318317,1540934949,1540934950,1 +318318,1540934950,1540934951,1 +318319,1540934951,1540934952,1 +318320,1540934952,1540934953,1 +318321,1540934953,797175436,1 +318322,1540934954,1540934955,1 +318323,1540934955,1540934956,1 +318324,1540934956,1540934957,1 +318325,1540934957,1540934958,1 +318326,1540934958,1540934959,1 +318327,1540934959,1540934960,1 +318328,1540934960,1342036678,1 +318329,1540934961,1540934962,1 +318330,1540934962,1540934963,1 +318331,1540934963,1540934964,1 +318332,1540934964,1342038248,1 +318333,1540934965,1343015534,1 +318334,1540934966,1540934967,1 +318335,1540934967,1342038263,1 +318336,1540934968,1540934969,1 +318337,1540934969,1342038268,1 +318338,1540934970,1540934971,1 +318339,1540934971,1540934972,1 +318340,1540934972,1540934973,1 +318341,1540934973,1540934974,1 +318342,1540934974,1540934975,1 +318343,1540934975,1540934976,1 +318344,1540934976,1540934977,1 +318345,1540934977,1540934978,1 +318346,1540934978,1540934979,1 +318347,1540934979,1540934980,1 +318348,1540934980,1540934981,1 +318349,1540934981,1342038308,1 +318350,1540934982,1540934983,1 +318351,1540934983,1540934984,1 +318352,1540934984,1540934985,1 +318353,1540934985,1540934986,1 +318354,1540934986,1343007080,1 +318355,1540934987,1540934988,1 +318356,1540934988,1540934989,1 +318357,1540934989,1540934990,1 +318358,1540934990,1540934991,1 +318359,1540934991,1540934992,1 +318360,1540934992,365925662,1 +319366,1540935998,1540935999,0 +319367,1540935999,1540936000,0 +319368,1540936000,1540936001,0 +319369,1540936001,1345680619,0 +319370,1540936002,1540936003,0 +319371,1540936003,1540936004,0 +319372,1540936004,1374274158,0 +319373,1540936005,1540936006,0 +319374,1540936006,584358284,0 +319825,1540936457,1540936458,1 +319826,1540936458,984771437,1 +319827,1540936459,1540936460,1 +319828,1540936460,1540936461,1 +319829,1540936461,984772461,1 +319830,1540936462,1540936463,1 +319831,1540936463,984771446,1 +319832,1540936464,1342991989,1 +319833,1540936465,1540936466,1 +319834,1540936466,1540936467,1 +319835,1540936467,1540936468,1 +319836,1540936468,1540936469,1 +319837,1540936469,1540936470,1 +319838,1540936470,1540936471,1 +319839,1540936471,1540936472,1 +319840,1540936472,1342992002,1 +319841,1540936473,1540936474,1 +319842,1540936474,1540936475,1 +319843,1540936475,1540936476,1 +319844,1540936476,1540936477,1 +319845,1540936477,1342038309,1 +319846,1540936478,1342993133,1 +319847,1540936479,1540936480,1 +319848,1540936480,1540936481,1 +319849,1540936481,1540936482,1 +319850,1540936482,1342993144,1 +319851,1540936483,1540936484,1 +319852,1540936484,1342994403,1 +319853,1540936485,1540936486,1 +319854,1540936486,1540936487,1 +319855,1540936487,1540936488,1 +319856,1540936488,1540936489,1 +319857,1540936489,1540936490,1 +319858,1540936490,1540936491,1 +319859,1540936491,1540936492,1 +319860,1540936492,1540936493,1 +319861,1540936493,1540936494,1 +319862,1540936494,1540936495,1 +319863,1540936495,1540936496,1 +319864,1540936496,1342992004,1 +319865,1540936497,1342993881,1 +319866,1540936498,1540936499,1 +319867,1540936499,1540936500,1 +319868,1540936500,1342993888,1 +319869,1540936501,1540936502,1 +319870,1540936502,1540936503,1 +319871,1540936503,1540936504,1 +319872,1540936504,1540936505,1 +319873,1540936505,1342993565,1 +319874,1540936506,1540936507,1 +319875,1540936507,1540936508,1 +319876,1540936508,1540936509,1 +319877,1540936509,1540936510,1 +319878,1540936510,1540936511,1 +319879,1540936511,1540936512,1 +319880,1540936512,1540936513,1 +319881,1540936513,1540936514,1 +319882,1540936514,1540936515,1 +319883,1540936515,1342993133,1 +319884,1540936516,1540936517,1 +319885,1540936517,1540936518,1 +319886,1540936518,1540936519,1 +319887,1540936519,1540936520,1 +319888,1540936520,1540936521,1 +319889,1540936521,1540936522,1 +319890,1540936522,1342993888,1 +319891,1540936523,1342993144,1 +319892,1540936524,1540936525,1 +319893,1540936525,1540936526,1 +319894,1540936526,1540936527,1 +319895,1540936527,1540936528,1 +319896,1540936528,1540936529,1 +319897,1540936529,1540936530,1 +319898,1540936530,1540936531,1 +319899,1540936531,1540936532,1 +319900,1540936532,1540936533,1 +319901,1540936533,1540936534,1 +319902,1540936534,1342994403,1 +319903,1540936535,1540936536,1 +319904,1540936536,1540936537,1 +319905,1540936537,1540936538,1 +319906,1540936538,1540936539,1 +319907,1540936539,1540936540,1 +319908,1540936540,1540936541,1 +319909,1540936541,1540936542,1 +319910,1540936542,1540936543,1 +319911,1540936543,1540936544,1 +319912,1540936544,1540936545,1 +319913,1540936545,1540936546,1 +319914,1540936546,1540936547,1 +319915,1540936547,1540936548,1 +319916,1540936548,1540936549,1 +319917,1540936549,1540936550,1 +319918,1540936550,1540936551,1 +319919,1540936551,1342992002,1 +319920,1540936552,1540936553,1 +319921,1540936553,1540936554,1 +319922,1540936554,1342996091,1 +319923,1540936555,1342991986,1 +319924,1540936556,1540936557,1 +319925,1540936557,1540936558,1 +319926,1540936558,1540936559,1 +319927,1540936559,1540936560,1 +319928,1540936560,1540936561,1 +319929,1540936561,1540936562,1 +319930,1540936562,1540936563,1 +319931,1540936563,1540936564,1 +319932,1540936564,1540936565,1 +319933,1540936565,1540936566,1 +319934,1540936566,1540936567,1 +319935,1540936567,1342996091,1 +319936,1540936568,1540936569,1 +319937,1540936569,1540936570,1 +319938,1540936570,1342993565,1 +319939,1540936571,1540936572,1 +319940,1540936572,1342999539,1 +319941,1540936573,1540936574,1 +319942,1540936574,1342999507,1 +319943,1540936575,1342999539,1 +319944,1540936576,1540936577,1 +319945,1540936577,1540936578,1 +319946,1540936578,1540936579,1 +319947,1540936579,797175451,1 +319948,1540936580,1343000610,1 +319949,1540936581,1540936582,1 +319950,1540936582,1540936583,1 +319951,1540936583,1540936584,1 +319952,1540936584,1343001627,1 +319953,1540936585,1540936586,1 +319954,1540936586,1540936587,1 +319955,1540936587,1540936588,1 +319956,1540936588,1540936589,1 +319957,1540936589,1540936590,1 +319958,1540936590,1540936591,1 +319959,1540936591,1540936592,1 +319960,1540936592,1540936593,1 +319961,1540936593,1540936594,1 +319962,1540936594,1540936595,1 +319963,1540936595,1343000736,1 +319964,1540936596,1540936597,1 +319965,1540936597,1540936598,1 +319966,1540936598,1540936599,1 +319967,1540936599,1540936600,1 +319968,1540936600,1540936601,1 +319969,1540936601,1540936602,1 +319970,1540936602,1540936603,1 +319971,1540936603,1540936604,1 +319972,1540936604,1540936605,1 +319973,1540936605,1540936606,1 +319974,1540936606,797175428,1 +319975,1540936607,1540936608,1 +319976,1540936608,1540936609,1 +319977,1540936609,1540936610,1 +319978,1540936610,1343001895,1 +319979,1540936611,1540936612,1 +319980,1540936612,1540936613,1 +319981,1540936613,1540936614,1 +319982,1540936614,1343001895,1 +319983,1540936615,1540936616,1 +319984,1540936616,1540936617,1 +319985,1540936617,1540936618,1 +319986,1540936618,1343001627,1 +319987,1540936619,1540936620,1 +319988,1540936620,1540936621,1 +319989,1540936621,1540936622,1 +319990,1540936622,1540936623,1 +319991,1540936623,1343003151,1 +319992,1540936624,1540936625,1 +319993,1540936625,1540936626,1 +319994,1540936626,1540936627,1 +319995,1540936627,1540936628,1 +319996,1540936628,1343003173,1 +319997,1540936629,1343021950,1 +319998,1540936630,1343003179,1 +319999,1540936631,1540936632,1 +320000,1540936632,1540936633,1 +320001,1540936633,1540936634,1 +320002,1540936634,1540936635,1 +320003,1540936635,803745138,1 +320004,1540936636,1343004356,1 +320005,1540936637,1540936638,1 +320006,1540936638,1343015679,1 +320007,1540936639,1343003730,1 +320008,1540936640,1540936641,1 +320009,1540936641,1540936642,1 +320010,1540936642,1343004240,1 +320011,1540936643,1540936644,1 +320012,1540936644,1343003489,1 +320013,1540936645,1343004240,1 +320014,1540936646,1540936647,1 +320015,1540936647,1343018567,1 +320016,1540936648,1343003174,1 +320017,1540936649,1343005049,1 +320018,1540936650,1343005566,1 +320019,1540936651,1540936652,1 +320020,1540936652,1343005396,1 +320021,1540936653,1540936654,1 +320022,1540936654,1343004731,1 +320023,1540936655,1343005408,1 +320024,1540936656,1343005413,1 +320025,1540936657,1540936658,1 +320026,1540936658,1540936659,1 +320027,1540936659,1343010433,1 +320028,1540936660,1540936661,1 +320029,1540936661,1540936662,1 +320030,1540936662,1540936663,1 +320031,1540936663,1540936664,1 +320032,1540936664,1540936665,1 +320033,1540936665,1540936666,1 +320034,1540936666,1144431660,1 +320035,1540936667,1540936668,1 +320036,1540936668,1540936669,1 +320037,1540936669,294184231,1 +320038,1540936670,1540936671,1 +320039,1540936671,1540936672,1 +320040,1540936672,1540936673,1 +320041,1540936673,1343007099,1 +320042,1540936674,1540936675,1 +320043,1540936675,1540936676,1 +320044,1540936676,1540936677,1 +320045,1540936677,1540936678,1 +320046,1540936678,1540936679,1 +320047,1540936679,1540936680,1 +320048,1540936680,1343007170,1 +320049,1540936681,1343009871,1 +320050,1540936682,1540936683,1 +320051,1540936683,1343010177,1 +320052,1540936684,1343011717,1 +320053,1540936685,1540936686,1 +320054,1540936686,1540936687,1 +320055,1540936687,1540936688,1 +320056,1540936688,1343032358,1 +320057,1540936689,1540936690,1 +320058,1540936690,1540936691,1 +320059,1540936691,1343029648,1 +320060,1540936692,1343029634,1 +320061,1540936693,1540936694,1 +320062,1540936694,1540936695,1 +320063,1540936695,1343029776,1 +320064,1540936696,1540936697,1 +320065,1540936697,1343032353,1 +320066,1540936698,1540936699,1 +320067,1540936699,1343011215,1 +320068,1540936700,938502337,1 +320069,1540936701,1540936702,1 +320070,1540936702,1343012210,1 +320071,1540936703,1540936704,1 +320072,1540936704,1540936705,1 +320073,1540936705,1540936706,1 +320074,1540936706,1540936707,1 +320075,1540936707,1540936708,1 +320076,1540936708,1343013705,1 +320077,1540936709,1343013713,1 +320078,1540936710,1343013713,1 +320079,1540936711,1342038263,1 +320080,1540936712,1342038268,1 +320081,1540936713,1343015137,1 +320082,1540936714,1343013852,1 +320083,1540936715,1540936716,1 +320084,1540936716,1540936717,1 +320085,1540936717,1342038248,1 +320086,1540936718,1540936719,1 +320087,1540936719,1540936720,1 +320088,1540936720,1343015142,1 +320089,1540936721,1343015493,1 +320090,1540936722,1540936723,1 +320091,1540936723,1540936724,1 +320092,1540936724,1540936725,1 +320093,1540936725,984771446,1 +320094,1540936726,1343015534,1 +320095,1540936727,1343013744,1 +320096,1540936728,1540936729,1 +320097,1540936729,1343013705,1 +320098,1540936730,1343021641,1 +320099,1540936731,1540936732,1 +320100,1540936732,1343018567,1 +320101,1540936733,803745160,1 +320102,1540936734,1343021643,1 +320103,1540936735,1343022330,1 +320104,1540936736,1343021949,1 +320105,1540936737,1343022469,1 +320106,1540936738,1343022467,1 +320107,1540936739,1540936740,1 +320108,1540936740,1343004354,1 +320109,1540936741,1343026052,1 +320110,1540936742,1540936743,1 +320111,1540936743,1540936744,1 +320112,1540936744,1540936745,1 +320113,1540936745,1540936746,1 +320114,1540936746,1343025546,1 +320115,1540936747,1540936748,1 +320116,1540936748,1540936749,1 +320117,1540936749,1540936750,1 +320118,1540936750,1540936751,1 +320119,1540936751,1540936752,1 +320120,1540936752,1540936753,1 +320121,1540936753,1540936754,1 +320122,1540936754,1540936755,1 +320123,1540936755,1342038308,1 +320124,1540936756,1540936757,1 +320125,1540936757,1343012220,1 +320126,1540936758,1343029632,1 +320127,1540936759,1343029634,1 +320128,1540936760,1540936761,1 +320129,1540936761,1343029646,1 +320130,1540936762,1343029648,1 +320131,1540936763,294163854,1 +320132,1540936764,1343032358,1 +320133,1540936765,1343038885,1 +320134,1540936766,1343038887,1 +320135,1540936767,1540936768,1 +320136,1540936768,1540936769,1 +320137,1540936769,1540936770,1 +320138,1540936770,1540936771,1 +320139,1540936771,1540936772,1 +320140,1540936772,1540936773,1 +320141,1540936773,1540936774,1 +320142,1540936774,1540936775,1 +320143,1540936775,1540936776,1 +320144,1540936776,1540936777,1 +320145,1540936777,1343038907,1 +320146,1540936778,1343038909,1 +320147,1540936779,1343038912,1 +320148,1540936780,1540936781,1 +320149,1540936781,1540936782,1 +320150,1540936782,1540936783,1 +320151,1540936783,1540936784,1 +320152,1540936784,1540936785,1 +320153,1540936785,1540936786,1 +320154,1540936786,1540936787,1 +320155,1540936787,938142814,1 +320156,1540936788,1540936789,1 +320157,1540936789,1343038907,1 +320158,1540936790,1540936791,1 +320159,1540936791,1540936792,1 +320160,1540936792,1343039951,1 +320161,1540936793,1540936794,1 +320162,1540936794,1540936795,1 +320163,1540936795,1540936796,1 +320164,1540936796,1540936797,1 +320165,1540936797,1343045617,1 +320166,1540936798,1540936799,1 +320167,1540936799,1540936800,1 +320168,1540936800,1343039924,1 +320169,1540936801,1343040231,1 +320170,1540936802,1540936803,1 +320171,1540936803,1540936804,1 +320172,1540936804,1540936805,1 +320173,1540936805,1343040246,1 +320174,1540936806,1540936807,1 +320175,1540936807,1540936808,1 +320176,1540936808,1540936809,1 +320177,1540936809,1540936810,1 +320178,1540936810,1540936811,1 +320179,1540936811,1343040253,1 +320180,1540936812,1540936813,1 +320181,1540936813,1343040256,1 +320182,1540936814,1540936815,1 +320183,1540936815,1540936816,1 +320184,1540936816,1540936817,1 +320185,1540936817,1343040755,1 +320186,1540936818,1343040693,1 +320187,1540936819,1540936820,1 +320188,1540936820,1540936821,1 +320189,1540936821,1540936822,1 +320190,1540936822,1343040698,1 +320191,1540936823,1343040246,1 +320192,1540936824,1343040698,1 +320193,1540936825,1540936826,1 +320194,1540936826,1540936827,1 +320195,1540936827,1540936828,1 +320196,1540936828,1540936829,1 +320197,1540936829,1540936830,1 +320198,1540936830,1540936831,1 +320199,1540936831,1540936832,1 +320200,1540936832,1540936833,1 +320201,1540936833,1540936834,1 +320202,1540936834,1540936835,1 +320203,1540936835,1343042207,1 +320204,1540936836,1540936837,1 +320205,1540936837,1540936838,1 +320206,1540936838,1540936839,1 +320207,1540936839,1540936840,1 +320208,1540936840,1343040231,1 +320209,1540936841,1343040693,1 +320210,1540936842,1343042207,1 +320211,1540936843,1540936844,1 +320212,1540936844,1540936845,1 +320213,1540936845,1540936846,1 +320214,1540936846,1540936847,1 +320215,1540936847,1540936848,1 +320216,1540936848,1343038885,1 +320217,1540936849,1343038887,1 +320218,1540936850,1540936851,1 +320219,1540936851,1540936852,1 +320220,1540936852,1343044019,1 +320221,1540936853,1540936854,1 +320222,1540936854,1540936855,1 +320223,1540936855,1343045621,1 +320224,1540936856,1540936857,1 +320225,1540936857,1540936858,1 +320226,1540936858,1540936859,1 +320227,1540936859,1540936860,1 +320228,1540936860,1343038910,1 +320229,1540936861,1343045380,1 +320230,1540936862,1343045382,1 +320231,1540936863,1540936864,1 +320232,1540936864,1343047808,1 +320233,1540936865,1343047814,1 +320234,1540936866,1343048642,1 +320235,1540936867,1343048642,1 +320236,1540936868,1343047818,1 +320237,1540936869,1343049094,1 +320238,1540936870,1540936871,1 +320239,1540936871,1540936872,1 +320240,1540936872,1540936873,1 +320241,1540936873,1540936874,1 +320242,1540936874,1540936875,1 +320243,1540936875,1540936876,1 +320244,1540936876,1540936877,1 +320245,1540936877,1540936878,1 +320246,1540936878,1540936879,1 +320247,1540936879,1540936880,1 +320248,1540936880,1540936881,1 +320249,1540936881,1540936882,1 +320250,1540936882,1540936883,1 +320251,1540936883,1540936884,1 +320252,1540936884,1540936885,1 +320253,1540936885,1540936886,1 +320254,1540936886,1540936887,1 +320255,1540936887,1343053028,1 +320256,1540936888,1540936889,1 +320257,1540936889,1540936890,1 +320258,1540936890,1343053044,1 +320259,1540936891,1540936892,1 +320260,1540936892,1343053061,1 +320261,1540936893,1540936894,1 +320262,1540936894,1540936895,1 +320263,1540936895,1540936896,1 +320264,1540936896,1343060791,1 +320265,1540936897,1540936898,1 +320266,1540936898,1343053076,1 +320267,1540936899,1343053078,1 +320268,1540936900,1343053080,1 +320269,1540936901,1343053083,1 +320270,1540936902,1540936903,1 +320271,1540936903,1343062012,1 +320272,1540936904,1343053087,1 +320273,1540936905,1343053090,1 +320274,1540936906,1343053092,1 +320275,1540936907,1540936908,1 +320276,1540936908,1540936909,1 +320277,1540936909,1540936910,1 +320278,1540936910,1540936911,1 +320279,1540936911,1343052619,1 +320280,1540936912,1540936913,1 +320281,1540936913,1540936914,1 +320282,1540936914,1540936915,1 +320283,1540936915,1540936916,1 +320284,1540936916,1540936917,1 +320285,1540936917,1540936918,1 +320286,1540936918,1540936919,1 +320287,1540936919,1540936920,1 +320288,1540936920,1540936921,1 +320289,1540936921,1343055386,1 +320290,1540936922,1343054385,1 +320291,1540936923,1540936924,1 +320292,1540936924,1343054276,1 +320293,1540936925,1343055731,1 +320294,1540936926,1540936927,1 +320295,1540936927,1540936928,1 +320296,1540936928,1540936929,1 +320297,1540936929,1343054282,1 +320298,1540936930,1540936931,1 +320299,1540936931,1540936932,1 +320300,1540936932,1343054287,1 +320301,1540936933,1540936934,1 +320302,1540936934,1540936935,1 +320303,1540936935,1540936936,1 +320304,1540936936,1540936937,1 +320305,1540936937,1540936938,1 +320306,1540936938,1540936939,1 +320307,1540936939,1540936940,1 +320308,1540936940,1540936941,1 +320309,1540936941,1343054297,1 +320310,1540936942,1540936943,1 +320311,1540936943,1540936944,1 +320312,1540936944,1540936945,1 +320313,1540936945,1540936946,1 +320314,1540936946,1540936947,1 +320315,1540936947,1343054304,1 +320316,1540936948,1540936949,1 +320317,1540936949,1540936950,1 +320318,1540936950,1540936951,1 +320319,1540936951,1540936952,1 +320320,1540936952,1343053061,1 +320321,1540936953,1540936954,1 +320322,1540936954,1343055179,1 +320323,1540936955,1540936956,1 +320324,1540936956,1540936957,1 +320325,1540936957,1540936958,1 +320326,1540936958,1343055185,1 +320327,1540936959,1540936960,1 +320328,1540936960,1540936961,1 +320329,1540936961,1540936962,1 +320330,1540936962,1540936963,1 +320331,1540936963,1343054276,1 +320332,1540936964,1540936965,1 +320333,1540936965,1343054383,1 +320334,1540936966,1540936967,1 +320335,1540936967,1540936968,1 +320336,1540936968,1540936969,1 +320337,1540936969,1540936970,1 +320338,1540936970,1540936971,1 +320339,1540936971,1343054282,1 +320340,1540936972,1540936973,1 +320341,1540936973,1540936974,1 +320342,1540936974,1343055731,1 +320343,1540936975,1343054287,1 +320344,1540936976,1540936977,1 +320345,1540936977,1343055888,1 +320346,1540936978,1343054283,1 +320347,1540936979,1540936980,1 +320348,1540936980,1540936981,1 +320349,1540936981,1540936982,1 +320350,1540936982,1343056328,1 +320351,1540936983,1540936984,1 +320352,1540936984,1540936985,1 +320353,1540936985,1540936986,1 +320354,1540936986,1540936987,1 +320355,1540936987,1343056831,1 +320356,1540936988,1540936989,1 +320357,1540936989,1343056328,1 +320358,1540936990,1343058473,1 +320359,1540936991,1343058486,1 +320360,1540936992,1540936993,1 +320361,1540936993,1540936994,1 +320362,1540936994,1540936995,1 +320363,1540936995,1343053044,1 +320364,1540936996,1540936997,1 +320365,1540936997,1343054304,1 +320366,1540936998,1540936999,1 +320367,1540936999,1343053078,1 +320368,1540937000,1540937001,1 +320369,1540937001,1540937002,1 +320370,1540937002,1540937003,1 +320371,1540937003,1343061714,1 +320372,1540937004,1540937005,1 +320373,1540937005,1540937006,1 +320374,1540937006,1540937007,1 +320375,1540937007,1540937008,1 +320376,1540937008,1540937009,1 +320377,1540937009,1540937010,1 +320378,1540937010,1540937011,1 +320379,1540937011,1540937012,1 +320380,1540937012,1540937013,1 +320381,1540937013,1343053076,1 +320382,1540937014,1540937015,1 +320383,1540937015,1540937016,1 +320384,1540937016,1540937017,1 +320385,1540937017,1343061729,1 +320386,1540937018,1540937019,1 +320387,1540937019,1343061714,1 +320388,1540937020,1540937021,1 +320389,1540937021,1540937022,1 +320390,1540937022,1540937023,1 +320391,1540937023,1540937024,1 +320392,1540937024,1540937025,1 +320393,1540937025,1343061729,1 +320394,1540937026,1540937027,1 +320395,1540937027,1540937028,1 +320396,1540937028,1540937029,1 +320397,1540937029,1540937030,1 +320398,1540937030,1540937031,1 +320399,1540937031,1540937032,1 +320400,1540937032,1343060791,1 +320401,1540937033,1343053080,1 +320402,1540937034,1540937035,1 +320403,1540937035,1343061751,1 +320404,1540937036,1540937037,1 +320405,1540937037,1343053081,1 +320406,1540937038,1540937039,1 +320407,1540937039,1540937040,1 +320408,1540937040,1540937041,1 +320409,1540937041,1343061807,1 +320410,1540937042,1540937043,1 +320411,1540937043,1343053083,1 +320412,1540937044,1540937045,1 +320413,1540937045,1343062012,1 +320416,1540937048,1540937049,1 +320417,1540937049,1540937050,1 +320418,1540937050,1540937051,1 +320419,1540937051,1540937052,1 +320420,1540937052,1343040691,1 +320421,1540937053,1540937054,1 +320422,1540937054,1540937055,1 +320423,1540937055,1540937056,1 +320424,1540937056,1343053088,1 +320425,1540937057,1540937058,1 +320426,1540937058,1540937059,1 +320427,1540937059,1540937060,1 +320428,1540937060,1540937061,1 +320429,1540937061,1343063215,1 +320430,1540937062,1540937063,1 +320431,1540937063,1540937064,1 +320432,1540937064,1540937065,1 +320433,1540937065,1343063250,1 +320434,1540937066,1540937067,1 +320435,1540937067,1540937068,1 +320436,1540937068,1540937069,1 +320437,1540937069,1343053090,1 +320438,1540937070,1540937071,1 +320439,1540937071,1540937072,1 +320440,1540937072,1343053092,1 +320441,1540937073,1343065078,1 +320443,1540937075,1540937076,1 +320444,1540937076,1540937077,1 +320445,1540937077,1343052623,1 +320446,1540937078,1343063968,1 +320447,1540937079,1343067056,1 +320448,1540937080,1540937081,1 +320449,1540937081,1540937082,1 +320450,1540937082,1540937083,1 +320451,1540937083,1540937084,1 +320452,1540937084,1540937085,1 +320453,1540937085,938142856,1 +320454,1540937086,361199627,1 +320455,1540937087,1343067373,1 +320456,1540937088,937216288,1 +320457,1540937089,1540937090,1 +320458,1540937090,1540937091,1 +320459,1540937091,1540937092,1 +320460,1540937092,1540937093,1 +320461,1540937093,1343067316,1 +320462,1540937094,937216310,1 +320463,1540937095,1540937096,1 +320464,1540937096,1540937097,1 +320465,1540937097,1343067335,1 +320466,1540937098,1343068265,1 +320467,1540937099,1343071761,1 +320468,1540937100,1540937101,1 +320469,1540937101,1540937102,1 +320470,1540937102,937216283,1 +320471,1540937103,937216310,1 +320472,1540937104,1540937105,1 +320473,1540937105,1343076833,1 +320474,1540937106,1540937107,1 +320475,1540937107,1540937108,1 +320476,1540937108,1540937109,1 +320477,1540937109,1540937110,1 +320478,1540937110,1343076830,1 +320479,1540937111,1540937112,1 +320480,1540937112,1540937113,1 +320481,1540937113,1343082653,1 +320482,1540937114,1540937115,1 +320483,1540937115,1540937116,1 +320484,1540937116,1540937117,1 +320485,1540937117,1540937118,1 +320486,1540937118,1540937119,1 +320487,1540937119,1540937120,1 +320488,1540937120,1540937121,1 +320489,1540937121,1343084488,1 +320490,1540937122,1540937123,1 +320491,1540937123,1540937124,1 +320492,1540937124,1540937125,1 +320493,1540937125,1343084494,1 +320494,1540937126,1540937127,1 +320495,1540937127,1540937128,1 +320496,1540937128,1540937129,1 +320497,1540937129,1540937130,1 +320498,1540937130,1540937131,1 +320499,1540937131,1540937132,1 +320500,1540937132,1540937133,1 +320501,1540937133,1540937134,1 +320502,1540937134,1540937135,1 +320503,1540937135,1540937136,1 +320504,1540937136,1540937137,1 +320505,1540937137,1540937138,1 +320506,1540937138,1540937139,1 +320507,1540937139,1540937140,1 +320508,1540937140,1540937141,1 +320509,1540937141,1540937142,1 +320510,1540937142,1540937143,1 +320511,1540937143,1540937144,1 +320512,1540937144,1540937145,1 +320513,1540937145,1540937146,1 +320514,1540937146,1540937147,1 +320515,1540937147,1540937148,1 +320516,1540937148,1540937149,1 +320517,1540937149,1540937150,1 +320518,1540937150,1540937151,1 +320519,1540937151,1540937152,1 +320520,1540937152,1540937153,1 +320521,1540937153,1540937154,1 +320522,1540937154,1343084389,1 +320523,1540937155,1540937156,1 +320524,1540937156,1540937157,1 +320525,1540937157,1343085165,1 +320526,1540937158,1540937159,1 +320527,1540937159,1540937160,1 +320528,1540937160,1343085169,1 +320529,1540937161,1540937162,1 +320530,1540937162,1540937163,1 +320531,1540937163,1343084494,1 +320532,1540937164,1540937165,1 +320533,1540937165,1540937166,1 +320534,1540937166,1540937167,1 +320535,1540937167,1343085165,1 +320536,1540937168,1540937169,1 +320537,1540937169,1540937170,1 +320538,1540937170,1540937171,1 +320539,1540937171,1343084488,1 +320540,1540937172,1540937173,1 +320541,1540937173,1343085694,1 +320542,1540937174,1540937175,1 +320543,1540937175,1540937176,1 +320544,1540937176,1540937177,1 +320545,1540937177,1540937178,1 +320546,1540937178,1540937179,1 +320547,1540937179,1540937180,1 +320548,1540937180,1540937181,1 +320549,1540937181,1540937182,1 +320550,1540937182,1540937183,1 +320551,1540937183,1540937184,1 +320552,1540937184,1343085169,1 +320553,1540937185,1540937186,1 +320554,1540937186,1540937187,1 +320555,1540937187,1540937188,1 +320556,1540937188,1540937189,1 +320557,1540937189,1540937190,1 +320558,1540937190,1343086013,1 +320559,1540937191,1540937192,1 +320560,1540937192,1540937193,1 +320561,1540937193,1343086640,1 +320562,1540937194,1540937195,1 +320563,1540937195,1540937196,1 +320564,1540937196,1540937197,1 +320565,1540937197,1343086030,1 +320566,1540937198,1540937199,1 +320567,1540937199,1540937200,1 +320568,1540937200,1343087271,1 +320569,1540937201,1540937202,1 +320570,1540937202,1540937203,1 +320571,1540937203,1540937204,1 +320572,1540937204,1540937205,1 +320573,1540937205,1540937206,1 +320574,1540937206,1540937207,1 +320575,1540937207,1540937208,1 +320576,1540937208,1540937209,1 +320577,1540937209,1540937210,1 +320578,1540937210,1343086632,1 +320579,1540937211,1540937212,1 +320580,1540937212,1540937213,1 +320581,1540937213,625904201,1 +320582,1540937214,1540937215,1 +320583,1540937215,1540937216,1 +320584,1540937216,1540937217,1 +320585,1540937217,1343086645,1 +320586,1540937218,1540937219,1 +320587,1540937219,1540937220,1 +320588,1540937220,1540937221,1 +320589,1540937221,1540937222,1 +320590,1540937222,1540937223,1 +320591,1540937223,1343086632,1 +320592,1540937224,1540937225,1 +320593,1540937225,1540937226,1 +320594,1540937226,1540937227,1 +320595,1540937227,1540937228,1 +320596,1540937228,1540937229,1 +320597,1540937229,1540937230,1 +320598,1540937230,1540937231,1 +320599,1540937231,1540937232,1 +320600,1540937232,1540937233,1 +320601,1540937233,1343086013,1 +320602,1540937234,1540937235,1 +320603,1540937235,1540937236,1 +320604,1540937236,1540937237,1 +320605,1540937237,1540937238,1 +320606,1540937238,1540937239,1 +320607,1540937239,1540937240,1 +320608,1540937240,1540937241,1 +320609,1540937241,1343089345,1 +320610,1540937242,1540937243,1 +320611,1540937243,1540937244,1 +320612,1540937244,1540937245,1 +320613,1540937245,1540937246,1 +320614,1540937246,1540937247,1 +320615,1540937247,1540937248,1 +320616,1540937248,1540937249,1 +320617,1540937249,1540937250,1 +320618,1540937250,1540937251,1 +320619,1540937251,677948378,1 +320692,1540937324,1540937325,1 +320693,1540937325,1540937326,1 +320694,1540937326,984332363,1 +320695,1540937327,1540937328,1 +320696,1540937328,1540937329,1 +320697,1540937329,1540937330,1 +320698,1540937330,984332590,1 +321057,1540937689,1307354683,1 +321058,1540937690,1540937691,1 +321059,1540937691,1540937692,1 +321060,1540937692,1540937693,1 +321061,1540937693,1540937694,1 +321062,1540937694,1540937695,1 +321063,1540937695,1540937696,1 +321064,1540937696,1540937697,1 +321065,1540937697,1540937698,1 +321066,1540937698,1540937699,1 +321067,1540937699,1540937700,1 +321068,1540937700,1540937701,1 +321069,1540937701,1540937702,1 +321070,1540937702,1540937703,1 +321071,1540937703,1540937704,1 +321072,1540937704,1540937705,1 +321073,1540937705,1540937706,1 +321074,1540937706,1540937707,1 +321075,1540937707,1540937708,1 +321076,1540937708,1345227526,1 +321077,1540937709,1540937710,1 +321078,1540937710,1540937711,1 +321079,1540937711,1540937712,1 +321080,1540937712,1540937713,1 +321081,1540937713,1540937714,1 +321082,1540937714,1540937715,1 +321083,1540937715,1540937716,1 +321084,1540937716,1345227245,1 +321085,1540937717,1540937718,1 +321086,1540937718,1345227663,1 +321087,1540937719,1540937720,1 +321088,1540937720,1540937721,1 +321089,1540937721,1540937722,1 +321090,1540937722,1540937723,1 +321091,1540937723,1345227669,1 +321092,1540937724,1540937725,1 +321093,1540937725,1540937726,1 +321094,1540937726,1345227673,1 +321095,1540937727,1540937728,1 +321096,1540937728,1540937729,1 +321097,1540937729,1345227677,1 +321098,1540937730,1540937731,1 +321099,1540937731,1540937732,1 +321100,1540937732,1540937733,1 +321101,1540937733,1345227250,1 +321102,1540937734,1540937735,1 +321103,1540937735,1540937736,1 +321104,1540937736,1540937737,1 +321105,1540937737,1540937738,1 +321106,1540937738,1540937739,1 +321107,1540937739,1540937740,1 +321108,1540937740,1540937741,1 +321109,1540937741,1540937742,1 +321110,1540937742,1540937743,1 +321111,1540937743,1540937744,1 +321112,1540937744,1540937745,1 +321113,1540937745,1540937746,1 +321114,1540937746,1345227264,1 +321115,1540937747,1540937748,1 +321116,1540937748,1540937749,1 +321117,1540937749,1540937750,1 +321118,1540937750,1345227269,1 +321119,1540937751,1540937752,1 +321120,1540937752,1540937753,1 +321121,1540937753,1540937754,1 +321122,1540937754,1540937755,1 +321123,1540937755,1540937756,1 +321124,1540937756,1540937757,1 +321125,1540937757,1540937758,1 +321126,1540937758,1334277145,1 +321127,1540937759,1540937760,1 +321128,1540937760,1540937761,1 +321129,1540937761,1540937762,1 +321130,1540937762,1540937763,1 +321131,1540937763,1540937764,1 +321132,1540937764,1540937765,1 +321133,1540937765,1334277099,1 +321134,1540937766,1540937767,1 +321135,1540937767,1540937768,1 +321136,1540937768,1345228049,1 +321137,1540937769,1345228054,1 +321138,1540937770,1345228056,1 +321139,1540937771,1540937772,1 +321140,1540937772,1540937773,1 +321141,1540937773,1345228517,1 +321142,1540937774,1540937775,1 +321143,1540937775,1540937776,1 +321144,1540937776,1345228517,1 +321145,1540937777,1540937778,1 +321146,1540937778,1540937779,1 +321147,1540937779,1540937780,1 +321148,1540937780,1345228744,1 +321149,1540937781,1540937782,1 +321150,1540937782,1345230181,1 +321151,1540937783,1540937784,1 +321152,1540937784,1345228054,1 +321153,1540937785,1540937786,1 +321154,1540937786,1540937787,1 +321155,1540937787,1345228064,1 +321156,1540937788,1540937789,1 +321157,1540937789,1540937790,1 +321158,1540937790,1540937791,1 +321159,1540937791,1540937792,1 +321160,1540937792,1540937793,1 +321161,1540937793,1345228049,1 +321162,1540937794,1540937795,1 +321163,1540937795,1345228050,1 +321164,1540937796,1345230438,1 +321165,1540937797,1540937798,1 +321166,1540937798,1540937799,1 +321167,1540937799,1540937800,1 +321168,1540937800,1540937801,1 +321169,1540937801,1540937802,1 +321170,1540937802,1540937803,1 +321171,1540937803,1540937804,1 +321172,1540937804,1540937805,1 +321173,1540937805,1540937806,1 +321174,1540937806,1540937807,1 +321175,1540937807,1345231627,1 +321176,1540937808,1540937809,1 +321177,1540937809,1540937810,1 +321178,1540937810,1540937811,1 +321179,1540937811,1345639827,1 +321180,1540937812,1540937813,1 +321181,1540937813,1540937814,1 +321182,1540937814,1540937815,1 +321183,1540937815,1540937816,1 +321184,1540937816,1334277160,1 +321185,1540937817,1540937818,1 +321186,1540937818,1540937819,1 +321187,1540937819,1540937820,1 +321188,1540937820,1540937821,1 +321189,1540937821,1540937822,1 +321190,1540937822,1540937823,1 +321191,1540937823,1345231643,1 +321192,1540937824,1540937825,1 +321193,1540937825,1540937826,1 +321194,1540937826,1540937827,1 +321195,1540937827,1540937828,1 +321196,1540937828,1540937829,1 +321197,1540937829,1540937830,1 +321198,1540937830,1540937831,1 +321199,1540937831,1334277192,1 +321200,1540937832,1540937833,1 +321201,1540937833,1540937834,1 +321202,1540937834,1540937835,1 +321203,1540937835,1540937836,1 +321204,1540937836,1345233464,1 +321205,1540937837,1540937838,1 +321206,1540937838,1540937839,1 +321207,1540937839,1540937840,1 +321208,1540937840,1540937841,1 +321209,1540937841,1540937842,1 +321210,1540937842,1540937843,1 +321211,1540937843,1540937844,1 +321212,1540937844,1345233476,1 +321213,1540937845,1540937846,1 +321214,1540937846,1345233480,1 +321215,1540937847,1540937848,1 +321216,1540937848,1540937849,1 +321217,1540937849,1540937850,1 +321218,1540937850,1540937851,1 +321219,1540937851,1540937852,1 +321220,1540937852,1540937853,1 +321221,1540937853,1540937854,1 +321222,1540937854,1540937855,1 +321223,1540937855,1540937856,1 +321224,1540937856,1540937857,1 +321225,1540937857,1540937858,1 +321226,1540937858,1540937859,1 +321227,1540937859,1540937860,1 +321228,1540937860,1540937861,1 +321229,1540937861,1345233476,1 +321230,1540937862,1540937863,0 +321231,1540937863,279590357,0 +321232,1540937864,1540937865,0 +321233,1540937865,1345509870,0 +321234,1540937866,1540937867,0 +321235,1540937867,360207820,0 +321236,1540937868,1540937869,0 +321237,1540937869,583434225,0 +321238,1540937870,1540937871,0 +321239,1540937871,583434227,0 +321240,1540937872,279590361,0 +321241,1540937873,1540937874,0 +321242,1540937874,583434227,0 +321243,1540937875,1540937876,0 +321244,1540937876,279590361,0 +321245,1540937877,1540937878,0 +321246,1540937878,583434230,0 +321247,1540937879,1540937880,1 +321248,1540937880,360209954,1 +321249,1540937881,360209955,1 +321250,1540937882,360209900,1 +321251,1540937883,1345508956,0 +321252,1540937884,1345509423,0 +321253,1540937885,1345509354,0 +321254,1540937886,1540937887,0 +321255,1540937887,1345509357,0 +321256,1540937888,1540937889,1 +321257,1540937889,1540937890,1 +321258,1540937890,279590313,1 +321259,1540937891,1540937892,1 +321260,1540937892,279590317,1 +321261,1540937893,1540937894,1 +321262,1540937894,360209875,1 +321263,1540937895,1540937896,1 +321264,1540937896,1540937897,1 +321265,1540937897,1345509358,1 +321266,1540937898,1540937899,0 +321267,1540937899,1345509870,0 +321268,1540937900,1540937901,0 +321269,1540937901,279590357,0 +321270,1540937902,1540937903,0 +321271,1540937903,360210092,0 +321272,1540937904,360206852,1 +321286,1540937918,1540937919,1 +321287,1540937919,1540937920,1 +321288,1540937920,1540937921,1 +321289,1540937921,775866154,1 +321290,1540937922,1540937923,1 +321291,1540937923,1540937924,1 +321292,1540937924,1345231654,1 +321293,1540937925,1540937926,1 +321294,1540937926,1540937927,1 +321295,1540937927,1540937928,1 +321296,1540937928,1540937929,1 +321297,1540937929,1540937930,1 +321298,1540937930,1540937931,1 +321299,1540937931,1345641518,1 +321300,1540937932,1540937933,1 +321301,1540937933,1345641518,1 +321302,1540937934,1345642880,1 +321303,1540937935,935855029,1 +321304,1540937936,1540937937,1 +321305,1540937937,1345642983,1 +321306,1540937938,1540937939,1 +321307,1540937939,1540937940,1 +321308,1540937940,1345643341,1 +321309,1540937941,1540937942,1 +321310,1540937942,1345643346,1 +321311,1540937943,1540937944,1 +321312,1540937944,1540937945,1 +321313,1540937945,1334277195,1 +321314,1540937946,1540937947,1 +321315,1540937947,1540937948,1 +321316,1540937948,1345643909,1 +321317,1540937949,1345643341,1 +321318,1540937950,1540937951,1 +321319,1540937951,1540937952,1 +321320,1540937952,1540937953,1 +321321,1540937953,1540937954,1 +321322,1540937954,1540937955,1 +321323,1540937955,1540937956,1 +321324,1540937956,1345644464,1 +321325,1540937957,1540937958,1 +321326,1540937958,1540937959,1 +321327,1540937959,1345642880,1 +321328,1540937960,935855621,1 +321329,1540937961,1345645494,1 +321331,1540937963,1334277095,1 +321332,1540937964,1540937965,1 +321333,1540937965,1540937966,1 +321334,1540937966,1540937967,1 +321335,1540937967,1540937968,1 +321336,1540937968,1540937969,1 +321337,1540937969,1345652044,1 +321338,1540937970,1540937971,1 +321339,1540937971,1307367454,1 +321340,1540937972,1540937973,1 +321341,1540937973,1345658074,1 +321342,1540937974,1345658491,1 +321343,1540937975,1345660368,1 +321344,1540937976,1540937977,1 +321345,1540937977,1345658489,1 +321346,1540937978,1540937979,1 +321347,1540937979,1345659192,1 +321348,1540937980,1345659198,1 +321349,1540937981,1345659306,1 +321350,1540937982,1345658969,1 +321351,1540937983,1540937984,1 +321352,1540937984,1540937985,1 +321353,1540937985,1540937986,1 +321354,1540937986,1540937987,1 +321355,1540937987,603748697,1 +321356,1540937988,1540937989,1 +321357,1540937989,1345660694,1 +321358,1540937990,1345662632,1 +321359,1540937991,1540937992,1 +321360,1540937992,1540937993,1 +321361,1540937993,1540937994,1 +321362,1540937994,1540937995,1 +321363,1540937995,1540937996,1 +321364,1540937996,1540937997,1 +321365,1540937997,1540937998,1 +321366,1540937998,1540937999,1 +321367,1540937999,1540938000,1 +321368,1540938000,1540938001,1 +321369,1540938001,1540938002,1 +321370,1540938002,1540938003,1 +321371,1540938003,1540938004,1 +321372,1540938004,1540938005,1 +321373,1540938005,1540938006,1 +321374,1540938006,937378304,1 +321495,1540938127,1540938128,1 +321496,1540938128,1540938129,1 +321497,1540938129,1540938130,1 +321498,1540938130,1540938131,1 +321499,1540938131,1540938132,1 +321500,1540938132,1540938133,1 +321501,1540938133,1540938134,1 +321502,1540938134,1540938135,1 +321503,1540938135,1345680895,1 +321504,1540938136,1345683061,1 +321505,1540938137,1540938138,1 +321506,1540938138,1345680899,1 +321507,1540938139,1345680901,1 +321508,1540938140,1540938141,1 +321509,1540938141,1345680604,1 +321510,1540938142,1345680614,1 +321511,1540938143,1345680899,1 +321512,1540938144,1540938145,1 +321513,1540938145,1540938146,1 +321514,1540938146,1540938147,1 +321515,1540938147,1540938148,1 +321516,1540938148,1540938149,1 +321517,1540938149,1540938150,1 +321518,1540938150,1540938151,1 +321519,1540938151,1540938152,1 +321520,1540938152,1540938153,1 +321521,1540938153,1345683061,1 +321522,1540938154,1540938155,1 +321523,1540938155,1345684280,1 +321524,1540938156,1345684255,1 +321525,1540938157,1345684365,1 +321526,1540938158,1540938159,1 +321527,1540938159,1345680895,1 +321528,1540938160,1540938161,1 +321529,1540938161,1540938162,1 +321530,1540938162,1540938163,1 +321531,1540938163,1345684844,1 +321532,1540938164,1540938165,1 +321533,1540938165,1540938166,1 +321534,1540938166,1540938167,1 +321535,1540938167,1345684852,1 +321536,1540938168,1345685959,1 +321537,1540938169,1540938170,1 +321538,1540938170,1540938171,1 +321539,1540938171,1540938172,1 +321540,1540938172,1540938173,1 +321541,1540938173,1540938174,1 +321542,1540938174,1540938175,1 +321543,1540938175,1540938176,1 +321544,1540938176,1345685044,1 +321545,1540938177,1540938178,1 +321546,1540938178,1345685994,1 +321547,1540938179,1345684852,1 +321548,1540938180,1540938181,1 +321549,1540938181,1540938182,1 +321550,1540938182,1345684854,1 +321551,1540938183,1540938184,1 +321552,1540938184,1540938185,1 +321553,1540938185,1540938186,1 +321554,1540938186,1540938187,1 +321555,1540938187,1345684861,1 +321556,1540938188,1345685994,1 +321557,1540938189,1540938190,1 +321558,1540938190,1345685959,1 +321559,1540938191,1345686701,1 +321560,1540938192,1540938193,1 +321561,1540938193,1345686701,1 +321562,1540938194,1540938195,1 +321563,1540938195,1540938196,1 +321564,1540938196,1540938197,1 +321565,1540938197,1540938198,1 +321566,1540938198,1540938199,1 +321567,1540938199,1540938200,1 +321568,1540938200,1540938201,1 +321569,1540938201,1540938202,1 +321570,1540938202,1540938203,1 +321571,1540938203,1540938204,1 +321572,1540938204,1540938205,1 +321573,1540938205,1540938206,1 +321574,1540938206,1540938207,1 +321575,1540938207,1540938208,1 +321576,1540938208,1540938209,1 +321577,1540938209,1540938210,1 +321578,1540938210,1540938211,1 +321579,1540938211,1540938212,1 +321580,1540938212,1540938213,1 +321581,1540938213,1540938214,1 +321582,1540938214,1540938215,1 +321583,1540938215,1540938216,1 +321584,1540938216,1345688945,1 +321585,1540938217,1540938218,1 +321586,1540938218,1540938219,1 +321587,1540938219,1540938220,1 +321588,1540938220,1540938221,1 +321589,1540938221,1345691552,1 +321590,1540938222,1540938223,1 +321591,1540938223,1540938224,1 +321592,1540938224,1345688956,1 +321593,1540938225,1540938226,1 +321594,1540938226,1540938227,1 +321595,1540938227,1345688960,1 +321596,1540938228,1540938229,1 +321597,1540938229,1345688963,1 +321598,1540938230,1540938231,1 +321599,1540938231,1540938232,1 +321600,1540938232,1540938233,1 +321601,1540938233,1345688971,1 +321602,1540938234,1540938235,1 +321603,1540938235,1540938236,1 +321604,1540938236,1540938237,1 +321605,1540938237,1345688863,1 +321607,1540938239,1540938240,1 +321608,1540938240,1540938241,1 +321609,1540938241,1345689091,1 +321610,1540938242,1345689094,1 +321611,1540938243,1345689096,1 +321612,1540938244,1540938245,1 +321613,1540938245,1540938246,1 +321614,1540938246,1345689101,1 +321618,1540938250,1540938251,1 +321619,1540938251,1540938252,1 +321620,1540938252,1540938253,1 +321621,1540938253,1540938254,1 +321622,1540938254,1540938255,1 +321623,1540938255,1540938256,1 +321624,1540938256,1540938257,1 +321625,1540938257,1540938258,1 +321626,1540938258,1540938259,1 +321627,1540938259,1345691509,1 +321628,1540938260,1345691539,1 +321629,1540938261,1345691757,1 +321630,1540938262,1540938263,1 +321631,1540938263,1540938264,1 +321632,1540938264,1540938265,1 +321633,1540938265,1540938266,1 +321634,1540938266,1540938267,1 +321635,1540938267,1345691764,1 +321636,1540938268,1540938269,1 +321637,1540938269,1540938270,1 +321638,1540938270,1540938271,1 +321639,1540938271,1345688945,1 +321640,1540938272,1540938273,1 +321641,1540938273,1540938274,1 +321642,1540938274,1540938275,1 +321643,1540938275,1540938276,1 +321644,1540938276,1345691764,1 +321645,1540938277,1540938278,1 +321646,1540938278,1540938279,1 +321647,1540938279,1540938280,1 +321648,1540938280,1540938281,1 +321649,1540938281,1540938282,1 +321650,1540938282,1345692023,1 +321651,1540938283,1540938284,1 +321652,1540938284,1345691755,1 +321653,1540938285,1345692028,1 +321654,1540938286,1345692030,1 +321655,1540938287,1540938288,1 +321656,1540938288,1540938289,1 +321657,1540938289,1540938290,1 +321658,1540938290,1333877956,1 +321659,1540938291,1540938292,1 +321660,1540938292,1540938293,1 +321661,1540938293,1540938294,1 +321662,1540938294,1345694274,1 +321665,1540938297,1540938298,1 +321666,1540938298,1540938299,1 +321667,1540938299,1540938300,1 +321668,1540938300,1540938301,1 +321669,1540938301,1540938302,1 +321670,1540938302,1540938303,1 +321671,1540938303,1345694817,1 +321699,1540938331,1540938332,1 +321700,1540938332,1540938333,1 +321701,1540938333,1540938334,1 +321702,1540938334,1540938335,1 +321703,1540938335,1540938336,1 +321704,1540938336,1540938337,1 +321705,1540938337,1540938338,1 +321706,1540938338,1540938339,1 +321707,1540938339,1540938340,1 +321708,1540938340,1540938341,1 +321709,1540938341,1540938342,1 +321710,1540938342,1540938343,1 +321711,1540938343,1540938344,1 +321712,1540938344,1540938345,1 +321713,1540938345,1540938346,1 +321714,1540938346,1540938347,1 +321715,1540938347,1540938348,1 +321716,1540938348,1540938349,1 +321717,1540938349,1540938350,1 +321718,1540938350,1540938351,1 +321719,1540938351,1540938352,1 +321720,1540938352,1540938353,1 +321721,1540938353,1540938354,1 +321722,1540938354,1540938355,1 +321723,1540938355,1540938356,1 +321724,1540938356,1540938357,1 +321725,1540938357,1540938358,1 +321726,1540938358,1540938359,1 +321727,1540938359,1345694274,1 +321728,1540938360,1540938361,1 +321729,1540938361,1540938362,1 +321730,1540938362,1540938363,1 +321731,1540938363,1540938364,1 +321732,1540938364,1540938365,1 +321733,1540938365,1540938366,1 +321734,1540938366,1540938367,1 +321735,1540938367,1540938368,1 +321736,1540938368,1540938369,1 +321737,1540938369,1540938370,1 +321738,1540938370,1334277131,1 +332889,1540949521,1371044228,1 +332890,1540949522,1037361704,1 +332891,1540949523,1298242187,1 +332892,1540949524,1037131100,1 +332893,1540949525,1540949526,1 +332894,1540949526,1540949527,1 +332895,1540949527,1540949528,1 +332896,1540949528,1540949529,1 +332897,1540949529,1540949530,1 +332898,1540949530,1540949531,1 +332899,1540949531,1540949532,1 +332900,1540949532,1540949533,1 +332901,1540949533,1371044405,1 +332902,1540949534,1540949535,1 +332903,1540949535,1540949536,1 +332904,1540949536,1540949537,1 +332905,1540949537,1540949538,1 +332906,1540949538,1540949539,1 +332907,1540949539,1540949540,1 +332908,1540949540,1371043839,1 +332909,1540949541,1540949542,1 +332910,1540949542,810716453,1 +332911,1540949543,1540949544,1 +332912,1540949544,1540949545,1 +332913,1540949545,1371044523,1 +332914,1540949546,1540949547,1 +332915,1540949547,1540949548,1 +332916,1540949548,1540949549,1 +332917,1540949549,1371043849,1 +332918,1540949550,1540949551,1 +332919,1540949551,1540949552,1 +332920,1540949552,1540949553,1 +332921,1540949553,1540949554,1 +332922,1540949554,810716444,1 +332923,1540949555,1540949556,1 +332924,1540949556,1540949557,1 +332925,1540949557,1540949558,1 +332926,1540949558,1540949559,1 +332927,1540949559,1540949560,1 +332928,1540949560,1540949561,1 +332929,1540949561,1540949562,1 +332930,1540949562,1540949563,1 +332931,1540949563,1540949564,1 +332932,1540949564,1371125119,1 +332933,1540949565,1540949566,1 +332934,1540949566,1540949567,1 +332935,1540949567,1540949568,1 +332936,1540949568,1540949569,1 +332937,1540949569,1540949570,1 +332938,1540949570,1540949571,1 +332939,1540949571,1371125090,1 +332940,1540949572,1540949573,1 +332941,1540949573,1540949574,1 +332942,1540949574,1540949575,1 +332943,1540949575,1540949576,1 +332944,1540949576,1540949577,1 +332945,1540949577,1540949578,1 +332946,1540949578,1540949579,1 +332947,1540949579,1540949580,1 +332948,1540949580,1540949581,1 +332949,1540949581,1540949582,1 +332950,1540949582,278009558,1 +332951,1540949583,1371044433,1 +332952,1540949584,1540949585,1 +332953,1540949585,1540949586,1 +332954,1540949586,1540949587,1 +332955,1540949587,1540949588,1 +332956,1540949588,1540949589,1 +332957,1540949589,1540949590,1 +332958,1540949590,1540949591,1 +332959,1540949591,1540949592,1 +332960,1540949592,1540949593,1 +332961,1540949593,1371043803,1 +332962,1540949594,1540949595,1 +332963,1540949595,1371043930,1 +332964,1540949596,1540949597,1 +332965,1540949597,1540949598,1 +332966,1540949598,1540949599,1 +332967,1540949599,1540949600,1 +332968,1540949600,1540949601,1 +332969,1540949601,1371043944,1 +332970,1540949602,1540949603,1 +332971,1540949603,1540949604,1 +332972,1540949604,1371043979,1 +332973,1540949605,1540949606,1 +332974,1540949606,1540949607,1 +332975,1540949607,1371044417,1 +332976,1540949608,1371044405,1 +332977,1540949609,1540949610,1 +332978,1540949610,1540949611,1 +332979,1540949611,1540949612,1 +332980,1540949612,1540949613,1 +332981,1540949613,1540949614,1 +332982,1540949614,1371044356,1 +332983,1540949615,1371044449,1 +332984,1540949616,1540949617,1 +332985,1540949617,1371044387,1 +332986,1540949618,1540949619,1 +332987,1540949619,1540949620,1 +332988,1540949620,1540949621,1 +332989,1540949621,1540949622,1 +332990,1540949622,1371044423,1 +332991,1540949623,1540949624,1 +332992,1540949624,1540949625,1 +332993,1540949625,1540949626,1 +332994,1540949626,1371043861,1 +332995,1540949627,1540949628,1 +332996,1540949628,1540949629,1 +332997,1540949629,1540949630,1 +332998,1540949630,1540949631,1 +332999,1540949631,1371043820,1 +333000,1540949632,1540949633,1 +333001,1540949633,810716445,1 +333002,1540949634,1540949635,1 +333003,1540949635,1540949636,1 +333004,1540949636,1540949637,1 +333005,1540949637,1540949638,1 +333006,1540949638,1540949639,1 +333007,1540949639,1540949640,1 +333008,1540949640,1540949641,1 +333009,1540949641,1540949642,1 +333010,1540949642,1540949643,1 +333011,1540949643,1540949644,1 +333012,1540949644,1540949645,1 +333013,1540949645,1540949646,1 +333014,1540949646,1540949647,1 +333015,1540949647,1540949648,1 +333016,1540949648,1540949649,1 +333017,1540949649,1540949650,1 +333018,1540949650,1371044356,1 +333019,1540949651,1540949652,1 +333020,1540949652,1540949653,1 +333021,1540949653,1540949654,1 +333022,1540949654,1371044354,1 +333023,1540949655,1371044398,1 +333024,1540949656,1540949657,1 +333025,1540949657,1540949658,1 +333026,1540949658,1371044449,1 +333027,1540949659,1038225162,1 +333028,1540949660,1371044523,1 +333029,1540949661,1540949662,0 +333030,1540949662,1540949663,0 +333031,1540949663,1540949664,0 +333032,1540949664,1371044480,0 +333033,1540949665,1540949666,0 +333034,1540949666,1540949667,0 +333035,1540949667,1540949668,0 +333036,1540949668,1371044459,0 +333037,1540949669,1540949670,0 +333038,1540949670,1540949671,0 +333039,1540949671,1540949672,0 +333040,1540949672,1371044448,0 +333041,1540949673,1540949674,0 +333042,1540949674,1540949675,0 +333043,1540949675,1371044471,0 +333044,1540949676,1371044018,1 +333045,1540949677,1371044561,1 +333046,1540949678,1038225120,1 +333047,1540949679,1540949680,1 +333048,1540949680,1540949681,1 +333049,1540949681,1540949682,1 +333050,1540949682,1540949683,1 +333051,1540949683,1540949684,1 +333052,1540949684,1540949685,1 +333053,1540949685,1540949686,1 +333054,1540949686,1540949687,1 +333055,1540949687,1371044144,1 +333056,1540949688,1540949689,1 +333057,1540949689,1540949690,1 +333058,1540949690,1540949691,1 +333059,1540949691,1371044166,1 +333060,1540949692,1540949693,1 +333061,1540949693,1371044184,1 +333062,1540949694,1540949695,1 +333063,1540949695,1540949696,1 +333064,1540949696,1371044229,1 +333065,1540949697,1540949698,1 +333066,1540949698,1540949699,1 +333067,1540949699,1540949700,1 +333068,1540949700,1371044253,1 +333069,1540949701,1540949702,1 +333070,1540949702,1540949703,1 +333071,1540949703,1540949704,1 +333072,1540949704,1540949705,1 +333073,1540949705,1371043850,1 +333074,1540949706,1540949707,1 +333075,1540949707,1371043865,1 +333076,1540949708,1540949709,1 +333077,1540949709,1371043887,1 +333078,1540949710,1371043915,1 +333079,1540949711,1540949712,1 +333080,1540949712,1540949713,1 +333081,1540949713,1540949714,1 +333082,1540949714,1540949715,1 +333083,1540949715,1371043988,1 +333084,1540949716,1540949717,1 +333085,1540949717,1540949718,1 +333086,1540949718,1540949719,1 +333087,1540949719,1371044014,1 +333088,1540949720,1540949721,1 +333089,1540949721,1371044022,1 +333090,1540949722,1540949723,1 +333091,1540949723,1540949724,1 +333092,1540949724,1540949725,1 +333093,1540949725,1371043890,1 +333094,1540949726,1371043896,1 +333095,1540949727,1540949728,1 +333096,1540949728,1540949729,1 +333097,1540949729,1540949730,1 +333098,1540949730,1371043983,1 +333099,1540949731,1540949732,1 +333100,1540949732,1540949733,1 +333101,1540949733,1540949734,1 +333102,1540949734,1371043996,1 +333103,1540949735,1540949736,1 +333104,1540949736,1540949737,1 +333105,1540949737,1540949738,1 +333106,1540949738,1540949739,1 +333107,1540949739,1540949740,1 +333108,1540949740,1371043965,1 +333109,1540949741,1540949742,1 +333110,1540949742,1540949743,1 +333111,1540949743,1540949744,1 +333112,1540949744,1540949745,1 +333113,1540949745,1371043907,1 +333114,1540949746,1540949747,1 +333115,1540949747,810716447,1 +333116,1540949748,1371044534,1 +333117,1540949749,1371044034,1 +333118,1540949750,1540949751,1 +333119,1540949751,810716450,1 +333120,1540949752,1540949753,1 +333121,1540949753,1540949754,1 +333122,1540949754,1540949755,1 +333123,1540949755,1371044561,1 +333124,1540949756,1540949757,1 +333125,1540949757,1371044555,1 +333126,1540949758,1540949759,1 +333127,1540949759,1371044543,1 +333128,1540949760,1540949761,1 +333129,1540949761,1371044511,1 +333130,1540949762,1371044437,1 +333131,1540949763,1371044419,1 +333132,1540949764,1371044365,1 +333133,1540949765,1540949766,1 +333134,1540949766,1540949767,1 +333135,1540949767,1371044262,1 +333136,1540949768,1540949769,1 +333137,1540949769,1540949770,1 +333138,1540949770,1540949771,1 +333139,1540949771,1540949772,1 +333140,1540949772,1540949773,1 +333141,1540949773,1540949774,1 +333142,1540949774,1371044130,1 +333143,1540949775,1540949776,1 +333144,1540949776,1540949777,1 +333145,1540949777,560944990,1 +333146,1540949778,1371044534,1 +333147,1540949779,1371044553,1 +333148,1540949780,1371044185,1 +333149,1540949781,1371044202,1 +333150,1540949782,1371044185,1 +333151,1540949783,1371044061,1 +333152,1540949784,1540949785,1 +333153,1540949785,1540949786,1 +333154,1540949786,1540949787,1 +333155,1540949787,1037361744,1 +333156,1540949788,1540949789,1 +333157,1540949789,1371044074,1 +333158,1540949790,1371044363,1 +333159,1540949791,1371044144,1 +333160,1540949792,1540949793,1 +333161,1540949793,1540949794,1 +333162,1540949794,1540949795,1 +333163,1540949795,789215874,1 +333164,1540949796,1540949797,1 +333165,1540949797,1540949798,1 +333166,1540949798,1371043961,1 +333167,1540949799,1540949800,1 +333168,1540949800,1371044114,1 +333169,1540949801,1371044128,1 +333170,1540949802,1371044000,1 +333171,1540949803,1540949804,1 +333172,1540949804,1540949805,1 +333173,1540949805,1371044012,1 +333174,1540949806,1540949807,1 +333175,1540949807,1371044502,1 +333176,1540949808,1540949809,1 +333177,1540949809,1371044538,1 +333178,1540949810,1371044562,1 +333179,1540949811,1540949812,1 +333180,1540949812,1540949813,1 +333181,1540949813,1540949814,1 +333182,1540949814,1540949815,1 +333183,1540949815,1540949816,1 +333184,1540949816,1540949817,1 +333185,1540949817,1540949818,1 +333186,1540949818,1480413415,1 +333187,1540949819,1540949820,1 +333188,1540949820,1540949821,1 +333189,1540949821,1371044541,1 +333190,1540949822,1371044533,1 +333191,1540949823,365388275,1 +333192,1540949824,1540949825,1 +333193,1540949825,1540949826,1 +333194,1540949826,1540949827,1 +333195,1540949827,1540949828,1 +333196,1540949828,1540949829,1 +333197,1540949829,1540949830,1 +333198,1540949830,1371043836,1 +333199,1540949831,1540949832,1 +333200,1540949832,1540949833,1 +333201,1540949833,1540949834,1 +333202,1540949834,1540949835,1 +333203,1540949835,1540949836,1 +333204,1540949836,1540949837,1 +333205,1540949837,1371125538,1 +333206,1540949838,1371125571,1 +333207,1540949839,1540949840,1 +333208,1540949840,1540949841,1 +333209,1540949841,1540949842,1 +333210,1540949842,1540949843,1 +333211,1540949843,1540949844,1 +333212,1540949844,1540949845,1 +333213,1540949845,1540949846,1 +333214,1540949846,1540949847,1 +333215,1540949847,1540949848,1 +333216,1540949848,1540949849,1 +333217,1540949849,1540949850,1 +333218,1540949850,1540949851,1 +333219,1540949851,704804622,1 +333220,1540949852,704804634,1 +333221,1540949853,1540949854,1 +333222,1540949854,1540949855,1 +333223,1540949855,1540949856,1 +333224,1540949856,1540949857,1 +333225,1540949857,1540949858,1 +333226,1540949858,1540949859,1 +333227,1540949859,1540949860,1 +333228,1540949860,789215894,1 +333229,1540949861,1540949862,1 +333230,1540949862,1540949863,1 +333231,1540949863,1540949864,1 +333232,1540949864,1371125030,1 +333233,1540949865,1540949866,1 +333234,1540949866,1540949867,1 +333235,1540949867,1371125021,1 +333236,1540949868,1540949869,1 +333237,1540949869,1540949870,1 +333238,1540949870,1540949871,1 +333239,1540949871,1371125290,1 +333240,1540949872,1540949873,1 +333241,1540949873,1371125217,1 +333242,1540949874,1371125662,1 +333243,1540949875,1540949876,1 +333244,1540949876,1540949877,1 +333245,1540949877,1540949878,1 +333246,1540949878,1540949879,1 +333247,1540949879,1540949880,1 +333248,1540949880,1540949881,1 +333249,1540949881,1540949882,1 +333250,1540949882,1540949883,1 +333251,1540949883,1371125704,1 +333252,1540949884,1540949885,1 +333253,1540949885,1540949886,1 +333254,1540949886,1371043825,1 +333255,1540949887,1371125558,1 +333256,1540949888,1540949889,1 +333257,1540949889,1540949890,1 +333258,1540949890,1540949891,1 +333259,1540949891,1371125497,1 +333260,1540949892,1540949893,1 +333261,1540949893,1540949894,1 +333262,1540949894,1371125139,1 +333263,1540949895,1540949896,1 +333264,1540949896,1540949897,1 +333265,1540949897,1540949898,1 +333266,1540949898,1540949899,1 +333267,1540949899,1540949900,1 +333268,1540949900,1540949901,1 +333269,1540949901,1371125324,1 +333270,1540949902,1540949903,1 +333271,1540949903,1540949904,1 +333272,1540949904,1540949905,1 +333273,1540949905,1371125591,1 +333274,1540949906,1540949907,1 +333275,1540949907,1371125618,1 +333276,1540949908,1540949909,1 +333277,1540949909,1540949910,1 +333278,1540949910,1371125634,1 +333279,1540949911,1540949912,1 +333280,1540949912,789215894,1 +333281,1540949913,1540949914,1 +333282,1540949914,1371125613,1 +333283,1540949915,1371125571,1 +333284,1540949916,704804636,1 +333285,1540949917,1371125565,1 +333286,1540949918,1371125593,1 +333287,1540949919,1540949920,1 +333288,1540949920,1540949921,1 +333289,1540949921,789215885,1 +333290,1540949922,1540949923,1 +333291,1540949923,1540949924,1 +333292,1540949924,1540949925,1 +333293,1540949925,1371125662,1 +333294,1540949926,1540949927,1 +333295,1540949927,704804657,1 +333296,1540949928,1540949929,1 +333297,1540949929,1371125024,1 +333298,1540949930,1540949931,1 +333299,1540949931,1540949932,1 +333300,1540949932,1540949933,1 +333301,1540949933,1371125184,1 +333302,1540949934,704804634,1 +333303,1540949935,1540949936,1 +333304,1540949936,1540949937,1 +333305,1540949937,1540949938,1 +333306,1540949938,1540949939,1 +333307,1540949939,1540949940,1 +333308,1540949940,1540949941,1 +333309,1540949941,1371124993,1 +333310,1540949942,1540949943,1 +333311,1540949943,1540949944,1 +333312,1540949944,1371125078,1 +333313,1540949945,1371125170,1 +333314,1540949946,1540949947,1 +333315,1540949947,1540949948,1 +333316,1540949948,1540949949,1 +333317,1540949949,1540949950,1 +333318,1540949950,1540949951,1 +333319,1540949951,1540949952,1 +333320,1540949952,1371125372,1 +333321,1540949953,1540949954,1 +333322,1540949954,1540949955,1 +333323,1540949955,1540949956,1 +333324,1540949956,1540949957,1 +333325,1540949957,1540949958,1 +333326,1540949958,1540949959,1 +333327,1540949959,1371125256,1 +333328,1540949960,1540949961,1 +333329,1540949961,1540949962,1 +333330,1540949962,1540949963,1 +333331,1540949963,1540949964,1 +333332,1540949964,1540949965,1 +333333,1540949965,1540949966,1 +333334,1540949966,1540949967,1 +333335,1540949967,1540949968,1 +333336,1540949968,1540949969,1 +333337,1540949969,1540949970,1 +333338,1540949970,1540949971,1 +333339,1540949971,1540949972,1 +333340,1540949972,1540949973,1 +333341,1540949973,1371125098,1 +333342,1540949974,1540949975,1 +333343,1540949975,1371125295,1 +333344,1540949976,1540949977,1 +333345,1540949977,1540949978,1 +333346,1540949978,1540949979,1 +333347,1540949979,1540949980,1 +333348,1540949980,1540949981,1 +333349,1540949981,1540949982,1 +333350,1540949982,1371125380,1 +333351,1540949983,1540949984,1 +333352,1540949984,1540949985,1 +333353,1540949985,789215839,1 +333354,1540949986,1540949987,1 +333355,1540949987,1540949988,1 +333356,1540949988,1540949989,1 +333357,1540949989,1540949990,1 +333358,1540949990,1540949991,1 +333359,1540949991,1540949992,1 +333360,1540949992,1540949993,1 +333361,1540949993,1540949994,1 +333362,1540949994,1540949995,1 +333363,1540949995,1540949996,1 +333364,1540949996,1540949997,1 +333365,1540949997,1540949998,1 +333366,1540949998,1540949999,1 +333367,1540949999,278012122,1 +333368,1540950000,278012066,1 +333369,1540950001,1540950002,1 +333370,1540950002,1540950003,1 +333371,1540950003,1371125642,1 +333372,1540950004,1540950005,1 +333373,1540950005,1540950006,1 +333374,1540950006,1540950007,1 +333375,1540950007,1540950008,1 +333376,1540950008,1540950009,1 +333377,1540950009,1371125554,1 +333378,1540950010,1540950011,1 +333379,1540950011,1540950012,1 +333380,1540950012,1540950013,1 +333381,1540950013,1540950014,1 +333382,1540950014,1540950015,1 +333383,1540950015,1371125366,1 +333384,1540950016,1540950017,1 +333385,1540950017,1540950018,1 +333386,1540950018,1540950019,1 +333387,1540950019,1540950020,1 +333388,1540950020,1540950021,1 +333389,1540950021,1540950022,1 +333390,1540950022,1540950023,1 +333391,1540950023,1540950024,1 +333392,1540950024,1540950025,1 +333393,1540950025,1371125039,1 +333394,1540950026,1540950027,1 +333395,1540950027,1540950028,1 +333396,1540950028,1540950029,1 +333397,1540950029,1371125158,1 +333398,1540950030,1540950031,1 +333399,1540950031,1540950032,1 +333400,1540950032,1540950033,1 +333401,1540950033,1540950034,1 +333402,1540950034,1371125325,1 +333403,1540950035,1540950036,1 +333404,1540950036,1540950037,1 +333405,1540950037,1371125672,1 +333406,1540950038,1540950039,1 +333407,1540950039,1371125684,1 +333408,1540950040,1540950041,1 +333409,1540950041,1540950042,1 +333410,1540950042,1540950043,1 +333411,1540950043,1371125688,1 +333412,1540950044,1540950045,1 +333413,1540950045,1540950046,1 +333414,1540950046,1371125686,1 +333415,1540950047,1540950048,1 +333416,1540950048,1540950049,1 +333417,1540950049,1540950050,1 +333418,1540950050,1371125704,1 +333419,1540950051,1540950052,1 +333420,1540950052,1540950053,1 +333421,1540950053,1540950054,1 +333422,1540950054,1540950055,1 +333423,1540950055,1371125497,1 +333424,1540950056,1540950057,1 +333425,1540950057,1540950058,1 +333426,1540950058,1540950059,1 +333427,1540950059,1371125360,1 +333428,1540950060,1540950061,1 +333429,1540950061,1540950062,1 +333430,1540950062,1540950063,1 +333431,1540950063,1540950064,1 +333432,1540950064,1371125161,1 +333433,1540950065,1540950066,1 +333434,1540950066,1371125131,1 +333435,1540950067,1540950068,1 +333436,1540950068,1540950069,1 +333437,1540950069,1540950070,1 +333438,1540950070,1540950071,1 +333439,1540950071,1540950072,1 +333440,1540950072,1540950073,1 +333441,1540950073,1371125421,1 +333442,1540950074,1540950075,1 +333443,1540950075,1540950076,1 +333444,1540950076,1371125435,1 +333445,1540950077,1540950078,1 +333446,1540950078,1540950079,1 +333447,1540950079,1371125355,1 +333448,1540950080,1540950081,1 +333449,1540950081,1540950082,1 +333450,1540950082,1540950083,1 +333451,1540950083,1540950084,1 +333452,1540950084,1371125181,1 +333453,1540950085,1371125098,1 +333454,1540950086,1540950087,1 +333455,1540950087,1540950088,1 +333456,1540950088,1371125427,1 +333457,1540950089,1371125454,1 +333458,1540950090,1371125466,1 +333459,1540950091,1540950092,1 +333460,1540950092,1371125477,1 +333461,1540950093,1371125457,1 +333462,1540950094,1540950095,1 +333463,1540950095,1540950096,1 +333464,1540950096,1540950097,1 +333465,1540950097,1540950098,1 +333466,1540950098,1371125350,1 +333467,1540950099,1540950100,1 +333468,1540950100,1540950101,1 +333469,1540950101,1371125206,1 +333470,1540950102,1540950103,1 +333471,1540950103,1371125131,1 +333472,1540950104,1371125699,1 +333473,1540950105,1371125538,1 +333474,1540950106,1371125375,1 +333475,1540950107,1371125665,1 +333476,1540950108,1371125536,1 +333477,1540950109,1540950110,1 +333478,1540950110,1371125673,1 +333479,1540950111,1540950112,1 +333480,1540950112,1371124965,1 +333481,1540950113,789215837,1 +333482,1540950114,1540950115,1 +333483,1540950115,1540950116,1 +333484,1540950116,1371125642,1 +333485,1540950117,1371124902,1 +333486,1540950118,1371124898,1 +333487,1540950119,1540950120,1 +333488,1540950120,1540950121,1 +333489,1540950121,1371125656,1 +333490,1540950122,1540950123,1 +333491,1540950123,1540950124,1 +333492,1540950124,1371125709,1 +333493,1540950125,1540950126,1 +333494,1540950126,1540950127,1 +333495,1540950127,1371125324,1 +333496,1540950128,1540950129,1 +333497,1540950129,1371125634,1 +333498,1540950130,1540950131,1 +333499,1540950131,1371125656,1 +333500,1540950132,1540950133,1 +333501,1540950133,1371125115,1 +333502,1540950134,1540950135,1 +333503,1540950135,1371125024,1 +333504,1540950136,1371124965,1 +333505,1540950137,1371124935,1 +333506,1540950138,1371125094,0 +333507,1540950139,789215839,1 +333508,1540950140,1540950141,1 +333509,1540950141,789215843,1 +333510,1540950142,789215847,1 +333511,1540950143,789215853,1 +333512,1540950144,1371125638,1 +333513,1540950145,1540950146,1 +333514,1540950146,1540950147,1 +333515,1540950147,1540950148,1 +333516,1540950148,1540950149,1 +333517,1540950149,1540950150,1 +333518,1540950150,789215866,1 +333519,1540950151,1540950152,1 +333520,1540950152,1540950153,1 +333521,1540950153,1540950154,1 +333522,1540950154,1540950155,1 +333523,1540950155,1540950156,1 +333524,1540950156,1540950157,1 +333525,1540950157,1540950158,1 +333526,1540950158,1184260752,1 +333685,1540950317,1540950318,1 +333686,1540950318,1540950319,1 +333687,1540950319,1540950320,1 +333688,1540950320,1371477967,1 +333759,1540950391,1540950392,1 +333760,1540950392,1540950393,1 +333761,1540950393,1540950394,1 +333762,1540950394,1540950395,1 +333763,1540950395,1540950396,1 +333764,1540950396,1540950397,1 +333765,1540950397,1345231654,1 +333813,1540950445,1540950446,0 +333814,1540950446,1374274153,0 +333815,1540950447,1540950448,0 +334106,1540950738,155587524,0 +334107,1540950739,1540950740,0 +334108,1540950740,1540950741,0 +334109,1540950741,963987470,0 +334110,1540950742,1540950743,0 +334111,1540950743,1540950744,0 +334112,1540950744,1540950745,0 +334113,1540950745,1540950746,0 +334114,1540950746,1540950747,0 +334115,1540950747,1540950748,0 +334116,1540950748,1540950749,0 +334117,1540950749,963987494,0 +334118,1540950750,1540950751,0 +334119,1540950751,1540950752,0 +334120,1540950752,1540950753,0 +334143,1540950775,360211857,0 +334301,1540950933,1540950934,1 +334302,1540950934,1540950935,1 +334303,1540950935,1540950936,1 +334304,1540950936,1540950937,1 +334305,1540950937,1540950938,1 +334306,1540950938,1540950939,1 +334307,1540950939,1385836393,1 +334710,1540951342,1387911658,1 +334711,1540951343,972481665,0 +334712,1540951344,1540951345,1 +334713,1540951345,1540951346,1 +334714,1540951346,1540951347,1 +334715,1540951347,1540951348,1 +334716,1540951348,1540951349,1 +334717,1540951349,1540951350,1 +334718,1540951350,1540951351,1 +334719,1540951351,1540951352,1 +334720,1540951352,1540951353,1 +334721,1540951353,1540951354,1 +334722,1540951354,1540951355,1 +334723,1540951355,1540951356,1 +334724,1540951356,1540951357,1 +334725,1540951357,1540951358,1 +334726,1540951358,1540951359,1 +334727,1540951359,1540951360,1 +334728,1540951360,1540951361,1 +334729,1540951361,1540951362,1 +334730,1540951362,1540951363,1 +334731,1540951363,1540951364,1 +334732,1540951364,1540951365,1 +334733,1540951365,1540951366,1 +334734,1540951366,1540951367,1 +334735,1540951367,1540951368,1 +334736,1540951368,1540951369,1 +334737,1540951369,1540951370,1 +334738,1540951370,1540951371,1 +334739,1540951371,1540951372,1 +334740,1540951372,1540951373,1 +334741,1540951373,1540951374,1 +334742,1540951374,1540951375,1 +334743,1540951375,1540951376,1 +334744,1540951376,1540951377,1 +334745,1540951377,1540951378,1 +334746,1540951378,1540951379,1 +334747,1540951379,600400026,1 +334748,1540951380,974066704,1 +334749,1540951381,360206846,1 +334750,1540951382,279591055,1 +334751,1540951383,279589959,1 +334752,1540951384,279591062,1 +334753,1540951385,1540951386,1 +334754,1540951386,1540951387,1 +334755,1540951387,279590130,1 +334756,1540951388,974067171,1 +334757,1540951389,1540951390,1 +334758,1540951390,1540951391,1 +334759,1540951391,974066281,1 +334760,1540951392,974067361,1 +334761,1540951393,1387915874,0 +334762,1540951394,1540951395,1 +334763,1540951395,1540951396,1 +334764,1540951396,279591454,1 +334765,1540951397,1540951398,1 +334766,1540951398,1540951399,1 +334767,1540951399,279591415,1 +334768,1540951400,1540951401,1 +334769,1540951401,1540951402,1 +334770,1540951402,279591457,1 +334771,1540951403,1540951404,1 +334772,1540951404,1540951405,1 +334773,1540951405,1540951406,1 +334774,1540951406,974031018,1 +334775,1540951407,279591459,1 +334776,1540951408,1540951409,1 +334777,1540951409,1540951410,1 +334778,1540951410,1540951411,1 +334779,1540951411,1540951412,1 +334780,1540951412,278009538,1 +334781,1540951413,972481687,0 +334782,1540951414,1540951415,0 +334783,1540951415,1540951416,0 +334784,1540951416,972481953,0 +334940,1540951572,1540951573,1 +334941,1540951573,360006879,1 +334942,1540951574,981693546,1 +336035,1540952667,360012539,1 +336036,1540952668,1540952669,1 +336037,1540952669,601017585,1 +336038,1540952670,1540952671,1 +336039,1540952671,1540952672,1 +336040,1540952672,1540952673,1 +336041,1540952673,891523982,1 +336231,1540952863,1411198243,1 +336232,1540952864,1540952865,1 +336233,1540952865,1540952866,1 +336234,1540952866,1540952867,1 +336235,1540952867,1411198209,1 +336236,1540952868,1411198297,1 +336496,1540953128,1540953129,1 +336497,1540953129,1411198323,1 +336498,1540953130,1540953131,1 +336499,1540953131,1540953132,1 +336500,1540953132,1540953133,1 +336501,1540953133,1540953134,1 +336502,1540953134,1113561541,1 +336503,1540953135,984634597,1 +336504,1540953136,1540953137,1 +336505,1540953137,1540953138,1 +336506,1540953138,1540953139,1 +336507,1540953139,1540953140,1 +336508,1540953140,1540953141,1 +336509,1540953141,1411198209,1 +336510,1540953142,737307347,1 +336511,1540953143,1540953144,1 +336512,1540953144,1540953145,1 +336513,1540953145,1540953146,1 +336514,1540953146,1540953147,1 +336515,1540953147,1540953148,1 +336516,1540953148,1540953149,1 +336517,1540953149,1540953150,1 +336518,1540953150,1540953151,1 +336519,1540953151,1540953152,1 +336520,1540953152,1540953153,1 +336521,1540953153,984634005,1 +336522,1540953154,1411198175,1 +336523,1540953155,1411198277,1 +336524,1540953156,1540953157,1 +336525,1540953157,1411198256,1 +336526,1540953158,981693556,1 +336527,1540953159,984634330,1 +336528,1540953160,1411198429,1 +336529,1540953161,1540953162,1 +336530,1540953162,1411198203,1 +336531,1540953163,1540953164,1 +336532,1540953164,985968666,1 +336533,1540953165,1540953166,1 +336534,1540953166,1411198190,1 +336535,1540953167,1411198409,1 +336536,1540953168,1540953169,1 +336537,1540953169,1411198419,1 +336538,1540953170,1540953171,1 +336539,1540953171,1540953172,1 +336540,1540953172,1411198368,1 +336541,1540953173,360010188,1 +336542,1540953174,1540953175,1 +336543,1540953175,1540953176,1 +336544,1540953176,1411198315,1 +336545,1540953177,1411198401,1 +336546,1540953178,1540953179,1 +336547,1540953179,1540953180,1 +336548,1540953180,1540953181,1 +336549,1540953181,984634563,1 +336550,1540953182,1540953183,1 +336551,1540953183,1540953184,1 +336552,1540953184,1411198277,1 +336553,1540953185,1540953186,1 +336554,1540953186,1540953187,1 +336555,1540953187,1540953188,1 +336556,1540953188,1540953189,1 +336557,1540953189,1540953190,1 +336558,1540953190,1411198386,1 +336559,1540953191,1540953192,1 +336560,1540953192,1540953193,1 +336561,1540953193,1411198387,1 +336562,1540953194,1540953195,1 +336563,1540953195,1113561537,1 +336564,1540953196,1540953197,1 +336565,1540953197,1540953198,1 +336566,1540953198,1411198252,1 +336567,1540953199,1411198242,1 +336568,1540953200,360008830,0 +336569,1540953201,360006483,0 +336570,1540953202,360006487,0 +336571,1540953203,1411198131,0 +336572,1540953204,1411198134,0 +336573,1540953205,1540953206,0 +336574,1540953206,1411198148,0 +336575,1540953207,1411198158,0 +336576,1540953208,360006477,0 +336577,1540953209,1540953210,1 +336578,1540953210,1540953211,1 +336579,1540953211,1540953212,1 +336580,1540953212,1540953213,1 +336581,1540953213,1540953214,1 +336582,1540953214,1540953215,1 +336583,1540953215,1540953216,1 +336584,1540953216,1540953217,1 +336585,1540953217,1540953218,1 +336586,1540953218,1175962890,1 +336587,1540953219,1540953220,1 +336588,1540953220,1540953221,1 +336589,1540953221,1540953222,1 +336590,1540953222,1540953223,1 +336591,1540953223,1540953224,1 +336592,1540953224,1540953225,1 +336593,1540953225,1540953226,1 +336594,1540953226,1540953227,1 +336595,1540953227,1540953228,1 +336596,1540953228,1540953229,1 +336597,1540953229,278007900,1 +336598,1540953230,1540953231,1 +336599,1540953231,1540953232,1 +336600,1540953232,278008163,1 +336601,1540953233,1540953234,1 +336602,1540953234,1540953235,1 +336603,1540953235,1540953236,1 +336604,1540953236,1540953237,1 +336605,1540953237,1540953238,1 +336606,1540953238,1540953239,1 +336607,1540953239,1540953240,1 +336608,1540953240,1540953241,1 +336609,1540953241,1540953242,1 +336610,1540953242,1540953243,1 +336611,1540953243,1540953244,1 +336612,1540953244,1540953245,1 +336613,1540953245,1540953246,1 +336614,1540953246,1540953247,1 +336615,1540953247,1540953248,1 +336616,1540953248,1540953249,1 +336617,1540953249,278008182,1 +336618,1540953250,1540953251,1 +336619,1540953251,1540953252,1 +336620,1540953252,1540953253,1 +336621,1540953253,1540953254,1 +336622,1540953254,1540953255,1 +336623,1540953255,1540953256,1 +336624,1540953256,1540953257,1 +336625,1540953257,1540953258,1 +336626,1540953258,1540953259,1 +336627,1540953259,1540953260,1 +336628,1540953260,278008196,1 +336629,1540953261,1540953262,1 +336630,1540953262,1540953263,1 +336631,1540953263,278008200,1 +336632,1540953264,1540953265,1 +336633,1540953265,1540953266,1 +336634,1540953266,278008204,1 +336635,1540953267,1540953268,1 +336636,1540953268,1540953269,1 +336637,1540953269,278008208,1 +336638,1540953270,1540953271,1 +336639,1540953271,278009544,1 +336640,1540953272,1540953273,1 +336641,1540953273,1540953274,1 +336642,1540953274,1540953275,1 +336643,1540953275,278009550,1 +336644,1540953276,1540953277,1 +336645,1540953277,1540953278,1 +336646,1540953278,1540953279,1 +336647,1540953279,278009554,1 +336648,1540953280,1371124946,1 +336649,1540953281,1540953282,1 +336650,1540953282,1371125001,1 +336651,1540953283,1540953284,1 +336652,1540953284,1540953285,1 +336653,1540953285,1540953286,1 +336654,1540953286,1540953287,1 +336655,1540953287,1540953288,1 +336656,1540953288,1540953289,1 +336657,1540953289,1540953290,1 +336658,1540953290,1540953291,1 +336659,1540953291,1540953292,1 +336660,1540953292,1540953293,1 +336661,1540953293,1540953294,1 +336662,1540953294,286077933,1 +336663,1540953295,1037131187,1 +336664,1540953296,1037130880,1 +336665,1540953297,278009571,1 +336666,1540953298,1540953299,1 +336667,1540953299,1540953300,1 +336668,1540953300,278009575,1 +336669,1540953301,278009577,1 +336670,1540953302,1540953303,1 +336671,1540953303,1540953304,1 +336672,1540953304,1037130885,1 +336673,1540953305,1540953306,1 +336674,1540953306,1540953307,1 +336675,1540953307,1036627996,1 +336676,1540953308,278009589,1 +336677,1540953309,278009592,1 +336678,1540953310,1036415652,1 +336679,1540953311,1036415699,1 +336680,1540953312,1540953313,1 +336681,1540953313,278009599,1 +336682,1540953314,278009600,1 +336700,1540953332,1411219070,1 +336701,1540953333,788840159,1 +336702,1540953334,1540953335,1 +336703,1540953335,1540953336,1 +336704,1540953336,1540953337,1 +336705,1540953337,1540953338,1 +336706,1540953338,1540953339,1 +336707,1540953339,788839873,1 +336708,1540953340,774085168,1 +336709,1540953341,775868313,1 +336710,1540953342,1333810274,1 +336711,1540953343,1540953344,1 +336712,1540953344,774085173,1 +336713,1540953345,1540953346,1 +336714,1540953346,1540953347,1 +336715,1540953347,1540953348,1 +336716,1540953348,1411219066,1 +344742,1540961374,737311467,1 +344743,1540961375,1540961376,1 +344744,1540961376,1540961377,1 +344745,1540961377,1540961378,1 +344746,1540961378,985968917,1 +344747,1540961379,737311465,1 +344748,1540961380,985968910,1 +344749,1540961381,1540961382,1 +344750,1540961382,737311467,1 +344751,1540961383,737311475,1 +344752,1540961384,737311477,1 +344753,1540961385,1540961386,1 +344754,1540961386,1540961387,1 +344755,1540961387,1540961388,1 +344756,1540961388,1540961389,1 +344757,1540961389,1540961390,1 +344758,1540961390,1540961391,1 +344759,1540961391,737998371,1 +344760,1540961392,1540961393,1 +344761,1540961393,1540961394,1 +344762,1540961394,1540961395,1 +344763,1540961395,1540961396,1 +344764,1540961396,1540961397,1 +344765,1540961397,1540961398,1 +344766,1540961398,1482899198,1 +344767,1540961399,1540961400,1 +344768,1540961400,737998390,1 +344769,1540961401,1540961402,1 +344770,1540961402,737998283,1 +344771,1540961403,1540961404,1 +344772,1540961404,1540961405,1 +344773,1540961405,1540961406,1 +344774,1540961406,279590323,1 +344775,1540961407,737998414,1 +344776,1540961408,1540961409,1 +344777,1540961409,1540961410,1 +344778,1540961410,1540961411,1 +344779,1540961411,1540961412,1 +344780,1540961412,1540961413,1 +344781,1540961413,737998430,1 +344782,1540961414,1540961415,1 +344783,1540961415,1540961416,1 +344784,1540961416,1540961417,1 +344785,1540961417,1540961418,1 +344786,1540961418,1482903115,1 +345774,1540962406,1540962407,1 +345775,1540962407,1540962408,1 +345776,1540962408,1540962409,1 +345777,1540962409,1540962410,1 +345778,1540962410,1540962411,1 +345779,1540962411,1540962412,1 +345780,1540962412,1540962413,1 +345781,1540962413,1540962414,1 +345782,1540962414,1540962415,1 +345783,1540962415,1540962416,1 +345784,1540962416,1172380425,1 +345785,1540962417,1540962418,1 +345786,1540962418,1540962419,1 +345787,1540962419,1540962420,1 +345788,1540962420,1540962421,1 +345789,1540962421,1540962422,1 +345790,1540962422,1540962423,1 +345791,1540962423,1540962424,1 +345792,1540962424,1540962425,1 +345793,1540962425,1172380260,1 +345794,1540962426,1540962427,1 +345795,1540962427,1540962428,1 +345796,1540962428,1172380342,1 +345797,1540962429,1540962430,1 +345798,1540962430,1540962431,1 +345799,1540962431,1540962432,1 +345800,1540962432,1540962433,1 +345801,1540962433,1540962434,1 +345802,1540962434,1540962435,1 +345803,1540962435,1540962436,1 +345804,1540962436,1540962437,1 +345805,1540962437,1540962438,1 +345806,1540962438,1540962439,1 +345807,1540962439,1172380409,1 +345808,1540962440,1540962441,1 +345809,1540962441,1540962442,1 +345810,1540962442,1540962443,1 +345811,1540962443,1540962444,1 +345812,1540962444,1540962445,1 +345813,1540962445,1540962446,1 +345814,1540962446,1540962447,1 +345815,1540962447,1172380271,1 +345816,1540962448,1540962449,1 +345817,1540962449,1540962450,1 +345818,1540962450,1540962451,1 +345819,1540962451,1540962452,1 +345820,1540962452,1540962453,1 +345821,1540962453,1540962454,1 +345822,1540962454,1540962455,1 +345823,1540962455,1540962456,1 +345824,1540962456,1540962457,1 +345825,1540962457,1540962458,1 +345826,1540962458,1540962459,1 +345827,1540962459,1540962460,1 +345828,1540962460,1540962461,1 +345829,1540962461,1540962462,1 +345830,1540962462,1540962463,1 +345831,1540962463,1540962464,1 +345832,1540962464,1540962465,1 +345833,1540962465,1540962466,1 +345834,1540962466,1540962467,1 +345835,1540962467,1540962468,1 +345836,1540962468,1540962469,1 +345837,1540962469,1540962470,1 +345838,1540962470,1540962471,1 +345839,1540962471,1540962472,1 +345840,1540962472,1540962473,1 +345841,1540962473,1540962474,1 +345842,1540962474,1540962475,1 +345843,1540962475,1540962476,1 +345844,1540962476,1540962477,1 +345845,1540962477,1540962478,1 +345846,1540962478,1540962479,1 +345847,1540962479,1540962480,1 +345848,1540962480,1540962481,1 +345849,1540962481,1540962482,1 +345850,1540962482,1540962483,1 +345851,1540962483,1540962484,1 +345852,1540962484,1172380410,1 +346062,1540962694,360192306,1 +346063,1540962695,360191387,1 +346064,1540962696,1540962697,0 +346065,1540962697,360190999,0 +346066,1540962698,972481839,0 +346067,1540962699,360469614,1 +346068,1540962700,360469893,1 +346069,1540962701,360468050,1 +346070,1540962702,706002877,1 +346071,1540962703,360473619,1 +346072,1540962704,360473619,0 +346279,1540962911,736968933,1 +346280,1540962912,737300234,1 +346281,1540962913,737253290,1 +346282,1540962914,737253235,1 +346283,1540962915,1540962916,1 +346284,1540962916,737260644,1 +346285,1540962917,737253199,1 +346286,1540962918,736968944,1 +346287,1540962919,736604731,1 +346288,1540962920,736607234,1 +346289,1540962921,737258698,1 +346290,1540962922,1540962923,1 +346291,1540962923,736607240,1 +346580,1540963212,360224995,0 +346581,1540963213,1540963214,1 +346582,1540963214,1540963215,1 +346583,1540963215,1540963216,1 +346584,1540963216,1540963217,1 +346585,1540963217,1540963218,1 +346586,1540963218,1540963219,1 +346587,1540963219,1540963220,1 +346588,1540963220,1540963221,1 +346589,1540963221,1540963222,1 +346590,1540963222,1540963223,1 +346591,1540963223,1540963224,1 +346592,1540963224,360206868,1 +346593,1540963225,1163936685,1 +346594,1540963226,1540963227,1 +346595,1540963227,1540963228,1 +346596,1540963228,1540963229,1 +346597,1540963229,1540963230,1 +346598,1540963230,1540963231,1 +346599,1540963231,1540963232,1 +346600,1540963232,1540963233,1 +346601,1540963233,1540963234,1 +346602,1540963234,1540963235,1 +346603,1540963235,1540963236,1 +346604,1540963236,1540963237,1 +346605,1540963237,1540963238,1 +346606,1540963238,1540963239,1 +346607,1540963239,1540963240,1 +346608,1540963240,1163936625,1 +346609,1540963241,1540963242,1 +346610,1540963242,1540963243,1 +346611,1540963243,1540963244,1 +346612,1540963244,1540963245,1 +346613,1540963245,1540963246,1 +346614,1540963246,1540963247,1 +346615,1540963247,1540963248,1 +346616,1540963248,1540963249,1 +346617,1540963249,1540963250,1 +346618,1540963250,1540963251,1 +346619,1540963251,1540963252,1 +346620,1540963252,1540963253,1 +346621,1540963253,1540963254,1 +346622,1540963254,1540963255,1 +346623,1540963255,1540963256,1 +346624,1540963256,1540963257,1 +346625,1540963257,1540963258,1 +346626,1540963258,1540963259,1 +346627,1540963259,1163936533,1 +346628,1540963260,1540963261,1 +346629,1540963261,1540963262,1 +346630,1540963262,1540963263,1 +346631,1540963263,1540963264,1 +346632,1540963264,1540963265,1 +346633,1540963265,1540963266,1 +346634,1540963266,1540963267,1 +346635,1540963267,1540963268,1 +346636,1540963268,1172485474,1 +346637,1540963269,1540963270,1 +346638,1540963270,1540963271,1 +346639,1540963271,1540963272,1 +346640,1540963272,1540963273,1 +346641,1540963273,1540963274,1 +346642,1540963274,1540963275,1 +346643,1540963275,1540963276,1 +346644,1540963276,1540963277,1 +346645,1540963277,1540963278,1 +346646,1540963278,1540963279,1 +346647,1540963279,1163936441,1 +346648,1540963280,1540963281,1 +346649,1540963281,1163936425,1 +346948,1540963580,1540963581,1 +346949,1540963581,1540963582,1 +346950,1540963582,1540963583,1 +346951,1540963583,1540963584,1 +346952,1540963584,1540963585,1 +346953,1540963585,1540963586,1 +346954,1540963586,1540963587,1 +346955,1540963587,1540963588,1 +346956,1540963588,1540963589,1 +346957,1540963589,1540963590,1 +347619,1540964251,1539669150,1 diff --git a/evaluation/shortest_path_evaluation/source/shortest_paths_comparison.m b/evaluation/shortest_path_evaluation/source/shortest_paths_comparison.m new file mode 100644 index 0000000..4efafd2 --- /dev/null +++ b/evaluation/shortest_path_evaluation/source/shortest_paths_comparison.m @@ -0,0 +1,443 @@ +% Shortest-path map construction evaluation 1.0 +% Copyright 2013 Sophia Karagiorgou and Dieter Pfoser +% +% Licensed under the Apache License, Version 2.0 (the "License"); +% you may not use this file except in compliance with the License. +% You may obtain a copy of the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, +% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +% See the License for the specific language governing permissions and +% limitations under the License. +% +% ------------------------------------------------------------------------ +% +% This software is based on the following article(s). Please cite this +% article when using this code as part of a research publication: +% +% S. Karagiorgou and D. Pfoser. On Vehicle Tracking Data-Based Road Network Generation. +% In Proc. 20th ACM SIGSPATIAL GIS Conference, pp. 89-98, 2012. +% +% S. Karagiorgou and D. Pfoser. Segmentation-Based Road Network Construction. +% In Proc. 21th ACM SIGSPATIAL GIS Conference, pp. 470-473, 2013. +% +% ------------------------------------------------------------------------ +% +% Author: Sophia Karagiorgou (karagior@gmail.com) +% Filename: shortest_paths_comparison.m + +currentFolder = pwd; +cd(currentFolder); +fprintf('Starting at %s\n', timestamp); + +vertices = load('vertices_original_osm.txt'); +edges = load('edges_original_osm.txt'); + + +hold on; +line = zeros(2); + +numofshortestpaths=500; +dy=50; +bbox=[]; +rbbox=[]; +rids=[]; +new_edges=[]; +new_vertices=[]; +fprintf('Loading ground truth road network\n'); +for k=1:length(edges) + rn1=find(vertices(:,1)==edges(k,2)); + rn2=find(vertices(:,1)==edges(k,3)); + + ndegrees=line_angle([vertices(rn1,2),vertices(rn1,3)],[vertices(rn2,2),vertices(rn2,3)]); + x1=vertices(rn1,2)+(dy)*cosd(ndegrees-90); + y1=vertices(rn1,3)+(dy)*sind(ndegrees-90); + x2=vertices(rn1,2)+(dy)*cosd(ndegrees+90); + y2=vertices(rn1,3)+(dy)*sind(ndegrees+90); + + x3=vertices(rn2,2)+(dy)*cosd(ndegrees-90); + y3=vertices(rn2,3)+(dy)*sind(ndegrees-90); + x4=vertices(rn2,2)+(dy)*cosd(ndegrees+90); + y4=vertices(rn2,3)+(dy)*sind(ndegrees+90); + + line(1,1)= vertices(rn1,2); + line(1,2)= vertices(rn1,3); + line(2,1)= vertices(rn2,2); + line(2,2)= vertices(rn2,3); + + node1=[x1 y1;x3 y3]; + node2=[x4 y4;x2 y2]; + bbox=vertcat(bbox,[node1(:,1) node1(:,2)]); + bbox=vertcat(bbox,[node2(:,1) node2(:,2)]); + bbox=vertcat(bbox,[x1 y1]); + bbox=vertcat(bbox,[NaN NaN]); + new_edges=vertcat(new_edges,[edges(k,1) edges(k,2) edges(k,3)]); + + new_vertices=vertcat(new_vertices,[vertices(rn1,1) vertices(rn1,2) vertices(rn1,3)]); + new_vertices=vertcat(new_vertices,[vertices(rn2,1) vertices(rn2,2) vertices(rn2,3)]); +end + + +nedges=load('tracebundle_edges.txt'); +nvertices=load('tracebundle_vertices.txt'); +fprintf('Loading generated road network\n'); +fprintf('Extracting correspondent road network links\n'); +hold on; +trids=[]; +nedges=unique(nedges,'rows'); +for k=1:length(nedges(:,1)) + c1=find(nvertices(:,1)==nedges(k,2)); + c2=find(nvertices(:,1)==nedges(k,3)); + + xy=[]; + xy=[nvertices(c1,2) nvertices(c1,3)]; + xy=vertcat(xy,[nvertices(c2,2) nvertices(c2,3)]); + line=createLine([nvertices(c1,2) nvertices(c1,3)], [nvertices(c2,2) nvertices(c2,3)]); + rc=isnan(bbox(:,1)); + irc=find(rc==1); + + for m=1:length(irc) + tbbox=[]; + if m==1 + rc1=1; + else + rc1=irc(m-1)+1; + end + + rc2=irc(m)-1; + tbbox=bbox(rc1:rc2,:); + [in on]=inpolygon(xy(:,1),xy(:,2),tbbox(:,1),tbbox(:,2)); + poly=[tbbox(1,1) tbbox(1,2);tbbox(2,1) tbbox(2,2);tbbox(3,1) tbbox(3,2);tbbox(4,1) tbbox(4,2)]; + + [xi, yi, ii] = polyxpoly(xy(:,1), xy(:,2), poly(:,1), poly(:,2)); + ri=find(in==1); + ro=find(on==1); + + if ~isempty(xi)&&~isempty(yi)||(~isempty(ri)||~isempty(ro)) + if ~isempty(ri) + for n=1:length(ri) + trids=vertcat(trids,[nedges(k,1) m ri(n)]); + end + end + if ~isempty(ro) + for n=1:length(ro) + trids=vertcat(trids,[nedges(k,1) m ro(n)]); + end + end + if ~isempty(xi) + for n=1:length(xi) + trids=vertcat(trids,[nedges(k,1) m ii(n,1)]); + end + end + end + end +end +dtrids=unique(trids(:,2)); + +redges=[]; +rnodes=[]; +line = zeros(2); +cnt=1; + +for k=1:length(dtrids(:,1)) + redges=vertcat(redges,[cnt edges(dtrids(k,1),2) edges(dtrids(k,1),3)]); + rn1=find(vertices(:,1)==edges(dtrids(k,1),2)); + rn2=find(vertices(:,1)==edges(dtrids(k,1),3)); + rnodes=vertcat(rnodes, [vertices(rn1,1) vertices(rn1,2) vertices(rn1,3)]); + rnodes=vertcat(rnodes, [vertices(rn2,1) vertices(rn2,2) vertices(rn2,3)]); + cnt=cnt+1; +end + +fprintf('Creating adjacency matrices\n'); +redges=unique(redges,'rows'); +rnodes=unique(rnodes,'rows'); +matrix_r=inf(length(rnodes(:,1)), length(rnodes(:,1))); +for i=1:length(rnodes(:,1)) + for j=1:length(rnodes(:,1)) + if i==j + matrix_r(i,j)=1; + end + end +end + +for k=1:length(redges(:,1)) + ri=find(rnodes(:,1)==redges(k,2)); + rj=find(rnodes(:,1)==redges(k,3)); + if ~isempty(ri)&&~isempty(rj) + cst=sqrt((rnodes(ri,2)-rnodes(rj,2))^2+(rnodes(ri,3)-rnodes(rj,3))^2); + matrix_r(ri, rj) = cst; + matrix_r(rj, ri) = cst; + end +end + + +minx=min(nvertices(:,2))-500; +maxx=max(nvertices(:,2))+500; +miny=min(nvertices(:,3))-500; +maxy=max(nvertices(:,3))+500; + +rc=find(nvertices(:,2)>=minx&nvertices(:,2)<=maxx&nvertices(:,3)>=miny&nvertices(:,3)<=maxy); +cvertices_tmp=nvertices(rc,:); +pedges=[]; +for g=1:length(cvertices_tmp(:,1)) + rs=find(nedges(:,2)==cvertices_tmp(g,1)); + if ~isempty(rs) + pedges=vertcat(pedges,nedges(rs,1)); + end + rs=find(nedges(:,3)==cvertices_tmp(g,1)); + if ~isempty(rs) + pedges=vertcat(pedges,nedges(rs,1)); + end +end + +pedges=unique(pedges,'rows'); +nodes=[]; + +for i=1:length(pedges(:,1)) + rc=find(nedges(:,1)==pedges(i,1)); + if ~isempty(rc) + rc1=find(nvertices(:,1)==nedges(rc,2)); + rc2=find(nvertices(:,1)==nedges(rc,3)); + nodes=vertcat(nodes,[nvertices(rc1,1) nvertices(rc1,2) nvertices(rc1,3)]); + nodes=vertcat(nodes,[nvertices(rc2,1) nvertices(rc2,2) nvertices(rc2,3)]); + end +end + +nodes=unique(nodes,'rows'); +matrix_p=inf(length(nodes(:,1)), length(nodes(:,1))); + +for i=1:length(nodes(:,1)) + for j=1:length(nodes(:,1)) + if i==j + matrix_p(i,j)=1; + end + end +end + +for k=1:length(pedges(:,1)) + sres=find(nedges(:,1)==pedges(k,1)); + c1=find(nvertices(:,1)==nedges(sres,2)); + c2=find(nvertices(:,1)==nedges(sres,3)); + + ri=find(nodes(:,1)==nvertices(c1,1)); + rj=find(nodes(:,1)==nvertices(c2,1)); + cst=sqrt((nodes(ri,2)-nodes(rj,2))^2+(nodes(ri,3)-nodes(rj,3))^2); + if ~isempty(ri)&&~isempty(rj) + matrix_p(ri, rj) = cst; + matrix_p(rj, ri) = cst; + end +end + +activeNodes = []; +for i = 1:length(nodes(:,1)) + farthestPreviousHop(i) = i; + farthestNextHop(i) = i; +end + + +fprintf('Generating uniformly distributed shortest paths\n'); +path_p=[]; +dpath_p=[]; +dpath_p=inf(length(nodes(:,1)), length(nodes(:,1))); + +for k=1:numofshortestpaths + rr=randi(length(nodes(:,1)),1,1); + circle = [[nodes(rr,2) nodes(rr,3)] 5000]; + x1=nodes(rr,2)+5000; + y1=nodes(rr,3)+5000; + x2=nodes(rr,2)-5000; + y2=nodes(rr,3)+5000; + x3=nodes(rr,2)-5000; + y3=nodes(rr,3)-5000; + x4=nodes(rr,2)+5000; + y4=nodes(rr,3)-5000; + node=[x1 y1;x2 y2;x3 y3;x4 y4;x1 y1]; + rx=find(nodes(:,2)~=nodes(rr,2)&nodes(:,3)~=nodes(rr,3)); + + in=inpolygon(nodes(rx,2), nodes(rx,3),node(:,1), node(:,2)); + rin=find(in~=0); + + Mdist=[nodes(rr,2) nodes(rr,3)]; + Mdist=vertcat(Mdist,[nodes(rx(rin),2) nodes(rx(rin),3)]); + Y = pdist(Mdist,'euclid'); + SQ=squareform(Y); + + maxd=max(SQ(:,1)); + r=find(SQ(:,1)==maxd); + + rc1=find(nodes(:,1)==nodes(rr,1)); + rrc2=find(nodes(:,2)==Mdist(r,1)&nodes(:,3)==Mdist(r,2)); + rc2=find(nodes(:,1)==nodes(rrc2,1)); + [path, totalCost, farthestPreviousHop, farthestNextHop] = dijkstra_1(length(nodes(:,1)), matrix_p, rc1, rc2, farthestPreviousHop, farthestNextHop); + d=0; + if length(path) ~= 0 + d=0; + for i = 1:(length(path)-1) + d=d+sqrt((nodes(path(i),2)-nodes(path(i+1),2))^2+(nodes(path(i),3)-nodes(path(i+1),3))^2); + end + end + if ~isempty(k)&& ~isempty(nodes(rr,1)) && ~isempty(nodes(rrc2,1)) && ~isempty(maxd) && ~isempty(d) && ~isempty(totalCost) + if ~isinf(totalCost) + path_p=vertcat(path_p,[k nodes(rr,1) nodes(rrc2,1) maxd d totalCost 0 0 0 0 0 0]); + for i=1:length(path) + dpath_p(k,i)=path(i); + end + end + end +end + + +activeNodes = []; +for i = 1:length(rnodes(:,1)) + farthestPreviousHop(i) = i; + farthestNextHop(i) = i; +end + +path_r=[]; +dpath_r=[]; +dpath_r=inf(length(rnodes(:,1)), length(rnodes(:,1))); +rs=~isinf(dpath_p(:,1)); +dpath_p=dpath_p(rs,:); +fprintf('Calculating corresponding shortest paths for the ground truth road network\n'); +for k=1:length(path_p(:,1)) + rr1=find(nodes(:,1)==path_p(k,2)); + rr2=find(nodes(:,1)==path_p(k,3)); + + x1=nodes(rr1,2)+100; + y1=nodes(rr1,3)+100; + x2=nodes(rr1,2)-100; + y2=nodes(rr1,3)+100; + x3=nodes(rr1,2)-100; + y3=nodes(rr1,3)-100; + x4=nodes(rr1,2)+100; + y4=nodes(rr1,3)-100; + node=[x1 y1;x2 y2;x3 y3;x4 y4;x1 y1]; + + if ~isnan(dpath_p(k,2)) + ndegrees=line_angle([nodes(rr1,2),nodes(rr1,3)],[nodes(dpath_p(k,2),2),nodes(dpath_p(k,2),3)]); + rpd=find(dpath_p(k,:)~=inf); + pdegrees=line_angle([nodes(dpath_p(k,length(rpd)-1),2),nodes(dpath_p(k,length(rpd)-1),3)],[nodes(rr2,2),nodes(rr2,3)]); + + in=inpolygon(rnodes(:,2), rnodes(:,3),node(:,1), node(:,2)); + rin1=find(in~=0); + mindist=1000; + minvdist=1000; + idx1=0; + for h=1:length(rin1) + adf=find(matrix_r(rin1(h),:)~=inf); + for n=1:length(adf) + if adf(n)~=rin1(h) + ndegrees1=line_angle([rnodes(rin1(h),2),rnodes(rin1(h),3)],[rnodes(adf(n),2),rnodes(adf(n),3)]); + dp=distancePoints([nodes(rr1,2),nodes(rr1,3)], [rnodes(rin1(h),2),rnodes(rin1(h),3)],2); + ledge=[nodes(rr1,2),nodes(rr1,3), nodes(dpath_p(k,2),2),nodes(dpath_p(k,2),3)]; + if dp130&&abs(ndegrees-ndegrees1)<230) + mindist=dp; + idx1=h; + end + end + end + end + + x1=nodes(rr2,2)+100; + y1=nodes(rr2,3)+100; + x2=nodes(rr2,2)-100; + y2=nodes(rr2,3)+100; + x3=nodes(rr2,2)-100; + y3=nodes(rr2,3)-100; + x4=nodes(rr2,2)+100; + y4=nodes(rr2,3)-100; + node=[x1 y1;x2 y2;x3 y3;x4 y4;x1 y1]; + + in=inpolygon(rnodes(:,2), rnodes(:,3),node(:,1), node(:,2)); + rin2=find(in~=0); + mindist=1000; + minvdist=1000; + idx2=0; + + for h=1:length(rin2) + adf=find(matrix_r(rin2(h),:)~=inf); + for n=1:length(adf) + if adf(n)~=rin2(h) + ndegrees2=line_angle([rnodes(adf(n),2),rnodes(adf(n),3)],[rnodes(rin2(h),2),rnodes(rin2(h),3)]); + + dp=distancePoints([nodes(rr2,2),nodes(rr2,3)], [rnodes(rin2(h),2),rnodes(rin2(h),3)],2); + ledge=[nodes(dpath_p(k,length(rpd)-1),2),nodes(dpath_p(k,length(rpd)-1),3),nodes(rr2,2),nodes(rr2,3)]; + if dp