001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.math.geometry.path.resample; 031 032import org.openimaj.math.geometry.line.Line2d; 033import org.openimaj.math.geometry.path.Polyline; 034import org.openimaj.math.geometry.point.Point2d; 035import org.openimaj.math.util.Interpolation; 036import org.openimaj.util.function.Function; 037import org.openimaj.util.function.Operation; 038 039/** 040 * Simple linear resampling. Only the end points are guaranteed to be preserved. 041 */ 042public class LinearResampler implements Function<Polyline, Polyline>, Operation<Polyline> { 043 int targetVertices; 044 045 /** 046 * Construct with the given number of target vertices for lines to have 047 * 048 * @param targetVertices 049 * number of required vertices 050 */ 051 public LinearResampler(int targetVertices) { 052 this.targetVertices = targetVertices; 053 } 054 055 @Override 056 public Polyline apply(Polyline in) { 057 final double length = in.calculateLength(); 058 final double step = length / (targetVertices - 1); 059 060 final Polyline out = new Polyline(); 061 out.points.add(in.begin().copy()); 062 063 Point2d begin = in.points.get(0); 064 Point2d end = in.points.get(1); 065 double lastLength = Line2d.distance(begin, end); 066 double distance = lastLength; 067 double pos = step; 068 for (int i = 1, c = 1; i < targetVertices - 1; i++, pos += step) { 069 while (pos > distance) { 070 // move through segments until we find the correct one 071 begin = end; 072 c++; 073 end = in.points.get(c); 074 lastLength = Line2d.distance(begin, end); 075 distance += lastLength; 076 } 077 078 final double offset = lastLength - (distance - pos); 079 080 final Point2d np = begin.copy(); 081 for (int j = 0; j < 2; j++) { 082 final double n = Interpolation.lerp(offset, 0, begin.getOrdinate(j).doubleValue(), lastLength, end 083 .getOrdinate(j).doubleValue()); 084 np.setOrdinate(j, n); 085 } 086 out.points.add(np); 087 } 088 out.points.add(in.end().copy()); 089 090 return out; 091 } 092 093 /** 094 * Apply the resampling operation in-place 095 */ 096 @Override 097 public void perform(Polyline object) { 098 final Polyline n = apply(object); 099 object.points = n.points; 100 } 101}