001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 * image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause).
006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved.
007 * Visit https://imagingbook.com for additional details.
008 ******************************************************************************/
009package imagingbook.common.geometry.line;
010
011import imagingbook.common.geometry.basic.Pnt2d;
012
013import java.util.Locale;
014
015/**
016 * <p>
017 * This class represents a straight line in Hessian normal form, i.e., x * cos(angle) + y * sin(angle) = radius. It is
018 * merely a subclass of {@link AlgebraicLine} with a different constructor and getter methods for angle and radius.
019 * Instances are immutable. Reference point is (0,0). See Sec. 10.1 and Appendix F.1 of [1] for details.
020 * </p>
021 * <p>
022 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing &ndash; An Algorithmic Introduction</em>, 3rd ed, Springer
023 * (2022).
024 * </p>
025 *
026 * @author WB
027 * @version 2022/11/18
028 */
029public class HessianLine extends AlgebraicLine {
030        
031        // static factory methods ----------------------------------------
032        
033        public static HessianLine from(Pnt2d p1, Pnt2d p2) {
034                return new HessianLine(AlgebraicLine.from(p1, p2));
035        }
036        
037        // constructors --------------------------------------------------
038
039        /**
040         * Constructor. Creates a new {@link HessianLine} instance with the specified angle and radius. Note that this
041         * really creates a normalized {@link AlgebraicLine}. The values returned by {@link #getAngle()} and
042         * {@link #getRadius()} may not be identical to the values passed to this constructor.
043         *
044         * @param angle the line's angle
045         * @param radius the line's radius
046         */
047        public HessianLine(double angle, double radius) {
048                super(Math.cos(angle), Math.sin(angle), -radius);       // = A, B, C
049        }
050        
051        public HessianLine(double a, double b, double c) {
052                super(a, b, c);                 // creates a normalized line
053        }
054        
055        public HessianLine(AlgebraicLine al) {
056                super(al.getParameters());
057        }
058        
059        public double getAngle() {
060                return Math.atan2(B, A);
061        }
062        
063        public double getRadius() {
064                return -C;
065        }
066        
067        // -------------------------------------------------------------------
068        
069        @Override
070        public String toString() {
071                return String.format(Locale.US, "%s <angle = %.3f, radius = %.3f>",
072                                this.getClass().getSimpleName(), getAngle(), getRadius());
073        }
074
075}