⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flushpoly.c

📁 就是将BMP文件转换为DXF格式的文件
💻 C
字号:
/*
 *  Ras2Vec by Davide Libenzi ( Raster to vector conversion program )
 *  Copyright (C) 1999  Davide Libenzi
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Davide Libenzi <davidel@maticad.it>
 *
 */


#include<windows.h>
#include<windowsx.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#include<malloc.h>
#include<math.h>
#include<float.h>
#include<limits.h>
#include"ras2vec.h"
#include"dbll_list.h"
#include"flushpoly.h"
#include"log.h"
#include"util.h"

#define TETA_TOLL                 ((PIG*2.0)/3.0)
#define OPT_MIN_NUM_POLY_PNTS     8
#define POLY_START_STR            "POLYLINE"
#define POLY_END_STR              "END"

typedef struct imp_line_2d_record
{
    double          a,
                    b,
                    c;
}               imp_line_2d;

static double   distance_pnt_2d(img_point * pnt1, img_point * pnt2);
static int      get_imp_line_eq_2d(img_point * p_pnt0, img_point * p_pnt1,
                        imp_line_2d * p_ile);
static double   pnt_line_position(img_point * p_pnt, imp_line_2d * p_ile);
static double   angle_value_xy(double x_val, double y_val);
static char    *get_token(char *str, int n_token, char *token, int max_token_size);
static int      read_file_line(FILE * fp_poly, char *buffer, int sizeof_buffer);
static int      is_integer(char *str);
static int      is_end_of_polyline(char *line_buffer);

/* OK */
static double   distance_pnt_2d(img_point * pnt1, img_point * pnt2)
{

    return (sqrt((double) pnt_distance_2(pnt1, pnt2)));

}

/* OK */
static int      get_imp_line_eq_2d(img_point * p_pnt0, img_point * p_pnt1, imp_line_2d * p_ile)
{

    double          distance,
                    k_norm;

    if ((distance = distance_pnt_2d(p_pnt0, p_pnt1)) == 0.0)
    {
        p_ile->a = p_ile->b = p_ile->c = 0.0;
        return (FALSE);
    }
    k_norm = 1.0 / distance;
    p_ile->a = k_norm * (double) (p_pnt1->y - p_pnt0->y);
    p_ile->b = -k_norm * (double) (p_pnt1->x - p_pnt0->x);
    p_ile->c = k_norm * (double) (p_pnt1->x * p_pnt0->y - p_pnt0->x * p_pnt1->y);
    return (TRUE);

}

/* OK */
static double   pnt_line_position(img_point * p_pnt, imp_line_2d * p_ile)
{

    return (p_ile->a * (double) p_pnt->x + p_ile->b * (double) p_pnt->y + p_ile->c);

}

/* OK */
static double   angle_value_xy(double x_val, double y_val)
{

    double          mod,
                    teta;

    if ((mod = sqrt(x_val * x_val + y_val * y_val)) == 0.0)
        return (0.0);
    teta = acos(x_val / mod);
    return ((y_val < 0.0) ? (2.0 * PIG - teta) : teta);

}

/* OK */
static char    *get_token(char *str, int n_token, char *token, int max_token_size)
{

    int             ii = 0,
                    ltk = 0,
                    n_tok = 0;

    do
    {
        ii += ltk;
        while ((str[ii] == ' ') || (str[ii] == '\t'))
            ++ii;
        if (str[ii] == '\0')
            break;
        ltk = 0;
        while ((str[ii + ltk] != ' ') && (str[ii + ltk] != '\t') && (str[ii + ltk] != '\0'))
        {
            if (ltk < max_token_size)
                token[ltk] = str[ii + ltk];
            ++ltk;
        }
        token[min(ltk, (max_token_size - 1))] = '\0';
        ++n_tok;
    } while ((n_tok < n_token) && (str[ii + ltk] != '\0'));
    return ((n_tok == n_token) ? (str + ii) : NULL);

}

/* OK */
static int      read_file_line(FILE * fp_poly, char *buffer, int sizeof_buffer)
{

    while (fgets(buffer, sizeof_buffer, fp_poly) != NULL)
    {
        char            token[256];

        buffer[strlen(buffer) - 1] = '\0';
        if (get_token(buffer, 1, token, sizeof(token) - 1) != NULL)
            return (TRUE);
    }
    return (FALSE);

}

