幾何庫從零開始
Point
import Segment from './Segment';
import MathUtils from '../math/MathUtils';
import Vector2f from './Vector2f';
export default class Point {
public readonly zero = new Point(0, 0);
public x: number;
public y: number;
public constructor(x: number = 0, y: number) {
this.x = x;
this.y = y;
}
/**
* @author lianbo
* @date 2020-09-30 18:48:03
* @Description: 兩個點比較
*/
public equalTo(p: Point) {
if (MathUtils.equal(this.x, p.x) && MathUtils.equal(this.y, p.y)) {
return true;
}
return false;
}
/**
* @author lianbo
* @date 2020-09-30 15:33:03
* @Description: 點線上段上,包括端點
*/
public on(seg: Segment) {
}
/**
* @author lianbo
* @date 2020-09-30 15:58:12
* @Description: 點到點的距離
*/
public distanceToPoint(p: Point): number {
let dx = p.x - this.x;
let dy = p.y - this.y;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* @author lianbo
* @date 2020-09-30 18:47:24
* @Description: 點按向量平移
*/
public translate(v: Vector2f): Point {
return new Point(this.x + v.x, this.y + v.y);
}
/**
* @author lianbo
* @date 2020-09-30 17:10:09
* @Description: 線段是否線上段範圍內,包括端點
*/
public inSegmentScope(seg: Segment): boolean {
const segV = new Vector2f(seg.start, seg.end);
const startV = new Vector2f(seg.start, this);
const endV = new Vector2f(seg.end, this);
const startDot = startV.dot(segV);
const endDot = -endV.dot(segV);
if (MathUtils.greaterEqual(startDot, 0) && MathUtils.greaterEqual(endDot, 0)) {
return true;
}
return false;
}
/**
* @author lianbo
* @date 2020-09-30 18:35:05
* @Description: 點到線段的距離
*/
public distanceToSegment(seg: Segment): number {
if (seg.start.equalTo(seg.end)) { //線段縮成一個點?
return this.distanceToPoint(seg.start);
}
const segV = new Vector2f(seg.start, seg.end);
const startV = new Vector2f(seg.start, this);
const endV = new Vector2f(seg.end, this);
const startDot = startV.dot(segV);
const endDot = -endV.dot(segV);
if (MathUtils.greaterEqual(startDot, 0) && MathUtils.greaterEqual(endDot, 0)) {
let v_unit = segV.normalize;
const dist = Math.abs(v_unit.cross(startV));
return dist;
} else if (startDot < 0) { /* point is out of scope closer to ps */
return this.distanceToPoint(seg.start);
} else { /* point is out of scope closer to pe */
return this.distanceToPoint(seg.end);
}
}
/**
* @author lianbo
* @date 2020-09-30 18:43:21
* @Description: 點到線的垂足
*/
public closestPoint(seg: Segment): Point {
const segV = new Vector2f(seg.start, seg.end);
const n = segV.normalize;
const startV = new Vector2f(seg.start, this);
const translateLength = segV.dot(startV);
return seg.start.translate(n.multiply(translateLength));
}
}
Segment
import Point from './Point';
export default class Segment {
public start: Point;
public end: Point;
}
Polygon
export default class Polygon {}
Vector2
import Point from './Point';
import MathUtils from '../math/MathUtils';
export default class Vector2f {
public pS: Point;
public pE: Point;
public x: number;
public y: number;
public constructor(pS: Point|number, pE: Point|number) {
if(pS instanceof Point && pE instanceof Point){
this.pS = pS;
this.pE = pE;
this.x = pE.x - pS.x;
this.y = pE.y - pS.y;
}
if(typeof pS === 'number' && typeof pE === 'number'){
this.x = pS;
this.y = pE;
}
}
public dot(vec: Vector2f): number {
return this.x * vec.x + this.y * vec.y;
}
public cross(vec: Vector2f): number {
return this.x * vec.y - this.y * vec.x;
}
public get length(): number {
const length = Math.sqrt(this.x & this.x + this.y & this.y);
return length;
}
public get normalize(): Vector2f {
if (this.isZero) {
throw new Error('0 向量,無單位向量');
}
const length = this.length;
return new Vector2f(this.x / length, this.y / length);
}
public get isZero(): boolean {
if (MathUtils.equal(this.length, 0)) {
return true;
}
return false;
}
public multiply(scalar: number) {
return new Vector2f(this.x * scalar,this.y * scalar);
}
}
MathUtils
export default class MathUtils {
public static readonly Deg2Rad: number = (Math.PI / 180.0);
public static readonly Rad2Deg: number = (180.0 / Math.PI);
public static readonly Epsilon: number = 0.000001;
public static equal(a: number, b: number, epsilon: number = MathUtils.Epsilon) {
return Math.abs(a - b) <= epsilon;
}
public static greater(a:number,b:number,epsilon: number = MathUtils.Epsilon) {
return a - b > epsilon;
}
public static greaterEqual(a:number,b:number,epsilon: number = MathUtils.Epsilon) {
return !MathUtils.less(a,b);
}
public static less(a:number,b:number,epsilon: number = MathUtils.Epsilon) {
return this.greater(b,a);
}
public static lessEqual(a:number,b:number,epsilon: number = MathUtils.Epsilon) {
return !MathUtils.greater(a,b);
}
}
相關文章
- 從零開始
- 不怕從零開始,只怕從未開始!
- 從零開始學netty——為何重寫方法不一樣Netty
- 從零開始-基礎流程圖編輯庫流程圖
- 從零開始學PythonPython
- flutter 從零開始-1Flutter
- 從零開始學習Git--遠端倉庫Git
- 從零開始認識 SparkSpark
- 從零開始學習laravelLaravel
- 從零開始學習KafkaKafka
- 【ROS】從零開始學ROSROS
- 從零開始--webpack 4 配置Web
- 從零開始學 Spring BootSpring Boot
- 線段樹從零開始
- 從零開始學正則
- 【從零開始學習 MySql 資料庫】(2) 函式MySql資料庫函式
- 從零開始開發一個 WebpackWeb
- 從零開始學Python:第22課-Python標準庫初探Python
- Re從零開始的UI庫編寫生活之按鈕UI
- Re從零開始的UI庫編寫生活之表格元件UI元件
- Re從零開始的UI庫編寫生活之表單UI
- 從零開始的Flutter之旅: NavigatorFlutter
- 從零開始認識堆排序排序
- 從零開始的Flutter之旅: ProviderFlutterIDE
- 從零開始的Flutter之旅: InheritedWidgetFlutter
- 從零開始的Flutter之旅: StatelessWidgetFlutter
- VUE從零開始環境搭建Vue
- 從零開始的Flutter之旅: MethodChannelFlutter
- 從零開始的 Flutter 動畫Flutter動畫
- 從零開始寫一個ExporterExport
- 從零開始dumpdecrypted砸殼解析
- 從零開始機器學習機器學習
- 從零開始的fgg--htmlHTML
- 從零開始搭建腳手架
- 從零開始學golang之TCPGolangTCP
- 從零開始搭建webpack應用Web
- 從零開始仿寫一個抖音App——開始APP
- 從零開始實現一個RPC框架(零)RPC框架