2018-07-27 21:00:30 +02:00
|
|
|
/*
|
|
|
|
* GDSII-Converter
|
|
|
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
|
|
|
*
|
|
|
|
* This file is part of GDSII-Converter.
|
|
|
|
*
|
|
|
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2019-11-17 15:52:28 +01:00
|
|
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
2018-07-27 21:00:30 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file vector-operations.c
|
|
|
|
* @brief 2D Vector operations
|
|
|
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
|
|
*/
|
|
|
|
|
2018-12-10 19:36:00 +01:00
|
|
|
/**
|
2019-03-26 19:57:19 +01:00
|
|
|
* @addtogroup geometric
|
2018-12-10 19:36:00 +01:00
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2018-07-28 10:37:00 +02:00
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2019-03-26 19:57:19 +01:00
|
|
|
#include <gds-render/geometric/vector-operations.h>
|
|
|
|
|
2019-08-20 22:42:44 +02:00
|
|
|
#define ABS_DBL(a) ((a) < 0.0 ? -(a) : (a))
|
2018-08-24 16:15:36 +02:00
|
|
|
|
2018-07-28 10:37:00 +02:00
|
|
|
double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b)
|
|
|
|
{
|
|
|
|
if (a && b)
|
|
|
|
return (a->x * b->x) + (a->y * b->y);
|
|
|
|
else
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2018-08-24 16:15:36 +02:00
|
|
|
void vector_2d_normalize(struct vector_2d *vec)
|
2018-07-28 10:37:00 +02:00
|
|
|
{
|
|
|
|
double len;
|
2019-10-28 23:55:22 +01:00
|
|
|
|
2018-07-28 10:37:00 +02:00
|
|
|
if (!vec)
|
|
|
|
return;
|
2019-10-28 23:55:22 +01:00
|
|
|
len = sqrt(pow(vec->x, 2) + pow(vec->y, 2));
|
2018-07-28 10:37:00 +02:00
|
|
|
vec->x = vec->x/len;
|
|
|
|
vec->y = vec->y/len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void vector_2d_rotate(struct vector_2d *vec, double angle)
|
|
|
|
{
|
|
|
|
double sin_val, cos_val;
|
|
|
|
struct vector_2d temp;
|
|
|
|
|
2018-08-01 12:42:41 +02:00
|
|
|
if (!vec)
|
|
|
|
return;
|
|
|
|
|
2018-07-28 10:37:00 +02:00
|
|
|
sin_val = sin(angle);
|
|
|
|
cos_val = cos(angle);
|
|
|
|
|
2020-06-29 20:03:38 +02:00
|
|
|
(void)vector_2d_copy(&temp, vec);
|
2018-07-28 10:37:00 +02:00
|
|
|
|
|
|
|
/* Apply rotation matrix */
|
|
|
|
vec->x = (cos_val * temp.x) - (sin_val * temp.y);
|
|
|
|
vec->y = (sin_val * temp.x) + (cos_val * temp.y);
|
|
|
|
}
|
|
|
|
|
2018-08-24 16:15:36 +02:00
|
|
|
struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec)
|
2018-07-28 10:37:00 +02:00
|
|
|
{
|
|
|
|
struct vector_2d *res;
|
|
|
|
|
|
|
|
if (!vec)
|
|
|
|
return NULL;
|
2018-12-22 19:31:36 +01:00
|
|
|
|
|
|
|
if (opt_res)
|
|
|
|
res = opt_res;
|
|
|
|
else
|
2018-07-28 10:37:00 +02:00
|
|
|
res = vector_2d_alloc();
|
2018-12-22 19:31:36 +01:00
|
|
|
|
|
|
|
if (res) {
|
|
|
|
res->x = vec->x;
|
|
|
|
res->y = vec->y;
|
2018-07-28 10:37:00 +02:00
|
|
|
}
|
2018-12-22 19:31:36 +01:00
|
|
|
return res;
|
2018-07-28 10:37:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct vector_2d *vector_2d_alloc(void)
|
|
|
|
{
|
|
|
|
return (struct vector_2d *)malloc(sizeof(struct vector_2d));
|
|
|
|
}
|
|
|
|
|
|
|
|
void vector_2d_free(struct vector_2d *vec)
|
|
|
|
{
|
2019-10-28 23:55:22 +01:00
|
|
|
if (vec)
|
2018-07-28 10:37:00 +02:00
|
|
|
free(vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vector_2d_scale(struct vector_2d *vec, double scale)
|
|
|
|
{
|
|
|
|
if (!vec)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vec->x *= scale;
|
|
|
|
vec->y *= scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
double vector_2d_abs(struct vector_2d *vec)
|
|
|
|
{
|
|
|
|
double len = 0.0;
|
2019-10-28 23:55:22 +01:00
|
|
|
|
|
|
|
if (vec)
|
|
|
|
len = sqrt(pow(vec->x, 2) + pow(vec->y, 2));
|
2018-07-28 10:37:00 +02:00
|
|
|
return len;
|
|
|
|
}
|
2018-08-24 16:15:36 +02:00
|
|
|
|
|
|
|
double vector_2d_calculate_angle_between(struct vector_2d *a, struct vector_2d *b)
|
|
|
|
{
|
|
|
|
double cos_angle;
|
|
|
|
|
|
|
|
if (!a || !b)
|
|
|
|
return 0.0;
|
|
|
|
|
|
|
|
cos_angle = ABS_DBL(vector_2d_scalar_multipy(a, b)) / (vector_2d_abs(a) * vector_2d_abs(b));
|
|
|
|
return acos(cos_angle);
|
|
|
|
}
|
|
|
|
|
|
|
|
void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b)
|
|
|
|
{
|
|
|
|
if (res && a && b) {
|
|
|
|
res->x = a->x - b->x;
|
|
|
|
res->y = a->y - b->y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b)
|
|
|
|
{
|
|
|
|
if (res && a && b) {
|
2019-10-28 23:55:22 +01:00
|
|
|
res->x = a->x + b->x;
|
2018-08-24 16:15:36 +02:00
|
|
|
res->y = a->y + b->y;
|
|
|
|
}
|
|
|
|
}
|
2018-12-10 19:36:00 +01:00
|
|
|
|
|
|
|
/** @} */
|