/* OK */
static int      is_integer(char *str)
{

    if ((*str == '+') || (*str == '-'))
        ++str;
    while (*str != '\0')
        if (!isdigit(*str++))
            return (FALSE);
    return (TRUE);

}

/* OK */
int             start_polyline(FILE * fp_poly)
{

    fprintf(fp_poly, "%s\n", POLY_START_STR);
    return (TRUE);

}

/* OK */
int             end_polyline(FILE * fp_poly)
{

    fprintf(fp_poly, "%s\n", POLY_END_STR);
    return (TRUE);

}

/* OK */
int             write_img_point(FILE * fp_poly, img_point * p_imgp)
{

    fprintf(fp_poly, "%-8ld %-8ld\n", (long int) p_imgp->x, (long int) p_imgp->y);
    return (TRUE);

}

/* OK */
int             read_start_polyline(FILE * fp_poly)
{

    char            line_buffer[256],
                    token[128];

    if (!read_file_line(fp_poly, line_buffer, sizeof(line_buffer) - 1))
        return (FALSE);
    if (get_token(line_buffer, 1, token, sizeof(token) - 1) == NULL)
        return (FALSE);
    return ((strcmp(token, POLY_START_STR) == 0) ? TRUE : FALSE);

}

/* OK */
static int      is_end_of_polyline(char *line_buffer)
{

    char            token[128];

    if (get_token(line_buffer, 1, token, sizeof(token) - 1) == NULL)
        return (FALSE);
    return ((strcmp(token, POLY_END_STR) == 0) ? TRUE : FALSE);

}

/* OK */
int             read_img_point(FILE * fp_poly, img_point * p_imgp)
{

    char            line_buffer[256],
                    token[128];

    if (!read_file_line(fp_poly, line_buffer, sizeof(line_buffer) - 1))
        return (FALSE);
    if (is_end_of_polyline(line_buffer))
        return (FALSE);
    if ((get_token(line_buffer, 1, token, sizeof(token) - 1) == NULL) ||
            (!is_integer(token)))
        return (FALSE);
    p_imgp->x = (int) atol(token);
    if ((get_token(line_buffer, 2, token, sizeof(token) - 1) == NULL) ||
            (!is_integer(token)))
        return (FALSE);
    p_imgp->y = (int) atol(token);
    return (TRUE);

}

/* OK */
void            update_min_max_pnt(img_point * p_imgp, img_point * p_min_imgp,
                        img_point * p_max_imgp)
{

    if (p_min_imgp->x > p_imgp->x)
        p_min_imgp->x = p_imgp->x;
    if (p_min_imgp->y > p_imgp->y)
        p_min_imgp->y = p_imgp->y;
    if (p_max_imgp->x < p_imgp->x)
        p_max_imgp->x = p_imgp->x;
    if (p_max_imgp->y < p_imgp->y)
        p_max_imgp->y = p_imgp->y;
    return;

}

/* OK */
double          img_points_dist(img_point * p_imgp0, img_point * p_imgp1)
{

    return (sqrt((double) pnt_distance_2(p_imgp0, p_imgp1)));

}

/* OK */
int             flush_polyline(FILE * fp_poly, link_list_hdr * p_polyline_list,
                        double min_polyline_lenght)
{

    int             num_pnts;
    double          polyline_lenght = 0.0;
    img_point       prev_pnt,
                    pnt;

    if ((num_pnts = ll_get_list_count(p_polyline_list)) < 2)
        return (FALSE);
    ll_set_list_currpntr(p_polyline_list, TG_HEAD);
    ll_get_list_user_data(p_polyline_list, &pnt);
    while (ll_set_list_currpntr(p_polyline_list, TG_AFTER) == TG_AFTER)
    {
        prev_pnt = pnt;
        if (!ll_get_list_user_data(p_polyline_list, &pnt))
            break;
        polyline_lenght += img_points_dist(&prev_pnt, &pnt);
    }
    if ((min_polyline_lenght > 0.0) && (polyline_lenght < min_polyline_lenght))
        return (FALSE);
    start_polyline(fp_poly);
    ll_set_list_currpntr(p_polyline_list, TG_HEAD);
    do
    {
        if (!ll_get_list_user_data(p_polyline_list, &pnt))
            break;
        if (!write_img_point(fp_poly, &pnt))
            return (FALSE);
    } while (ll_set_list_currpntr(p_polyline_list, TG_AFTER) == TG_AFTER);
    end_polyline(fp_poly);
    return (TRUE);

}

