1 /* 2 * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT, 3 * Applied Mathematics, Norway. 4 * 5 * Contact information: E-mail: tor.dokken@sintef.no 6 * SINTEF ICT, Department of Applied Mathematics, 7 * P.O. Box 124 Blindern, 8 * 0314 Oslo, Norway. 9 * 10 * This file is part of SISL. 11 * 12 * SISL is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU Affero General Public License as 14 * published by the Free Software Foundation, either version 3 of the 15 * License, or (at your option) any later version. 16 * 17 * SISL is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU Affero General Public License for more details. 21 * 22 * You should have received a copy of the GNU Affero General Public 23 * License along with SISL. If not, see 24 * <http://www.gnu.org/licenses/>. 25 * 26 * In accordance with Section 7(b) of the GNU Affero General Public 27 * License, a covered work must retain the producer line in every data 28 * file that is created or manipulated using SISL. 29 * 30 * Other Usage 31 * You can be released from the requirements of the license by purchasing 32 * a commercial license. Buying such a license is mandatory as soon as you 33 * develop commercial activities involving the SISL library without 34 * disclosing the source code of your own applications. 35 * 36 * This file may be used in accordance with the terms contained in a 37 * written agreement between you and SINTEF ICT. 38 */ 39 40 #include "sisl-copyright.h" 41 42 /* 43 * 44 * $Id: s6dline.c,v 1.2 2001-03-19 15:59:01 afr Exp $ 45 * 46 */ 47 48 49 #define S6DLINE 50 51 #include "sislP.h" 52 53 #if defined(SISLNEEDPROTOTYPES) 54 double s6dline(double estart[],double eend[],double epoint[],int idim,int * jstat)55 s6dline(double estart[],double eend[],double epoint[], 56 int idim,int *jstat) 57 #else 58 double s6dline(estart,eend,epoint,idim,jstat) 59 double estart[]; 60 double eend[]; 61 double epoint[]; 62 int idim; 63 int *jstat; 64 #endif 65 /* 66 ********************************************************************* 67 * 68 ********************************************************************* 69 * 70 * PURPOSE : Compute the distance between a line segment and a point. 71 * 72 * 73 * 74 * INPUT : estart - Start point of line segment. Dimension is idim. 75 * eend - End point of line segment. Dimension is idim. 76 * epoint - Point. Dimension is idim. 77 * idim - Dimension of geometry space. 78 * 79 * 80 * 81 * OUTPUT : s6dline - Distance between line and point. 82 * jstat - status messages 83 * = 2 : Zero line segment. Closest point 84 * is outside segment. 85 * = 1 : Closest point on the extended 86 * line through estart and end is 87 * outside the segment. 88 * = 0 : ok 89 * < 0 : error 90 * 91 * 92 * METHOD : 93 * 94 * 95 * 96 * REFERENCES : 97 * 98 *- 99 * CALLS : s6scpr - Scalar product between two vectors. 100 * s6diff - Difference vector between two vectors. 101 * s6length - Length of vector. 102 * 103 * WRITTEN BY : Vibeke Skytt, SI, 91-02. 104 * 105 ********************************************************************* 106 */ 107 { 108 int kstat = 0; /* Local status varaible. */ 109 int ki; /* Counter. */ 110 double tpar; /* Parameter of closest point. */ 111 double tdist; /* Distance between point and line. */ 112 double t1; /* Scalar product. */ 113 double *sline = SISL_NULL; /* Line vector. */ 114 double *sdiff = SISL_NULL; /* Difference vector. */ 115 116 /* Allocate scratch for local vectors. */ 117 118 if ((sline = newarray(idim,DOUBLE)) == SISL_NULL) goto err101; 119 if ((sdiff = newarray(idim,DOUBLE)) == SISL_NULL) goto err101; 120 121 /* Compute help vectors. */ 122 123 s6diff(eend,estart,idim,sline); 124 s6diff(epoint,estart,idim,sdiff); 125 126 /* Compute parameter of closest point. */ 127 128 t1 = s6scpr(sline,sline,idim); 129 if (t1 <= REL_COMP_RES) 130 { 131 /* Compute distance between point and first endpoint of line. */ 132 133 tdist = s6dist(estart,epoint,idim); 134 135 /* Set a warning. */ 136 137 *jstat = 2; 138 goto out; 139 } 140 141 tpar = s6scpr(sline,sdiff,idim)/t1; 142 143 /* Compute vector between input point and closest point on 144 line. */ 145 146 for (ki=0; ki<idim; ki++) 147 sdiff[ki] = estart[ki] + tpar*sline[ki] - epoint[ki]; 148 149 /* Compute length of vector. */ 150 151 tdist = s6length(sdiff,idim,&kstat); 152 153 /* Set status. */ 154 155 *jstat = (tpar < 0 || tpar > 1) ? 1 : 0; 156 goto out; 157 158 /* Error in scratch allocation. */ 159 160 err101 : *jstat = -101; 161 goto out; 162 163 out : 164 /* Free space occupied by local arrays. */ 165 166 if (sline != SISL_NULL) freearray(sline); 167 if (sdiff != SISL_NULL) freearray(sdiff); 168 169 return tdist; 170 } 171