/* OK */
int             opt_flush_polyline(FILE * fp_poly, link_list_hdr * p_polyline_list,
                        double pnt_error_tollerance, double min_polyline_lenght)
{

    int             poly_num_pnts,
                    start_seq_index,
                    curr_index;
    double          prev_teta,
                    teta;
    link_list_hdr  *p_opt_polyline_list;
    img_point     **pp_poly_pnts;

    if ((poly_num_pnts = (int) ll_get_list_count(p_polyline_list)) < OPT_MIN_NUM_POLY_PNTS)
        return (flush_polyline(fp_poly, p_polyline_list, min_polyline_lenght));
    if ((pp_poly_pnts = (img_point **) malloc(poly_num_pnts * sizeof(img_point *))) == NULL)
        return (FALSE);
    if ((p_opt_polyline_list = ll_create_list()) == NULL)
    {
        free(pp_poly_pnts);
        return (FALSE);
    }
    poly_num_pnts = 0;
    ll_set_list_currpntr(p_polyline_list, TG_HEAD);
    do
    {
        void           *p_user_data_addr;

        if ((p_user_data_addr = ll_get_list_user_data_addr(p_polyline_list)) == NULL)
            break;
        pp_poly_pnts[poly_num_pnts++] = (img_point *) p_user_data_addr;
    } while (ll_set_list_currpntr(p_polyline_list, TG_AFTER) == TG_AFTER);
    if (!ll_add_list_data(p_opt_polyline_list, TG_TAIL, pp_poly_pnts[0]))
    {
        ll_empty_free_list(p_opt_polyline_list);
        free(pp_poly_pnts);
        return (FALSE);
    }
    teta = angle_value_xy((double) (pp_poly_pnts[1]->x - pp_poly_pnts[0]->x),
            (double) (pp_poly_pnts[1]->y - pp_poly_pnts[0]->y));
    for (curr_index = 1, start_seq_index = 0; curr_index < poly_num_pnts; curr_index++)
    {
        int             index;
        double          pnt_error = 0.0;
        imp_line_2d     ile;

        prev_teta = teta;
        teta = angle_value_xy(
                (double) (pp_poly_pnts[curr_index]->x - pp_poly_pnts[start_seq_index]->x),
                (double) (pp_poly_pnts[curr_index]->y - pp_poly_pnts[start_seq_index]->y));
        get_imp_line_eq_2d(pp_poly_pnts[start_seq_index], pp_poly_pnts[curr_index], &ile);
        for (index = start_seq_index + 1; index < curr_index; index++)
        {
            double          error = fabs(pnt_line_position(pp_poly_pnts[index], &ile));

            if (error > pnt_error)
                pnt_error = error;
        }
        if ((pnt_error < pnt_error_tollerance) && (fabs(teta - prev_teta) < TETA_TOLL))
            continue;
        if (!ll_add_list_data(p_opt_polyline_list, TG_TAIL, pp_poly_pnts[curr_index - 1]))
        {
            ll_empty_free_list(p_opt_polyline_list);
            free(pp_poly_pnts);
            return (FALSE);
        }
        start_seq_index = curr_index - 1;
        teta = angle_value_xy(
                (double) (pp_poly_pnts[curr_index]->x - pp_poly_pnts[start_seq_index]->x),
                (double) (pp_poly_pnts[curr_index]->y - pp_poly_pnts[start_seq_index]->y));
    }
    if (!ll_add_list_data(p_opt_polyline_list, TG_TAIL, pp_poly_pnts[curr_index - 1]))
    {
        ll_empty_free_list(p_opt_polyline_list);
        free(pp_poly_pnts);
        return (FALSE);
    }
    free(pp_poly_pnts);
    if (!flush_polyline(fp_poly, p_opt_polyline_list, min_polyline_lenght))
    {
        ll_empty_free_list(p_opt_polyline_list);
        return (FALSE);
    }
    ll_empty_free_list(p_opt_polyline_list);
    return (TRUE);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -